java - 如何在 Java 中使用 Swing JSpinner 的焦点事件?
问题描述
我正在使用 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:接下来我删除了 Class 级别的 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 行。这清除了我刚刚设置的监听器。我将这两行移到了设置侦听器之前,现在以下两组代码都适用于我。
使用焦点适配器:
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);
};
});
我怀疑但没有尝试过,如果我在附加监听器之前也将这两行移到了我尝试的第一种方法(在我上面的原始问题中)也可以工作。
推荐阅读
- python - 将变量导出到第二个脚本的函数并在第一个脚本中运行该函数
- javascript - Redux 减速器参考
- visual-studio-code - 我在cmd窗口中使用了命令(代码。-r),但是-r是什么意思?(vscode)
- java - 正则表达式将第一个从“/token1/token2/token3”中拆分出来
- reactjs - 测试全栈 Apollo React 应用程序的建议?(即 Apollo Server BE;CRA + Apollo Client FE)
- spring - 基于 Kotlin 的 Spring RabbitListener 产生无限循环,试图发回 `kotlin.Unit`
- firebase - 如何在列表视图构建器中显示 3 个文本小部件?
- python - 相应地更新显示以使每帧产生函数
- arduino - Esp32 csi 转 rssi
- linux - OpenSSL 编译版本与安装版本不匹配?