2015-04-15 41 views
9

Zainstalowałem aplikację Swing na Java 8, a ostatnio widzimy następujący wyjątek NPE.Wyjątek NullPointerException na 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) 

Migracja z powrotem do J7 jest problemem, ponieważ lambda są używane, więc nie można łatwo potwierdzić, że to naprawdę jest problem J8. Ale kod, o którym mowa, działa już od kilku lat, przetrwał w Javie 5, 6 i 7. Jest więc szansa, że ​​jest specyficzny dla J8.

Powodem wyjątku jest to, że currentEvent w EventQueue nie jest ustawione. Odbywa się to za pomocą setCurrentEventAndMostRecentTimeImpl (AWTEvent e). Jednakże, jeśli prześledzę wstecz w stos, widzę, że w EventQueue: 756 (Java 1.8.0u45) wysyłanie odbywa się po dokładnie tej metody jest wywoływana.

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

Jestem po ciemku, dlaczego ta zmienna ma wartość zerową. Debugowanie jest prawie niemożliwe, ze względu na wszystkie zdarzenia obsługiwane przez ten fragment kodu.

Czy ktoś jest świadomy zmian w obsłudze zdarzeń Swing w J8?

+2

I potwierdziły to J8, bo miałem klasę testową dla StandardComponentPopupMenu widać w stosie. Działa poprawnie na J6 i J7, ale kończy się niepowodzeniem z NPE na J8. – tbeernot

+2

Czy jest ktoś [wypychający nową instancję 'EventQueue'] (http://docs.oracle.com/javase/8/docs/api/java/awt/EventQueue.html#push-java.awt.EventQueue-)? – Holger

Odpowiedz

4

W końcu otwarcie menu podręcznego musiało zostać przełożone na EDT, mimo że kod otwierający go działa na EDT.

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

Tylko podczas jazdy na J8.

+0

Ponieważ używasz Java 8, możesz użyć 'SwingUtilities.invokeLater (() -> jpopupMenu.show (c, x, y));' – Holger

+0

Tak, cóż, biblioteka Swing, skąd pochodzi ten kod (używany w aplikacja J8) jest oparty na J6. – tbeernot

2

także upewnić się, że w przypadku instalacji alternatywnej kolejki zdarzeń, że robisz to na jego własnym przypadku, jak:

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

Problem polega na tym, że pchnięcie kolejka zdarzenie nie jest migracja bieżącego zdarzenia, tylko oczekujące wydarzenia.

+0

Czy masz źródło tego stwierdzenia? – Ramses

-1

Poniżej działa dobrze:

SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         Toolkit.getDefaultToolkit().getSystemEventQueue().push(Customized Event); 
        } 
       }); 
Powiązane problemy