Step 4: クライアントのイベント管理

目次:Google Web Toolkit チュートリアル(目次) - webとかmacとかやってみようか
原文:http://code.google.com/intl/ja/webtoolkit/doc/1.6/tutorial/manageevents.html

(このペースでやってるといつまでたっても終わらないため、ここからはかなりはしょります)

多くのUIフレームワークのように、GWTもイベントベースです。イベントが起きたときにコードが実行される。多くの場合、イベントはユーザのマウス、キーボードをトリガーとする。

1. イベントハンドルの仕様検討

StockWathcerでどのようなイベントが起きるのか見てみる。

タスク UIイベント 反応
株コードの入力 追加ボタンをクリックか、入力ボックスでリターン 入力の検証、既に登録されていないかチェック、新しい行の追加、削除ボタンの作成
株の削除 削除ボタンを押す テーブルから行を削除

GWTは多数のイベントハンドラのインターフェースを提供する。追加/削除ボタンのクリックイベントには ClickHandler が使える。インプットボックスでのキーボードイベントには KeyPressHandler インターフェースが使える。

GWT 1.6 からは ClickHandler, KeyDownHandler, KeyPressHandler, and KeyUpHandler になった。ClickListener と KeyBoardListener は非推奨となった。

2. イベントのリスニング

イベントハンドラ インターフェース

GWTイベントハンドラは他のUIフレームワークとよく似ている。あるイベントを受け取るには、使用するウィジェットイベントハンドラを登録する。イベントハンドラはいくつかのメソッドを持ち、ウィジェットはイベントを配信する。

マウスイベントの処理

StockWatcher で株コードを追加するには、追加ボタンをマウスでクリックする。

ClickHandlerインターフェースを実装したオブジェクトを使ってクリックイベントを処理する。ClickHandler インターフェースは onClickメソッドを持ち、これはユーザがクリックしたときに呼ばれる。

ユーザが追加ボタンを押したとき、株テーブルに追加しなければいけない。そのためクリックイベントを処理するために、addStock メソッドを呼ぶ。まだ addStockメソッドはないけど、スタブを作って次のセクションで実装する。

1. 追加ボタンにイベントハンドラを追加する。
Stockwatcher.java の onModuleLoad に、"Listen for mouse events on the Add button."のコメントが付いているコードをコピペする。

2. ClickHandler と ClickEvent インポート宣言をする

3. StockWatcher.java で addStock メソッドのスタブを作成
Eclipse ショートカットか、次のコードをコピペする。

注意: Eclipseの設定次第では、addStockメソッドが protected になるかもしれない。StockWathcer のサブクラスの予定は無いので、private にしておくこと。

package com.google.gwt.sample.stockwatcher.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class StockWatcher implements EntryPoint {

  private VerticalPanel mainPanel = new VerticalPanel();
  private FlexTable stocksFlexTable = new FlexTable();
  private HorizontalPanel addPanel = new HorizontalPanel();
  private TextBox newSymbolTextBox = new TextBox();
  private Button addStockButton = new Button("Add");
  private Label lastUpdatedLabel = new Label();

  /**
   * Entry point method.
   */
  public void onModuleLoad() {
    // Create table for stock data.
    stocksFlexTable.setText(0, 0, "Symbol");
    stocksFlexTable.setText(0, 1, "Price");
    stocksFlexTable.setText(0, 2, "Change");
    stocksFlexTable.setText(0, 3, "Remove");

    // Assemble Add Stock panel.
    addPanel.add(newSymbolTextBox);
    addPanel.add(addStockButton);

    // Assemble Main panel.
    mainPanel.add(stocksFlexTable);
    mainPanel.add(addPanel);
    mainPanel.add(lastUpdatedLabel);

    // Associate the Main panel with the HTML host page.
    RootPanel.get("stockList").add(mainPanel);

    // Move cursor focus to the input box.
    newSymbolTextBox.setFocus(true);

    // Listen for mouse events on the Add button.
    addStockButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        addStock();
      }
    });

  }

  /**
   * Add stock to FlexTable. Executed when the user clicks the addStockButton or
   * presses enter in the newSymbolTextBox.
   */
  private void addStock() {
    // TODO Auto-generated method stub

  }

}

実装の注意: イベントの少ないStockWathcerのような小さなアプリケーションでは匿名のインナークラスを使うのが最小コードで実装できる。しかし、イベントハンドラが多い場合は、この方法は効率的ではない。なぜなら、これは沢山の分割されたイベントハンドラオブジェクトを作成してしまう。その場合、複数のイベントを処理するハンドラを実装する方がよい。getSrouce() メソッドでイベントの発生元を識別できる。これはメモリ使用的によいが、すこしコードが多くなる。コード例は、ディベロッパーズガイドの Event and Handlers を参照。

