focusFX

Focus Manager for JavaFX

License

License

GroupId

GroupId

de.saxsys
ArtifactId

ArtifactId

focusfx
Last Version

Last Version

0.1
Release Date

Release Date

Type

Type

jar
Description

Description

focusFX
Focus Manager for JavaFX
Project Organization

Project Organization

Saxonia Systems AG
Source Code Management

Source Code Management

https://github.com/sialcasa/focusFX

Download focusfx

How to add to project

<!-- https://jarcasting.com/artifacts/de.saxsys/focusfx/ -->
<dependency>
    <groupId>de.saxsys</groupId>
    <artifactId>focusfx</artifactId>
    <version>0.1</version>
</dependency>
// https://jarcasting.com/artifacts/de.saxsys/focusfx/
implementation 'de.saxsys:focusfx:0.1'
// https://jarcasting.com/artifacts/de.saxsys/focusfx/
implementation ("de.saxsys:focusfx:0.1")
'de.saxsys:focusfx:jar:0.1'
<dependency org="de.saxsys" name="focusfx" rev="0.1">
  <artifact name="focusfx" type="jar" />
</dependency>
@Grapes(
@Grab(group='de.saxsys', module='focusfx', version='0.1')
)
libraryDependencies += "de.saxsys" % "focusfx" % "0.1"
[de.saxsys/focusfx "0.1"]

Dependencies

test (3)

Group / Artifact Type Version
junit : junit jar 4.11
org.testfx : testfx-core jar 4.0.1-alpha
org.testfx : testfx-junit jar 4.0.1-alpha

Project Modules

There are no modules declared in this project.

FocusManager for JavaFX

First implementation of a FocusManager for JavaFX. Feedback is welcome in the issuetracker. Please file enhancement requests for your use-cases.

Currently I'm working on the API which is based on the java.awt.FocusTraversalPolicy.

The default implementation has a very basic behavior: DefaultFocusTraversalPolicy. You can use it by calling FXFocusManager.applyDefaultPolicy.

Build Status Hex.pm

###Maven dependency (Sonatype Snapshot Repo)###

<dependency>
		<groupId>de.saxsys</groupId>
		<artifactId>focusfx</artifactId>
		<version>0.2-SNAPSHOT</version>
</dependency>

###Usage of the DefaultFocusTraversalPolicy###

public class FocusExample extends Application {
	

	@Override
	public void start(Stage primaryStage) throws Exception {
				tf1 = new TextField("1");
		TextField tf2 = new TextField("2");
		TextField tf3 = new TextField("3");
		TextField tf4 = new TextField("4");
		TextField tf5 = new TextField("5");
		VBox vbox1 = new VBox(tf1, tf2, tf3, tf4, tf5);
		FocusFX.applyDefaultPolicy(vbox1, FXCollections.observableArrayList(tf5, tf3, tf2, tf4));
		
		TextField tf6 = new TextField("6");
		TextField tf7 = new TextField("7");
		TextField tf8 = new TextField("8");
		TextField tf9 = new TextField("9");
		TextField tf10 = new TextField("10");
		VBox vbox2 = new VBox(tf6, tf7, tf8, tf9, tf10);
		
		ObservableList<Node> nodesToFocus = FXCollections.observableArrayList(tf6, tf7, tf8, tf9);
		FocusFX.applyDefaultPolicy(vbox2, nodesToFocus);
		
		// Is not in traversal chaing, because it was not added to the nodesToFocus list
		TextField tf10a = new TextField("10");
		vbox2.getChildren().add(tf10a);
		
		TextField tf11 = new TextField("11");
		TextField tf12 = new TextField("12");
		TextField tf13 = new TextField("13");
		TextField tf14 = new TextField("14");
		TextField tf15 = new TextField("15");
		VBox vbox3 = new VBox(tf11, tf12, tf13, tf14, tf15);
		
		FocusFX.applyDefaultPolicy(vbox3, vbox3.getChildren());
		
		// Is also in traversal cycle, because setAllChildrenFocusTraversalEnabled was called
		TextField tf16 = new TextField("16");
		vbox3.getChildren().add(tf16);
		
		FocusFX.setParentTraversalChain(vbox1, vbox3, vbox2);		
		primaryStage.setScene(new Scene(new VBox(vbox1, vbox2, vbox3)));
		primaryStage.show();
	}	
}

