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

Java Swing 開發實戰:從零構建功能完整的桌面鬧鐘應用程式

     編輯:Java 程式設計入門

前言

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

運行截圖

專案結構圖

主介面效果圖一

主介面效果圖二

主介面效果圖三

關於對話框

二、核心功能模組設計

1. 程式入口 AlarmMain

package 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");
    }
}

2. 選單模組化設計

  • AlarmFile:僅提供 exit() 靜態方法,解耦退出邏輯
  • AlarmBackground:集中管理背景圖片路徑陣列,支援循環切換
  • AlarmHelp:繼承 JFrame 的獨立對話框,使用 GroupLayout 精確佈局
  • AlarmTools:委派 DesktopCapture 實現截圖功能

3. 核心邏輯 MyAlarm 類別

繼承 JFrame,實作 ActionListener,集中處理所有 UI 事件。

關鍵欄位

  • 時間選擇:三個 JComboBox(時/分/秒),含「關閉」選項
  • 快速設定按鈕:±1/±5/±30 分鐘
  • 鬧鈴聲選擇:JComboBox 含 7 種預設聲音
  • 狀態標籤:now 顯示當前時間,result 顯示倒數剩餘時間
  • 系統托盤:MyTray 實例
  • 執行緒控制:running、iconed 標誌

初始化流程 init()

  1. 建立自訂繪圖 JPanel(覆寫 paintComponent 繪製背景)
  2. 建立所有元件、註冊監聽器
  3. 使用 GroupLayout 進行精確佈局(IDE 產生代碼)
  4. 啟動兩個守護執行緒:
    • timeListener():每秒更新當前時間與倒數
    • myListener():每秒檢查是否觸發鬧鈴
  5. 註冊視窗事件:最小化至托盤、關閉確認對話框
  6. 初始化系統托盤 MyTray

倒數計算邏輯 surplus_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(); // 更新狀態:顯示停止鈕、倒數、禁用設定
}

4. 系統托盤 MyTray

  • 實作 MouseListener、ActionListener
  • 左鍵單擊:切換主視窗顯示/隱藏
  • 右鍵選單:截圖、還原、退出
  • 背景執行緒 displayInfoListener():剩餘 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 或獨立執行緒
GroupLayoutIDE 視覺化產生手寫極難維護,建議改用 MigLayout 或 GridBagLayout

四、代碼優化建議(現代化重構方向)

  1. 執行緒安全: 使用 SwingWorker 或 Timer 替代手動 Thread,確保 UI 更新在 EDT
  2. 資源管理: 圖片/聲音改用 getClass().getResourceAsStream() 載入,支援 JAR 打包
  3. 模組解耦: 將鬧鈴邏輯、聲音播放、托盤管理拆分為獨立 Service 類別
  4. 配置外部化: 背景、鈴聲路徑、預設時間移至 properties 檔案
  5. Java 8+ 時間 API: 以 LocalTime、Duration 替代 Calendar 計算倒數
  6. 打包部署: 使用 Maven/Gradle + maven-shade-plugin 或 jpackage 產出原生安裝包

五、完整核心代碼附錄

點擊展開 MyAlarm.java 完整代碼
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
}
點擊展開 MyTray.java 完整代碼
package com.b510.ui.main;
// ... (imports)

public class MyTray implements ActionListener, MouseListener {
    // ... 構造器、actionPerformed、mouseClicked
    // ... displayInfoListener() 背景執行緒
    // ... friendListSet() 視窗顯示控制
}

六、總結

本專案展示了 Swing 開發桌面應用的完整流程:視窗構建、事件驅動、多執行緒協作、系統整合(托盤、聲音、截圖)、資源管理與打包部署。雖然代碼屬教學示範級別,但涵蓋的核心知識點具有普適價值。建議讀者在理解基礎上,嘗試重構為模組化、執行緒安全、可配置的生產級代碼,並嘗試遷移至 JavaFX 體驗現代 UI 開發範式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved