【发布时间】:2011-09-10 14:13:36
【问题描述】:
我是 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());
}
});
}
}
日志输出为:
(程序开始,焦点自动设置到按钮 1)
PermanentFocusOwner 更改自:null
PermanentFocusOwner 更改为:javax.swing.JButton[,0,18,41x26,(跳过)]
(点击按钮 2)
PermanentFocusOwner 更改自:javax.swing.JButton[,0,18,41x26,(已跳过)]
permanentFocusOwner 更改为:null
permanentFocusOwner 更改自:null
PermanentFocusOwner 改为:javax.swing.JButton[,41,18,41x26, (skipped)]
(可选部分,关于代码意图)
我的目标是制作看起来像列表视图的东西,其中条目在获得焦点时展开并显示更多信息(并在失去焦点时折叠回来)。展开的视图包含一些额外的按钮。
JList 似乎不是合适的控件,因为(1)它不允许点击按钮,(2)它的条目具有恒定的高度,而我希望条目在焦点上动态扩展. JTable 及其编辑模式似乎也不是一个合适的解决方案,至少因为条目大小不变。
所以我使用带有垂直框布局的普通JPanel 作为容器,并订阅模型更改并手动更新视觉效果。问题是当我单击一个按钮时,包含的列表项会失去焦点。如果焦点不会暂时更改为null,我可以检测到焦点仍保留在列表项中。
【问题讨论】:
-
+1 表示sscce,但有关目标的更多详细信息可能会为更好的解决方案提供信息。
-
@trashgod:添加了一些关于代码意图的细节