読者です 読者をやめる 読者になる 読者になる

IChoiceRenderer ラムダ化

Wicket7IChoiceRenderer で 選択したものを特定するのに getObject で 先日書いた実装するくらいなら、getObject は、default メソッドにして、
プルダウンとして表示する <option>タグbody を決定する IChoiceRenderer#getDisplayValue の方をラムダ式にしたくなってきた。

用意しなくてはならないのは、まず、プルダウンアイテムのオブジェクトが <option>タグの value属性値を返せるようにするインターフェース

public interface ChoiceValue {
   public String getOptionValue();
}


そして、IChoiceRenderer extend して getIdValue getObject default メソッドにする。
@FunctionalInterface を付与する。

import java.util.List;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
/**
 * ExIChoiceRenderer
 */

@FunctionalInterface

public interface ExIChoiceRenderer<T extends ChoiceValue> extends IChoiceRenderer<T>{
   @Override
   default
   public String getIdValue(T t, int index){
      return ((ChoiceValue)t).getOptionValue();
   }
   @Override
   default
   public T getObject(String value, IModel<? extends List<? extends T>> models){
      return models.getObject().stream().filter(e->value.equals(((ChoiceValue)e).getOptionValue())).findFirst().orElse(null);
   }
}


これを使う DropDownChoice として以下のように拡張した DropDownChoiceEx を用意する。

public class DropDownChoiceEx<T> extends DropDownChoice<T>{
   public DropDownChoiceEx(String id, IModel<T> model, List<? extends T> choices, ExIChoiceRenderer<? super T> renderer){
      super(id, model, choices, renderer);
   }
   public DropDownChoiceEx(String id, IModel<T> model, IModel<? extends List<? extends T>> choices, ExIChoiceRenderer<? super T> renderer){
      super(id, model, choices, renderer);
   }
   public DropDownChoiceEx(String id, List<? extends T> choices, ExIChoiceRenderer<? super T> renderer){
      super(id, choices, renderer);
   }
   public DropDownChoiceEx(String id, IModel<? extends List<? extends T>> choices, ExIChoiceRenderer<? super T> renderer){
      super(id, choices, renderer);
   }
}



そして、目的の DropDownChoiceEx 使用は
プルダウン表示のオブジェクトを以下のように、ChoiceValue をインターフェースに持って、
public class Item implements ChoiceValue, Serializable{
   public int id;
   public String name;

   public Item(){}

   public Item(int id, String name){
      this.id = id;
      this.name = name;
   }
   @Override
   public String getOptionValue(){
      return Integer.toString(id);
   }

}


以下のように書くことができる。

final DropDownChoiceEx<Item> select_item
= new DropDownChoiceEx<Item>("select_item", new Model<Item>(), createItemList(), e->e.name );

ExIChoiceRenderer を書くところを、<option>タグbody を返すラムダ式なり、IChoiceRender が目指していたであろう
プルダウンの <option> タグの指定、表現を簡単にすることになってくると思う。