Kategorie szkoleń | Egzaminy | Kontakt
  • 1
  • 5
  • 716

Jak uruchomić w tle czasochłonny proces np. odpytywanie bazy, aby nie zablokować GUI i wyświetlić użytkownikowi np pasek postępu?

Gdy umieściłem w metodzie słuchacza odpytanie bazy i wyświetlanie komunikatów na JTextArea,  to dopiero po skończonej operacji Java wyświetliła komunikaty o postępie i efektach wyszukiwania.

KrzysztofB
  • Zapytał
  • @ KrzysztofB | 16.04.2014
    • 13
    • 6
    • 49

Odpowiedź (1)

  • 15

Obsługą wszystkich zdarzeń w Swingu zajmuje się wątek główny (wątek interfejsu użytkownika - UI) - ten sam, który odpowiada za rysowanie interfejsu. Umieszczenie w obsłudze zdarzenia czasochłonnej operacji może więc skutkować "zamrożeniem" interfejsu.

Rozwiązaniem problemu jest delegowanie czasochłonnych operacji do wątków roboczych. Należy pamiętać, że jakakolwiek aktualizacja UI musi mieć miejsce z poziomu wątku głównego. Powstaje więc problem przekazania wyniku końcowego (a także wyników pośrednich) z wątku roboczego do wątku głównego.

Bardzo eleganckie rozwiązanie, które izoluje nas od API wątków, oferuje generyczna klasa abstrakcyjna javax.swing.SwingWorker<T,V> (dostępna od Javy SE6).

Dziedzicząc po tej klasie, należy:

  • w metodzie doInBackground zawrzeć czasochłonne operacje (np. odpytanie bazy danych)
    Metoda będzie wykonana w wątku roboczym. Typ wyniku końcowego opisuje typ generyczny T.
  • Jeśli chcemy publikować wyniki pośrednie, to z wnętrza metody doInBackground należy wywołać metodę publish (typ wyników pośrednich opisuje typ V).
  • W wyniku wywołania metody publish zostanie wywołana w wątku głównym metoda process, której zostaną przekazane wyniki pośrednie.
  • Po zakończeniu wykonania metody doInBackground zostanie wywołana w wątku głównym metoda done
    Tu można "posprzątać", odebrać wynik końcowy za pomocą metody get i przedstawić go w interfejsie.


Do uruchomienia zadania asynchronicznego służy metoda execute (wywołujemy ją na obiekcie typu SwingWorker).

W sytuacji, gdy zadanie asynchroniczne nie zwraca wyników pośrednich lub wyniku końcowego, jako typu generycznego, należy użyć typu Void (typ obiektowy).

  • Odpowiedział
  • @ | 17.04.2014
  • TRENER MODERATOR ALTKOM AKADEMII