首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Swing 視窗關閉按鈕無法退出程式解決方案

     編輯:程式設計綜合問答

問題

繼承 `JFrame` 的視窗,點擊自訂「退出」按鈕或視窗關閉鈕無法結束應用程式。`setDefaultCloseOperation`、`addWindowListener` 均無效。

根本原因

  • 程式中可能啟動了**非守護執行緒**(如資料庫連線池、Timer、第三方庫執行緒),JVM 等待所有非守護執行緒結束才退出。
  • 按鈕事件處理器中未呼叫 `System.exit(0)` 或正確關閉資源。
  • `setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)` 僅在點擊視窗標題列關閉鈕時生效,自訂按鈕需手動處理。

正確退出模式

// 1. 視窗關閉操作設為 EXIT_ON_CLOSE(關閉視窗即退出 JVM)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// 2. 自訂退出按鈕
btnExit.addActionListener(e -> {
    // 執行清理:關閉資料庫、儲存設定、停止執行緒池
    cleanupResources(); 
    System.exit(0); // 強制終止 JVM
});

// 3. 視窗監聽器(可選,用於確認對話框)
addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        int opt = JOptionPane.showConfirmDialog(
            MyFrame.this, "確定要離開?", "確認", JOptionPane.YES_NO_OPTION);
        if (opt == JOptionPane.YES_OPTION) {
            cleanupResources();
            System.exit(0);
        }
        // 否則不處理,視窗保持開啟(需設定 DO_NOTHING_ON_CLOSE)
    }
});

關鍵檢查清單

  1. 是否有非守護執行緒未停止?→ 執行緒建立時 `setDaemon(true)` 或提供 `shutdown()` 方法。
  2. 資料庫連線池(HikariCP、DBCP)是否關閉?→ `dataSource.close()`。
  3. Timer / ScheduledExecutorService 是否關閉?→ `timer.cancel()` / `executor.shutdown()`。
  4. 是否在事件派發執行緒 (EDT) 外操作 Swing 元件?→ 用 `SwingUtilities.invokeLater`。

最佳實踐

  • 統一封裝 `shutdown()` 方法,按鈕、視窗關閉、系統關閉訊號(`Runtime.addShutdownHook`)皆呼叫它。
  • 避免直接 `System.exit(0)` 而不清理,導致資料損毀或資源洩漏。
  • 若為單視窗應用,`EXIT_ON_CLOSE` 最簡單;多視窗應用需管理視窗關閉邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved