2009-08-27 13 views
16

Po uruchomieniu programu tworzona jest nowa ramka JFrame. Gdy użytkownik kliknie przycisk Start, zostanie utworzony i uruchomiony wątek. Częścią tego wykonania wątków jest weryfikacja danych w formularzu, a następnie wykonanie z tymi danymi. Po sprawdzeniu danych wątek wywołuje metodę dispose() na oryginalnej ramce, a następnie tworzy nową ramkę JFrame, która działa jako panel sterowania.Jak sprawić, aby wątek czekał na zamknięcie JFrame w Javie?

Istnieje również tryb automatyczny programu, który nie wyświetla żadnego GUI, tryb ten odczytuje dane z pliku konfiguracyjnego, a następnie uruchamia wątek wykonywania i uruchamia wszystko, ale bez panelu sterowania.

Chcę, aby program zakończył się po zakończeniu wątku, ale w trybie GUI, tylko jeśli użytkownik również zamknął panel sterowania. Czy jest możliwe, aby wątek czekał na zamknięcie ramki. Zakładam, że ramka jest uruchamiana z własnego wątku? czy tak nie jest.

Dzięki.

Odpowiedz

23

Wybrana przez ciebie odpowiedź jest trochę niezręczna. Użycie Thread.sleep (1000) będzie sprawdzać stan okna co sekundę. To nie jest problem z wydajnością, ale po prostu zły styl kodowania. A Ty możesz mieć czas reakcji na sekundę.

Ten kod jest trochę lepszy.

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

Tak, rozumiem, dlaczego byłoby lepiej. Dzięki. –

+0

Myślę, że na końcu brakuje t.join() –

+0

Tak, dziękuję. –

1

Możesz odwołać się ze swojego wątku do ramki JFrame. Następnie ustaw domyślną operację zamknięcia JFrame na HIDE_ON_CLOSE. Jeśli ramka JFrame jest zamknięta, możesz zatrzymać wątek.

Przykładowy kod:

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

Dzięki temu właśnie tego potrzebowałem. –

2

Wszystkie komponenty Swing, w tym JFrame, są zarządzane przez jeden wątek, zwany wątek zdarzenia wysyłki lub EDT. (Możliwe jest wywoływanie metod na obiektach Swing z innych wątków, ale zwykle jest to niebezpieczne, z wyjątkiem kilku nieistotnych tutaj przypadków).

Prawdopodobnie dokonasz tego, czego chcesz, wprowadzając kod weryfikacji i wykonania danych w swoim własnym obiekcie, który inaczej nie byłby całkowicie świadomy świata zewnętrznego. Następnie wywołaj go z jednego z dwóch innych obiektów: jednego, który zarządza GUI, a drugi działa w "trybie automatycznym".

Powiązane problemy