該程序使用 `java.awt` 包構建獨立窗口應用(繼承 `Frame`),核心邏輯封裝在 `CalenderCreator` 類中,包含:
p1 = new Panel(new FlowLayout()); // 頂部控制區
p2 = new Panel(new GridLayout(7, 7, 10, 10)); // 日曆網格
for (int i = 0; i < 49; i++) {
days[i] = new Button(""); // 預創建 49 個按鈕
p2.add(days[i]);
}
固定 49 個按鈕(7 行 × 7 列),避免動態創建開銷,體現資源復用思想。
void setVal(Date date, int iday, int iselMonth, int iselYear) {
gc.setTime(date);
if (大月) totdays = 31;
else if (小月) totdays = 30;
else if (二月) totdays = gc.isLeapYear(iselYear) ? 29 : 28;
setButtons(iday, totdays); // 填充按鈕標籤
}
利用 `GregorianCalendar.isLeapYear()` 簡化閏年判斷,代碼清晰易維護。
void setButtons(int myday, int mytotdays) {
// 表頭
days[0].setLabel("SUN"); ... days[6].setLabel("SAT");
// 空白佔位(上月尾巴)
int count = 7;
for (int blank = myday; blank > 0; blank--, count++) days[count].setLabel("");
// 當月日期
for (int i = 1; i <= mytotdays; i++, count++) days[count].setLabel(String.valueOf(i));
// 清空剩餘
while (count < 49) days[count++].setLabel("");
}
`myday` 為當月 1 號對應的星期索引(0=周日),精確控制對齊。
myLis:月份/年份下拉框變化 → 重新計算並刷新網格。myAction:年份輸入框回車 → 動態擴充年份下拉框選項(1990 至輸入年份)。| 維度 | AWT 原版 | Swing 改造 | JavaFX 改造 |
|---|---|---|---|
| 組件體系 | 重量級、平台相關 | 輕量級、跨平台一致 | 場景圖、GPU 加速、CSS 樣式 |
| 佈局管理 | FlowLayout/GridLayout | BorderLayout/MigLayout 更靈活 | FXML + AnchorPane/GridPane 聲明式 |
| 日期時間 API | Date/Calendar(已過時) | 同左 | java.time.LocalDate/YearMonth(現代標準) |
| 事件模型 | Listener 接口匿名類 | 同左,可用 Lambda 簡化 | Lambda + 方法引用,更簡潔 |
| 打包部署 | JAR + JRE | 同左 | jlink 定制運行時、原生安裝包 |
這段 AWT 代碼雖屬教學級示例,但展示了日曆核心算法(星期對齊、月長度、閏年)與事件驅動架構的經典實現。理解其邏輯後,遷移至 Swing/JavaFX 僅是組件替換與 API 升級,**核心算法完全可復用**。建議初學者先跑通 AWT 版理解原理,再嘗試 JavaFX 版體驗現代開發效率。