2011-01-28 12 views
11

Typowa aplikacja Swing uruchamia edytor tekstu na początku, a gdy ostatnie okno jest zamknięte, aplikacja zatrzymuje się zasadniczo z wynikiem System.exit, który jest jawny lub jawny.Jak zatrzymać Swing EDT

Ale moja mała aplikacja to wtyczka do frameworka, który nic nie wie o Swingu. Moja wtyczka będzie wywoływana, gdy zostanie wywołana, wyświetlając okno dialogowe, aby uzyskać pewne dane wejściowe od użytkownika i następnie zakończyć, ale struktura będzie musiała/nadal działać. Nie mogę więc zadzwonić pod numer System.exit.

Ale jeśli ja nie że EDT będzie nadal działać i po zakończeniu ramy EDT będzie nadal działać i biec i biec ...

Więc chciałbym zabić EDT bez zabicie aplikacji. Jak mogę to zrobić?

Odpowiedz

11

Poniższy dokument z Oracle/Sun rzucić trochę światła na ten problem: AWT Threading Issues

[...]

Przed 1,4, nici pomocnicze nigdy nie zostały zakończone.

Począwszy 1,4, zachowanie zmieniło się w wyniku poprawki do 4030718. Przy obecnej implementacji, AWT kończy wszystkie jej wątki pomocnicze umożliwiając zastosowanie do wyjść czysto, jeśli poniższe warunki są spełnione:

  • Brak wyświetlanych elementów AWT lub Swing.
  • Brak rodzimych zdarzeń w rodzimej kolejce zdarzeń.
  • Brak zdarzeń AWT w zdarzeniach EventQueues Java.

Dlatego aplikacja AWT stand-alone, który chce wyjść czysto bez wywoływania System.exit musi:

  • Upewnij się, że wszystkie komponenty AWT lub Swing są stanie obejrzeć Po zakończeniu aplikacji. Można to zrobić, wywołując Window.dispose na wszystkich systemach Windows najwyższego poziomu. Zobacz Frame.getFrames. ...
  • Upewnij się, że żadna metoda detektorów zdarzeń AWT zarejestrowana przez aplikację z dowolnym komponentem AWT lub Swing nie może zostać uruchomiona w nieskończonej pętli lub zawiesić się w nieskończoność. Na przykład metoda detektora AWT wyzwalana przez pewne zdarzenie AWT może opublikować nowe zdarzenie AWT tego samego typu w EventQueue. Argumentem jest, że metody detektorów zdarzeń AWT są zwykle wykonywane na wątkach pomocniczych.

[...]

+2

Istnieje pewien problem, IIRC. Musisz upewnić się, że "wyrzucisz" ** wszystkie ** swoich zasobów. –

0

Mogą istnieć pewne ukryte okna (na przykład dialogi wyświetlane przy użyciu JOptionPane.showMessageDialog(…) które są już zamknięte) zapobieganie Swing z wyjściem. Można to sprawdzić za pomocą

Stream.of(Window.getWindows()).forEach(System.out::println); 

Jeśli nie potrzebujemy ich więcej, można pozbyć się ich łatwo:

Stream.of(Window.getWindows()).forEach(Window::dispose); 

Event Dispatch Temat powinien następnie zatrzymać.