为什么 JFXPanel 将重点放在 TextField 上
Why is JFXPanel giving focus to TextField
以下代码生成包含 JFXPanel
和 JPanel
的 JFrame
。每个面板都包含一个文本字段。
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));
假设我们从聚焦 Swing 文本字段开始。然后假设我在 JFXPanel
内部单击(但不在其文本字段的范围内)。 JFXPanel
将焦点放在 TextField
。
为什么会这样?为什么 JFXPanel 不保持自己的焦点?为什么将它提供给文本字段?它如何选择要关注的组件?防止它把焦点放在文本字段上的正确方法是什么?
原因是 JFXPanel
的 Scene
更接近 focusOwnerProperty。
创建 Scene
时,它会将焦点赋予存储在此 属性 中的 Node
。
这是因为TextField
是scene-graph中唯一的Node
,即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().
作为解决方案,您可以添加以下内容
Platform.runLater(() -> {
root.setOnMouseClicked(e -> root.requestFocus());
});
这将使 FlowPane
集中在点击上。
以下代码生成包含 JFXPanel
和 JPanel
的 JFrame
。每个面板都包含一个文本字段。
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));
假设我们从聚焦 Swing 文本字段开始。然后假设我在 JFXPanel
内部单击(但不在其文本字段的范围内)。 JFXPanel
将焦点放在 TextField
。
为什么会这样?为什么 JFXPanel 不保持自己的焦点?为什么将它提供给文本字段?它如何选择要关注的组件?防止它把焦点放在文本字段上的正确方法是什么?
原因是 JFXPanel
的 Scene
更接近 focusOwnerProperty。
创建 Scene
时,它会将焦点赋予存储在此 属性 中的 Node
。
这是因为TextField
是scene-graph中唯一的Node
,即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().
作为解决方案,您可以添加以下内容
Platform.runLater(() -> {
root.setOnMouseClicked(e -> root.requestFocus());
});
这将使 FlowPane
集中在点击上。