Swing 是 Java 標準庫提供的輕量級 GUI 工具包,雖然現代開發多轉向 JavaFX 或 Web 技術,但 Swing 仍廣泛應用於企業內部工具、教學示範與跨平台桌面小工具。本文將完整呈現一個基於 Swing 的鬧鐘專案:從專案結構、UI 佈局、系統托盤整合、多執行緒計時、聲音播放到背景切換,助你掌握 Swing 核心開發流程。
Alarm/
├── src/
│ ├── com/b510/main/AlarmMain.java // 程式入口
│ ├── com/b510/menu/ // 選單功能模組
│ │ ├── AlarmBackground.java // 背景圖片管理
│ │ ├── AlarmFile.java // 檔案選單(退出)
│ │ ├── AlarmHelp.java // 關於對話框
│ │ └── AlarmTools.java // 工具選單(截圖)
│ └── com/b510/ui/main/ // 核心 UI 與邏輯
│ ├── MyAlarm.java // 主視窗、計時、鬧鈴邏輯
│ └── MyTray.java // 系統托盤圖示與右鍵選單
└── image/ // 圖片、聲音資源
├── background.png
├── background1.png
├── background2.png
├── sound/alarm0.wav ~ alarm8.wav
└── mytray.png





AlarmMainpackage com.b510.main;
import com.b510.ui.main.MyAlarm;
public class AlarmMain {
public static void main(String[] args) {
new MyAlarm("Alarm hongten v-1.0");
}
}
exit() 靜態方法,解耦退出邏輯JFrame 的獨立對話框,使用 GroupLayout 精確佈局DesktopCapture 實現截圖功能MyAlarm 類別繼承 JFrame,實作 ActionListener,集中處理所有 UI 事件。
JComboBox(時/分/秒),含「關閉」選項JComboBox 含 7 種預設聲音now 顯示當前時間,result 顯示倒數剩餘時間MyTray 實例running、iconed 標誌init()JPanel(覆寫 paintComponent 繪製背景)GroupLayout 進行精確佈局(IDE 產生代碼)timeListener():每秒更新當前時間與倒數myListener():每秒檢查是否觸發鬧鈴MyTraysurplus_time()核心邏輯:目標時間 - 當前時間,處理跨時、跨分、跨秒借位,跨天加 24 小時。若剩餘 30 秒觸發托盤提醒。
executeSound()AlarmSound 內部類實作 Runnable,使用 javax.sound.sampled 串流播放 WAV以 +30 為例:
private void add30Action() {
isHMSZero(); // 若未設定,先同步當前時間
if (minuteCombo.getSelectedIndex() + 30 > 60) {
minuteCombo.setSelectedIndex(minuteCombo.getSelectedIndex() - 30);
hourCombo.setSelectedIndex(hourCombo.getSelectedIndex() + 1); // 進位
} else {
minuteCombo.setSelectedIndex(minuteCombo.getSelectedIndex() + 30);
}
valueJudgment(); // 更新狀態:顯示停止鈕、倒數、禁用設定
}
MyTrayMouseListener、ActionListenerdisplayInfoListener():剩餘 30 秒彈出 TrayIcon.displayMessage 提醒;背景切換時提示| 技術點 | 實現方式 | 注意事項 |
|---|---|---|
| 自訂背景繪製 | 繼承 JPanel 覆寫 paintComponent() | 需調用 super.paintComponent(g);圖片路徑相對 classpath |
| 多執行緒定時 | new Thread + while(true) + Thread.sleep(1000) | UI 更新需在 EDT 執行,示例直接更新較簡單但非最佳實踐 |
| 聲音播放 | AudioSystem → AudioInputStream → SourceDataLine | 需處理格式轉換、緩衝區讀寫、資源關閉 |
| 系統托盤 | SystemTray + TrayIcon + PopupMenu | 需檢查 SystemTray.isSupported();圖示載入用 ClassLoader |
| 視窗震動 | 循環 setLocation(x±5, y±5) | 循環次數過多會卡死 EDT,建議用 Timer 或獨立執行緒 |
| GroupLayout | IDE 視覺化產生 | 手寫極難維護,建議改用 MigLayout 或 GridBagLayout |
SwingWorker 或 Timer 替代手動 Thread,確保 UI 更新在 EDTgetClass().getResourceAsStream() 載入,支援 JAR 打包LocalTime、Duration 替代 Calendar 計算倒數maven-shade-plugin 或 jpackage 產出原生安裝包package com.b510.ui.main;
// ... (imports)
public class MyAlarm extends JFrame implements ActionListener {
// ... 完整欄位、init()、initMainPanel()、omponentLayout()
// ... timeListener(), myListener(), surplus_time(), executeSound()
// ... actionPerformed() 事件分發
// ... addXAction(), minusXAction(), valueJudgment(), hsmCheck()
// ... stopActionPerformed(), changeBG(), shack()
// ... 內部類 AlarmSound implements Runnable
}
package com.b510.ui.main;
// ... (imports)
public class MyTray implements ActionListener, MouseListener {
// ... 構造器、actionPerformed、mouseClicked
// ... displayInfoListener() 背景執行緒
// ... friendListSet() 視窗顯示控制
}
本專案展示了 Swing 開發桌面應用的完整流程:視窗構建、事件驅動、多執行緒協作、系統整合(托盤、聲音、截圖)、資源管理與打包部署。雖然代碼屬教學示範級別,但涵蓋的核心知識點具有普適價值。建議讀者在理解基礎上,嘗試重構為模組化、執行緒安全、可配置的生產級代碼,並嘗試遷移至 JavaFX 體驗現代 UI 開發範式。