繁体   English   中英

关于swing AWT线程的`NullPointerException` - JLightweightFrame上的游标更新

[英]`NullPointerException` on swing AWT thread - cursor update on JLightweightFrame

我的应用程序中有一个NullPointerException ,它只在一台特定的PC上发生,并且是可重现的。 我通过SwingNode使用Javafx和一些Swing JPanels编写了我的GUI。

我该怎么办?

Exception-Time = 2016-08-30 06:55:50  UTC Exception-Tag = 0 Exception-Message = Thread AWT-EventQueue-0 (Id = 55) throw exception: null Stack-Trace = java.lang.NullPointerException
    at sun.swing.JLightweightFrame.updateClientCursor(Unknown Source)
    at sun.swing.JLightweightFrame.access$000(Unknown Source)
    at sun.swing.JLightweightFrame$1.updateCursor(Unknown Source)
    at sun.awt.windows.WLightweightFramePeer.updateCursorImmediately(Unknown Source)
    at java.awt.Component.updateCursorImmediately(Unknown Source)
    at java.awt.Container.validate(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

更多关于这个问题:

显然,这是JDK本身的一个错误(版本8和9),并且在JDK10之前可能不会得到修复。

updateClientCursor函数的sun.swing.JLightweightFrame.java类中抛出此异常(第472-749行):

private void updateClientCursor() {
    Point p = MouseInfo.getPointerInfo().getLocation();
    SwingUtilities.convertPointFromScreen(p, this);
    Component target = SwingUtilities.getDeepestComponentAt(this, p.x, p.y);
    if (target != null) {
        content.setCursor(target.getCursor());
    }
}

通常,这是因为MouseInfo.getPointerInfo()可以返回NULL,例如,当您在图形设备之间移动时。 'MouseInfo'仍然可以保存以前的图形设备信息,如果鼠标已经移动到新的图形设备并且MouseInfo仍未更新为新的图形设备信息,则getPointerInfo()可以返回NULL。 此方案将在此行上导致Null Pointer Exception MouseInfo.getPointerInfo().getLocation()用于尝试运行NULL对象的方法。

对我来说,当我在多屏幕机器上的显示器之间移动JavaFX应用程序窗口时,会抛出NPE。 它不是每次都发生,但它很容易重现。 我在JavaFX SwingNode组件中使用Swing组件。

此错误已成为 Oracle错误列表中的已知问题

代码修复:此代码段显示了此错误的可选修复:

private void updateClientCursor() {
    PointerInfo pointerInfo = MouseInfo.getPointerInfo();
    if (pointerInfo == null) {
        /*
         * This can happen when JavaFX cannot decide
         * which graphics device contains the current
         * mouse position.
         */
        return;
    }
    Point p = pointerInfo.getLocation();
    SwingUtilities.convertPointFromScreen(p, this);
    Component target = SwingUtilities.getDeepestComponentAt(this, p.x, p.y);
    if (target != null) {
        content.setCursor(target.getCursor());
    }
}

取自JetBrains存储库

可选方案:

由于它是正式Oracle JDK的一个错误,因此我无能为力。 有一些修复程序应用于其他非正式的JDK,例如OpenJDK ,它应用了一个修复程序,但我不知道哪个版本将应用此修复程序。

对我来说,我可能会尝试编译并使用我自己的JDK和应用的修复程序并在我的项目中使用它,但这是一个难以维护而且不那么灵活的解决方案。 如果有人有其他修复/解决方法,我会很高兴听到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM