Zdarzenie wysyłki wątek - Event dispatching thread

Wątek zdarzenie wysyłki (EDT) jest tło gwint stosowany w Javie przetwarzać zdarzenia z Abstract Window Toolkit (AWT) graficzny interfejs użytkownika kolejki zdarzeń . Jest przykładem pojęcia rodzajowego programowania zdarzeniami , który jest popularny w wielu innych kontekstach niż Java, na przykład przeglądarek internetowych lub serwerów internetowych .

Zdarzenia są głównie zdarzenia, które powodują aktualizację interfejsu użytkownika elementy do ponownego same, lub zdarzenia wejściowe z urządzeń wejściowych , takich jak myszy lub klawiatury. AWT używa pojedynczego gwintowane malowania modelu , w którym wszystkie aktualizacje ekran musi być wykonana z jednego wątku. Gwint zdarzenie Uruchamianie jest ważny tylko nitki aktualizuje stan wyświetlania widocznych elementów interfejsu użytkownika. Aktualizacja widoczne elementy z innych wątków jest źródłem wielu typowych błędów w Javie programów wykorzystujących Swing . Dysponowanie wątek zdarzenie nazywa się pierwotną pracownika w programie Adobe Flash i wątku UI w SWT , .NET Framework i Androida .

Wiadomość Loop dla szeregowania dostępy GUI

Aplikacja składa się zazwyczaj z wielu wątków i jednym GUI struktury danych. Oznacza to GUI jest wspólna struktura danych i potrzebne jest pewne synchronizacja, aby zapewnić, że tylko jeden wątek dostępów go naraz. Choć AWT i Swing wystawiać ( gwint niebezpieczne ) metody tworzenia i dostęp do komponentów GUI i metody te są widoczne dla wszystkich wątków aplikacji, podobnie jak w innych ram GUI, tylko jeden, Event-rozdzielający wątek ma prawo do wykonywania tych metod. Ponieważ programiści często brakuje tego wymogu, innej firmy Look i czuje , jak Substance iść tak daleko, aby odmówić wystąpienia jakiegokolwiek komponentu Swing, gdy nie jest uruchomiony w ramach obsługi zdarzenia wątek, aby uniknąć takiego błędu kodowania. Dostęp do GUI jest seryjny i inne wątki mogą złożyć jakiś kod wykonywany w EDT poprzez kolejki komunikatów EDT .

Oznacza to, że podobnie jak w innych ram GUI, zdarzenie rozdzielający wątek spędza swoje życie pompowania wiadomości: utrzymuje kolejkę komunikatów działań, które zostaną wykonane przez GUI. Wnioski te są przekazywane do kolejki przez system i wszelkie wątku aplikacji. EDT zużywa je jeden po drugim i reaguje poprzez aktualizację komponentów GUI. Komunikaty mogą być znane działania lub obejmować wywołania zwrotne, odniesienia do klientów użytkownika metod, które muszą być wykonane za pomocą EDT.

Ważną nałożony na wszystkich wiadomości jest to, że muszą one być wykonywane szybko do GUI pozostać elastyczne. W przeciwnym razie, pętla wiadomość jest zablokowana i GUI zamrażanie jest doświadczony.

Złożenie kodu użytkownika do EDT

Istnieją różne rozwiązania do składania kod do EDT i wykonywania zadań bez blokowania długich pętli.

Komponent obsługi zdarzeń (słuchacze)

GUI elementy pomocnicze wykazy wywołań zwrotnych, zwanych słuchaczy, które są zazwyczaj zaludnionych, gdy składniki są tworzone. EDT wykonuje słuchaczy, gdy użytkownik excitates składniki jakoś (kliknięciu przycisku myszy jest przesuwany, element jest zaznaczony, ostrość jest stracone, komponent zmieniany i tak dalej).

Regulator czasowy

Dla krótkich zadań, które musi uzyskać dostęp / modyfikacja GUI okresowo lub w określonym czasie, javax.swing.Timerjest używany. Można go uznać za niewidzialną komponentu GUI, którego słuchacze są zarejestrowane do pożaru w określonym czasie (s).

ekwiwalenty

Wnioski od innych wątków

