setFocusTraversable for a Node with children in JavaFX

1.4k views Asked by At

(My) expected behaviour:

When you call setFocusTraversable(false) on a Node with children (i.e. the Node has a method getChildren() that returns a List of Nodes) the focusTraversable properties of that node and all its children get the value false.

Actual behaviour:

However, when I call setFocusTraversable(false) on for example a TextFlow, its children are still being able to receive focus. This is illustrated in the code below.

Why does the setFocusTraversable(boolean) method work this way, and how should one work around this limitation?

// File: App.java
package nl.aronhoogeveen.bugreports;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;


/**
 * JavaFX App
 */
public class App extends Application {

    @Override
    public void start(Stage stage) {
        // TextFlow 1
        Text text1 = new Text("This is text1");
        Hyperlink hyperlink1 = new Hyperlink("This is hyperlink1");
        Text text2 = new Text("This is text2");
        Hyperlink hyperlink2 = new Hyperlink("This is hyperlink2");

        TextFlow textFlow1 = new TextFlow(text1, hyperlink1, text2, hyperlink2);
        textFlow1.setFocusTraversable(false);

        // TextFlow 2 (CustomTextFlow)
        Text text3 = new Text("This is text3");
        Hyperlink hyperlink3 = new Hyperlink("This is hyperlink3");
        Text text4 = new Text("This is text4");
        Hyperlink hyperlink4 = new Hyperlink("This is SPARTAAAAA");

        CustomTextFlow textFlow2 = new CustomTextFlow(text3, hyperlink3, text4, hyperlink4);
        textFlow2.customSetFocusTraversable(false);

        BorderPane rootBorderPane = new BorderPane();
        rootBorderPane.setTop(textFlow1);
        rootBorderPane.setBottom(textFlow2);
        stage.setScene(new Scene(rootBorderPane));
        stage.sizeToScene();
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}
// File: CustomTextFlow.java
package nl.aronhoogeveen.bugreports;

import javafx.scene.Node;
import javafx.scene.text.TextFlow;

public class CustomTextFlow extends TextFlow {
    public CustomTextFlow(Node... children) {
        super(children);
    }

    /**
     * Sets the property focusTraversable of all children's children to {@code b}.
     *
     * @param b the value to set for the properties
     */
    public void customSetFocusTraversable(boolean b) {
        for (Node child : getChildren()) {
            // Assume for simplicity that the children are not Parents or other types that have children
            child.setFocusTraversable(b);
        }
    }
}

I filed a bug on the ControlsFX component HyperlinkLabel regarding this behaviour, and after investigating I discovered that this behaviour was already present in the JavaFX TextFlow component that is used by the HyperlinkLabel and therefore I am posting this question.

0

There are 0 answers