如何在 Swing 应用程序中使用退出按钮?

Posted

技术标签:

【中文标题】如何在 Swing 应用程序中使用退出按钮?【英文标题】:How to use Exit button in Swing Application? 【发布时间】:2014-10-16 06:52:54 【问题描述】:

我是使用 Swing 开发 Java 表单应用程序的新手。退出应用程序的退出按钮的合适代码是什么?

例如: 在 C# (.NET Framework) 中,我们使用 Application.Exit(); 作为退出什么按钮的代码。 Java中退出应用程序的等效代码是什么?

【问题讨论】:

鉴于它是 Swing,我会说 JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE).. @AndrewThompson 我认为您的意思是 EXIT_ON_CLOSE。然后让按钮关闭 JFrame。相关可能重复:***.com/questions/1234912/… @Gimby 不,我绝对没有的意思是EXIT_ON_CLOSE。如果其他线程正在运行,则不应“杀死 VM”。如果它们没有运行,DISPOSE_ON_CLOSE 就足够了。否则,应该明确关闭/清理这些线程。 How to close a Java Swing application from the code的可能重复 @AndrewThompson 从来没有这样想过。谢谢! 【参考方案1】:
jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

现在稍微解释一下。与问题中最接近的等价物是..

jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

但这会杀死整个 JRE,而与正在运行的其他非守护线程无关。如果它们正在运行,则应明确关闭或清理它们。

如果没有其他非守护线程在运行,DISPOSE_ON_CLOSE 将释放当前的JFrame 并结束虚拟机。

【讨论】:

不同意在一个 JVM 实例中看到许多 JFrame/JDialogs 的区别(最后一关),JVM 可以在调用 JFrame.DISPOSE_ON_CLOSE 后保持活跃,不是吗 @mKorbel “JVM 可以在调用 JFrame.DISPOSE_ON_CLOSE 后保持活动状态” 当然可以。当然,如果它在最后一个 GUI 元素关闭后仍然存在,那么是时候开始查看是什么让 JVM 无法结束了。 我也不同意。 JFrame.EXIT_ON_CLOSE 很好,如果您在覆盖的 JFrame.processWindowEvent(WindowEvent) 中处理清理检查 WindowEvent.WINDOW_CLOSING 事件。 @Andrew Thompson it is time to start looking at what is keeping - 是的,我想念在有活动线程的情况下必须使用 System.exit 关闭 JVM +1 特别适用于最后 2 段。但是我更喜欢JFrame.DO_NOTHING_ON_CLOSE 并处理所有待处理的东西(例如注销、记录器的东西、资源释放……),将WindowAdapter 添加到框架并覆盖windowClosing() 方法,最后执行@ 987654332@电话【参考方案2】:

如果您想创建一个在用户单击时退出应用程序的按钮,请尝试以下操作:

JButton exit = new JButton("exit");

ActionListener al = new ActionListener() 
    @Override
    public void actionPerformed(ActionEvent e) 
        System.exit(0);
    
;

exit.addActionListener(al);

现在,当您按下该按钮时,应用程序将退出。

【讨论】:

【参考方案3】:

@AndrewThompson 对 JFrame.EXIT_ON_CLOSE 的看法是正确的,但您可以采取措施避免仅仅杀死东西。

JFrame.EXIT_ON_CLOSE 很好,如果您在覆盖的JFrame.processWindowEvent(WindowEvent) 中处理清理检查WindowEvent.WINDOW_CLOSING 事件。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.Timer;

public class ExitJFrame extends JFrame 

    public ExitJFrame() 
        setLayout(new BorderLayout());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("Exit");
        add(button);

        button.addActionListener(new ActionListener() 
            public void actionPerformed(ActionEvent e) 
                ExitJFrame.this.processWindowEvent(
                        new WindowEvent(
                                ExitJFrame.this, WindowEvent.WINDOW_CLOSING));
            
        );

        setSize(200, 200);
        setLocationRelativeTo(null);
    

    @Override
    protected void processWindowEvent(WindowEvent e) 
        // more powerful as a WindowListener, since you can consume the event 
        // if you so please - asking the user if she really wants to exit for
        // example, do not delegate to super if consuming.
        if (e.getID() == WindowEvent.WINDOW_CLOSING) 
            doCleanup();
            super.processWindowEvent(e); 
         else         
            super.processWindowEvent(e); 
        
    

    private void doCleanup() 
        final JDialog dialog = new JDialog(this, true);
        dialog.setLayout(new BorderLayout());
        dialog.setUndecorated(true);
        JProgressBar progress = new JProgressBar();
        dialog.add(progress);
        dialog.add(new JLabel("Waiting for non-daemon threads to exit gracefully..."), BorderLayout.NORTH);
        progress.setIndeterminate(true);

        Timer timer = new Timer(2000, new ActionListener() 

            public void actionPerformed(ActionEvent e) 
                dialog.setVisible(false);
                dialog.dispose();
            
        );
        timer.setRepeats(false);
        timer.start();
        dialog.pack();
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    

    public static void main (String[] args) 
        new ExitJFrame().setVisible(true);
    


【讨论】:

【参考方案4】:

正如@Andrew Thompson 所说,答案非常简单。

jFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

如果你想通过代码以其他方式制作它。然后你可以把这段代码放在任何地方。在事件中。

System.exit(0);

希望这会有所帮助。

【讨论】:

【参考方案5】:

如果您正在谈论要放入表单的JButton,那么您想在表单的构造函数中调用JFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE),然后您的按钮处理程序可以调用

dispose()

关闭表单。

【讨论】:

使用EXIT_ON_CLOSE 是不好的做法。详情见我的回答。 @AndrewThompson 是的,这就是我的意思。已更正。

以上是关于如何在 Swing 应用程序中使用退出按钮?的主要内容,如果未能解决你的问题,请参考以下文章

第 3 方 Jar 退出我的程序?

SWING

使用 JFrame/Swing 实现 macOS 隐藏时退出行为

如何使用按钮退出应用程序[重复]

即使在应用退出后,如何使用 UIAutomation 工具继续测试 iOS 应用?

如何从代码中关闭 Java Swing 应用程序