Wicket の tree のデモを見て学びたく読んでみた。
デモ用に書かれているので、これを実践で使うのにどうすれば良いか苦労する。
treeコンポーネントを使用するのに、org.apache.wicket.model.IDetachable として実装するのが鍵みたいだ。
デモでは、org.apache.wicket.examples.tree.content.Content
というのが作ってあってこれが、以下の様に抽象メソッドを宣言してる。
public abstract Component newContentComponent(String id, AbstractTree<Foo> tree,
IModel<Foo> model);
これでは、Foo オブジェクト依存で実用向きではない。
簡単なことで、総称型にして、名前も Content ではあんまりなので、以下のようにする。
import org.apache.wicket.Component;
import org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IModel;
/**
* TreeContent
*/
public abstract class TreeContent<T> implements IDetachable{
public abstract Component newContentComponent(String id, AbstractTree<T> tree, IModel<T> model);
@Override
public void detach(){
}
}
Wicket のデモを参考に、以下のようなサンプルを作ることができる。
public class SamplePage extends WebPage{
Logger logger = LoggerFactory.getLogger(this.getClass());
NestedTree<Foo> tree;
TreeContent<Foo> content;
public BasicTreePage(){
tree = new NestedTree<Foo>("tree", new FooProvider(), new FooExpansionModel()){
@Override
protected Component newContentComponent(String _id, IModel<Foo> _model){
return BasicTreePage.this.newContentComponent(_id, _model);
}
};
// Windowsデザインのテーマを使用するように設定
tree.add(new WindowsTheme());
content = new TreeContent<Foo>(){
@Override
public Component newContentComponent(String id, AbstractTree<Foo> _tree, IModel<Foo> model) {
return new Folder<Foo>(id, tree, model){
@Override
protected MarkupContainer newLinkComponent(String _id, final IModel<Foo> _model){
Foo foo = _model.getObject();
if (tree.getProvider().hasChildren(foo)){
// ツリー node をクリックした時
return super.newLinkComponent(_id, _model);
}
// ツリー leaf をクリックした時の動作
return new AjaxLink<Foo>(_id, _model){
@Override
public void onClick(AjaxRequestTarget target){
logger.debug("# click object = " + _model.getObject().id );
}
};
}
};
}
};
add(tree);
add(new Link<Void>("expandAll"){
@Override
public void onClick(){
FooExpansion.get().expandAll();
}
});
add(new Link<Void>("collapseAll"){
@Override
public void onClick(){
FooExpansion.get().collapseAll();
}
});
}
protected Component newContentComponent(String id, IModel<Foo> model){
return content.newContentComponent(id, tree, model);
}
/* expandAll と collapseAll を動作させるために状態を持つ FooExpansion を返す */
private class FooExpansionModel extends AbstractReadOnlyModel<Set<Foo>>{
@Override
public Set<Foo> getObject(){
return FooExpansion.get();
}
}
}