aplikacja okienkowa + swing + wątki

0

Z tego co pamiętam to w javie nie nalezy operowac na komponentach Swing w zadnym innym watku niz watek dystrybucji zdarzen wiec nalezy uzyc konstrukcji EventQueue.invokeLater(new Runnable() { public void run() { //operacje na komponencie Swing } }). Co też u mnie jest w klasie Watek w metodzie run(). **Zastanawiam się natomiast czy powinienem również użyć konstrukcji EventQueue.invokeLater w metodzie metoda() dla jOptionPane2.showMessageDialog, bo metoda() jest wywoływana w klasie Watek w run()?? **

 
public class DesktopApplication2View extends FrameView {
     
     private void jButton1MouseClicked(java.awt.event.MouseEvent evt) { 
        Runnable r = new Watek();
        Thread t = new Thread(r);
        t.start();        
    }          

    private void metoda() {     
                try {
                    .......
                } 
                catch (IOException e) {
                    jOptionPane2.showMessageDialog(null, e, "Błąd", JOptionPane.ERROR_MESSAGE);
                }      
    }

    class Watek implements Runnable
    {
        public void run()
        {       
            metoda();

            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    jButton1.setEnabled(true);
                }
            });
        }
    }



}
1

Nie musiałbyś tego robić gdybyś wywoływał tę metodę z procedury obsługi zdarzenia, która jest wywoływana z wątku Swinga. W każdym innym wypadku musisz zlecić operacje na obiektach swingowych za pomocą invokeLater lub invokeAndWait, dzięki czemu wykonane zostaną z wątku Swinga.

Tu na dodatek umieściłeś wywołanie operacji swingowej w obsłudze wyjątku, co może spowodować jeszcze większe problemy ponieważ w takim miejscu należy umieszczać wyłącznie taki kod, który sam nie spowoduje kolejnego wyjątku (a wszystkie operacje GUI mogą je spowodować). Przede wszystkim dlatego, że wtedy powstanie łańcuch wyjątków, a wcześniejsze wyjątki Java zastępuje nowymi (wtedy nie będzie można się wydobyć z sytuacji wyjątkowej).

Dlatego aby ułatwić problem z używaniem wątków w Swingu stworzono klasę SwingWorker, które efektywnie zastępują wszelkie typowe potrzeby użycia klasy Thread.
Używanie Thread jest od kilku wersji Javy podobne do używania tablic, metod wait/notify, czy operatorów bitowych - jako operacja niskopoziomowa która służy do zbudowania wysokopoziomowych struktur programu. Do używania wielowątkowości używa się aktualnie różnych executorów, Swingworkera, liczników, zatrzasków i barier.

ps. Jest jeden wyjątek kiedy możesz zupełnie bezpiecznie wywołać dialog czy messageboxa nie z EDT - kiedy nie istnieje jeszcze pętla EDT czyli na przykład z metody main() gdy żadne okno nie zostało jeszcze uaktywnione przez setVisible(true) lub jakieś inne showDialog (choć mogłoby być utworzone).

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