VaadinによるWebページのレイアウト

Vaadin」は、JavaのコードのみでAjaxを利用したリッチなWebアプリケーションを開発することができるRIAフレームワークである。前回の記事は、このVaadinをNetBeansにおいて利用する方法を紹介した。今回は実際にコードを書いてUIコンポーネントを配置してみよう。

NetBeansプラグインを利用してプロジェクトを生成した場合、デフォルトではトップページに図1のように表示する雛形が構築される。

図1 NetBeans用Vaadinプラグインで作成された雛形のページ

クラス名はプロジェクト生成時に設定するが、本稿では「MyVaadinApplication.java」がメインクラス用のソースファイルとなっている。このソースの中身は次のようなものである。

リスト1

public class MyVaadinApplication extends Application {
    @Override
    public void init() {
    Window mainWindow = new Window("MyVaadinApplication");
        Label label = new Label("Hello Vaadin user");
    mainWindow.addComponent(label);
    setMainWindow(mainWindow);
    }
}

MyVaadinApplicationが継承しているApplicationクラスはVaadinアプリケーションメインとなるクラスであり、この上にウィンドウや各種UIコンポーネントを配置していく。Applicationは抽象クラスなので、継承する場合にはinit()メソッドをオーバーライドする必要がある。init()はアプリケーションが実行されたとき(サイトにアクセスがあったとき)に最初に呼び出されるメソッドとなる。

Windowクラスは、Webブラウザ内に表示するウィンドウやサブウィンドウを表すクラスである。ここれはWindowオブジェクトをひとつ作成し、それをsetMainWindow()メソッドを使ってApplicationのメインウィンドウに設定している。Labelはテキストを描画するためのコンポーネントである。Windowなどのコンポーネントの上に別のコンポーネントを配置する場合にはaddComponent()メソッドを利用する。

このサンプルを見ると、VaadinのコンポーネントモデルはAWT/Swingのものとよく似ていることがわかるだろう。

入力フォームをレイアウトする

次に、init()メソッドを書き換えて図2のようなページを作成してみよう。ボタンを押した際の処理はひとまず後回しにして、とりあえずはレイアウトだけを構築する。

図2 入力フォームを持ったページをレイアウトする

まず「Hello Vaadin user」というタイトルだが、これも先ほどの例と同じようにLabelクラスを使えばよい。Labelクラスでは通常のテキストだけでなく、XHTMLやXML形式のコンテンツを表示することもできるようになっている。たとえば次のように、コンストラクタの第二引数にコンテンツタイプとして「Label.CONTENT_XHTML」を指定すれば、第1引数に渡されたテキストをXHTML形式だと判断し、適切にフォーマットして表示してくれる。今回はこの方法で<h1>を使用している。

リスト2

Label label = new Label("<h1>Hello Vaadin user</h1>", Label.CONTENT_XHTML);

フォーム部分はTextFieldクラスとButtonクラスを利用して作成している。TextFieldは1行の入力フィールド(テキストフィールド)を表示するためのクラスだが、キャプションをセットにして使うことができる。それには次のようにコンストラクタにキャプションとなるテキストを渡してTextFieldオブジェクトを生成すればよい。

TextField nameField = new TextField("名前");

ただし、これをそのままWindowに追加すると、図3に示すようにキャプションと入力フィールドが縦に並べられてしまう。コンポーネントの間にも隙間がなくて見づらい。これは、Windowのレイアウトがデフォルトで縦にコンポーネントを並べる形式になっているためである。そこで、入力フォームを作る場合に便利なFormLayoutというクラスが用意されている。FormLayoutクラスはコンテナ用コンポーネント(AWT/SwingのPanelのようなもの)のひとつで、コンポーネントのキャプションと本体が横に整列するようにレイアウトしてくれる。図2を見ると、キャプションの長さに関わらず2つの入力フィールドの位置がきちんと揃っていることや、2つのテキストフィールドの間に適切なスペースが設けられていることなどがわかるだろう。

図3 Windowクラスのデフォルトのレイアウトだと少々見づらい

FormLayoutはFormクラスとセットで利用する。Formは文字通り入力フォームをレイアウトするためのコンポーネントで、サブコンポーネントとしてFieldオブジェクトを配置することができる。TextFieldなどフォーム用のコンポーネントはいずれもFieldインタフェースを継承している。FormとFormLayoutはセットで次のような使い方をする。

リスト3

FormLayout formLayout = new FormLayout();
Form form = new Form(formLayout);
TextField nameField = new TextField("名前");
formLayout.addComponent(nameField);
TextField messageField = new TextField("メッセージ");
messageField.setWidth("300px");
formLayout.addComponent(messageField);

あとは、このFormオブジェクトをWindowなどのコンテナコンポーネントに追加すればよい。なお、テキストフィールドの横幅はsetWidth()メソッドで設定できる。

ボタンの表示にはButtonクラスを使用する。次のように、コンストラクタに表示したいキャプションを指定すればよい。

リスト4

Button submitButton = new Button("書き込み");

以上をまとめると、init()メソッドは以下のようになる。

リスト5

Public void init() {
    // メインウィンドウの作成
    Window mainWindow = new Window("MyVaadinApplication");
    // XHTMLコンテンツ用のラベルを作成してウィンドウに追加
    Label label = new Label("<h1>Hello Vaadin user</h1>", Label.CONTENT_XHTML);
    mainWindow.addComponent(label);

    // 入力フォームをレイアウト
    // テキストフィールドを作成してレイアウトする
    FormLayout formLayout = new FormLayout();
    Form form = new Form(formLayout);
    TextField nameField = new TextField("名前");
    formLayout.addComponent(nameField);
    TextField messageField = new TextField("メッセージ");
    messageField.setWidth("300px");
    formLayout.addComponent(messageField);
    // 入力フォームをウィンドウに追加
    mainWindow.addComponent(form);

    // ボタンを作成してウィンドウに追加
    Button submitButton = new Button("書き込み");
    mainWindow.addComponent(submitButton);

    // メインウィンドウの設定
    setMainWindow(mainWindow);
}

コンテナそのものがレイアウトマネージャの機能を果たす点がAWT/Swingとは異なるが、コンテナの組み合わせで全体のレイアウトを構成していくというやり方は同様なので、一度仕組みを理解してしまえばそれほど戸惑うことはないと思う。

この状態ではまだボタンをクリックしても何も起こらない。次回は、ボタンが押された場合のイベント処理の方法について解説する。