Java 8、Swing和OSX:对话框使UI对鼠标没有响应



好吧,这是我们公司的应用程序遇到的一个非常非常奇怪的问题。我会尽我所能描述这件事。

首先,这是一个带有Swing UI的遗留应用程序。

第二,只有当它被编译&使用Java 8运行。对于Java7及以下版本,这种情况不会发生。

因此,问题是:当显示对话框(模态或非模态,无关紧要)时,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]);

这段代码是在EventThread上调用的,所以我不认为这是线程问题。

我对这件事的起因完全不明白。到目前为止,我们已经通过在Java7中编译和运行它忽略了它,但在某些时候,随着版本的发展,我们需要更直接地处理这个问题。

有人有什么想法吗?

编辑:感谢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上的Drag N Drop in Swing并没有释放对MouseEvent或Listener的控制,所以当显示模式对话框时,鼠标无法获得新的事件。这是一个疯狂而愚蠢的错误,但它确实存在。

解决方案是将我的代码包装在SwingUtilities.invokeLater(…)中。通过让显示对话框的代码与拖放代码异步执行,拖放操作能够完成并释放对鼠标连接的控制(因为没有更好的描述)。还有中提琴!问题解决了。

感谢所有试图提供帮助的人。希望这篇文章能帮助其他人处理这个问题。

最新更新