javax.swing.JOptionPane 提供標準化模態對話框,涵蓋確認、輸入、信息、選項四大類型,是桌面應用快速交互的首選工具。本文系統整理 API 分類、參數含義、實戰代碼模板與進階定製技巧。
| 類型 | 靜態方法 | 用途 | 返回值 |
|---|---|---|---|
| 確認對話框 | showConfirmDialog | 是/否/取消決策 | int (YES/NO/CANCEL/OK/CLOSED_OPTION) |
| 輸入對話框 | showInputDialog | 文本輸入/下拉選擇 | String 或 Object (用戊選項) |
| 信息對話框 | showMessageDialog | 提示/警告/錯誤通知 | void |
| 選項對話框 | showOptionDialog | 完全自定義按鈕組合 | int (按鈕索引 0-based) |
// 完整參數列表 (以 showOptionDialog 為例)
public static int showOptionDialog(
Component parentComponent, // 父組件,null=居中螢幕
Object message, // 顯示內容:String、Component、Icon、Object[]
String title, // 標題欄文字
int optionType, // 按鈕組合類型
int messageType, // 圖標類型
Icon icon, // 自定義圖標 (覆蓋 messageType)
Object[] options, // 自定義按鈕文本/組件數組
Object initialValue // 默認聚焦按鈕
)
DEFAULT_OPTION:單「OK」按鈕YES_NO_OPTION:「是/否」YES_NO_CANCEL_OPTION:「是/否/取消」OK_CANCEL_OPTION:「確定/取消」ERROR_MESSAGE:紅叉 ❌INFORMATION_MESSAGE:藍 i ℹ️WARNING_MESSAGE:黃 ⚠️QUESTION_MESSAGE:藍 ? ❓PLAIN_MESSAGE:無圖標
JOptionPane.showMessageDialog(
null, // 居中
"操作成功完成!", // 內容
"成功", // 標題
JOptionPane.INFORMATION_MESSAGE // 圖標
);
int result = JOptionPane.showConfirmDialog(
parentFrame,
"確定要刪除選中的 3 條記錄嗎?\n此操作不可恢復。",
"確認刪除",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.YES_OPTION) {
// 執行刪除
}
String input = JOptionPane.showInputDialog(
null,
"請輸入用戶名:",
"用戶登錄",
JOptionPane.QUESTION_MESSAGE
);
if (input != null && !input.trim().isEmpty()) {
// 用戶點擊 OK 且輸入非空
}
Object[] roles = {"管理員", "操作員", "訪客", "審核員"};
Object selected = JOptionPane.showInputDialog(
null,
"選擇角色:",
"角色授權",
JOptionPane.INFORMATION_MESSAGE,
null, // 無自定義圖標
roles, // 選項數組
roles[0] // 默認選中
);
if (selected != null) {
System.out.println("用戶選擇: " + selected);
}
Object[] options = {"查詢餘額", "存款", "取款", "退出"};
int choice = JOptionPane.showOptionDialog(
null,
"請選擇業務類型",
"ATM 服務",
JOptionPane.YES_OPTION, // optionType 忽略 (有自定義 options)
JOptionPane.PLAIN_MESSAGE, // 無圖標
null, // 無自定義圖標
options, // 按鈕文本
options[0] // 默認聚焦
);
switch (choice) {
case 0: showMessage("您選擇了查詢餘額"); break;
case 1: showMessage("您選擇了存款"); break;
case 2: showMessage("您選擇了取款"); break;
case 3: showMessage("您選擇了退出"); break;
case JOptionPane.CLOSED_OPTION: showMessage("用戶關閉對話框"); break;
}
ImageIcon icon = new ImageIcon(getClass().getResource("/icons/logo.png"));
JOptionPane.showMessageDialog(null, "品牌專屬提示", "標題", JOptionPane.PLAIN_MESSAGE, icon);
JPanel panel = new JPanel(new GridLayout(3,2));
panel.add(new JLabel("用戶名:")); panel.add(new JTextField(15));
panel.add(new JLabel("密碼:")); panel.add(new JPasswordField(15));
panel.add(new JLabel("記住我:")); panel.add(new JCheckBox());
int result = JOptionPane.showConfirmDialog(null, panel, "登錄", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
// 從 panel 子組件獲取值
}
// JOptionPane 本身是模態的,如需非模態需直接使用 JDialog
JDialog dialog = new JDialog(frame, "非模態提示", false);
dialog.add(new JLabel("後台處理中..."));
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
UIManager 控制:UIManager.put("OptionPane.yesButtonText", "確定")UIManager.setLookAndFeel(new FlatLightLaf()) (FlatLaf 現代主題)| 問題 | 原因 | 解決 |
|---|---|---|
| 對話框不居中 | parentComponent 為 null 但有多螢幕 | 傳入具體 Frame 或用 setLocationRelativeTo |
| 輸入框返回 null | 用戶點擊取消/關閉/ESC | 判空處理:if (input != null) |
| 中文顯示方塊 | 字體不支援中文 | 設置全局字體:UIManager.put("OptionPane.font", new Font("微軟雅黑", Font.PLAIN, 14)) |
| 模態阻塞 EDT | 長耗時操作在事件線程 | 耗時任務放 SwingWorker,對話框僅收集參數 |
JOptionPane 以靜態工廠方法封裝了最常見的模態交互模式,**優先使用最簡單的方法** (showMessageDialog/showConfirmDialog/showInputDialog),複雜場景才用 showOptionDialog 或直接構建 JDialog。注意模態阻塞 EDT,保持對話框邏輯輕量,複雜表單建議獨立視圖組件。