對話框是擁有標題與邊框的頂層彈出視窗,常用於接收用戶輸入。在 JDK 5.0 及更早版本中,建立對話框時必須指定一個框架視窗或另一個對話框作為其擁有者,即使該視窗不可見。當擁有者視窗最小化時,對話框會自動隱藏;擁有者恢復時,對話框隨之重現。
對話框分為模態與非模態兩種。模態對話框會阻擋除其擁有者視窗外的所有其他頂層視窗輸入,並捕獲焦點直到關閉(通常響應按鈕點擊)。非模態對話框則允許用戶在其他視窗仍可獲取焦點時改變其狀態,常用於工具欄視窗,如圖像編輯程式中的面板。
舊版模態模型存在諸多限制與問題,最著名的是 JavaHelp 工具視窗無法與模態對話框(如標準「另存為」對話框)同時互動。Java 6(代號 Mustang)透過全新的抽象視窗工具箱(AWT)模態模型徹底解決了這些問題。新模型允許開發者根據所選模態類型指定對話框模態阻擋的範圍,並支援真正無父視窗(null 父視窗)的視窗與對話框,有助於限制作用域與模態範圍。
Java 6 支援四種模態類型,按阻擋強度遞增排序:
預設情況下對話框為無模態;在 Mustang 中建構模態對話框預設使用應用程式模態。模態優先權反映阻擋範圍的巢狀關係:無模態(空範圍)→ 文檔模態(特定應用程式內)→ 應用程式模態(整個應用程式)→ 工具箱模態(整個工具箱)。需注意新模型未實現系統模態(阻擋桌面上所有應用程式)。
為實現真正無父視窗且保持向後相容,AWT 團隊引入了新建構器。JDK 5.0 允許傳遞 null 作為 JDialog/JWindow 父視窗,實際上會建立一個不可見的共享擁有者框架視窗。Java SE 6 引入文檔模態對話框後,工具箱能識別真正無父視窗的對話框/視窗。
Mustang 仍允許向舊版建構器傳遞 null(行為不變,保證相容),但新增 Dialog/Window 及 JDialog/JWindow 建構器可接受 null 並建立真正無父視窗的對話框。常用建構器包括:
JDialog(Dialog owner):建立無標題、指定對話框為父視窗的非模態對話框JDialog(Dialog owner, boolean modal):指定擁有者與模態JDialog(Dialog owner, String title):指定標題與擁有者的非模態對話框JDialog(Dialog owner, String title, boolean modal):指定標題、模態與擁有者JDialog(Dialog owner, String title, boolean modal, GraphicsConfiguration gc):完整參數建構JDialog(Frame owner):指定框架為擁有者的非模態對話框JDialog(Window owner, String title, Dialog.ModalityType modalityType):關鍵新增,支援指定模態類型(如 DOCUMENT_MODAL、APPLICATION_MODAL 等)使用新模態模型時需注意:
以下示範新模態 API 應用,包含 java.awt.Dialog.ModalExclusionType 與 java.awt.Dialog.ModalityType 的靈活運用:

圖1:對話框的模態優先權

圖2:被阻擋與未被阻擋的對話框
關鍵程式碼片段:
// 設定 DOCUMENT_MODAL 對話框
d22.setBounds(sw - 500 + 32, 232, 300, 200);
d22.addWindowListener(closeWindow);
d22.setLayout(new BorderLayout());
Label l = new Label("DOCUMENT_MODAL");
l.setBackground(Color.BLUE);
l.setAlignment(Label.CENTER);
l.setFont(labelFont);
d22.add(l, BorderLayout.CENTER);
// 排除模態的框架視窗
Frame f3 = new Frame("Excluded Frame");
f3.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
// ... 設定位置、監聽器、標籤與按鈕 ...
f3.setVisible(true);
// 檔案對話框(向後相容,預設 APPLICATION_MODAL)
FileDialog fd4 = new FileDialog(f4, "File Dialog", FileDialog.LOAD);
fd4.setBounds(sw - 400 + 32, sh - 300 + 32, 300, 200);
當非置頂的模態對話框阻擋置頂視窗時,Z-Order 未明確定義且平台相依。解決方案:將對話框亦設為置頂(d.setAlwaysOnTop(true))。
模態對話框應永遠位於被阻擋視窗上方。被阻擋視窗移至前景時,其阻擋對話框會隨之移至前景並置於上方;模態對話框移至背景時,所有被阻擋視窗亦會移至背景。
用戶通常無法互動式最小化/最大化/關閉被阻擋視窗(平台相依),但可透過程式呼叫 setVisible(false) 或 dispose() 關閉。
選擇被阻擋視窗時,可能連同阻擋對話框一起移至前景並成為活動視窗(平台相依)。
擁有焦點的模態對話框隱藏時,其擁有者可能成為活動視窗(平台相依);無焦點時活動視窗保持不變。
顯示工具箱模態對話框需 AWTPermission "toolkitModality",防止 Applet 對話框阻擋瀏覽器/JWS 視窗。同樣權限用於從工具箱模態排除視窗。
使用 Toolkit.isModalityTypeSupported(modalityType) 與 Toolkit.isModalExclusionTypeSupported(modalExclusionType) 檢查平台支援度。不支援時模態對話框表現為非模態,排除標記無效果。
預設模態類型為應用程式模態(Dialog.setModal(true)、Dialog(owner, true) 等 API 使用)。JDK 6 前預設為工具箱模態,兩者差異僅在於 JWS 啟動的 Applet 與應用程式互動行為。所有 Java SE 平台 API 變更須經 JSR 270 專家組審核同意。