java - 焦点所有者临时更改为空

标签 java swing focus

我是 Swing 开发的新手,希望我的问题不是一个愚蠢的问题。

我遇到了以下问题。我正在使用 KeyboardFocusManager 跟踪焦点,监听属性 permanentFocusOwner 的变化。但是,当焦点从一个控件更改为另一个控件时,我将 permanentFocusOwner 属性中间更改为 null

当焦点位于其中一个面板或其子面板内时,我当前的 UI 逻辑正在对控件进行一些更改。然而,获得中间 null 打破了这个逻辑。

我在 Google 中搜索了有关此问题的信息,但没有找到任何相关信息。

问题是,这种行为是否是设计使然,以及是否有某种方法可以解决中间空值。

这是重现上述行为的最小应用程序:

import java.awt.*;
import java.beans.*;
import javax.swing.*;

public class FocusNullTest extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                FocusNullTest self = new FocusNullTest();
                self.setVisible(true);
            }
        });
    }

    public FocusNullTest() {
        setSize(150, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container contentPane = getContentPane(); 
        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));

        contentPane.add(new JButton("1"));
        contentPane.add(new JButton("2"));

        KeyboardFocusManager focusManager =
            KeyboardFocusManager.getCurrentKeyboardFocusManager();
        focusManager.addPropertyChangeListener(
                "permanentFocusOwner",
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent e) {
                        System.out.println("permanentFocusOwner changed from: "
                                           + e.getOldValue());
                        System.out.println("permanentFocusOwner changed to  : "
                                           + e.getNewValue());
                    }
                });
    }
}

日志输出为:

(program start, focus sets to button 1 automatically)
permanentFocusOwner changed from: null
permanentFocusOwner changed to : javax.swing.JButton[,0,18,41x26, (skipped)]
(clicked on button 2)
permanentFocusOwner changed from: javax.swing.JButton[,0,18,41x26, (skipped)]
permanentFocusOwner changed to : null
permanentFocusOwner changed from: null
permanentFocusOwner changed to : javax.swing.JButton[,41,18,41x26, (skipped)]


(可选部分,关于代码意图)
我的目标是制作一些看起来像 ListView 的东西,其中的条目在获得焦点时展开并显示更多信息(并在失去焦点时折叠起来)。展开的 View 包含一些额外的按钮。

JList 似乎不是合适的控件,因为 (1) 它不允许点击按钮,并且 (2) 它的条目具有恒定高度,而我想要条目在焦点上动态扩展。 JTable 及其编辑模式似乎也不是合适的解决方案,至少因为条目大小不变。

所以我使用带有垂直框布局的普通 JPanel 作为容器,并订阅模型更改并手动更新视觉效果。问题是当我点击一个按钮时,包含的列表项失去了焦点。如果焦点暂时不会更改为 null,我可以检测到焦点仍停留在列表项中。

最佳答案

KeyboardFocusManager 正在为大多数属性触发两个事件(根据 beans 规范,它不应该 - 从未发现原因,只是猜测焦点的异步性质可能是原因)

   firePropertyChange(someProperty, oldValue, null)
   firePropertyChange(someProperty, null, newValue)

要根据 newVaue 做事,等待第二个

关于java - 焦点所有者临时更改为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7372296/

相关文章:

java - JTable单元格中,如何正确处理多个超链接?

java - 使组件对 Swing 中的拖动不太敏感

windows - 当窗口失去焦点或调整大小时如何阻止 OpenGL 暂停?

java - 标准控制台输入

java - eclipse 警告 : Unknown Faceted Project

java - Hadoop MapReduce 作业在本地无法加载库并且在 OS X 上连接失败

java - 是否可以将 JComponent 默认设置为不可聚焦?

java - 从 servlet 访问 WebContent 文件夹中的文件

java - 我的第二个 JPanel 去哪里了?

java - 获取 ID,Selenium 中当前关注的元素的类