テキストフィールドに入力したり、セレクトリストから選択した後にフォームをサブミットすると、通常はTextFieldなりのコンポーネントにセットしたModelの内容に、サブミットした文字列が入ります。これがWicketのデフォルトの動作です。HTMLからサブミットする内容は常に文字列なので、Wicketは何もしなければ文字列をモデルに格納します。

しかしセレクトリストのような、選択肢が固定されているものをサブミットした場合、Modelに文字列ではなくて選択肢に合致したオブジェクトを格納してもらった方がうれしいことが結構あります。

WicketにはこういったときのためにIConverterというインターフェースと、Component#getConverter()というメソッドが用意されています。

getConverter()はあってもsetConverter()はありません。コンポーネントのModelに格納するときには、コンポーネント・クラスのgetConverter()メソッドをオーバーライドし、IConveterオブジェクトを返すようにします。IConverterは「文字列を特定のオブジェクトに変換する」「オブジェクトを文字列に変換する」の双方の機能があります。コンポーネントがIConveterを返すようにすることで、あなたはModelのオブジェクトとして独自のクラスを設定することができるようになるわけです。WicketはコンポーネントのgetConveter()メソッドが返すコンバータを使って、Model内のオブジェクトを相互変換します。

具体的なコードは下記のようになるでしょう。

  1. new TextField("yourTextFieldId") {
  2. IConverter getConveter(Class type) {
  3. //必要ならtype引数を使ってコンバータを切り替える。
  4. //今回はいずれのクラスにも同じコンバータを返す。
  5. return new IConverter() {
  6. Object convertToObject(String value, Locale locale) {
  7. //文字列からListModelを生成して返す
  8. }
  9. String convertToString(Object value, Locale locale) {
  10. //オブジェクトを文字列に変換する。
  11. return String.valueOf(value);
  12. }
  13. }
  14. }
  15. };

この機能を使うためにはもう一つだけ作業が必要です。ほとんどのコンポーネントのコンストラクタには引数としてClass typeを受けるものが用意されています。ここであなたが期待しているモデルオブジェクトのクラスを指定することで、Wicketはそのコンポーネントのモデルからオブジェクトを取り出したり、オブジェクトをセットするときにはコンバータを使う必要があるのだとわかります。この指定をしないかぎり、コンポーネントのモデルオブジェクトはStringであると解釈されます。

コンストラクタでクラスを指定する以外にも、コンポーネントのsetType()メソッドを使う方法もあります。