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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1341699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:26:28  来源:igfitidea点击:

How do I make a thread wait for JFrame to close in Java?

javamultithreadinguser-interface

提问by A Hymanson

When the program starts, a new JFrame is created. Once the user clicks the start button a thread is created and started. Part of this threads execution is to validate the data on the form and then execute with that data. Once the data has been validated the thread calls dispose() on the original frame and then creates a new JFrame that acts as a control panel.

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

There is also an automatic mode of the program that doesn't display any GUI at all, this mode reads data from a configuration file and then starts the execution thread and runs everything but without the control panel.

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

I want the program to end once the thread completes, but in GUI mode, only if the user has closed the control panel as well. Is it possible to make the thread wait for the frame to close. I assuming that the frame is run from it's own Thread? or is that not the case.

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

Thanks.

谢谢。

采纳答案by Denis Tulskiy

The answer you chose is a little awkward. Using Thread.sleep(1000) will check for window state every second. It is not a performance issue, but just bad coding style. And you may have a one second response time.

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

This code is a little bit better.

这段代码要好一些。

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

回答by nanda

You can make reference from your thread to the JFrame. Then set the default close operation of JFrame to HIDE_ON_CLOSE. If the JFrame is closed, you can stop the thread.

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

Example code:

示例代码:

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

回答by Paul Brinkley

All Swing components, including JFrame, are managed by a single thread, called the Event Dispatch Thread, or EDT. (It's possible to call methods on Swing objects from other threads, but this is usually unsafe, except in a few cases not relevant here.)

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

You'll probably accomplish what you want here by putting the data validation and execution code in its own object which is otherwise completely unaware of the outside world. Then, call it from one of two other objects: one that manages a GUI, and another that runs in "automatic mode".

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