JavaFX: How to change the focus traversal policy?

后端 未结 10 1906
广开言路
广开言路 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:29

    This is the accepted answer adapted to change of internal api (happened at some point of fx-8, my current version is 8u60b5). Obviously the original disclaimer still applies: it's internal api, open to change without notice at any time!

    The changes (compared to the accepted answer)

    • Parent needs a TraversalEngine of type ParentTraversalEngine
    • nav is no longer a method of TraversalEngine (nor ParentTE) but only of TopLevelTraversalEngine
    • the navigation implementation is delegated to strategy called Algorithm
    • actual focus transfer is (seems to be?) handled by TopLevelTE, Algorithm only finds and returns the new target

    The plain translation of the example code:

    /**
     * Requirement: configure focus traversal
     * old question with old hack (using internal api):
     * http://stackoverflow.com/q/15238928/203657
     * 
     * New question (closed as duplicate by ... me ..)
     * http://stackoverflow.com/q/30094080/203657
     * Old hack doesn't work, change of internal api
     * rewritten to new internal (sic!) api
     * 
     */
    public class FocusTraversal extends Application {
    
        private Parent getContent() {
            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");
    
            Algorithm algo = new Algorithm() {
    
                @Override
                public Node select(Node node, Direction dir,
                        TraversalContext context) {
                    Node next = trav(node, dir);
                    return next;
                }
    
                /**
                 * Just for fun: implemented to invers reaction
                 */
                private Node trav(Node node, Direction drctn) {
                    int index = vb.getChildren().indexOf(node);
    
                    switch (drctn) {
                        case DOWN:
                        case RIGHT:
                        case NEXT:
                        case NEXT_IN_LINE:    
                            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 + ">");
    
                    return vb.getChildren().get(index);
                }
    
                @Override
                public Node selectFirst(TraversalContext context) {
                    return vb.getChildren().get(0);
                }
    
                @Override
                public Node selectLast(TraversalContext context) {
                    return vb.getChildren().get(vb.getChildren().size() - 1);
                }
    
            };
            ParentTraversalEngine engine = new ParentTraversalEngine(vb, algo);
            // internal api in fx8
            // vb.setImpl_traversalEngine(engine);
            // internal api since fx9
            ParentHelper.setTraversalEngine(vb, engine);
            vb.getChildren().addAll(button1, button2, button3);
            return vb;
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            primaryStage.setScene(new Scene(getContent()));
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

提交回复
热议问题