キーボードイベントの処理

追加ボタンに加えて、インプットボックスでリターンを押したときにも株コードを追加できる。

キーボードイベントを受信するのに、KeyPressHandler の addKeyPressHandler を使う。

1. 入力ボックス newSymbolTextBox に keypress イベントを引っかける。
onModuleLoad メソッドで、 "Listen for keyboard events in the input box." のコメントがとこのコードをコピペする。

    // Listen for mouse events on the Add button.
    addStockButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        addStock();
      }
    });

    // Listen for keyboard events in the input box.
    newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
      public void onKeyPress(KeyPressEvent event) {
        if (event.getCharCode() == KeyCodes.KEY_ENTER) {
          addStock();
        }
      }
    });

  }

  /**
   * Add stock to FlexTable. Executed when the user clicks the addStockButton or
   * presses enter in the newSymbolTextBox.
   */
  private void addStock() {
    // TODO Auto-generated method stub

  }

}

2. import宣言の取り込み

import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;

これでイベントハンドラの準備は出来たよ。次で addStock メソッドの中身を埋めるよ。

3. ユーザイベントの応答

ここまででユーザが株コードをマウスやキーボードから入力したイベントをリスニングできるようになったね。次は、株を尽かしたイベントを検出したときに期待通りに動くかどうかをテストしてみよう。StockWathcer はサーバに何もリクエストを送らず、リロードもせずにクライアントサイトだけで動くよ。

株テーブルに株の追加

StockWathcer では、ユーザはモニターしたい株の証券コードをインプットボックスに入力するよ。Enterを押すか追加ボタンをクリックしたとき、StockWathcer は次の反応をするようにしたいよね。

  1. 入力の検証
  2. 重複チェック
  3. 株の追加
  4. リストから削除するボタンを追加

このセクションでは、最初に応答、入力の検証、それからイベントハンドラが動いているかを見てみるよ。次のセクション クライアント機能のコーディング で 残りの機能を実装するよ。

addStockメソッドの機能を実装しよう。

テキストボックスの入力の検証

入力された株コードが正しいものか検証したいよね。このチュートリアルの目的的には、実際の株式コードにあっているかを検証するよりも、単純な文字列チェックを行うよ。

最初に、株コードを取得するよ。TextBoxウィジェットから取得するために、getTextメソッドを使うよ。

次に、不正な文字が入っていないことを保証するようにするよ。ユーザの入力を標準的な形に変換した後に、正規表現でチェックするよ。JavaJavaScript正規表現は同じだよ。

入力が妥当なら、テキストボックスをクリアして、別のコードを入れられるようにするよ。

1. 株コードの入力チェック
StockWatcher.java の スタブメソッド addStock を以下のコードで置き換える。

  private void addStock() {
    final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
    newSymbolTextBox.setFocus(true);

    // Stock code must be between 1 and 10 chars that are numbers, letters, or dots.
    if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) {
      Window.alert("'" + symbol + "' is not a valid symbol.");
      newSymbolTextBox.selectAll();
      return;
    }

    newSymbolTextBox.setText("");

    // TODO Don't add the stock if it's already in the table.

    // TODO Add the stock to the table.

    // TODO Add a button to remove this stock from the table.

    // TODO Get the stock price.

  }

2. インポート宣言のインクルード

import com.google.gwt.user.client.Window;

4. イベント処理のテスト

これで、もし不正な文字を入れると、警告がポップアップで表示されるべきだ。やってみよう。

1. ホストモードでイベント処理をテストする
既に開いているホストモードのブラウザをクリック
更新を押す

2. イベントハンドラが動くことをテストする
入力ボックスに株コードを入力する。リターンを押すのと、追加ボタンのクリックの両方を使う。
ここでは 株はテーブルに追加されないが、入力ボックスはクリアされて、別のを追加できる。

3. 妥当性チェックとエラーメッセージのテスト
不正な文字を入れてみる。

http://code.google.com/intl/ja/webtoolkit/doc/1.6/tutorial/images/ManageEvents.png

Tip: Javaコードの変更はすぐにホストモードブラウザに表示される。もし既にホストモードブラウザを開いているなら、再起動する必要はない。更新ボタンを押すだけだ。

まだ StockWathcer をコンパイルしていないけど、Run StockWathcer で、webモードでテストできるよ。

つぎは

これで、ユーザが入力したマウスとキーボードイベントの処理を実装できた。入力のチェックも行う。

テーブルに株の追加と削除ボタンの追加を行うクライアントコードを実装する準備が出来た。また、株の価格と更新したときにタイムスタンプを表示するようにする。

Step 5: クライアント機能のコーディング - webとかmacとかやってみようか