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

Java Swing 自定義日期選擇器元件:DateButton 與 CalendarChooser 完整實作

     編輯:Java 程式設計入門

Java 標準庫雖提供 `java.util.Date`、`Calendar`、`DateFormat` 等日期處理類別,但 Swing 缺乏原生日期選擇元件。本文呈現一套完整的自定義解決方案:`DateButton` (顯示/觸發按鈕) + `CalendarChooser` (彈出式月曆對話框),支援視覺化日期選擇、無效日期攔截、多國語系月份/星期顯示。

核心類別架構

類別職責關鍵 API
`DateButton`繼承 `JButton`,顯示格式化日期,點擊彈出 `CalendarChooser``getDate()`、`setDate(Date)`、`addPropertyChangeListener`
`CalendarChooser`繼承 `JDialog`,月曆網格、年/月下拉選單、確定/取消按鈕`select(Date)`、`select()` (回傳選中 Date 或 null)

DateButton 實作精華


public class DateButton extends JButton {
    private Date date;
    private DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT);

    public DateButton() { this(new Date()); }
    public DateButton(Date d) { setDate(d); addActionListener(e -> showChooser()); }

    public Date getDate() { return date; }
    public void setDate(Date d) {
        Date old = this.date;
        this.date = d;
        setText(formatter.format(d));
        firePropertyChange("date", old, d); // 支援 Bean 綁定
    }

    private void showChooser() {
        CalendarChooser chooser = new CalendarChooser(SwingUtilities.getWindowAncestor(this));
        Date selected = chooser.select(date);
        if (selected != null) setDate(selected);
    }
}

CalendarChooser 核心邏輯

1. 月曆網格產生

  • 使用 `GregorianCalendar` 計算某月 1 號星期幾、該月天數。
  • 動態建立 `JButton` 矩陣 (6 行 x 7 列),空白格填入前/後月日期 (灰色)。
  • 今日高亮、選中日期不同背景色。

2. 年/月導航

  • 兩個 `JComboBox`:年份範圍由常數 `FIRST_YEAR` (如 1900) 至 `LAST_YEAR` (如 2100) 定義;月份使用 `DateFormatSymbols.getMonths()` 取得當地化名稱。
  • 切換年/月即時重繪網格。

3. 模態對話框回傳值


public Date select(Date initialDate) {
    setDate(initialDate); // 設定內部日曆顯示
    setVisible(true);     // 阻塞直到使用者按確定/取消/關閉
    return selectedDate;  // 確定回傳選中日期,取消/關閉回傳 null
}

視覺化效果展示

DateButton 外觀:顯示日期的按鈕

圖 A:DateButton 外觀 — 標準按鈕顯示格式化日期 (如「2024/03/15」)。

CalendarChooser 彈出月曆對話框

圖 B:CalendarChooser 月曆對話框 — 年/月下拉選單、星期標題、日期網格、確定/取消按鈕。

國際化與客製化支援

  • 語系適配: 透過 `Locale.getDefault()` 取得預設語系,`DateFormatSymbols` 提供月份/星期名稱。若需指定語系,建構子傳入 `Locale` 參數。
  • 日期格式: `DateButton` 使用 `DateFormat.getDateInstance(SHORT, locale)`,符合各地習慣 (如美式 MM/dd/yyyy、歐式 dd.MM.yyyy)。
  • 視覺微調: 色彩常數 (`TODAY_COLOR`、`SELECTED_COLOR`、`WEEKEND_COLOR`) 集中定義,易於主題切換。

使用範例


JPanel panel = new JPanel();
DateButton db = new DateButton(); // 預設今日
panel.add(db);

// 監聽日期變更
db.addPropertyChangeListener("date", evt -> {
    Date newDate = (Date) evt.getNewValue();
    System.out.println("使用者選擇: " + newDate);
    // 觸發業務邏輯:查詢該日期報表、設定截止日等
});

設計模式應用

  • Composite: `CalendarChooser` 內部月曆網格由 `JPanel` 容器管理 `JButton` 子元件。
  • Factory Method: `CalendarChooser.select()` 靜態工廠方法封裝對話框建立、顯示、回傳流程。
  • Observer: `DateButton` 透過 `PropertyChangeSupport` 發射日期變更事件。

這套元件展示了 Swing 輕量級元件模型的擴充威力:無需原生對等體 (Peer),純 Java 即可構建豐富、跨平台、可高度客製化的 UI 控制項。

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