簡體   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