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ページ>ユーザページ
とパンくずリスト表示できる。