基於 Java Swing 的桌面日曆應用,整合日曆顯示、日記管理、單詞學習、版本資訊等模組,採用多線程架構,展示 Swing 事件處理、檔案序列化、自定義繪圖等核心技術。
| 類別 | 職責 | 關鍵技術 |
| CalendarApp | 主視窗、模組整合、事件分發 | JFrame、BorderLayout、多線程啟動 |
| CalendarPanel | 日曆核心繪製、月份切換、今日高亮 | GridLayout、GregorianCalendar、自定義渲染 |
| Diary | 日記資料模型、序列化持久化 | Serializable、ObjectOutputStream/InputStream |
| thread_keepDiary | 新增/編輯日記對話框 | Swing 彈窗、即時儲存 |
| thread_scanDiary | 日記列表瀏覽、刪除、彈出選單 | JTable、DefaultTableModel、JPopupMenu |
| thread_showEnglish | 背單詞跑馬燈效果 | 檔案讀取、隨機展示、定時更新 |
| thread_mottoSparkle | 格言閃爍動畫 | 字串截取動畫、獨立線程 |
核心模組代碼精華
1. 日曆面板繪製邏輯
private void showDays() {
jpDays.removeAll();
showDayNames(); // 星期標題
int startingDay = calendar.get(Calendar.DAY_OF_WEEK);
// 上月尾部日期
for (int i = 0; i < startingDay - 1; i++) { ... }
// 本月日期
for (int i = 1; i <= daysInMonth; i++) {
JLabel lbl = jlblDay[...];
if (isToday(i)) {
lbl.setForeground(Color.RED); // 今日紅字
lbl.setFont(boldFont);
} else {
lbl.setForeground(Color.DARK_GRAY);
}
lbl.setText(String.valueOf(i));
jpDays.add(lbl);
}
// 下月開頭日期
...
jpDays.repaint();
}
2. 日記序列化存取
public class Diary implements Serializable {
private String filename, theme, content;
public void write() throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(this);
oos.close();
}
public Diary read() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
return (Diary) ois.readObject();
}
}
3. 背單詞隨機展示線程
public void run() {
// 讀取單詞檔建立索引
List words = Files.readAllLines(Paths.get(wordFile));
SecureRandom random = new SecureRandom();
int[] order = random.ints(0, words.size()).distinct().limit(words.size()).toArray();
while (true) {
for (int idx : order) {
jlbl.setText(words.get(idx));
Thread.sleep(3500); // 3.5 秒切換
}
}
}
技術亮點與改良建議
| 亮點 | 說明 | 現代化改良 |
| 模組化線程設計 | 各功能獨立線程,互不阻塞 | 改用 SwingWorker 或 CompletableFuture |
| 序列化持久化 | 物件直接存檔,無需資料庫 | 改用 JSON (Jackson/Gson) 或 SQLite |
| 自定義日曆渲染 | GridLayout + JLabel 矩陣,控制力強 | 考慮 JCalendar 等成熟元件庫 |
| 彈出選單操作 | JTable 整合 JPopupMenu,體驗佳 | 保留,或改用 JavaFX ContextMenu |
遺留問題與重構方向
- 硬編碼路徑:
C:/Calendar/Diary → 改用 System.getProperty("user.home") + 設定檔
- 單執行緒 GUI 更新:部分線程直接操作 Swing 元件 → 必須用
SwingUtilities.invokeLater
- 異常處理簡陋:僅
printStackTrace → 加入使用者友善提示與日誌記錄
- Java 版本:代碼風格停留在 Java 6/7 → 升級至 Java 17+,使用 var、record、模組化
此專案雖屬教學示例,但完整展示了 Swing 應用的典型架構模式,是理解事件驅動程式設計、多線程 GUI、本地持久化的優秀案例。
- 上一篇文章: Shell 腳本實戰:Linux 伺服器監控與網站可用性檢測自動化
- 下一篇文章: Java 權重演算法實作:廣告加權隨機展示策略
Copyright ©
程式碼之家 All Rights Reserved