Focus on the next item in the container

Is there a way to programmatically focus on the next custom node in the container without directly invoking a specific requestFocus()method component ? This feature will be similar to pressing a tab button to move focus between components where nodes are skipped disabled.

+4
source share
3 answers

There is no public method for this. Only hacks and workarounds.

You can use node

impl_traverse(Direction.NEXT);

method. But this option is deprecated and can be deleted at any time, and your code is broken into a new version of java.

. .

, , :

if( textfield.getSkin() instanceof BehaviorSkinBase) {
    ((BehaviorSkinBase) textfield.getSkin()).getBehavior().traverseNext();  
}

, api.

:

Method[] allMethods = scene.getClass().getDeclaredMethods();
for (Method m : allMethods) {
    String mname = m.getName();
    if (mname.startsWith("traverse")) {
        m.setAccessible(true);
        m.invoke(scene, new Object[] { textfield, Direction.NEXT });
    }
}

Direction, .

, , .

+7

Enter Tab :

@Override
public void start( final Stage primaryStage )
{
    TextField field1 = new TextField();
    TextField field2 = new TextField();
    TextField field3 = new TextField();
    VBox vbox = new VBox( field1, field2, field3 );

    vbox.addEventFilter( KeyEvent.KEY_PRESSED, ( KeyEvent event ) ->
    {
        if ( event.getCode() == KeyCode.ENTER )
        {
            KeyEvent newEvent
                    = new KeyEvent(
                            null,
                            null,
                            KeyEvent.KEY_PRESSED,
                            "",
                            "\t",
                            KeyCode.TAB,
                            event.isShiftDown(),
                            event.isControlDown(),
                            event.isAltDown(),
                            event.isMetaDown()
                    );

            Event.fireEvent( event.getTarget(), newEvent );
            event.consume();
        }
    } );
    final Scene scene = new Scene( vbox, 800, 600 );
    primaryStage.setScene( scene );
    primaryStage.show();

}
+4

, , , .

(: TextFields, setOnAction ENTER):

textField.setOnAction((ActionEvent e) -> {
    boolean isThisField = false;
    for (Node child : textField.getParent().getChildrenUnmodifiable()) {
        if (isThisField) {

            //This code will only execute after the current Node
            if (child.isFocusTraversable() && !child.isDisabled()) {
                child.requestFocus();

                //Reset check to prevent later Node from pulling focus
                isThisField = false;
            }
        } else {

            //Check if this is the current Node
            isThisField = child.equals(textField);
        }
    }

    //Check if current Node still has focus
    boolean focusChanged = !textField.isFocused();
    if (!focusChanged) {
        for (Node child : textField.getParent().getChildrenUnmodifiable()) {
            if (!focusChanged && child.isFocusTraversable() && !child.isDisabled()) {
                child.requestFocus();

                //Update to prevent later Node from pulling focus
                focusChanged = true
            }
        }
    }
});
0
source

All Articles