2009-08-27 9 views
16

All'avvio del programma, viene creato un nuovo JFrame. Una volta che l'utente fa clic sul pulsante di avvio, viene creato e avviato un thread. Parte dell'esecuzione di questi thread consiste nel convalidare i dati nel modulo e quindi eseguirli con tali dati. Una volta che i dati sono stati convalidati, il thread chiama dispose() sul frame originale e quindi crea un nuovo JFrame che funge da pannello di controllo.Come faccio ad aspettare un thread per chiudere JFrame in Java?

C'è anche una modalità automatica del programma che non visualizza alcuna GUI, questa modalità legge i dati da un file di configurazione e quindi avvia il thread di esecuzione ed esegue tutto ma senza il pannello di controllo.

Desidero terminare il programma una volta completato il thread, ma in modalità GUI, solo se l'utente ha chiuso anche il pannello di controllo. E 'possibile fare in modo che il thread attenda che il frame si chiuda. Presumo che il frame sia eseguito dal proprio Thread? o non è così.

Grazie.

risposta

23

La risposta che hai scelto è un po 'imbarazzante. L'uso di Thread.sleep (1000) controllerà lo stato della finestra ogni secondo. Non è un problema di prestazioni, ma solo uno stile di programmazione errato. E potresti avere un tempo di risposta di un secondo.

Questo codice è leggermente migliore.

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ì, capisco perché sarebbe meglio. Grazie. –

+0

Penso che alla fine t.join() manchi –

+0

Sì, grazie. –

1

È possibile fare riferimento dalla propria discussione a JFrame. Quindi imposta l'operazione di chiusura predefinita di JFrame su HIDE_ON_CLOSE. Se JFrame è chiuso, puoi interrompere il thread.

codice Esempio:

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

Grazie è proprio quello di cui avevo bisogno. –

2

Tutti i componenti Swing, tra cui JFrame, sono gestiti da un unico filo, chiamato thread evento Dispatch, o EDT. (È possibile chiamare metodi su oggetti Swing da altri thread, ma di solito non è sicuro, tranne in alcuni casi non rilevanti.)

Probabilmente riuscirai a realizzare ciò che desideri inserendo la convalida dei dati e il codice di esecuzione nel suo stesso oggetto che è altrimenti completamente inconsapevole del mondo esterno. Quindi, chiamalo da uno degli altri due oggetti: uno che gestisce una GUI e un altro che viene eseguito in "modalità automatica".

Problemi correlati