我有一个复杂且重的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方法有许多同步块、互斥对象等,我认为可能会出现一些死锁。
有更好的机制建议或想法吗?我知道最好的解决方案是检查当前应用程序,分析它或重写它。但是这很复杂,而且模型和视图没有很好地组织起来。因为客户正在等待,所以我需要一些临时解决方案、技巧或黑科技。