2011-08-29 10 views
6

Tengo un programa principal, en el que la GUI se basa en oscilación y, dependiendo de uno de cuatro estados, los elementos de la GUI tienen diferentes parámetros.Actualizar GUI por otro hilo en java (columpio)

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); 
} 

Y si quiero actualizar la GUI solo invoca updateGUI con el parámetro apropiado, y todo está bien. Pero el programa también crea un hilo adicional, que luego de procesar los datos relevantes debería cambiar el programa principal de la GUI. Desafortunadamente no puedo en este hilo llamar al método updateGUI (..).

Sé que puedo usar invokeLater o SwingWorker para actualizar pero hay más de 10 elementos, por lo que preferiría usar el método udpateGUI().

Estaré agradecido por cualquier pista.

+0

Por favor, eche un vistazo a las respuestas sobre eventos y eventos del bus en esta pregunta: http://stackoverflow.com/questions/7131484/how-to-pass-the-message-from-working-thread-to -gui-in-java/7131574 # 7131574 –

+0

¿Por qué no puedes llamar a updateGUI desde el otro hilo? Aparte del acceso no sincronizado a la variable de estado, no veo por qué no podría usar este método desde el otro subproceso. –

+0

si invoca Frame f = new Frame(); f.udpateGUI (..); entonces, por supuesto, nada sucedió. ¿De qué otra manera puedo invocar ese método? – galica

Respuesta

7

Si realiza el hilo status campo seguro, entonces se puede llamar directamente desde su setStatus subproceso en segundo plano. Para que el estado sea seguro para subprocesos, coloque los cambios en un bloque de sincronización y haga que la variable sea volátil para que las actualizaciones en otros subprocesos se vuelvan visibles.

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; 
} 

Con estos cambios en el lugar, que está bien para llamar desde cualquier setStatus hilo.

16

Aquí hay un pequeño fragmento que puede agregar a un método para asegurarse de que se ejecuta en el hilo de la GUI. Se basa en 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

gracias, eso también fue útil. – galica

Cuestiones relacionadas