我是 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/