JavaFX: How to change the focus traversal policy?

后端 未结 10 1907
广开言路
广开言路 2020-11-30 04:34

Is it possible in JavaFX to change the focus traversal policy, like in AWT?

Because the traversal order for two of my HBoxes is wrong.

10条回答
  •  伪装坚强ぢ
    2020-11-30 05:34

    In common case the navigation is done in a container order, in order of children, or according to arrow keys pressing. You can change order of nodes - it will be the optimal solution for you in this situation.

    There is a back door in JFX about traversal engine strategy substitution :

    you can subclass the internal class com.sun.javafx.scene.traversal.TraversalEngine

    engine = new TraversalEngine(this, false) {
                @Override public void trav(Node owner, Direction dir) {
                    // do whatever you want
                }
            };
    

    And use

    setImpl_traversalEngine(engine); 
    

    call to apply that engine.

    You can observe the code of OpenJFX, to understand, how it works, and what you can do.

    Be very careful : it is an internal API, and it is likely to change, possibly, in the nearest future. So don't rely on this (you cannot rely on this officialy, anyway).

    Sample implementation :

    public void start(Stage stage) throws Exception {
        final VBox vb = new VBox();
    
        final Button button1 = new Button("Button 1");
        final Button button2 = new Button("Button 2");
        final Button button3 = new Button("Button 3");
    
        TraversalEngine engine = new TraversalEngine(vb, false) {
            @Override
            public void trav(Node node, Direction drctn) {
                int index = vb.getChildren().indexOf(node);
    
                switch (drctn) {
                    case DOWN:
                    case RIGHT:
                    case NEXT:
                        index++;
                        break;
                    case LEFT:
                    case PREVIOUS:
                    case UP:
                        index--;
                }
    
                if (index < 0) {
                    index = vb.getChildren().size() - 1;
                }
                index %= vb.getChildren().size();
    
                System.out.println("Select <" + index + ">");
    
                vb.getChildren().get(index).requestFocus();
            }
        };
    
        vb.setImpl_traversalEngine(engine);
    
        vb.getChildren().addAll(button1, button2, button3);
        Scene scene = new Scene(vb);
        stage.setScene(scene);
        stage.show();
    }
    

    It will require strong analitical skills for common case ;)

提交回复
热议问题