杰瑞科技汇

Java Swing窗口关闭事件如何监听与处理?

我们必须显式地告诉程序在窗口关闭时应该做什么,最常见的需求是完全退出应用程序

Java Swing窗口关闭事件如何监听与处理?-图1
(图片来源网络,侵删)

下面我将从最推荐的方法开始,逐步介绍其他情况和相关知识点。


最推荐的方法:使用 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

这是最直接、最常用的方法,它告诉窗口,当用户尝试关闭窗口时,应该执行一个“JVM退出”的操作。

代码示例:

import javax.swing.JFrame;
public class SimpleWindowCloseExample {
    public static void main(String[] args) {
        // 1. 创建一个 JFrame 窗口实例
        JFrame frame = new JFrame("我的 Swing 窗口");
        // 2. 设置窗口关闭时的默认操作
        // 这是最关键的一行代码!
        // 它告诉程序,当点击关闭按钮时,调用 System.exit(0) 来终止 Java 虚拟机。
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 3. 设置窗口大小
        frame.setSize(400, 300);
        // 4. 设置窗口在屏幕上可见
        frame.setVisible(true);
        // 5. 可选:设置窗口关闭时无法被调整大小
        // frame.setResizable(false);
    }
}

代码解释:

Java Swing窗口关闭事件如何监听与处理?-图2
(图片来源网络,侵删)
  • JFrame.EXIT_ON_CLOSE:这是一个 int 类型的常量,其值为 3,它被预定义为关闭窗口时终止应用程序。
  • 当你运行这段代码并点击窗口的 "X" 按钮时,整个 Java 程序会立即终止。

其他可用的关闭操作

setDefaultCloseOperation 方法可以接收以下几个预定义的常量,每种常量对应一种不同的行为:

常量 描述
JFrame.DO_NOTHING_ON_CLOSE 0 什么都不做,窗口会保持打开状态,你需要通过编程方式(一个“退出”按钮的点击事件)来手动关闭它。
JFrame.HIDE_ON_CLOSE 1 隐藏窗口,窗口会从屏幕上消失,但窗口对象仍然存在,程序的后台线程继续运行,这是默认行为。
JFrame.DISPOSE_ON_CLOSE 2 销毁窗口,窗口会被销毁并释放其占用的系统资源(如内存),如果这是最后一个显示的窗口,程序可能会继续运行,但没有可见的 GUI 界面。
JFrame.EXIT_ON_CLOSE 3 退出程序,调用 System.exit(0) 来终止整个应用程序。这是桌面应用程序最常用的选项。

示例:使用 DISPOSE_ON_CLOSE

如果你希望关闭一个窗口后,只销毁它而不退出整个程序(一个多文档界面MDI的应用程序),可以使用 DISPOSE_ON_CLOSE

import javax.swing.JFrame;
import javax.swing.JLabel;
public class DisposeOnCloseExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("DISPOSE_ON_CLOSE 示例");
        frame.add(new JLabel("点击关闭按钮,此窗口将被销毁,但程序不会退出。"));
        frame.setSize(350, 200);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // 使用 DISPOSE_ON_CLOSE
        frame.setVisible(true);
        // 为了演示程序没有退出,我们可以再创建一个窗口
        JFrame anotherFrame = new JFrame("另一个窗口");
        anotherFrame.add(new JLabel("这个窗口仍然可以操作。"));
        anotherFrame.setSize(350, 200);
        anotherFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 这个窗口关闭时才退出程序
        anotherFrame.setLocationRelativeTo(frame); // 让它显示在第一个窗口旁边
        anotherFrame.setVisible(true);
    }
}

高级用法:添加窗口监听器(WindowListener

当你需要执行更复杂的关闭逻辑时,

  • 在关闭前弹出确认对话框:“您确定要退出吗?”
  • 保存未保存的数据到文件。
  • 关闭网络连接或数据库连接。

这时,你就需要使用 WindowListener 接口。

Java Swing窗口关闭事件如何监听与处理?-图3
(图片来源网络,侵删)

WindowListener 接口有多个方法,但最常用的是 windowClosing(WindowEvent e),这个方法会在窗口即将关闭时被调用。

代码示例:

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class WindowListenerExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("窗口监听器示例");
        // 使用匿名内部类来创建一个 WindowAdapter
        // WindowAdapter 是 WindowListener 的一个方便实现,我们只需要重写需要的方法即可
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                // 弹出一个确认对话框
                int option = JOptionPane.showConfirmDialog(
                        frame,
                        "您确定要退出程序吗?",
                        "确认退出",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.WARNING_MESSAGE
                );
                // 如果用户点击了 "是"
                if (option == JOptionPane.YES_OPTION) {
                    // 执行退出操作
                    System.exit(0);
                }
                // 如果用户点击了 "否",或者关闭了对话框,则什么都不做,窗口保持打开状态
            }
        });
        frame.add(new JLabel("尝试关闭窗口,会看到一个确认对话框。"));
        frame.setSize(400, 300);
        // 注意:这里我们没有设置默认关闭操作,因为监听器会接管它
        // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 如果加上这句,监听器中的 System.exit(0) 就会执行两次
        frame.setVisible(true);
    }
}

代码解释:

  1. frame.addWindowListener(...): 为窗口添加一个窗口监听器。
  2. new WindowAdapter(): WindowListener 接口有7个方法,为了方便,Swing 提供了 WindowAdapter 这个适配器类,它实现了所有方法,但方法体都是空的,我们只需要继承它并重写我们关心的方法(这里是 windowClosing),而不用实现所有7个方法。
  3. windowClosing(WindowEvent e): 当用户点击关闭按钮时,这个方法被触发。
  4. JOptionPane.showConfirmDialog(...): 显示一个标准的确认对话框。
  5. System.exit(0): 只有在用户确认后,才真正退出程序。

总结与最佳实践

场景 推荐方法 说明
简单的桌面应用程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 这是最简单、最直接的方式,确保程序能正确退出。
需要自定义关闭逻辑(如保存数据、弹出确认框) frame.addWindowListener(new WindowAdapter() { ... }); windowClosing 方法中编写你的逻辑,并在最后决定是否调用 System.exit(0)
隐藏窗口但不销毁 frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 用于系统托盘功能,点击关闭按钮后窗口隐藏到托盘。
创建一个非顶级窗口(如MDI子窗口) frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 关闭单个窗口,释放其资源,但不影响其他窗口或主程序。

核心要点:

  1. 永远不要依赖默认行为,默认的 HIDE_ON_CLOSE 会让你的程序看起来已经退出了,但实际上可能还在后台运行。
  2. 对于大多数独立的 Swing 应用程序,setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) 是你的首选。
  3. 当你需要执行“关闭前”的任何操作时,WindowListener 是你的不二之选。
分享:
扫描分享到社交APP
上一篇
下一篇