【问题标题】:Why is JFXPanel giving focus to TextField为什么 JFXPanel 将重点放在 TextField
【发布时间】:2023-03-04 06:32:02
【问题描述】:

以下代码生成一个JFrame,其中包含一个JFXPanel 和一个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 不保持自己的焦点?为什么将它提供给文本字段?它如何选择要关注的组件?防止它把焦点放在文本字段上的正确方法是什么?

【问题讨论】:

    标签: java swing javafx javafx-8 jfxpanel


    【解决方案1】:

    原因是JFXPanelScene,更接近的是focusOwnerProperty

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

    这是因为TextField 是场景图中唯一的Node,即focus traversable

    指定此节点是否应成为焦点遍历循环的一部分。 当此属性为 true 时,焦点可以移动到此节点并从 此节点使用常规焦点遍历键。在桌面上这样的键 通常是 TAB 用于向前移动焦点,SHIFT+TAB 用于移动 重点向后。 创建场景时,系统会将焦点放在 其 focusTraversable 变量为 true 且符合条件的节点 接收焦点,除非焦点已通过调用明确设置 到 requestFocus()。

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

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

    这将使FlowPane 聚焦在点击上。

    【讨论】:

    • 那么,调用root.setFocusTraversable(true); 会导致 OP 想要的行为吗?
    • @James_D,不幸的是没有。
    • 那么焦点可遍历的解释是假的,否则这种方法有什么问题?
    • 解释不假。如果将TextField 的focusTraversable 属性设置为false,则默认情况下它不会成为焦点。我想关键在于文档的“并且有资格获得焦点”部分。
    猜你喜欢
    • 1970-01-01
    • 2020-07-04
    • 2011-10-06
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 2012-04-02
    • 2013-12-14
    相关资源
    最近更新 更多