Swing焦点问题:失去焦点,未触发焦点获取

5

我有一个复杂且重的Swing客户端应用程序,其中包含许多模态组件、JDialogs、内部框架等。在某些情况下,出现问题后就不可能再聚焦于Swing文本字段了。您可能会单击某些JButtons、JCheckBoxes,但无法再聚焦和编辑可编辑的JTextFields中的值。可编辑文本字段的gainfocus事件不再触发,只有在单击文本字段时才调用requestfocus方法。

我找到了一种解决问题的方式(即hack),当出现问题时,您显示一些joptionpane消息或模态jdialog,并通过单击或处理它来关闭,问题就会消失,您可以单击文本字段并对其进行编辑。

作为解决方案,如果您尝试聚焦于组件,我会在单击文本字段的requestfocus事件中启动一个计时器线程,并将实例保留为focusrequesting组件。过一段时间后,我通过

KeyboardManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner()

检查最后一个聚焦的组件。如果没有出现问题,而文本字段获得了焦点,则返回的对象(即getPermanentFocusOwner的返回值)与focusrequesting组件是相同的实例。但如果出现问题,返回的对象与请求焦点的组件不同,我会打开我的临时jdialog:

JDialog dialog=new OptionPane().createDialog(KeyboardFocusManager.getCurrentFocusManager().getActiveWindow(), "");
dialog.setModal(true); 
// MUST be modal to fix the lost focus case
// start closing thread, which closes the dialog after some few time by dialog.dispose
new Closer(dialog).start();
dialog.setVisible(true);

这种机制可以工作,但并不是非常稳定。在某些情况下,dialog.dispose()无法正常工作,暂时的窗口仍然停留在屏幕上,无法关闭,并且由于它是模态的,客户端不能再执行任何操作。对话框必须是模态的才能解决焦点问题,因为非模态对话框无法解决上述声明的焦点问题。jdialog的dispose方法有许多同步块、互斥对象等,我认为可能会出现一些死锁。

有更好的机制建议或想法吗?我知道最好的解决方案是检查当前应用程序,分析它或重写它。但是这很复杂,而且模型和视图没有很好地组织起来。因为客户正在等待,所以我需要一些临时解决方案、技巧或黑科技。

1个回答

3

您可以单击某些jbutton、jcheckbox,但是不再能够聚焦和编辑可编辑的jtextfields。

  • 这是在没有父级(JFrame)的JWindow中使用JTextField时的常见问题,最好使用无边框的JDialog

  • 我在这里看到了一些关于Linux OS上的FocusFocusSubsystem的问题,使用最新的Java版本,但从未导致阻止用户输入到JTextField

  • 对于上述问题,最好的解决方法是由@camickr提供的RequestFocusListener

  • dialog.setVisible(true);应该包含在invokeLater()中,更多信息请参见Initial Thread (valid for all Top-Level Containers created on runtime too)

  • 如果没有发布一个SSCCE,短小、可运行、可编译、演示、引起上述问题,你的问题就不清楚。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接