Implement own FocusTraversalPolicy###

	@Override
	public void start(Stage primaryStage) throws Exception {
		
		FocusTraversalPolicy focusTraversalPolicy1 = new FocusTraversalPolicy() {
			
			@Override
			public Node getNodeBefore(Parent aContainer, Node aNode) {
				Node focusOwner = vbox1.getScene().getFocusOwner();
				ObservableList<Node> children = vbox1.getChildren();
				int indexOfFocusOwner = children.indexOf(focusOwner);
				return children
						.get(indexOfFocusOwner == 0 ? children.size() - 1
								: indexOfFocusOwner - 1);
			}
			
			@Override
			public Node getNodeAfter(Parent aContainer, Node aNode) {
				Node focusOwner = vbox1.getScene().getFocusOwner();
				ObservableList<Node> children = vbox1.getChildren();
				int indexOfFocusOwner = children.indexOf(focusOwner);
				
				//Skip second TextField				
				if (indexOfFocusOwner == 0) {
					return vbox1.getChildren().get(2);
				}
				
				if (indexOfFocusOwner == children.size() - 1) {
					return null; //Exit this Focus Cycle and move to unmanaged Node with Focus
				}
				
				return vbox1.getChildren().get(indexOfFocusOwner + 1);
			}
			
			@Override
			public Node getLastNode(Parent aContainer) {
				return vbox1.getChildren().get(vbox1.getChildren().size() - 1);
			}
			
			@Override
			public Node getFirstNode(Parent aContainer) {
				return vbox1.getChildren().get(0);
			}
			
			@Override
			public Node getDefaultNode(Parent aContainer) {
				return vbox1.getChildren().get(0);
			}
		};
		
		FocusTraversalPolicy focusTraversalPolicy2 = new FocusTraversalPolicy() {
			
			
			@Override
			public Node getNodeBefore(Parent aContainer, Node aNode) {
				Node focusOwner = vbox2.getScene().getFocusOwner();
				ObservableList<Node> children = vbox2.getChildren();
				int indexOfFocusOwner = children.indexOf(focusOwner);
				
				if (indexOfFocusOwner == 0) {
					return null; // Exit Focus Cycle
				}
				
				return children
						.get(indexOfFocusOwner - 1);
			}
			
			@Override
			public Node getNodeAfter(Parent aContainer, Node aNode) {
				Node focusOwner = vbox2.getScene().getFocusOwner();
				ObservableList<Node> children = vbox2.getChildren();
				int indexOfFocusOwner = children.indexOf(focusOwner);
				
				if (indexOfFocusOwner == children.size() - 1) {
					//Exit this Focus Cycle and move to unmanaged Node with Focus
					return null;
				}
				
				return vbox2.getChildren().get(indexOfFocusOwner + 1);
			}
			
			@Override
			public Node getLastNode(Parent aContainer) {
				return vbox2.getChildren().get(0);
			}
			
			@Override
			public Node getFirstNode(Parent aContainer) {
				return vbox2.getChildren().get(vbox1.getChildren().size() - 1);
			}
			
			@Override
			public Node getDefaultNode(Parent aContainer) {
				return vbox2.getChildren().get(0);
			}
		};
		
		
		TextField tf1 = new TextField("1");
		TextField tf2 = new TextField("2");
		TextField tf3 = new TextField("3");
		TextField tf4 = new TextField("4");
		TextField tf5 = new TextField("5");
		VBox vbox1 = new VBox(tf1, tf2, tf3, tf4, tf5);
		
		FocusFX.applyFocusTraversalPolicy(focusTraversalPolicy1, vbox1, vbox1.getChildren(),
				FXCollections.observableArrayList(EventTuple.TAB_FORWARD),
				FXCollections.observableArrayList(EventTuple.SHIFT_TAB_BACKWARDS));
				
				
		TextField tf6 = new TextField("6");
		TextField tf7 = new TextField("7");
		TextField tf8 = new TextField("8");
		TextField tf9 = new TextField("9");
		TextField tf10 = new TextField("10");
		VBox vbox2 = new VBox(tf6, tf7, tf8, tf9, tf10);
		
		FocusFX.applyFocusTraversalPolicy(focusTraversalPolicy2, vbox2, vbox2.getChildren(),
				FXCollections.observableArrayList(EventTuple.TAB_FORWARD),
				FXCollections.observableArrayList(EventTuple.SHIFT_TAB_BACKWARDS));
				
		TextField unmanaged1 = new TextField("unmanaged1");
		TextField unmanaged2 = new TextField("unmanaged2");
		
		primaryStage.setScene(new Scene(new VBox(vbox1, unmanaged1, unmanaged2, vbox2)));
		primaryStage.show();
	}

Versions

Version
0.1