Articulo de referencia

Trabajador de turno

SwingWorker es una clase de utilidad desarrollada por Sun Microsystems para la biblioteca Swing del lenguaje de programación Java . SwingWorker permite el uso adecuado del hilo ...

SwingWorker es una clase de utilidad desarrollada por Sun Microsystems para la biblioteca Swing del lenguaje de programación Java . SwingWorker permite el uso adecuado del hilo de despacho de eventos . A partir de Java 6 , SwingWorker está incluido en el JRE . [ 1 ]

Entre 1998 y 2006 se produjeron varias versiones incompatibles y no oficiales de SwingWorker, por lo que hay que tener cuidado para evitar la abundante documentación sobre estas versiones anteriores a Java 6.

Uso en Java 6.0

El problema del hilo de despacho de eventos

SwingWorker es útil cuando se debe realizar una tarea que consume mucho tiempo después de un evento de interacción del usuario (por ejemplo, analizar un archivo XML enorme al presionar un JButton). La forma más sencilla de hacerlo es  :

private Document doc ; ... JButton button = new JButton ( "Abrir XML" ); button.addActionListener ( new ActionListener ( ) { @Override public void actionPerformed ( ActionEvent e ) { doc = loadXML ( ); } });

Esto funcionará, pero desafortunadamente, el loadXML()método se llamará en el mismo hilo que el hilo principal de Swing (el hilo de despacho de eventos ), por lo que si el método necesita tiempo para ejecutarse, la interfaz gráfica de usuario se congelará durante ese tiempo.

Solución SwingWorker

Este problema no es exclusivo de Java, sino común a muchos modelos de interfaz gráfica de usuario (GUI ). SwingWorkerSe propone una forma de solucionarlo ejecutando la tarea que consume mucho tiempo en otro hilo en segundo plano, manteniendo la interfaz gráfica de usuario receptiva durante ese tiempo.

Creando al trabajador

El siguiente código define el SwingWorker, que encapsula la loadXML()llamada al método  :

SwingWorker worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } };

Ejecución del trabajador

La ejecución se inicia utilizando el SwingWorker.execute()método.

Recuperando el resultado

El resultado se puede obtener utilizando el SwingWorker.get()método.

Dado que llamar get()al hilo de despacho de eventos bloquea el procesamiento de todos los eventos, incluidos los repintados, hasta que la tarea se complete, se debe evitar llamarlo antes de que la operación prolongada haya terminado. Hay dos maneras de recuperar el resultado después de la finalización de la tarea  :

private Document doc ; ... SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () { @Override public Document doInBackground () { Document intDoc = loadXML ( ) ; return intDoc ; } @Override public void done () { try { doc = get ( ); } catch ( InterruptedException ex ) { ex.printStackTrace ( ); } catch ( ExecutionException ex ) { ex.printStackTrace ( ); } } }
  • Registra un oyente utilizando el SwingWorker.addPropertyChangeListener(PropertyChangeListener)método worker. El oyente recibirá notificaciones sobre los cambios en el estado del worker.

Ejemplo de trabajador completo

private Document doc ; ... JButton button = new JButton ( "Abrir XML" ); button . addActionListener ( new ActionListener () { @Override public void actionPerformed ( ActionEvent e ) { SwingWorker < Document , Void > worker = new SwingWorker < Document , Void > () {@Override public Document doInBackground () { Document intDoc = loadXML (); return intDoc ; } @Override public void done () { try { doc = get (); } catch ( InterruptedException ex ) { ex . printStackTrace (); } catch ( ExecutionException ex ) { ex . printStackTrace (); } } }; worker . execute (); } });

Historial: Uso anterior a Java 6.0

SwingWorker forma parte de Java SE desde Java 6.0. Sun lanzó versiones para usar con JDK anteriores, aunque eran versiones no oficiales que no formaban parte de Java SE y no se mencionaban en la documentación de la biblioteca estándar. [ 2 ] La más reciente de estas versiones data de 2003 y se suele denominar SwingWorker versión 3. [ 3 ] Desafortunadamente, SwingWorker de JDK 6.0 y SwingWorker versión 3 usan nombres de métodos diferentes y no son compatibles. Ahora se recomienda la versión retrocompatible (ver más abajo) para su uso en versiones anteriores a Java 6.

A continuación se muestra un ejemplo de cómo instanciar SwingWorker 3:

SwingWorker worker = new SwingWorker () { public Object construct () { ... // Agrega el código para el hilo en segundo plano } public void finished ( ) { ... // El código que agregues aquí se ejecutará en el hilo de la interfaz de usuario } }; worker.start (); // Inicia el hilo en segundo plano

Este start()método ejecuta el código añadido en el método `construct()` en un hilo independiente. Para recibir una notificación cuando finalice el hilo en segundo plano, basta con sobrescribir el finished()método. Este construct()método puede devolver un resultado que posteriormente se puede recuperar mediante el método de SwingWorker get().

Retrocompatibilidad del SwingWorker de Java 6

Una versión adaptada de Java 6 SwingWorker a Java 5 está disponible en http://swingworker.java.net/ . Aparte del nombre del paquete ( ), es compatible con Java 6 SwingWorker.org.jdesktop.swingworker

Equivalentes

Referencias

  1. SwingWorker
  2. Consulte eljavax.swingresumen del paquete antes y después de J2SE 6.0. Observe también que no hay ninguna clase SwingWorker listada en las páginas de índice de la documentación, hasta la versión 6.0:,.
  3. Puedes descargarlo: "SwingWorker 3" . Archivo de Internet. Archivado del original el 26 de junio de 2012.
  • Documentación de la clase SwingWorker para Java 7.
  • Hilos de trabajo y SwingWorker del tutorial de Oracle sobre concurrencia en Java Swing .
  • Mejore el rendimiento de su aplicación con SwingWorker en Java SE 6, por John O'Conner, enero de 2007.