パンくずリスト

Wicketパンくずリストを実現する場合、よく紹介されるのが、
wicket-extensions のある org.apache.wicket.extensions.breadcrumb であるが、
これは、Panel を対象にしている。Page 遷移でのパンくずリストには使えそうもない。

そこで、アノテーションで Page クラスに、パンくずリスト
表示する名称を与える方法を考えた。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * パンくずリストに表示する Page クラスアノテーション
 * リスト表示のラベル名を付ける
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CrumbsMark{
   String value();
}

--------------------------------------------------
import java.io.Serializable;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
/**
 * パンくずリストPageリンクStack要素
 */

public final class Crumbs implements Serializable{
   private Class<? extends Page> pageclass;
   private PageParameters params;
   private String linkDisplay;
   private int mountcount;
   protected Crumbs(String linkDisplay
,Class<? extends Page> pageclass
,PageParameters params,int mountcount){
      this.linkDisplay = linkDisplay;
      this.pageclass = pageclass;
      this.params = params;
      this.mountcount = mountcount;
   }
   public Class<? extends Page> getPageclass(){
      return this.pageclass;
   }
   public PageParameters getParams(){
      return this.params;
   }
   public String getLinkDisplay(){
      return this.linkDisplay;
   }
   public int getMountcount(){
      return this.mountcount;
   }
}
-------------------------------------------------------------

WebSession で、Crumbs のStack を用意する。

public class FooSession extends WebSession{
   private Stack<Crumbs> crumbsStack;
   public FooSession(Request request){
      super(request);
      this.crumbsStack = new Stack<Crumbs>();
   }
   public void pushCrumbsStack(Crumbs c){
      if (this.crumbsStack.isEmpty()){
         this.crumbsStack.push(c);
         dirty();
      }else{
         Crumbs top = this.crumbsStack.peek();
         if (!top.getPageclass().equals(c.getPageclass())){
            this.crumbsStack.push(c);
            dirty();
         }
      }
   }
   public Crumbs popCrumbsStack(){
      Crumbs rtn = this.crumbsStack.pop();
      dirty();
      return rtn;
   }
   public boolean isEmptyCrumbsStack(){
      return this.crumbsStack.isEmpty();
   }
   public Iterator<Crumbs> iteratorCrumbsStack(){
      if (this.crumbsStack==null) this.crumbsStack = new Stack<Crumbs>();
      return this.crumbsStack.iterator();
   }
   public int sizeCrumbsStack(){
      return this.crumbsStack.size();
   }

}
-------------------------------------------------------------

各ページの基底ページを用意してそこでパンくずリストを表示する

public class BaseWebPage extends WebPage{
   public BaseWebPage(){
      super();
      // パンくずリスト
      List<Crumbs> crumbsList = new ArrayList<Crumbs>();
      for(Iterator<Crumbs> it=session.iteratorCrumbsStack();it.hasNext();){
         Crumbs p = it.next();
         crumbsList.add(p);
      }
      add(new ListView<Crumbs>("crumbs",crumbsList){
         @Override
         protected void populateItem(ListItem<Crumbs> item){
            final Crumbs pageTrace = item.getModelObject();
            item.add(new Link<Void>("crumbslink"){
               @Override
               public void onClick(){
                  int popcount = session.sizeCrumbsStack() - pageTrace.getMountcount();
                  for(int i=0;i < popcount;i++){
                     session.popCrumbsStack();
                  }
                  setResponsePage(pageTrace.getPageclass(),pageTrace.getParams());
               }
            }.add(new Label("crumbsDisplay",pageTrace.getLinkDisplay())
            ));
         }
      });
      CrumbsMark mark = this.getClass().getAnnotation(CrumbsMark.class);
      if (mark != null){
         session.pushCrumbsStack(new Crumbs(mark.value()
,this.getClass(),getRequestCycle().getPageParameters()
,session.sizeCrumbsStack()));
      }
      add(new Label("curentPage",mark==null ? "" : mark.value()));   }

   // BaseWebPage(IModel model) や、BaseWebPage(IPageMap pageMap,IModel model)
   // も同様に
}
-------------------------------------------------------------
BaseWebPage.html を用意して、<wicket:child></wicket:child> の外側に、
パンくずリスト表示のタグを書く。

<div class="crumbs">
<table><tr><td><span wicket:id="crumbs"><a wicket:id="crumbslink">
<span wicket:id="crumbsDisplay"></span></a>></span>
<span wicket:id="curentPage"></span></td></tr></table>
</div>


パンくずリスト表示させる Page クラスに、、、

@CrumbsMark("TOPページ")
public class IndexPage extends BaseWebPage{
}

@CrumbsMark("ユーザページ")
public class UserPage extends BaseWebPage{
}

とすれば、


 TOPページ>ユーザページ

パンくずリスト表示できる。