2015-04-15 49 views
9

Ich habe eine Swing-Anwendung nach Java 8 migriert und vor kurzem sehen wir die folgende NPE-Ausnahme.NullPointerException bei java.awt.EventQueue.getCurrentEventImpl

java.lang.NullPointerException 
at java.awt.EventQueue.getCurrentEventImpl(EventQueue.java:848) 
at java.awt.EventQueue.getCurrentEvent(EventQueue.java:842) 
at java.awt.Component.requestFocusHelper(Component.java:7628) 
at java.awt.Component.requestFocusHelper(Component.java:7620) 
at java.awt.Component.requestFocus(Component.java:7495) 
at javax.swing.JComponent.requestFocus(JComponent.java:1504) 
at javax.swing.plaf.basic.BasicPopupMenuUI$MenuKeyboardHelper.stateChanged(BasicPopupMenuUI.java:1173) 
at javax.swing.MenuSelectionManager.fireStateChanged(MenuSelectionManager.java:202) 
at javax.swing.MenuSelectionManager.setSelectedPath(MenuSelectionManager.java:129) 
at javax.swing.JPopupMenu.setVisible(JPopupMenu.java:784) 
at javax.swing.JPopupMenu.show(JPopupMenu.java:965) 
at org.tbee.swing.StandardComponentPopupMenu.showJTableMenu(StandardComponentPopupMenu.java:555) 
at org.tbee.swing.StandardComponentPopupMenu$2.run(StandardComponentPopupMenu.java:175) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756) 
at java.awt.EventQueue.access$500(EventQueue.java:97) 
at java.awt.EventQueue$3.run(EventQueue.java:709) 
at java.awt.EventQueue$3.run(EventQueue.java:703) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 

zu J7 Migration zurück ist ein Problem, weil LAMBDA verwendet werden, so dass ich nicht so leicht kann bestätigen, dass dies wirklich ein J8 Problem. Aber der betreffende Code läuft seit einigen Jahren und überlebt Java 5, 6 und 7. Es ist also wahrscheinlich, dass er J8-spezifisch ist.

Der Grund für die Ausnahme ist, dass currentEvent in EventQueue nicht festgelegt ist. Dies geschieht durch setCurrentEventAndMostRecentTimeImpl (AWTEvent e). Wenn ich jedoch im Stapel zurückverfolge, sehe ich, dass in EventQueue: 756 (Java 1.8.0u45) der Versand erfolgt, nachdem genau diese Methode aufgerufen wurde.

if (event instanceof ActiveEvent) { 
     // This could become the sole method of dispatching in time. 
     setCurrentEventAndMostRecentTimeImpl(event); 
     ((ActiveEvent)event).dispatch(); 

Ich bin im Dunkeln, warum diese Variable null ist. Das Debuggen ist nahezu unmöglich, da alle Ereignisse von diesem Code verarbeitet werden.

Sind Änderungen in der Ereignisbehandlung von Swing in J8 bekannt?

+2

Ich habe bestätigt, es J8 ist, weil ich eine Testklasse für die StandardComponentPopupMenu hatte man in dem Stapel zu sehen. Es läuft korrekt auf J6 und J7, scheitert aber mit der NPE auf J8. – tbeernot

+2

Gibt es jemanden, der [eine neue 'EventQueue'-Instanz anstößt] (http://docs.oracle.com/javase/8/docs/api/java/awt/EventQueue.html#push-java.awt.EventQueue-)? – Holger

Antwort

4

Am Ende musste das Öffnen des Popup-Menüs auf dem EDT neu geplant werden, obwohl der Code, der es öffnet, auf dem EDT läuft.

SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      jpopupMenu.show(c, x, y); 
     } 
    }); 

Nur wenn auf J8 ausgeführt wird.

+0

Da Sie Java 8 verwenden, können Sie 'SwingUtilities.invokeLater (() -> jpopupMenu.show (c, x, y));' – Holger

+0

Ja, nun, die Swing-Bibliothek, woher dieser Code stammt (in eine J8-Anwendung) basiert immer noch auf J6. – tbeernot

2

außerdem sicher, dass, wenn Sie eine alternative Ereigniswarteschlange installieren, dass Sie es auf seine eigene Veranstaltung machen, wie:

Swingutilities.invokeLater(){ 
    ... run() { 
     ..do event queue push(); 
    } 
} 

Das Problem ist, dass die Push-Ereignis-Warteschlange ist nicht das aktuelle Ereignis der Migration nur ausstehende Ereignisse

+0

Haben Sie eine Quelle für diese Aussage? – Ramses

-1

arbeitet Unten fein:

SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         Toolkit.getDefaultToolkit().getSystemEventQueue().push(Customized Event); 
        } 
       }); 
Verwandte Themen