2010-11-23 11 views
13

Decir que tengo el siguiente código:¿Cómo espero el método doInBackground() de SwingWorker?

import java.lang.InterruptedException; 
import javax.swing.SwingWorker; 

public class Test 
{ 
    private JDialog window; 

    public Test 
    { 
     // instantiate window 
    } 

    private class Task extends SwingWorker<Void, Void> 
    { 
     public Void doInBackground() 
     { 
      try { Thread.currentThread().sleep(5000); } 
      catch(InterruptedException e) {} 
      return null; 
     } 
    } 

    public void doTask() 
    { 
     Task task = new Task(); 
     task.execute(); 
    } 

    protected void process() 
    { 
     // update various GUI components here 
    } 

    public static void main(String args[]) 
    { 
     Test t = new Test(); 
     t.doTask(); 
     System.out.println("done"); 
    } 
} 

tengo que esperar hasta t.doTask() se realiza antes de imprimir 'hecho', pero no estoy seguro exactamente cómo. Sé que probablemente debería usar join() aquí, pero necesito un hilo para invocarlo, y no sé cómo obtener el hilo doInBackground() desde donde necesito llamar al join(). Gracias por cualquier ayuda.


EDIT: Gracias por las respuestas. Desafortunadamente, get() y similares no resuelven del todo el problema. En mi código actual, SwingWorker también tiene una función process() reemplazada que actualiza una ventana de GUI mientras se ejecuta el hilo de fondo. get() detiene la impresión de 'listo' hasta después de doInBackground, pero luego la GUI no se actualiza. Actualicé mi código de muestra para reflejar esto, aunque ahora, por supuesto, no compilará.

¿Hay alguna forma de 'hacerlo' para imprimir solo una vez que doInBackground haya terminado? ¿El código de actualización de la GUI y la declaración 'done' están en el mismo hilo? ¿Necesito hacer un nuevo hilo?

Respuesta

11

Normalmente todo lo que debe hacerse después de completar SwingWorker su trabajo de fondo se realiza anulando el método done() en él. Este método es invocado en el hilo del evento Swing después de la finalización, lo que le permite actualizar la GUI o imprimir algo o lo que sea. Si realmente necesita bloquear hasta que se complete, puede llamar al get().

NB. Si llama al get() dentro del método done(), se devolverá el resultado de inmediato, por lo que no debe preocuparse por el bloqueo de la interfaz de usuario.

+0

Bien, lo tengo trabajando usando 'done()'. Gracias por tu ayuda. – Max

+1

Nota para futuros usuarios de Google: esto realmente no ayuda cuando el SwingWorker ha sido cancelado. 'done()' puede ejecutarse antes de que 'doInBackground()' complete. :-(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6826514 http: // stackoverflow.com/questions/6204141/swingworker-when-exactly-is-called-done-method – kmort

9

Llamar a get() provocará el bloqueo de SwingWorker.

De los Javadocs:

T get() 
     Waits if necessary for the computation to complete, 
     and then retrieves its result. 

Su código será el siguiente aspecto:

public static void main(String args[]) 
{ 
    Test t = new Test(); 
    t.doTask(); 
    t.get(); // Will block 
    System.out.println("done"); 
} 
0

En general, debe mantenerse en el SwingWorker hasta que termina, que se puede probar llamando isDone() en eso. De lo contrario, simplemente llame al get(), que lo hace esperar.

5

Puede anular el método done(), que se invoca cuando se completa doInBackground(). El método done() se llama en EDT. Así que algo como:

@Override 
protected void done() { 
    try { 
    super.get(); 

    System.out.println("done"); 
    //can call other gui update code here 
    } catch (Throwable t) { 
    //do something with the exception 
    } 
} 

Al llamar al método get() dentro del hecho ayuda a volver las excepciones que fueron lanzados durante la doInBackground, por lo que recomiendo encarecidamente. SwingWorker usa Callable y Future internamente para administrar el hilo de fondo, lo cual es posible que desee leer en lugar de intentar el enfoque de unión/rendimiento.

+0

Debería haber hecho un comentario a la respuesta de Colin D's. – Jim

+0

Buen punto sobre el uso de get() para obtener excepciones – HaveAGuess

Cuestiones relacionadas