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

Posted

技术标签:

【中文标题】如何让线程等待 JFrame 在 Java 中关闭?【英文标题】:How do I make a thread wait for JFrame to close in Java? 【发布时间】:2010-11-23 10:11:13 【问题描述】:

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

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

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

谢谢。

【问题讨论】:

【参考方案1】:

你选择的答案有点尴尬。使用 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();

【讨论】:

是的,我明白为什么这样会更好。谢谢。 我认为最后缺少一个 t.join()【参考方案2】:

您可以从您的线程中引用 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();
    
 

【讨论】:

谢谢,这正是我所需要的。 这具有比其他答案更不紧密的优势。框架和线程都必须在另一个答案中相互了解这一事实对我来说有些问题。此外,睡眠可能会下降很多并且不会影响性能。我经常睡觉(100)几乎完全不引人注意。【参考方案3】:

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

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

【讨论】:

以上是关于如何让线程等待 JFrame 在 Java 中关闭?的主要内容,如果未能解决你的问题,请参考以下文章

java中关闭窗口的方法

如何在线程中关闭 QWebSocket?

如何从 Swift 中的主线程中关闭

如何从 ViewModel 命令生成的线程中关闭窗口? [复制]

如何在另一个线程中关闭 MFC 模态对话框并获得对话框返回值?

Java IOException 流在服务器客户端程序中关闭