En general, SwingWorker se utiliza para realizar tareas de larga ejecución en Swing.
Ejecución de tareas de larga ejecución en el hilo de despacho de eventos (EDT) puede causar la interfaz gráfica de usuario se bloquee, por lo que una de las cosas que se hicieron es utilizar SwingUtilities.invokeLater
y invokeAndWait
que mantiene la interfaz gráfica de usuario que responde por el cual priorizar la otra AWT eventos antes de ejecutar la tarea deseada (en forma de Runnable
). Sin embargo, el problema con SwingUtilities
es que no permitió devolver datos del Runnable
ejecutado al método original. Esto es lo que SwingWorker
fue diseñado para abordar.
El tutorial de Java tiene una sección en SwingWorker.
Aquí hay un ejemplo en el que se usa SwingWorker
para ejecutar una tarea que consume mucho tiempo en un subproceso separado, y muestra un cuadro de mensaje un segundo más tarde con la respuesta.
En primer lugar, se hará una clase que se extiende SwingWorker
:
class AnswerWorker extends SwingWorker<Integer, Integer>
{
protected Integer doInBackground() throws Exception
{
// Do a time-consuming task.
Thread.sleep(1000);
return 42;
}
protected void done()
{
try
{
JOptionPane.showMessageDialog(f, get());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
El tipo de retorno de los métodos doInBackground
y get
se especifican como el primer tipo de la SwingWorker
, y el segundo tipo es del tipo usado para return para los métodos publish
y process
, que no se usan en este ejemplo.
Luego, para invocar el SwingWorker
, se llama al método execute
. En este ejemplo, vamos a conectar un ActionListener
a un JButton
para ejecutar el AnswerWorker
:
JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
new AnswerWorker().execute();
}
});
El botón de arriba se puede añadir a un JFrame
, y seleccionada para conseguir un cuadro de mensaje, un segundo después. A continuación se puede utilizar para inicializar la interfaz gráfica de usuario para una aplicación Swing:
private void makeGUI()
{
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new FlowLayout());
// include: "class AnswerWorker" code here.
// include: "JButton" b code here.
f.getContentPane().add(b);
f.getContentPane().add(new JButton("Nothing"));
f.pack();
f.setVisible(true);
}
Una vez que se ejecuta la aplicación, habrá dos botones. Uno etiquetado como "¡Respuesta!" y otro "Nada". Cuando uno hace clic en "¡Responder!" botón, nada sucederá al principio, pero al hacer clic en el botón "Nada" funcionará y demostrará que la GUI responde.
Y, un segundo después, el resultado de AnswerWorker
aparecerá en el cuadro de mensaje.
No creo que lo que estoy haciendo sea una tarea larga. He pensado en una forma alternativa de tratar este tema, y lo haré en otra pregunta. Gracias – Relequestual
+1 muchas gracias! :) – coder9
@ coder9 De nada :) – coobird