2011-08-29 12 views
6

Mam program główny, w którym GUI opiera się na swing i w zależności od jednego z czterech stanów elementy GUI mają różne parametry.Odświeżające GUI przez inny wątek w java (swing)

public class Frame extends JFrame implements Runnable { 
Status status = 1; 
... 
@Override 
public void run() { 
    switch (status) { 
     case 1: 
     ... 
     case 2: 
     ... 
} 

public void updateGUI(Status status) { 
    this.status = status; 
    SwingUtilities.invokeLater(this); 
} 

A jeśli chcę odświeżyć GUI wywołuje tylko updateGUI z odpowiednim parametrem i wszystko jest w porządku. Ale program tworzy również dodatkowy wątek, który po przetworzeniu odpowiednich danych powinien zmienić główny program GUI. Niestety nie mogę w tym wątku wywołać metody updateGUI (..).

Wiem, że można użyć invokeLater lub SwingWorker do odświeżenia, ale jest więcej niż 10 elementów, więc wolałbym użyć metody udpateGUI().

Będę wdzięczny za wszelkie wskazówki.

+0

Proszę spojrzeć na odpowiedzi o wydarzeniach & Bus wydarzenie w tej kwestii: http://stackoverflow.com/questions/7131484/how-to-pass-the-message-from-working-thread-to -gui-in-java/7131574 # 7131574 –

+0

Dlaczego nie możesz wywołać updateGUI z innego wątku? Oprócz niezsynchronizowanego dostępu do zmiennej status, nie widzę powodu, dla którego nie można użyć tej metody z innego wątku. –

+0

jeśli wzywam Frame f = new Frame(); f.udpateGUI (..); wtedy oczywiście nic się nie stało. Jak inaczej mogę skorzystać z tej metody? – galica

Odpowiedz

7

Jeśli się nić status pola bezpieczne, to można nazwać setStatus bezpośrednio z wątku tła. Aby uczynić stan bezpiecznym dla wątków, umieść zmiany w bloku synchronizacji i ustaw zmienną zmienność, aby aktualizacje innych wątków stały się widoczne.

E.g.

public class Frame extends JFrame implements Runnable { 
private volatile Status status = 1; 
... 
@Override 
public void run() { 
    switch (status) { 
     case 1: 
     ... 
     case 2: 
     ... 
} 

public void updateGUI(Status status) { 
    setStatus(status); 
    SwingUtilities.invokeLater(this); 
} 

private synchronized void setStatus(Status status) { 
    this.status = status; 
} 

Z tych zmian w miejscu, to jest ok, aby zadzwonić setStatus z dowolnego wątku.

16

Oto mały fragment, który można dodać do metody, aby upewnić się, że jest wykonywany w wątku GUI. Opiera się na isEventDispatchThread().

public void updateGUI(final Status status) { 
    if (!SwingUtilities.isEventDispatchThread()) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      updateGUI(status); 
     } 
    }); 
    return; 
    } 
    //Now edit your gui objects 
    ... 
} 
+0

dziękuję, to też było pomocne. – galica