如何使线程等待JFrame在Java中关闭?

时间:2009-08-27 15:06:35

标签: java multithreading user-interface

程序启动时,会创建一个新的JFrame。用户单击开始按钮后,将创建并启动一个线程。此线程执行的一部分是验证表单上的数据,然后使用该数据执行。一旦验证了数据,线程就会在原始帧上调用dispose(),然后创建一个充当控制面板的新JFrame。

程序的自动模式根本不显示任何GUI,此模式从配置文件中读取数据,然后启动执行线程并运行所有内容但没有控制面板。

我希望程序在线程完成后结束,但是在GUI模式下,只有用户也关闭了控制面板。 是否可以让线程等待帧关闭。我假设框架是从它自己的线程运行的?或者情况并非如此。

感谢。

3 个答案:

答案 0 :(得分:24)

你选择的答案有点尴尬。使用Thread.sleep(1000)将每秒检查窗口状态。这不是性能问题,而只是糟糕的编码风格。你可能有一秒的响应时间。

这段代码更好一点。

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 :(得分:2)

所有Swing组件(包括JFrame)都由一个称为Event Dispatch Thread或EDT的线程管理。 (可以从其他线程调用Swing对象上的方法,但这通常是不安全的,除非在少数情况下这里不相关。)

通过将数据验证和执行代码放在自己的对象中,您可能会完成您想要的任务,否则完全不了解外部世界。然后,从另外两个对象中调用它:一个管理GUI,另一个以“自动模式”运行。

答案 2 :(得分:1)

您可以从线程引用JFrame。然后将JFrame的默认关闭操作设置为 HIDE_ON_CLOSE 。如果JFrame已关闭,则可以停止该线程。

示例代码:

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();
    }
}