SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaで軽快に使える「軽量フレームワーク」特集

Javaで軽快に使える「軽量フレームワーク」特集
低い学習コストを重視した「Apache Click」 (3)

第6回

コントロールの作成

 画面の構成を考えるとき、重要となるのが「コントロール」でしょう。他の要素はいくらでも操作できますが、コントロールは自動的に表示が生成されてしまいます。カスタマイズするためには、独自のコントロールを作成することを考えることになります。

 コントロールは、org.apache.click.controlにある「AbstractControl」というクラスを継承して作られています。入力関係はこのサブクラスにあるFieldというクラスを継承して作られています。ここでは、AbstractControlを継承して、独自のコントロールを作ってみましょう。一例として、ラベルと入力フィールドをテーブルでレイアウトして表示する「BoxField」を作ってみます。また入力制御の一例として、入力されたアルファベットはすべて大文字に変換されるようにしてみましょう。

 では、src内のjp.codezine.clickパッケージ内に「BoxField.java」というソースファイルを作成してください。そして次のように記述をしましょう。

package jp.codezine.click;

import org.apache.click.control.*;
import org.apache.click.util.HtmlStringBuffer;

public class BoxField extends AbstractControl {
    private String value = "";
    private String label = "";

    public BoxField(String name, String label) {
        super(name);
        setLabel(label);
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public void onInit() {
        super.onInit();
    }

    @Override
    public String getTag() {
        return "input";
    }

    @Override
    public boolean onProcess() {
        String requestValue = getContext().getRequestParameter(getName());
        if (requestValue != null)
            setValue(requestValue.toUpperCase());
        registerActionEvent();
        return true;
    }

    @Override
    public void render(HtmlStringBuffer buffer) {
        buffer.elementStart("table");
        buffer.appendAttribute("class", "boxfield");
        buffer.appendAttribute("border", "1");
        buffer.elementStart("tr");
        buffer.elementStart("th");
        buffer.append(">" + label);
        buffer.elementEnd("th");
        buffer.elementEnd("tr");
        buffer.elementStart("tr");
        buffer.elementStart("td");
        renderTagBegin(getTag(), buffer);
        renderTagEnd(getTag(), buffer);
        buffer.elementEnd("td");
        buffer.elementEnd("tr");
        buffer.elementEnd("table");
    }

    @Override
    protected void renderTagBegin(String tagName,
            HtmlStringBuffer buffer) {
        super.renderTagBegin(tagName,buffer);
        String val = getValue();
        if (val != null) {
            buffer.appendAttribute("value", val);
        }
        appendAttributes(buffer);
    }
    
    @Override
    protected void renderTagEnd(String tagName,
            HtmlStringBuffer buffer) {
        super.renderTagEnd(tagName, buffer);
    }

}

 作成したら、入力フィールドとしてこのBoxFieldを使ってみましょう。利用の一例を以下にあげておきます。

利用クラス例
public class HeloPage extends Page {
    public String header = "";
    public String footer = "";
    public String title = "";
    public String msg = "";
    public Form form;
    private BoxField box;
    private Submit submit;
    
    public HeloPage(){
        this.getContext().setLocale(Locale.JAPAN);
    }

    @Override
    public void onInit(){
        header = this.getMessage("layout.header");
        footer = this.getMessage("layout.footer");
        title = this.getMessage("page.title");
        msg = this.getMessage("page.init_msg");
        
        form = new Form("form");
        box = new BoxField("box","box");
        form.add(box);
        submit = new Submit("submit","submit");
        form.add(submit);
        this.addControl(form);
    }

    @Override
    public void onPost() {
        msg = box.getValue();
    }
    
}
利用テンプレート例
<style>
.boxfield tr th { background: #9999FF; }
.boxfield tr td { background: #CCCCFF; }
</style>
<h2 id="title">$title</h2>
<p>$msg</p>
<p>$form</p>
図4 BoxFieldの利用例。背景色などはスタイルシートで設定できる。
図4 BoxFieldの利用例。背景色などはスタイルシートで設定できる。

 BoxFieldインスタンスを作成してフォームに組み込むことで、一般のコントロールと同様に使うことができるようになります。またboxfieldというクラスにスタイルシートを設定することで、表示スタイルを設定することもできます。

まとめ

 今回は、表示についていろいろと考えてみました。Apache Clickで表示を考えるとき、はずせないのが「Velocity」の存在です。今回もメニュー作成でVelocityのマクロを利用したりしています。表示を考えるとき、テンプレートエンジンの存在は重要です。

 この他、独自のコントロールとして部品を定義しておき、それらを組み合わせて表示を構成していくのも一つのアイデアです。よく使われる部品類を独自定義しておくことで、全体で統一したデザインを構築することができます。

 また、Apache Clickでは、「ダイレクトレンダリング」といって、直接HTMLのソースをクライアントに出力させることもできます。これはPageのgetContext().getResponse()でHttpServletResponse を取得してしまい、そのままサーブレットなどの出力と同じ要領で書き出してしまおう、というものです。この場合、ページの描画終了を示すため、最後に「setPath」でパスをnullに設定するのを忘れないようにします。これで出力をすべてJava側から行わせることもできるようになります。この機能についても、興味があれば調べてみると面白いでしょう。

 とりあえず、これでPage側の処理からデザインまで一通り理解できました。ごく基本的な機能を使ったものなら、Webアプリケーション開発に使えるようにはなったはずです。実際に利用してみて、それまでのStrutsなどのフレームワークとどう違うか、実感してください。それがApache Clickを理解する最適な道と言えるでしょう。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Javaで軽快に使える「軽量フレームワーク」特集連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4557 2009/12/10 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー