AJAXカレンダー(2)

デザインまで依存すれば、前回の投稿AJAXカレンダーのように、Panel の呼び出し側で
負担がかかることはない。しかし、デザインは自由度が制限される
ここで悩んでいた。
突き詰めれば、以下のWebPage記述で済む。
public class CalendarTestPage extends WebPage{

   public CalendarTestPage(){

      CalenderHelper helper = new CalenderHelper(getRequestCycle());
      
      add(new CalendarPanel("calendar",new Model<CalendarRequest>(
            new CalendarRequestImpl(helper.getTargetDate(),FooPage.class,new PageParameters())
      ))
);
   }
}
--------------------------------------------
これを実現するためにHTMLとPanel クラスは以下のようになる。

CalendarPanel.html の記述、、、、

<wicket:panel>
<table class="calendar">
<tr><td><a wicket:id="prev" class="calendar"><</a></td>
<td colspan="5"><span wicket:id="year"></span>年  <span wicket:id="month"></span>月</td>
<td><a wicket:id="next" class="calendar">></a></td>
</tr>
<tr class="head"><th class="sun">日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th class="sat">土</th></tr>
<tbody wicket:id="tbody">
<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">1</span></a></td>
    <td><a wicket:id="tue" class="calendar"><span wicket:id="tue_day" class="calendar">1</span></a></td>
    <td><a wicket:id="wed" class="calendar"><span wicket:id="wed_day" class="calendar">1</span></a></td>
    <td><a wicket:id="thu" class="calendar"><span wicket:id="thu_day" class="calendar">1</span></a></td>
    <td><a wicket:id="fri" class="calendar"><span wicket:id="fri_day" class="calendar">1</span></a></td>
    <td><a wicket:id="sat" class="calendar"><span wicket:id="sat_day" class="calendar">1</span></a></td>
</tr>
</tbody>
</table>
</wicket:panel>

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.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.WebMarkupContainer;
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.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

/**
 * 月移動リンク付きカレンダー.
 * 前月、翌月リンクは、このPanel内で生成される。
 */

public class CalendarPanel extends Panel{
   private IModel<Date> targetDateModel;
   private SimpleDateFormat formatYMD
    = new SimpleDateFormat(CalendarRequest.CALENDAR_PARAM_FORMAT);
   private IModel<CalendarRequest> reqModel;
   public CalendarPanel(String id,final IModel<CalendarRequest> model){
      super(id,model);
      this.reqModel = model;
      final CalenderHelper helper = new CalenderHelper(getRequestCycle());
      final Calendar cal = Calendar.getInstance();
      final CalendarRequest req = model.getObject();
      cal.setTime(req.getDate());
      cal.set(Calendar.DAY_OF_MONTH,1);
      this.targetDateModel = new Model<Date>(cal.getTime());
      // table  tbody
      final WebMarkupContainer tbody = new WebMarkupContainer("tbody");
      tbody.setOutputMarkupId(true);
      final ListView<String> daylist = createListView(req);
      daylist.setOutputMarkupId(true);
      tbody.add(daylist);
      add(tbody);
      // 年の表示
      final Label year = new Label("year",new AbstractReadOnlyModel<String>(){
         @Override
         public String getObject(){
            Calendar c = Calendar.getInstance();
            c.setTime(getTargetDateModel().getObject());
            return Integer.toString(c.get(Calendar.YEAR));
         }
      });
      year.setOutputMarkupId(true);
      add(year);
      // 月の表示
      final Label month = new Label("month",new AbstractReadOnlyModel<String>(){
         @Override
         public String getObject(){
            Calendar c = Calendar.getInstance();
            c.setTime(getTargetDateModel().getObject());
            return Integer.toString(c.get(Calendar.MONTH)+1);
         }
      });
      month.setOutputMarkupId(true);
      add(month);
      // 前月&翌月リンク
      add(new WebMarkupContainer("prev").add(new AjaxEventBehavior("onclick"){
         @Override
         protected void onEvent(AjaxRequestTarget target){
            setTargetDateModelDate(helper.prevDate(getTargetDateModel()));
            CalendarRequest calendarRequest = getReqModel().getObject();
            calendarRequest.setDate(getTargetDateModelDate());
            tbody.remove("calendar_days");
            tbody.add(createListView(calendarRequest));
            target.addComponent(tbody);
            target.addComponent(year);
            target.addComponent(month);
         }
      }));
      add(new WebMarkupContainer("next").add(new AjaxEventBehavior("onclick"){
         @Override
         protected void onEvent(AjaxRequestTarget target){
            setTargetDateModelDate(helper.nextDate(getTargetDateModel()));
            CalendarRequest calendarRequest = getReqModel().getObject();
            calendarRequest.setDate(getTargetDateModelDate());
            tbody.remove("calendar_days");
            tbody.add(createListView(calendarRequest));
            target.addComponent(tbody);
            target.addComponent(year);
            target.addComponent(month);
         }
      }));
   }

   protected ListView<String
> createListView(final CalendarRequest req){
      final String wds = {"sun","mon","tue","wed","thu","fri","sat"};
      final Calendar cal = Calendar.getInstance();
      final Calendar calx = Calendar.getInstance();
      cal.setTime(req.getDate());
      cal.set(Calendar.DAY_OF_MONTH,1);
      this.targetDateModel = new Model<Date>(cal.getTime());
      calx.setTime(cal.getTime());
      return  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;
   }

   protected void setTargetDateModelDate(Date dt){
      this.targetDateModel.setObject(dt);
   }
   protected Date getTargetDateModelDate(){
      return this.targetDateModel.getObject();
   }
   protected IModel<Date> getTargetDateModel(){
      return this.targetDateModel;
   }

   protected IModel<CalendarRequest> getReqModel(){
      return this.reqModel;
   }
   protected void setReqModel(IModel<CalendarRequest> reqModel){
      this.reqModel = reqModel;
   }

}