Problem z wywoływaniem wątku i czekaniem na jego zakończenie w Swingu

0

Witam,
Napotkałem następujący problem:
piszę mała aplikację do użytku własnego, która ma mi wyświetlać co jakiś czas komunikaty (dowolne) zawierające się w JFrame. Do odmierzania czasu użyłem java.util.Timer oraz stworzyłem odpowiednie okienko implementujące Runnable żeby mogło ono być wyświetlane jako osobny wątek. Problem polega na tym, że nie wiem jak zsynchronizowac działanie aplikacji, aby timer odpalal licznik dopiero po zatwierdzeniu przez użytkownika poprzedniego komunikatu, tzn. aby program czekał aż potwierdze okienko i dopiero zaczynal odliczać czas do wyświetlenia następnego.

Teraz jest tak, ze wyswietlaja mi sie kolejne okienka i np. mam 5 okienek z komunikatami, a chce aby jednoczesnie na ekranie bylo tylko jedno. join() nie pomógł, gdyż tylko jak wywoła się metoda setVisible() wyskakującego okienka sterowanie powraca do glownego watku i timera zaczyna odliczac. (inaczej: chciałbym, aby w JFramie po setVisible() sterowanie nie bylo przekazywane z powrotem do glownego watku). Dodatkowo chciałbym aby w tle (w trayu) bylo kolejne okienko z ustawieniami globalnymi dla programu (ale to juz inny temat).

Prosiłbym o sugestie jak rozwiązać powyższy problem z timerem.

0

Hmm...a nie mozesz zrobic ta, że gdy pojawia się pierwszy komunikat stopujesz timer, a restartujesz timer gdy użytkownik zatwierdzi komunikat?

0

Też by tak można, tylko pytanie jak?

public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainWindow window = new MainWindow();
                    UIManager
                            .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                    window.frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        class Task extends TimerTask {
            @Override
            public void run() {
                try {
                    Thread thread = new Thread(new TaskWindow());
                    thread.start();
                    thread.join();
                    System.out.println("JOIN");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        timer.schedule(new Task(), 3000, 3000);

    } 

Klasa TaskWindow po prostu dziedziczy z JFrame i implementuje Runnable i w niej ma sie wyswietlac informacja.

public class TaskWindow extends JFrame implements Runnable {
...
...
@Override
    public void run() {
        try {
            TaskWindow frame = new TaskWindow();
            frame.setVisible(true);
            System.out.println("wyjscie z łajla");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
} 
0

Utworzyeś wątki:

  1. main (pojedynczy)
  2. swingowy w invokeLater (pojedynczy)
  3. run w każdym obiekcie Task
    W tym ostatnim również powinieneś wszystkie operacje swingowe umieścić w invokeLater (wymóg projektowy), aby wyzwalało się w wątku nr 3, ale właściwe operacje okienkowe wykonywały się w wątku nr 2.

Jeżeli chcesz synchronizować wątki to do tego używa się synchronizatorów. W tym wypadku albo CountDownLatch, albo (prawdopodobnie tu lepszy) CyclicBarrier. Poczytaj sobie ich javadoca, to Ci się rozjaśni.

0

Dziekuje za wskazowki, biore sie za czytanie i implementacje. Pozdrawiam.

0

Ja też muszę doczytać bo wydawało mi się że CyclicBarrier stosuje się wtedy gdy mamy wiele wątków i chcemy je synchronizować aby doszły do wybranego wspólnego punktu.

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