JavaFX Cell Factory(5)日期選擇器 by 黃嘉輝 | CodeData
top

JavaFX Cell Factory(5)日期選擇器

分享:

JavaFX Cell Factory(4)樹狀表格 << 前情

JavaFX 8新增日期選擇器 (Date Picker),其類別為DatePicker,用以選擇日期,DatePicker繼承自ComboBoxBase抽象類別,因此其樣式類似於複合方塊 (Combo Box)。下圖為JavaFX日期選擇器的樣式,包括左側的編輯物件與右側的按鈕,當點選按鈕時,則顯示日期選擇器:

Date Picker

DatePicker類別定義以下的屬性值:

  • chronology:年曆系統。
  • converter:日期字串與日期格式間之型別轉換器。
  • dayCellFactory:日期選擇器的Cell Factory。
  • editor:日期選擇器的編輯物件。
  • showWeekNumbers:是否顯示週次。

其中年曆系統由java.time.chrono套件處理,chrono為Java S.E. 8新增的套件,內建支援以下年曆系統之類別:

  • HijrahChronology類別:伊斯蘭年曆系統。
  • IsoChronology類別:支援ISO-8601日期與時間表示方法之年曆系統。
  • JapaneseChronology類別:日本年曆系統,如明治、大正、昭和、平成等年曆。
  • MinguoChronology類別:中華民國年曆系統。
  • ThaiBuddhistChronology類別:泰國佛歷系統。

此外,DatePicker類別如同ComboBox類別一樣支援Cell Factory,藉由設定Cell Factory將日期選擇器中的每一個日期變更為其他內容與格式。

DatePicker類別的建構函式如下,其中參數localDate設定指定日期:

  public DatePicker()
  public DatePicker(java.time.LocalDate localDate)

DatePicker類別的方法包括:

  • getChronology():取得日期選擇器的年曆系統。
  • setChronology():設定日期選擇器的年曆系統。
  • getConverter():取得日期格式的型別轉換器。
  • setConverter():設定日期格式的型別轉換器。
  • getDayCellFactory():取得日期選擇器的Cell Factory。
  • setDayCellFactory():設定日期選擇器的Cell Factory。
  • getEditor():取得日期選擇器的編輯物件。
  • isShowWeekNumbers():判斷是否顯示週次。
  • setShowWeekNumbers():設定是否顯示週次。
  • getValue():取得所選擇的日期。
  • setValue():設定日期。

以下範例以選單分別選擇年曆系統、設定今天日期與是否顯示週次。以選擇年曆系統為例,當選擇各年曆的選單項目時,則以setChronology()方法設定日期選擇器的年曆系統:

ToggleGroup togglegroup = new ToggleGroup();

RadioMenuItem radiomenuitem1 = new RadioMenuItem("Hijrah");
radiomenuitem1.setSelected(false);
radiomenuitem1.setToggleGroup(togglegroup);
radiomenuitem1.setOnAction((ActionEvent e) -> {
  // 設定伊斯蘭年曆系統
  datepicker.setChronology(HijrahChronology.INSTANCE);
});

RadioMenuItem radiomenuitem2 = new RadioMenuItem("ISO-8601");
radiomenuitem2.setSelected(true);
radiomenuitem2.setToggleGroup(togglegroup);
radiomenuitem2.setOnAction((ActionEvent e) -> {
  // 設定ISO-8601年曆系統
  datepicker.setChronology(IsoChronology.INSTANCE);
});

RadioMenuItem radiomenuitem3 = new RadioMenuItem("Japanese");
radiomenuitem3.setSelected(false);
radiomenuitem3.setToggleGroup(togglegroup);
radiomenuitem3.setOnAction((ActionEvent e) -> {
  // 設定日本年曆系統
  datepicker.setChronology(JapaneseChronology.INSTANCE);
});

RadioMenuItem radiomenuitem4 = new RadioMenuItem("R.O.C.");
radiomenuitem4.setSelected(false);
radiomenuitem4.setToggleGroup(togglegroup);
radiomenuitem4.setOnAction((ActionEvent e) -> {
  // 設定中華民國年曆系統
  datepicker.setChronology(MinguoChronology.INSTANCE);
});

RadioMenuItem radiomenuitem5 = new RadioMenuItem("Thai Buddhist");
radiomenuitem5.setSelected(false);
radiomenuitem5.setToggleGroup(togglegroup);
radiomenuitem5.setOnAction((ActionEvent e) -> {
  // 設定泰國佛歷年曆系統
  datepicker.setChronology(ThaiBuddhistChronology.INSTANCE);
});
...

【執行結果】

以下為選擇伊斯蘭年曆系統的執行結果:

Date Picker

以下為選擇中華民國年曆系統的執行結果:

Date Picker

當選擇設定今天日期的選單項目時,則以setValue()方法設定今天日期:

CheckMenuItem checkmenuitem1 = new CheckMenuItem("Set Date");
checkmenuitem1.setSelected(false);
checkmenuitem1.setOnAction((ActionEvent e) -> {
  CheckMenuItem chkmenuitem = (CheckMenuItem) e.getSource();

  if (chkmenuitem.isSelected()) {
    LocalDate today = LocalDate.now();
    // 設定今天日期
    datepicker.setValue(today);
  }
});
...

【執行結果】

以下為設定今天日期的執行結果,並以中華民國年曆系統呈現:

Date Picker

以下範例設定日期格式與日期選擇器的Cell Factory。以設定日期格式為例,範例以DateTimeFormatter類別設定日期格式,並以DatePicker類別的setConverter()方法設定日期格式的型別轉換器:

// 設定日期格式
String pattern = "MMM-dd-yyyy";

StringConverter converter = new StringConverter() {
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

  @Override public String toString(LocalDate date) {
    if (date != null) {
      return formatter.format(date);
    } 
    else {
      return "";
    }
  }

  @Override public LocalDate fromString(String string) {
    if (string != null && !string.isEmpty()) {
      return LocalDate.parse(string, formatter);
    } 
    else {
      return null;
    }
  }
};             

datepicker = new DatePicker(); 
// 設定日期格式的型別轉換器
datepicker.setConverter(converter);
...

【執行結果】

Date Picker

欲設定日期選擇器的Cell Factory,則以setDayCellFactory()方法設定日期選擇器的Cell Factory,並在Cell Factory中分別設定今日之前日期的背景顏色與今日之後日期的提示說明:

// 設定日期選擇器的Cell Factory
datepicker.setDayCellFactory(new Callback<DatePicker, DateCell>() {
  @Override public DateCell call(final DatePicker datePicker) {
    return new DateCell() {
      @Override public void updateItem(LocalDate item, boolean empty) {
        super.updateItem(item, empty);

        LocalDate today = LocalDate.now();
        LocalDate tomorrow = today.plusDays(1);

        if (item.isBefore(today)) {
          setDisable(true);
          // 設定背景顏色
          setStyle("-fx-background-color: #93d1f0;");
        }   
        else if (item.equals(today)) {
          // 設定提示說明
          setTooltip(new Tooltip("Today is " + today));
        }
        else if (item.equals(tomorrow)) {
          // 設定提示說明
          setTooltip(new Tooltip("Tomorrow is " + tomorrow));
        }
        // 設定提示說明
        else if (item.isAfter(tomorrow)) {
          setTooltip(new Tooltip("Day after " + tomorrow));
        }
      }
    };
  }
});
...

【執行結果】

Date Picker

【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

關於作者

黃嘉輝副教授,目前任職於國立臺北商業大學企業管理學系,喜歡寫程式,特別愛Java,範例可參考教學網站

熱門論壇文章

熱門技術文章