| 屬性 | 值 |
| id | startCalendar |
| dateFormatPatternHelp | MM/dd/yyyy |
| label | Start Date: |
| required | true |
- 右側放置 訊息 組件,Ctrl+Shift 拖曳連線至日曆(綁定錯誤訊息顯示)
- 下方放置 靜態文字(id:
validationMsgStaticText)與 按鈕(id: validateButton,文字 "Validate")
2. 驗證按鈕 Action 程式碼
public String validateButton_action() {
validationMsgStaticText.setText(
(String) DateFormat.getDateInstance(DateFormat.MEDIUM)
.format(startCalendar.getSelectedDate())
+ " is a valid date.");
return null;
}
- 右鍵程式碼 → 修正匯入 解決
DateFormat 找不到
- 部署執行:預設可選範圍為「今天前 100 年 ~ 後 100 年」


第二階段:限制日曆範圍(今天 ~ 一年後)
1. preprocess() 清除舊訊息
public void preprocess() {
validationMsgStaticText.setText("");
}
2. prerender() 預填今天日期
public void prerender() {
java.util.Calendar date = GregorianCalendar.getInstance();
if (startCalendar.getSelectedDate() == null) {
startCalendar.setSelectedDate(date.getTime());
}
}
3. 新增 getMinCalDate() / getMaxCalDate() 方法
private Date minCalDate;
public Date getMinCalDate() {
java.util.Calendar date = java.util.Calendar.getInstance(
FacesContext.getCurrentInstance().getViewRoot().getLocale());
// 歸零時間部分,避免時分秒影響比較
date.set(java.util.Calendar.HOUR_OF_DAY, 0);
date.set(java.util.Calendar.MINUTE, 0);
date.set(java.util.Calendar.SECOND, 0);
date.set(java.util.Calendar.MILLISECOND, 0);
return date.getTime(); // 今天 00:00:00
}
private Date maxCalDate;
public Date getMaxCalDate() {
java.util.Calendar date = GregorianCalendar.getInstance();
date.set(java.util.Calendar.HOUR_OF_DAY, 0);
date.add(java.util.Calendar.YEAR, 1); // 一年後
maxCalDate = date.getTime();
return maxCalDate;
}
4. 屬性綁定
- 右鍵日曆 → 屬性綁定
minDate 綁定 Page1.minCalDate
maxDate 綁定 Page1.maxCalDate

第三階段:雙日期區間驗證(行程至少一週)
1. 新增結束日期日曆
- id:
endCalendar,label: "End Date:",required: true
- 同樣綁定
minDate/maxDate 至同一組 getter
- 右側加 訊息 組件綁定錯誤顯示

2. 結束日期驗證事件
- 右鍵
endCalendar → 編輯事件處理程序 → validate
public void endCalendar_validate(FacesContext context,
UIComponent component, Object value) {
java.util.Calendar endDate = GregorianCalendar.getInstance();
endDate.setTime((Date) value);
java.util.Calendar startDate = GregorianCalendar.getInstance();
startDate.setTime(startCalendar.getSelectedDate());
if (startCalendar.getSelectedDate() != null) {
if (startDate.after(endDate)) {
throw new ValidatorException(new FacesMessage(
"End date must be after start date."));
} else {
startDate.add(java.util.Calendar.DATE, 7); // 加 7 天
if (startDate.after(endDate)) {
throw new ValidatorException(new FacesMessage(
"End date must be at least one week after the start date."));
}
}
}
}
- 右鍵 → 修正匯入 解決
FacesMessage, ValidatorException
3. 修改驗證按鈕顯示區間
public String validateButton_action() {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, MMM d, yyyy");
validationMsgStaticText.setText(
formatter.format(startCalendar.getSelectedDate())
+ " - "
+ formatter.format(endCalendar.getSelectedDate())
+ " is a valid date range.");
return null;
}

第四階段:日曆樣式客製化
- 將圖片
table_title_solid.gif 放入 web/resources/
- 編輯
stylesheet.css,視 JSF 版本貼上對應 CSS:
JSF 1.1
.CalPopDiv .DatSelDiv { background-image: url(table_title_solid.gif); }
.CalPopDiv .DatDayHdrTxt { color: red; }
JSF 1.2
.CalPopDiv_sun4 .DatSelDiv_sun4 { background-image: url(table_title_solid.gif); }
.CalPopDiv_sun4 .DatDayHdrTxt_sun4 { color: red; }
- 第一行:彈出日曆標題背景圖
- 第二行:星期標題字體變紅
完整 CSS 類別清單請參考 NetBeans 線上說明搜尋「日曆組件 CSS 類」。
進階技巧:動態調整日期範圍
| 需求 | 程式碼片段 |
| 最大日期 = 最小日期 + 1 週 | date.add(java.util.Calendar.DATE, 7); |
| 顯示前 10 年 | date.add(java.util.Calendar.YEAR, -10); |
| 自訂日期格式 | 屬性視窗 dateFormatPattern 點選省略號按鈕,或手動輸入如 yyyy/MM/dd |
總結
本教學完整涵蓋:
- 日曆組件基本佈局與驗證訊息綁定
preprocess/prerender 生命週期控制預設值與清除舊訊息
- Getter 方法動態提供
minDate/maxDate 並透過屬性綁定生效
- 雙日期跨欄位驗證(
validate 事件)實作業務規則
- CSS 客製化日曆外觀
掌握這套流程,即可在任何 JSF 專案中快速建構健壯、美觀的日期輸入介面。
- 上一篇文章: Java 核心基礎知識深度解析:六大必懂觀念,初學者與進階者的分水嶺
- 下一篇文章: Java 面向對象技術在軟體重用與系統架構中的核心應用
Copyright ©
程式碼之家 All Rights Reserved