2009-08-27 25 views
16

Cuando se inicia el programa, se crea un nuevo JFrame. Una vez que el usuario hace clic en el botón de inicio, se crea y se inicia un hilo. Parte de esta ejecución de subprocesos es validar los datos en el formulario y luego ejecutarlos con esa información. Una vez que los datos han sido validados, el hilo llama a disponer() en el marco original y luego crea un nuevo JFrame que actúa como un panel de control.¿Cómo hago para que un subproceso espere a que JFrame se cierre en Java?

También hay un modo automático del programa que no muestra ninguna GUI en absoluto, este modo lee datos de un archivo de configuración y luego inicia el hilo de ejecución y ejecuta todo pero sin el panel de control.

Quiero que el programa finalice una vez que se completa la secuencia, pero en modo GUI, solo si el usuario también ha cerrado el panel de control. ¿Es posible que el subproceso espere a que se cierre el marco? Supongo que el cuadro se ejecuta desde su propio hilo? o ese no es el caso.

Gracias.

Respuesta

23

La respuesta que eliges es un poco incómoda. El uso de Thread.sleep (1000) verificará el estado de la ventana cada segundo. No es un problema de rendimiento, sino un mal estilo de codificación. Y puede tener un tiempo de respuesta de un segundo.

Este código es un poco mejor.

private static Object lock = new Object(); 
private static JFrame frame = new JFrame(); 
/** 
* @param args 
*/ 
public static void main(String[] args) { 

    frame.setSize(300, 300); 
    frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 
    frame.setVisible(true); 

    Thread t = new Thread() { 
     public void run() { 
      synchronized(lock) { 
       while (frame.isVisible()) 
        try { 
         lock.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       System.out.println("Working now"); 
      } 
     } 
    }; 
    t.start(); 

    frame.addWindowListener(new WindowAdapter() { 

     @Override 
     public void windowClosing(WindowEvent arg0) { 
      synchronized (lock) { 
       frame.setVisible(false); 
       lock.notify(); 
      } 
     } 

    }); 

    t.join(); 
} 
+1

Sí, puedo ver por qué eso sería mejor. Gracias. –

+0

Creo que falta un t.join() al final –

+0

Sí, gracias. –

1

Puede hacer referencia desde su hilo al JFrame. A continuación, establezca la operación de cierre predeterminada de JFrame en HIDE_ON_CLOSE. Si JFrame está cerrado, puede detener el hilo.

código Ejemplo:

import java.awt.Dimension; 

import javax.swing.JFrame; 

public class FrameExample extends JFrame { 

    public FrameExample() { 
     setSize(new Dimension(100, 100)); 
     setDefaultCloseOperation(HIDE_ON_CLOSE); 
     setVisible(true); 

    } 

    private static class T implements Runnable { 

     private FrameExample e; 

    public T(FrameExample e) { 
     this.e = e; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      if (e.isVisible()) { 
       // do the validation 
       System.out.println("validation"); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e1) { 
        break; 
       } 
      } 
     } 
    } 

} 

public static void main(String[] args) { 
    FrameExample frameExample = new FrameExample(); 

    new Thread(new T(frameExample)).start(); 
    } 
} 
+0

Gracias eso es justo lo que necesitaba. –

2

Todos los componentes Swing, incluyendo JFrame, son gestionados por un solo hilo, llamado el hilo de eventos Dispatch, o EDT. (Es posible invocar métodos en objetos Swing de otros hilos, pero esto generalmente no es seguro, excepto en algunos casos no relevantes aquí)

Probablemente logre lo que quiera aquí al poner el código de validación y ejecución de datos en su propio objeto, que de otro modo sería completamente ajeno al mundo exterior. Luego, llámelo desde uno de los otros dos objetos: uno que administra una GUI y otro que se ejecuta en "modo automático".

Cuestiones relacionadas