You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CardLayout的JFrame面板切换后关闭异常问题咨询

问题原因

你遇到的问题核心在于JFrame默认关闭操作未被正确拦截:

  • JFrame默认的defaultCloseOperation是HIDE_ON_CLOSE,当点击关闭按钮时,即便你在windowClosing回调里切换回SettingsPanel,后续默认的窗口隐藏操作依然会执行,导致SettingsPanel刚显示就被隐藏,进程因未触发退出逻辑而保持活跃。
  • 你在windowClosing方法中调用的super.windowClosing(e);无实际作用(父类方法为空实现),但关键是没有阻止JFrame执行默认的关闭行为。
解决方案
  1. 在JMate构造函数中添加setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);,禁用默认关闭操作,完全由自定义逻辑处理关闭事件。
  2. 移除windowClosing方法中的super.windowClosing(e);(无实际意义)。
修改后的核心代码
public JMate(){
    setTitle("JMate v1.0.0");
    setLocationRelativeTo(null);
    setResizable(false);
    // 禁用默认关闭操作,交由自定义逻辑处理
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

    container = new JPanel();
    settingsPanel = new SettingsPanel(this);
    playingPanel = new PlayingPanel(this);

    cardLayout = new CardLayout();
    container.setLayout(cardLayout);

    container.add(settingsPanel, settingsPanel.getClass().getName());
    container.add(playingPanel, playingPanel.getClass().getName());

    cardLayout.show(container, settingsPanel.getClass().getName());
    activePanel = settingsPanel;

    add(container);
    setSize(settingsPanel.getPreferredSize());

    addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            if(activePanel == settingsPanel){
                System.exit(0);
            }
            else{
                cardLayout.show(container, settingsPanel.getClass().getName());
                setSize(settingsPanel.getPreferredSize());
                activePanel = settingsPanel;
                //TODO: stop engine etc.
            }
        }
    });

    setVisible(true);
}
额外优化建议
  • 避免用setSize硬设窗口大小,推荐调用pack()让窗口自动适配面板首选尺寸,更符合Swing布局规范。
  • 将面板标识字符串(如settingsPanel.getClass().getName())替换为常量,避免类名变化引发错误,提升代码可读性。

内容的提问来源于stack exchange,提问作者smilly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:15:47