Estoy desarrollando una aplicación pequeña, que tendría la GUI Swing. La aplicación está realizando una tarea de E/S en otro subproceso, cuando termine el subproceso, la GUI se debe actualizar de forma correspondiente para reflejar el resultado de la operación del subproceso. La clase que se ejecuta en un (worker, non-GUI) tiene un objeto pasado en contructor que se usaría para actualizar la GUI, así que no necesito poner cosas de GUI en una clase que no sea GUI, sino pasar el objeto para actualizar la GUI a esa clase. Según tengo entendido, la forma de leer aquí, las opciones de seguridad (hilo/balanceo) para actualizar (cambiar) la GUI de Swing sería usar javax.swing.SwingUtilities.invokeLater()
, javax.swing.SwingUtilities.invokeLaterWait()
y/o javax.swing.SwingWorker()
que básicamente están haciendo lo mismo. Este problema de enhebrado con Swing es un poco confuso para mí, y necesito usar hilos para hacer algo significativo en aplicaciones GUI y GUI no colgado mientras proceso en EDT, entonces lo que me interesa por ahora es esto:Actualizando el componente Swing desde otro hilo con invokeLater o SwingWorker
son
invokeLater
yinvokeLaterWait
como el envío de mensajes a EDT y esperar a que lo haga cuando se termina de procesar los mensajes que han sido antes de esa llamada?¿es cierto aspecto de la seguridad de hilo Swing, hay que hacer algo como esto:
interface IUPDATEGUI { public void update(); } // in EDT/where I can access components directly class UpdateJList implements IUPDATEGUI { public void update() { // update JList... someJList.revalidate(); someJList.repain(); } } class FileOperations implements Runnable { private IUPDATEGUI upObj; List<File> result = new ArrayList<File>; // upObject is accessing this public void FileOperations(IUPDATEGUI upObj) { this.upObj = upObj; } private void someIOTask() { // ... // IO processing finished, result is in "result" } public void run() { someIOTask(); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { upObj.update(); // access result and update JList } };); } }
En caso de que esto no es correcto, entonces ¿cómo debe hacerse esto?
Si pudiera, yo preferiría usar invokeLater
en lugar de SwingWorker
si es posible, porque no tendría que cambiar toda mi clase y es de alguna manera más ordenada/distinta mí (como el envío de un mensaje en aplicaciones Win32).
Gracias de antemano.
¿Las llamadas a revalidar() y volver a pintar() son necesarias después de actualizar el componente en este caso? – Mil