自定義對話框通過繼承 javax.swing.JDialog 實現,核心要點:
super(parent, title, modal) 設置模態性ActionListener 或內部類show() 或 setVisible(true) 顯示入口class HelpAbout extends JDialog implements ActionListener {
JavaWord mainFrame;
JButton okButton;
javax.swing.Timer myTimer;
int counter = 0;
public HelpAbout(JavaWord mainFrame) {
super(mainFrame, "關於本程序的說明", true); // true = 模態
this.mainFrame = mainFrame;
// === 主面板:BorderLayout ===
JPanel contentPanel = new JPanel(new BorderLayout());
// 西側:Logo 圖標
JLabel imageLabel = new JLabel(new ImageIcon(".\\images\\javalogo.gif"));
contentPanel.add(imageLabel, BorderLayout.WEST);
// 北側:作者信息 (不可編輯文本域)
JPanel authorInfoPane = new JPanel(new GridLayout(1, 1));
JTextArea aboutContent = new JTextArea(
"本程序是作者在學習 Java2 Swing 編程的一個簡單程序,\n" +
"並不作為商業目的使用。\n" +
"作者的聯系方式是:\n"
);
aboutContent.setEnabled(false);
authorInfoPane.add(aboutContent);
contentPanel.add(authorInfoPane, BorderLayout.NORTH);
// 中央:系統信息 (降邊框面板 + GridLayout)
JPanel sysInfoPane = new JPanel(new GridLayout(5, 1));
sysInfoPane.setBorder(BorderFactory.createLoweredBevelBorder());
sysInfoPane.add(new JLabel("本機用戶名:" + System.getProperty("user.name")));
sysInfoPane.add(new JLabel("操作系統:" + System.getProperty("os.name")));
sysInfoPane.add(new JLabel("Java 版本:" + System.getProperty("java.version")));
sysInfoPane.add(new JLabel("JVM 總內存:" + Runtime.getRuntime().totalMemory() + " 字節"));
sysInfoPane.add(new JLabel("JVM 剩餘內存:" + Runtime.getRuntime().freeMemory() + " 字節"));
contentPanel.add(sysInfoPane, BorderLayout.CENTER);
// 南側:確定按鈕面板
JPanel okPane = new JPanel();
okButton = new JButton("確定 (O)", new ImageIcon(".\\images\\ok.gif"));
okButton.setMnemonic('O'); // Alt+O 快捷鍵
// 滾動圖標效果
okButton.setRolloverEnabled(true);
okButton.setIcon(new ImageIcon(".\\images\\ok.gif")); // 正常
okButton.setRolloverIcon(new ImageIcon(".\\images\\exit.gif")); // 懸停
okButton.setPressedIcon(new ImageIcon(".\\images\\help.gif")); // 按下
this.getRootPane().setDefaultButton(okButton); // 回車鍵觸發
okButton.addActionListener(this);
okPane.add(okButton);
contentPanel.add(okPane, BorderLayout.SOUTH);
setContentPane(contentPanel);
// setResizable(false); // 可選:固定大小
// 定時器:每秒更新標題演示
myTimer = new javax.swing.Timer(1000, this);
myTimer.start();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == okButton) {
dispose(); // 釋放資源並關閉
} else if (e.getSource() == myTimer) {
counter++;
setTitle("當前定時器值:" + counter + " 秒");
}
}
}
// 在某個事件處理器中 (如菜單項 actionPerformed)
HelpAbout aboutDialog = new HelpAbout(this); // this 為父 Frame
aboutDialog.setSize(500, 500);
aboutDialog.show(); // 或 setVisible(true)
| 技術點 | 實現方式 | 作用 |
|---|---|---|
| 模態對話框 | super(..., true) | 阻塞父窗口交互,聚焦用戶響應 |
| 佈局管理 | BorderLayout + GridLayout | 自適應不同分辨率/字體大小 |
| 系統屬性獲取 | System.getProperty() | 跨平台獲取用戶/OS/Java 信息 |
| 運行時內存信息 | Runtime.getRuntime().totalMemory()/freeMemory() | 監控 JVM 內存狀態 |
| 按鈕滾動效果 | setRolloverIcon/PressedIcon | 增強交互視覺反饋 |
| 默認按鈕 | rootPane.setDefaultButton() | 回車鍵自動觸發確定 |
| 快捷鍵 | setMnemonic('O') | Alt+O 快速關閉 |
| 定時器 | javax.swing.Timer | EDT 安全的周期性任務 |
| 資源釋放 | dispose() | 釋放原生窗口資源,防止內存洩漏 |
getClass().getResource())GridBagLayout 實現更複雜的響應式佈局BaseDialog 封裝通用邏輯 (居中顯示、圖標加載、關閉處理等)JOptionPane.createDialog() 簡化標準對話框創建繼承 JDialog 實現自定義對話框是 Swing 開發核心技能。本例展示了模態設置、多區域佈局、系統信息集成、按鈕狀態圖標、鍵盤交互、定時器任務、資源清理等實戰要點。掌握此模式,可構建從簡單 About 彈窗到複雜向導/屬性編輯器的各類交互組件。