好的,所以这是我们在公司的应用程序中遇到的一个非常非常奇怪的问题.我将尝试尽我所能地描述这一点.
首先,这是一个带有Swing UI的遗留应用程序.
其次,只有在使用Java 8编译和运行时才会出现此问题.对于Java 7及更低版本,不会发生这种情况.
所以,问题是:当显示对话框时(模态或非模态,无关紧要),UI对鼠标点击没有反应.然而,真正疯狂的是UI并未被冻结.将鼠标悬停在某物上可以正常生成悬停突出显示.完全接收键盘命令.但是,鼠标点击不起作用.
这也只发生在OSX上.Windows和Linux没有这个问题.我在OSX El Capitan上运行它.
就代码示例而言,它会影响整个应用程序的所有对话框.JOptionPanes和JDialogs,似乎并不重要.这是一个简单的JOptionPane声明:
int n = JOptionPane.showOptionDialog(mcContext.getMapperView(), "xPath of dropping target can't be evaluated" +
"\nPlease, select xPath for dropped node",
"xPath calculation for dropped node",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
Run Code Online (Sandbox Code Playgroud)
这个代码是在EventThread上调用的,所以我不认为它是一个线程问题.
我对这个原因感到非常难过.到目前为止,我们通过在Java 7中编译和运行它来忽略它,但在某些时候,随着版本的进展,我们需要更直接地处理这个问题.
有人有主意吗?
编辑:感谢SSCCE的想法.现在我比以前更困惑.当我组装一个快速框架/对话框演示时,它完美地工作.没有问题.所以我不知道应用程序中可能导致这种情况的原因.有什么好地方可以开始寻找吗?
编辑2:在SwingUtilities.invokeLater中包装其中一个声明,它工作正常.好的...现在罪魁祸首是什么?它仍然是Java 8编译与Java 7不同的东西.
编辑3:更奇怪的行为.我将IDE移动到一个单独的"桌面"而不是它运行的应用程序,当显示错误对话框时,我无法切换到该桌面.我可以切换到当前桌面上的任何应用程序,但不能切换到其他桌面.
编辑4:有问题的对话框由拖放操作触发.不确定这是否有帮助,但我确实看到使用sun.lwawt.macosx.CDragSourceContextPeer类在线程转储的后台有一个线程.
好吧,花了一段时间,但我想我找到了。我发现一篇 OpenJDK 的帖子似乎非常清楚地描述了这个问题。
https://bugs.openjdk.java.net/browse/JDK-8139393
不知何故,java 8 OSX 上的 Swing 中的 Drag N Drop 不会释放其对 MouseEvent 或 Listener 的保留,因此当显示模式对话框时,鼠标无法获取新事件。这是一个疯狂愚蠢的错误,但它确实存在。
解决方案是将我的代码包装在 SwingUtilities.invokeLater(...) 中。通过从拖放代码异步执行显示对话框的代码,拖放操作能够完成并释放其对鼠标连接的控制(由于缺乏更好的描述)。还有中提琴!问题解决了。
感谢所有试图提供帮助的人。希望这篇文章可以帮助其他处理此问题的人。