1

以下代码生成JFrame包含 aJFXPanel和 a 的 a JPanel。每个面板都包含一个文本字段。

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 不保持自己的焦点?为什么将它提供给文本字段?它如何选择要关注的组件?防止它把焦点放在文本字段的正确方法是什么?

4

1 回答 1

1

原因是它ScenefocusOwnerPropertyJFXPanel

创建Scene时,它会将焦点赋予Node存储在此属性中的对象。

这是因为是场景图中TextField唯一的,它是焦点可遍历的:Node

指定此节点是否应成为焦点遍历循环的一部分。当此属性为 true 时,可以使用常规焦点遍历键将焦点移动到该节点并从该节点移动。在桌面上,这些键通常是用于向前移动焦点的 TAB 和用于向后移动焦点的 SHIFT+TAB。创建场景时,系统将焦点分配给其 focusTraversable 变量为 true 且有资格接收焦点的节点,除非已通过调用 requestFocus() 显式设置焦点。

作为解决方案,您可以添加以下内容

Platform.runLater(() -> {
    root.setOnMouseClicked(e -> root.requestFocus());
});

这将专注FlowPane于点击。

于 2016-07-18T14:22:16.320 回答