Inne wątki aplikacji mogą przechodzić jakiś kod wykonywany w wysyłającego wątku zdarzeń za pomocą SwingUtilitiesklas pomocniczych (lub EventQueuejeśli robisz AWT ). Przedstawiony kod musi zostać owinięte Runnableobiektu. Dwie metody tych klas pozwalają:

od przypadku wysyłania nici.

Metoda invokeAndWait()nie powinna być wywoływana z imprezy wysyłającego wątku to wygeneruje wyjątek . Sposób SwingUtilities.isEventDispatchThread()i EventQueue.isDispatchThread()mogą być wywoływane w celu określenia, czy obecny jest gwint zdarzenie wysyłania nici.

Kod dostarczany za pomocą przycisków invokeLateri invokeAndWaitdo EDT musi być jak najszybciej, aby zapobiec zamarzaniu. Zwykle są one przeznaczone do dostarczania wynik długich obliczeń do GUI (użytkownika).

wzornictwo pracownik

Zarówno wykonanie zadania w innym gwintem i przedstawiając wyniki w EDT mogą być łączone za pomocą projektowania pracownik wzór . javax.swing.SwingWorkerClass, opracowany przez Sun Microsystems , jest implementacja wzorca projektowego pracownika, jak i Java 6 jest częścią standardowej dystrybucji Swing. SwingWorker jest zwykle wywoływane z EDT-wykonywanego detektor zdarzeń przeprowadzić czasochłonne zadanie, aby nie blokować EDT.

próbki

SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() {
    public Document doInBackground() throws IOException {
        return loadXML(); // heavy task
    }
    
    public void done() {
        try {
            Document doc = get();
            display(doc);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
};
worker.execute();

Jeśli używasz Groovy i groovy.swing.SwingBuildermożna używać doLater(), doOutside()i edt(). Następnie można napisać prościej tak:

doOutside {
    def doc = loadXML() // heavy task
    edt { display(doc) }
}

ekwiwalenty

Modal Execution

SwingWorker jest zwykle tworzone przez dłuższy zadań przez EDT podczas obsługi wywołań zwrotnych (listener) wydarzenia. Tarła wątku roboczego, EDT przebiega obsługi bieżącej wiadomości bez czekania pracownikowi do wykonania. Często nie jest to pożądane.

Często Twój EDT obsługuje działanie komponentu GUI, która wymaga od użytkownika, aby dokonać wyboru za pomocą innego okna, jak JFileChooser, która pojawia się, pozostaje reaguje natomiast użytkownik wybiera własnego uznania i działania wpływy z wybranego pliku tylko po przycisku „OK” jest wciśnięty. Widzisz, to wymaga czasu (użytkownik odpowie w ciągu kilku sekund) i trzeba czułe GUI (wiadomości są nadal pompowana w EDT) przez cały ten czas, gdy EDT blokuje (nie obsługiwać nowsze, np JFileChooser, wiadomości w kolejka przed okna są zamknięte i prąd działanie składnikiem jest zakończone). Błędne koło jest podzielona przez EDT wprowadzania nowej pętli komunikatów, które wysyła komunikaty, jak na normalne aż „okno jest modalne na” przybywa normalne przetwarzanie komunikatu wznawia się od położenia zablokowanego w działaniu elementów.

Open source Foxtrot projekt emuluje pętlę komunikatów Swing pompowania, aby zapewnić „synchroniczny” mechanizm wykonania dla dowolnych zadań użytkownika, po czym udają się dopiero po zakończeniu przez pracownika zadania.

  button.addActionListener(new ActionListener()
  {
	 public void actionPerformed(ActionEvent e)
	 {
		button.setText("Sleeping...");

		String text = null;
		try
		{
		   text = (String)Worker.post(new Task()
		   {
			  public Object run() throws Exception
			  {
				 Thread.sleep(10000);
				 return "Slept !";
			  }
		   });
		}
		catch (Exception x) ...

		button.setText(text);

		somethingElse();
	 }
  });

Ponieważ Java 1.7, Java zawiera standardowe rozwiązanie niestandardowe komunikat dodatkowy pętle przez wystawienie createSecondaryLoop () w systemie EventQueue ().

Zobacz też

Referencje

Linki zewnętrzne