SimpleAutoLinkColumn

clickのTableの内容に、シンプルにaタグを付加するColumnクラス。

class SimpleAutoLinkColumn

import net.sf.click.Context;
import net.sf.click.control.Column;
import net.sf.click.control.Decorator;
import net.sf.click.util.HtmlStringBuffer;

public class SimpleAutoLinkColumn extends Column {
    private static final long serialVersionUID = 1L;
    public SimpleAutoLinkColumn(String name, String title) {
        super(name, title);
        super.setDecorator(new SimpleAutoLinkColumnDecorator(this));
    }
    
    public class SimpleAutoLinkColumnDecorator implements Decorator {
        private final Column column;
        
        public SimpleAutoLinkColumnDecorator(Column column) {
            this.column = column;
        }
        
        @Override
        public String render(Object object, Context context) {
            String url = String.valueOf(column.getProperty(object));
            HtmlStringBuffer buffer = new HtmlStringBuffer();
            buffer.elementStart("a");
            buffer.appendAttribute("href", url);
            buffer.closeTag();
            buffer.append(url);
            buffer.elementEnd("a");
            return buffer.toString();
        }
    }
}

使い方

table.addColumn(new SimpleAutoLinkColumn("url", "リンク先"));

当初はDecoratorだけで実現しようしたけど、そうとするとranderに渡されるobjectから、該当する要素を取り出すのが難しくなる。*1
ということで、SimpleAutoLinkColumnDecoratorはColumnを受け取って、そのgetPropertyを呼び出すことでも悪くはないが、結局双方向な密結合になるので、それなら内部クラス化してもいいんじゃないかという方針です。

SimpleAutoLinkColumnDecoratorが依存するのはSimpleAutoLinkColumnではなくColumnなので、SimpleAutoLinkColumnの内部クラスとして扱うのは間違いな気がしてきた。記法を楽にする目的ではSimpleAutoLinkColumnとしてラップするのはいいが、SimpleAutoLinkColumnDecoratorだけでも動作は問題ない。

*1:objectはMapまたはbeanとなっていて、テーブル描画の際にColumnのnameから該当する要素を取り出しているってのが、clickのColumn.getProperty(String name, Object object)の振舞い。