[英]`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組件。
代碼修復:此代碼段顯示了此錯誤的可選修復:
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());
}
}
可選方案:
由於它是正式Oracle JDK的一個錯誤,因此我無能為力。 有一些修復程序應用於其他非正式的JDK,例如OpenJDK ,它應用了一個修復程序,但我不知道哪個版本將應用此修復程序。
對我來說,我可能會嘗試編譯並使用我自己的JDK和應用的修復程序並在我的項目中使用它,但這是一個難以維護而且不那么靈活的解決方案。 如果有人有其他修復/解決方法,我會很高興聽到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.