Wątki, problem z dostępem do klasy głównej

0

Wiatam!
Mam taki oto problem:
Mój program okienkowy dziedzczący po JFrame ma przykładowo Buttona. Po kliknięciu na niego tworzy się nowy wątek. Po następnym kliknięciu następny... Wątki sobie działają, ale mnie nurtuje pytanie:
JAK UZYSKAĆ DOSTĘP Z TYCH WĄTKÓW DO METODY PAINT() W GŁÓWNEJ KLASIE. ALBO MOŻE INACZEJ: JAK ZROBIĆ ABY STWORZONE KOLEJNO WĄTKI MOGŁY NARYSOWAĆ COŚ NA PŁÓTNIE OKNA DEFAKTO STWORZONEGO PRZEZ WĄTEK GŁÓWNY [!!!]

[browar] Z góry dzięki...

0

Programy Swing działają w taki sposób:

  1. Uruchamia się jakiś wątek startowy odpalany przez system i wywołuje on metodę main()

  2. Równocześnie uruchamia się wątek obsługi zdarzeń Swing, do którego nie masz żadnego dostępu. Jego zadaniem jest odczytywanie zdarzeń (wygenerowanych przez kod obsługi systemu operacyjnego) i reagowanie przez odmalowywanie okienek i komponentów zgodnie z bieżącym stanem.
    Na przykład po naciśnięciu LPM na jakimś przycisku wątek Swing odrysowuje jego przyciśnięcie, a potem puszczenie. Jednocześnie wyzwala zdarzenie, które uruchamia metody ActionPerformed() dla wszystkich obiektów słuchających, zarejestrowanych dla tego przycisku. Pierwotnie nie ma żadnych zarejestrowanych obiektów lub ich metody są puste, więc nie ma żadnego innego efektu poza wizualnym.

  3. W metodzie main() uruchamiasz wywołanie invokeLater() dla klasy implementującej Runnable, co powoduje, że kod, który napisałeś zostanie wywołany przez Swing jako część swojej obsługi okienkowej. Od tego momentu większość programów GUI kończy działanie metody main() i wątek ten kończy się. Oznacza to, że nad Twoim programem pełnię władzy przejął kod klas Swing, który w pewnej części używa kodu, który podałeś mu do wykonania.

  4. Nad metodą paint() również pełną kontrolę ma Swing.

  5. Twoje metody wywoływane przez Swing mogą utworzyć kolejne wątki, które coś robią. Mogą na przykład przygotowywać obrazy, z których skorzysta metoda paint(), której kod dostarczyłeś do Swinga. Mogą również samodzielnie rysować coś na jakichś komponentach (używając klas AWT) - ale nie mogą zmieniać stanu samych komponentów Swing inaczej jak przez podłożenie kodu do wykonania przez wywołanie invokeLater() lub invokeAndWait().
    Krótko mówiąc - dane przygotowywane przez te wątki muszą nie tyle być wpychane do paint przez nie, ile "pozwalać się użyć" przez metodę paint(). I to tak, żeby nie nastąpiła kolizja w sytuacji w której paint właśnie odczytuje te dane, a kod wątków właśnie je zmienia. Trzeba bardzo uważać, żeby kod podany do wykonania przez Swing ( w tym kod metody paint()) nie zatrzymał się, ani nie zakleszczył (polecenia takie jak sleep() są absolutnie niedopuszczalne). Jeżeli dane nie są dostępne, to musi to zignorować i działać dalej.
    Większość problemów z synchronizacją wątków w programie Swing można łatwo przeskoczyć za pomocą klasy SwingWorker wprowadzonej w Java 1.6. To bardzo ważna klasa i warto nauczyć się jej na pamięć. Programy wielowątkowe pisane z jej użyciem stają się banalnie proste.

Tak więc jak widzisz musisz zupełnie zmienić swoje podejście do tego jak działa program okienkowy. To nie ty wywołujesz jakiś kod. To Twój kod jest wywoływany. Z władcy stajesz się petentem. Jedyny kod nad którym masz władzę i w każdej chwili możesz go bezkarnie zatrzymać, to kod utworzonych wątków przez kod, który podstawiłeś Swingowi do wykonania.
Jeszcze do niedawna tylko taki kod mógł być debugowany bo do kodu Swinga dostęp był ograniczony. Dzisiaj na szczęście można debugować kod Swing, który samemu się podstawiło do wykonania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1