首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Swing 視窗開發技巧:模態對話框與螢幕置中顯示實作

     編輯:Java 相關知識

一、模態視窗:唯有 JDialog 原生支援

在 Swing 中,只有 JDialog 可直接設定為模態:

  • 建構子指定:new JDialog(Frame owner, boolean modal)
  • 動態切換:dialog.setModal(true)(繼承自 Dialog)

JFrame 無法直接設為模態。網路上常見變通做法:在 windowDeactivated 事件中呼叫 requestFocus() 強制搶回焦點,模擬模態行為。但此法存在焦點閃爍、跨平台不穩定等問題,**不推薦生產使用**。

模擬模態 JFrame 參考代碼(僅供理解原理)

public class MyModalFrame extends JFrame implements WindowListener {
    private JFrame parent;
    private boolean modal;

    public MyModalFrame(JFrame parent, boolean modal, String title) {
        super(title);
        this.parent = parent;
        this.modal = modal;
        addWindowListener(this);
        if (modal) parent.setEnabled(false); // 禁用父視窗
    }

    @Override public void windowClosing(WindowEvent e) {
        if (modal) parent.setEnabled(true); // 關閉時恢復父視窗
    }

    @Override public void windowDeactivated(WindowEvent e) {
        if (modal) this.requestFocus(); // 失去焦點立即搶回
    }
    // 其他 WindowListener 方法留空...
}

二、視窗螢幕置中:一行代碼搞定

傳統計算法(Java 1.4 前)

Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Dimension size = frame.getSize();
int x = (screen.width - size.width) / 2;
int y = (screen.height - size.height) / 2;
frame.setLocation(x, y);

現代標準寫法(Java 1.4+)

frame.setLocationRelativeTo(null); // null 表示相對螢幕置中

API 文檔行為: 若元件未顯示或參數為 null,視窗置於螢幕中央;若指定元件,視窗置於該元件中心,並自動避開螢幕邊界。

關鍵調用順序陷阱

⚠️ 必須先呼叫 setSize() 或 pack(),再呼叫 setLocationRelativeTo()。
若順序顛倒,視窗左上角雖對準中心,但整體視覺會偏向右下角。

// 正確順序
frame.pack();                          // 或 frame.setSize(w, h);
frame.setLocationRelativeTo(null);     // 置中
frame.setVisible(true);

三、完整範例:模態對話框 + 置中顯示

public class LoginDialog extends JDialog {
    public LoginDialog(JFrame parent) {
        super(parent, "用戶登錄", true); // true = 模態
        initUI();
        pack();
        setLocationRelativeTo(parent); // 相對父視窗置中
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    private void initUI() {
        setLayout(new GridBagLayout());
        // ... 添加用戶名/密碼欄位、登錄按鈕 ...
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("主視窗");
            frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
            frame.setSize(400, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);

            new LoginDialog(frame).setVisible(true); // 模態阻塞,直到關閉
        });
    }
}

總結

需求推薦方案避坑指南
模態視窗直接使用 JDialog(owner, true)JFrame 不支援原生模態,勿用焦點搶佔大法
螢幕/父視窗置中setLocationRelativeTo(null/parent)先 pack()/setSize() 再置中,否則偏移
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved