カレンダー(1)

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();
}