JavaFX: How to change the focus traversal policy?

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

    You can use NodeName.requestFocus() as said above; furthermore, make sure you request this focus after instantiating and adding all of your nodes for the root layout, because as you do so, the focus will be changing.

    0 讨论(0)
  • 2020-11-30 05:15

    In scene builder go to the view menu and select show document. on the left will be all objects in your current fxml document. drag controls up or down in the list to reorder for tab index. Select hide document to use the other tools since the document pane hogs the space.

    0 讨论(0)
  • 2020-11-30 05:16

    I used Eventfilter as solution in combination with referencing the field ID's, so all you have to do is name the fields like (field1,field2,field3,field4) so you can place the fields where u want:

    mainScene.addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
            if(event.getCode().equals(KeyCode.TAB)){
                event.consume();
                final Node node =  mainScene.lookup("#field"+focusNumber);
                if(node!=null){
                    node.requestFocus();
                }
                focusNumber ++;
                if(focusNumber>11){
                  focusNumber=1;
                }
            }
        }); 
    
    0 讨论(0)
  • 2020-11-30 05:24

    I had a problem in which a JavaFX Slider was capturing right and left arrow keystrokes that I wanted to be handled by my method keyEventHandler (which handled key events for the Scene). What worked for me was to add the following line to the code that initialized the Slider:

    slider.setOnKeyPressed(keyEventHandler);
    

    and to add

    keyEvent.consume();
    

    at the end of keyEventHandler.

    0 讨论(0)
  • 2020-11-30 05:27

    Bluehair's answer is right, but you can do this even in JavaFX Scene Builder.

    You have Hierarchy panel in left column. There are all your components from scene. Their order represents focus traversal order and it responds to their order in FXML file.

    I found this tip on this webpage:www.wobblycogs.co.uk

    0 讨论(0)
  • 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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题