Wicket の tree を学ぶ(3)

Wicket の tree を学ぶ(2)を書いてしまうと次に、選択状態にしての、
選択状態を認識した処理を書けるようにしておくことである。

f:id:posturan:20160313174029j:plain


このツリー図のように、選択状態を保持した表示にして認識できるようにすることである。
これも前回同様に、TreeContent を選択状態認識専用に用意する。

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree;
import org.apache.wicket.extensions.markup.html.repeater.tree.ITreeProvider;
import org.apache.wicket.extensions.markup.html.repeater.tree.content.Folder;
import org.apache.wicket.model.IModel;
/**
 * SelectableTreeContent.
 */

public abstract class SelectableTreeContent<T> extends TreeContent<T>{
   private IModel<T> selected;
   private ITreeProvider<T> provider;

   public abstract void onClickModel(AjaxRequestTarget target, T t);

   public abstract void onSelected(IModel<T> model);


   public SelectableTreeContent(ITreeProvider<T> provider){
      this.provider = provider;
   }

   @Override
   public void detach(){
      if (selected != null){
         selected.detach();
      }
   }
   protected boolean isSelected(T t){
      IModel<T> model = provider.model(t);
      try{
         return selected != null && selected.equals(model);
      }finally{
         model.detach();
      }
   }
   protected void select(T t, AbstractTree<T> tree, final AjaxRequestTarget target){
      if (selected != null){
         tree.updateNode(selected.getObject(), target);
         selected.detach();
         selected = null;
      }
      selected = provider.model(t);
      tree.updateNode(t, target);
   }

   @Override
   public Component newContentComponent(String id, final AbstractTree<T> tree, final IModel<T> model){
      return new Folder<T>(id, tree, model){

         @Override
         protected boolean isClickable(){
            return true;
         }
         @Override
         protected void onClick(AjaxRequestTarget target){
            SelectableTreeContent.this.select(getModelObject(), tree, target);

            onClickModel(target, getModelObject());
         }
         @Override
         protected boolean isSelected(){
            boolean rtn = SelectableTreeContent.this.isSelected(getModelObject());

            if (rtn) onSelected(model);
            return rtn;
         }

      };
   }
}


ツリーになる Foo もnode か leaf か判定できるようにするため、
以下のようにする。

public class Foo {
   /** 親 Object. */
   public Foo parent;
   /** node 判定. true=ノード(節)である */
   public boolean isNode = true;

   private List<Foo> foos = new ArrayList<Foo>();

   public String name;

   /**
    * node生成コンストラクタ.
    * @param name tree表示名
    */

   public Foo(String name){
      this.name = name;
   }
   /**
    * leaf生成コンストラクタ.
    * @param parent 親ノード
    * @param name tree表示名
    */

   public Foo(Foo parent, String name){
      this(name);
      this.parent = parent;
      this.isNode = false;
      this.parent.isNode = true;
      this.parent.foos.add(this);
   }
   /**
    * @return parent
    */

   public Foo getParent(){
      return parent;
   }
   /**
    * @param parent セットparent
    */

   public void setParent(Foo parent){
      this.parent = parent;
   }
   public List<Foo> getFoos(){
      return Collections.unmodifiableList(foos);
   }
   @Override
   public String toString(){
      return name;
   }
}