Wicket で、カレンダー表示を汎用的にできないかと考えた。
すくなくとも、HTMLタグと、日付部分だけでも使い回せれば楽になると思った。
<wicket:panel>
<tr class="head">
<th class="sun">日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th class="sat">土</th>
</tr>
<tr wicket:id="calendar_days" class="days">
<td><a wicket:id="sun" class="calendar">
<span wicket:id="sun_day" class="calendar">1</span></a></td>
<td><a wicket:id="mon" class="calendar">
<span wicket:id="mon_day" class="calendar">2</span></a></td>
<td><a wicket:id="tue" class="calendar">
<span wicket:id="tue_day" class="calendar">3</span></a></td>
<td><a wicket:id="wed" class="calendar">
<span wicket:id="wed_day" class="calendar">4</span></a></td>
<td><a wicket:id="thu" class="calendar">
<span wicket:id="thu_day" class="calendar">5</span></a></td>
<td><a wicket:id="fri" class="calendar">
<span wicket:id="fri_day" class="calendar">6</span></a></td>
<td><a wicket:id="sat" class="calendar">
<span wicket:id="sat_day" class="calendar">7</span></a></td>
</tr>
</wicket:panel>
-----------------------------------------------------------
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
/**
* カレンダー日付Panel.
* 前月、翌月リンクは、生成されない
* 前月、翌月リンクデザインを別に用意するためにこのクラスが存在する
*/
public class CalendarDaysPanel extends Panel{
private SimpleDateFormat formatYMD
= new SimpleDateFormat(CalendarRequest.CALENDAR_PARAM_FORMAT);
public CalendarDaysPanel(String id,IModel<CalendarRequest> model){
super(id,model);
final String wds = {"sun","mon","tue","wed","thu","fri","sat"};
final Calendar cal = Calendar.getInstance();
final Calendar calx = Calendar.getInstance();
final CalendarRequest req = model.getObject();
cal.setTime(req.getDate());
cal.set(Calendar.DAY_OF_MONTH,1);
calx.setTime(cal.getTime());
add(new ListView<String>("calendar_days",calendarList(req.getDate()," ")){
@Override
protected void populateItem(ListItem<String> item){
final String days = item.getModelObject();
for(int i=0; i < 7; i++){
final int index = i;
item.add(new BookmarkablePageLink<String>(
wds[i],req.getLinkClass(),makeParameter(
cal.getTime(),req.getPageParameters(),req.getDateParameterName())){
@Override
public boolean isEnabled(){
if (days[index].equals(" ")) return false;
calx.set(Calendar.DAY_OF_MONTH,Integer.parseInt(days[index]));
return req.enable(calx.getTime());
}
}.add(new Label(wds[i]+"_day",days[i]).setEscapeModelStrings(false)
));
if (!days[i].equals(" ")) cal.add(Calendar.DAY_OF_MONTH,1);
}
}
});
}
private List<String> calendarList(Date date,String blank){
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),1);
int firstWeek = c.get(Calendar.DAY_OF_WEEK);
c.add(Calendar.MONTH, 1);
c.set(c.get(Calendar.YEAR),c.get(Calendar.MONTH),1);
c.add(Calendar.DAY_OF_MONTH, - c.get(Calendar.DAY_OF_MONTH));
int endday = c.get(Calendar.DAY_OF_MONTH);
List<String> list = new ArrayList<String>();
int day = 1;
int week = 0;
String s = new String[7];
int o = firstWeek - 1;
for(;week < o;week++){
s[week] = blank;
}
for(int d=day;d <= endday;d++){
if (week==7){
list.add(s);
s = new String[7];
week = 0;
}
s[week] = Integer.toString(d);
week++;
}
for(;week < 7;week++){
s[week] = blank;
}
list.add(s);
return list;
}
// 日付リンクのパラメータ
protected PageParameters makeParameter(Date ndt,PageParameters p,String key){
p.put(key,this.formatYMD.format(ndt));
return p;
}
}
-------------------------------------------------
import java.io.Serializable;
import java.util.Date;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
/**
* カレンダー日付リンク、CalendarDaysPanel よりコールバックされる。.
* enable(Date) を実装し、Date により、日付リンクを張るかどうかを戻すようにする。
* getDateParameterName() で、リンクに付与する日付パラメータ名を戻すようにする。
* 日付パラメータ値=カレンダーの日付文字列は、書式 "yyyyMMdd" である。
* 日付リンクでcallされるページクラスを返すように実装する
*/
public interface CalendarRequest extends Serializable{
public final static String CALENDAR_PARAM_KEY = "ymd";
public final static String CALENDAR_PARAM_FORMAT = "yyyyMMdd";
/**
* カレンダー表示指定する日付 getter
* @return 対象の年、月の日付を返す
*/
public Date getDate();
/**
* カレンダー表示指定する日付 setter
* @return 対象の年、月の日付を返す
*/
public void setDate(Date dt);
/**
* 日付リンク有効性
* @param dt OldCalendarPanel よりコールバックで、日付が指定される
* @return true=日付リンクを張る
*/
public boolean enable(Date dt);
/**
* 日付リンクでcallされるページクラスを返す。
* @return
*/
public Class<? extends WebPage> getLinkClass();
/**
* 日付パラメータ名をCalendarPanel に渡す
* CALENDAR_PARAM_KEY = "ymd" を返すことを奨励
* @return パラメータ名
*/
public String getDateParameterName();
/**
* 日付リンクで日付パラメータ以外に付与するページパラメータを返す
* パラメータ名 = getDateParameterName() が返す値をキーに使用してはいけない。
* @return ページパラメータ
*/
public PageParameters getPageParameters();
}