Reputation: 1083
The following code produces a JFrame
containing a JFXPanel
and a JPanel
. Each of the panels contains a text field.
JFXPanel fxPanel = new JFXPanel();
JPanel swingPanel = new JPanel(new FlowLayout());
swingPanel.add(new JTextField("Swing"));
JPanel contentPanel = new JPanel(new BorderLayout());
contentPanel.add(fxPanel, BorderLayout.PAGE_START);
contentPanel.add(swingPanel, BorderLayout.CENTER);
JFrame frame = new JFrame("Main Frame");
frame.setContentPane(contentPanel);
FlowPane root = new FlowPane();
root.getChildren().add(new TextField("FX"));
Scene scene = new Scene(root);
Platform.runLater(() -> fxPanel.setScene(scene));
SwingUtilities.invokeLater(() -> frame.setVisible(true));
Suppose we start with the Swing text field focused. Then suppose I click inside the JFXPanel
(but not within the bounds of its text field). The JFXPanel
gives focus to the TextField
.
Why does this happen? Why does the JFXPanel not keep its own focus? Why does it give it to the text field? How does it choose which of its components to give focus to? What is the correct way to prevent it giving its focus to the text field?
Upvotes: 1
Views: 251
Reputation: 21799
The reason is the Scene
of the JFXPanel
and more closely its focusOwnerProperty.
When the Scene
is created, it gives the focus to the Node
stored in this property.
This is because of the TextField
is the only Node
in the scene-graph, which is focus traversable:
Specifies whether this Node should be a part of focus traversal cycle. When this property is true focus can be moved to this Node and from this Node using regular focus traversal keys. On a desktop such keys are usually TAB for moving focus forward and SHIFT+TAB for moving focus backward. When a Scene is created, the system gives focus to a Node whose focusTraversable variable is true and that is eligible to receive the focus, unless the focus had been set explicitly via a call to requestFocus().
As a solution you can add the following
Platform.runLater(() -> {
root.setOnMouseClicked(e -> root.requestFocus());
});
This will focus the FlowPane
on click.
Upvotes: 1