问题描述
我正在使用 NetBeans 创建桌面 Java 应用程序(只是为了好玩和扩展知识)。我在面板中有一个微调器(和一个按钮),我需要检测微调器何时失去焦点。我已经尝试了几件事,但没有任何东西会为 Spinner 触发 focusGained 或 focusLost。我怎样才能让它工作?
我尝试过的:
尝试 1: 我尝试在类级别使用“实现 FocusListener”,然后按如下方式覆盖 focusGained 和 focusLost 事件。
@Override
public void focusGained(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus gained : " + name);
}
@Override
public void focusLost(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus lost : " + name);
}
我添加了如下监听器。我一开始只有注释掉的行。这对按钮非常有效,但 Spinner 在单击它时从未触发任何一个事件,更改它,然后单击它到按钮。然后我尝试注释掉该行并添加下面的行以尝试使用底层 TextField。这再次不起作用。
jButton1.addFocusListener(this);
//jSpinner1.addFocusListener(this);
((JSpinner.DefaultEditor)jSpinner1.getEditor()).getTextField().addFocusListener(this);
尝试 2: 接下来,我删除了类级别的 FocusListener 并尝试构建一个新的内联,如下所示。我再次尝试首先直接在 Spinner 上构建它,当这不起作用时,我尝试在底层 TextField 上构建它。同样,这两个事件都没有触发。
//jSpinner1.addFocusListener(new FocusListener() {
((JSpinner.DefaultEditor)jSpinner1.getEditor()).getTextField().addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus gained : " + name);
};
@Override
public void focusLost(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus lost : " + name);
};
});
尝试 3: 最后,我尝试构建一个单独的 focusAdapter,如下所示。我再次尝试先将它直接附加到 Spinner,然后再附加到底层的 TextField,但同样没有触发任何事件。
FocusAdapter focusAdapter = new FocusAdapter()
{
public void focusGained(FocusEvent e)
{
String name = e.getComponent().getClass().getName();
System.out.println("Focus gained : " + name);
}
public void focusLost(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus lost : " + name);
};
};
//jSpinner1.addFocusListener(focusAdapter);
((JSpinner.DefaultEditor)jSpinner1.getEditor()).getTextField().addFocusListener(focusAdapter);
我要补充一点,我已经尝试同时使用 AdoptOpenJDK jdk-11.0.11.9-hotspot 和 Oracle OpenJDK jdk-16.0.1,只是想看看这是否会有所作为。两者结果相同。
我还应该补充一点,我已确保 Spinner 的“focusable”属性和“requestFocusEnabled”属性都设置为“true”。
我完全不知所措。所有 3 种方法都应该适用于其他非 Spinner 组件。焦点是被 Spinners 打断了还是我遗漏了什么?
解决方法
感谢@MadProgrammer 的提示,我有了答案。我在下面设置监听器的地方有 DateEditor 和 setEditor 行。这正在清除我刚刚设置的监听器。我在设置 Listener 之前将这两行移到了,现在以下两组代码都适用于我。
使用 FocusAdapter:
JSpinner.DateEditor de = new JSpinner.DateEditor(jSpinner1,"h:mm:ss a");
jSpinner1.setEditor(de);
FocusAdapter focusAdapter = new FocusAdapter()
{
public void focusGained(final FocusEvent e)
{
String name = e.getComponent().getClass().getName();
System.out.println("Focus gained : " + name);
}
public void focusLost(final FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus lost : " + name);
};
};
((JSpinner.DefaultEditor)jSpinner1.getEditor()).getTextField().addFocusListener(focusAdapter);
使用内联侦听器:
((JSpinner.DefaultEditor)jSpinner1.getEditor()).getTextField().addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus gained : " + name);
};
@Override
public void focusLost(FocusEvent e) {
String name = e.getComponent().getClass().getName();
System.out.println("Focus lost : " + name);
};
});
我怀疑但没有尝试过,如果我在附加监听器之前也将这两行移到,我尝试的第一种方法(在我上面的原始问题中)也将起作用。