GoogleからJava開発者へのサプライズ!な贈り物、Google Web Toolkit[3]

JavaScript×HTMLとJavaのシームレスな開発環境を体験してみよう


リトルソフト株式会社 長尾寿宏
2006/8/26


 グリッドの利用

 検索結果はユーザーインターフェイス左側スクロールパネルの中に一覧形式で表示します。ここで利用するのがグリッド(com.google.gwt.user.client.ui.Grid)クラスです。

 ImageSearchResultSetオブジェクトのarrayからResultオブジェクトを取り出し、以下のようなコードでグリッドの各セル内にウィジェットとして設定します。

  Grid grid = this.client.resultGrid;
  for (int i=0; i<resultSet.array.size(); i++) {
    ImageSearchResultSet.Result rs = (ImageSearchResultSet.Result)
resultSet. array.get(i);(本来は1行)
    int row = grid.getRowCount();
    grid.resizeRows(row + 1);
    grid.setWidget(row, 0, new Label("No." + (row + 1)));
    grid.setWidget(row,1, new Image(rs.thumbnail.url));
    grid.setWidget(row,2, new Label(rs.summary));
    grid.setWidget(row,3, new Label(rs.refererUrl));
    grid.getWidget(row,3).setVisible(false);
  }

 グリッドのバグ回避

 当記事で使用しているGWT(Version 1.0.21 Windows版)のGridには、resizeRowsメソッドで行数を減少させた際、内部カウンターが不正な値になるというバグが含まれています (http://code.google.com/webtoolkit/issues/3733199.html)。

 また、resizeRowsメソッドでは行数をゼロにすると例外になるという仕様で、今回のアプリケーションで利用するには少々厄介です。

 そこで、Gridのサブクラスを作成し、上記バグを回避するとともに行数ゼロ設定を許容するように改造することにしました。

 まずImageSearchClientクラスの内部クラスとしてMyGridを作成します。次にresizeRowsメソッドをオーバーライドし、以下のように書き換えます。

  class MyGrid extends Grid {
    /* 中略 */    
    public void resizeRows(int rows) { 
      if (numRows == rows) return; 
      if (rows < 0) { 
        throw new IndexOutOfBoundsException("Cannot set number 
of rows to" + rows);(本来は1行) 
      } 
      while (numRows < rows) { 
        // More rows. Add them where necessary. 
        insertRow(numRows); 
        insertCells(numRows, 0, numColumns); 
        ++numRows; 
      } 
      while (numRows > rows) { 
        // Fewer rows. Remove extraneous ones. 
        removeRow(--numRows); 
      } 
    } 
  }

 ImageSearchClientクラスも以下のように変更します。

public class ImageSearchClient implements EntryPoint , WindowResize
Listener, (本来は1行)
                                          ClickListener {
  /* 中略 */  
  MyGrid resultGrid = new MyGrid(0,4);
  /* 以下略 */

  ここまで完了したら、ホステッドモードで実行してみましょう。

 EclipseのパッケージエクスプローラからImageSearchClient-shell.cmdを選択、ダブルクリックし、ホステッドブラウザを起動します。

 アプリケーションが表示されたら検索キーワードに何かを設定し、検索ボタンをクリックしてみてください。

 以下のように検索結果が一覧で表示されれば完ぺきです。

画面1 GWTのグリッドのバグを回避して検索結果を表示させてみよう

 スクロールに伴う自動読み込み

 検索結果が一覧表示できたので、この機能をグレードアップしていきましょう。

 現在、一覧表示されている内容は、検索サービスメソッドを呼び出す際に指定された16件が表示されているだけで、17件目以降を表示させることができません。

 そこでスクロールの操作に伴い、自動的に検索結果を読み込み、一覧表示の最後へ追加する機能を実装します。

 これを実現するためには、検索結果一覧(グリッド)が格納されているスクロールパネル(ScrollPanel)のサブクラスを作成し、スクロールイベントをとらえます。

  class MyScrollPanel extends ScrollPanel {

    Widget grid;
    ImageSearchClient client;
    
    public MyScrollPanel(Widget child, ImageSearchClient client) {
      super(child);
      this.client = client;
      this.grid = child;
      this.sinkEvents(Event.ONSCROLL);
    }
    
    public void onBrowserEvent(Event event) { 
      if (DOM.eventGetType(event) == Event.ONSCROLL) { 
        /* 中略 */
      }
    } 
  }

 MyScrollPanel コンストラクタ内のthis.sinkEvents(Event.ONSCROLL)に注意してください。このメソッドによって宣言されたイベントが発生するとonBrowserEventが呼ばれます。

 onBrowserEventではグリッドの高さやスクロール位置によって、doSearchメソッドを呼び出し、これにより一覧表示を追加します。doSearchメソッドのパラメータtrueは、検索結果を追加で取得することを意味しています。

    public void onBrowserEvent(Event event) { 
      if (DOM.eventGetType(event) == Event.ONSCROLL) { 
        if ( (this.grid.getOffsetHeight() - this.getOffsetHeight()) 
                < (this.getOffsetHeight() + this.getScrollPosition
()) ) {(本来は1行)
          client.doSearch(true);
        }
      } else { 
        super.onBrowserEvent(event); 
      } 
    }

ImageSearchClientクラスも以下のように変更します。

public class ImageSearchClient implements EntryPoint , 
WindowResize Listener,(本来は1行) 
                                          ClickListener {
  /* 中略 */  
  MyScrollPanel resultGridScroll = new MyScrollPanel
(resultGrid, this);(本来は1行)
  /* 以下略 */ 

 ところで、このようなスクロールイベントのとらえ方が、ほかのウィジェットのようにListenerパターンでないことに不自然さを感じますね。

 GWTでは、ScrollListener、SourcesScrollEventsといったスクロールイベントをListenerパターンで捕捉するためのインターフェイスがすでに定義されているのですが、肝心なScrollPanelにまだその機能が実装されていないようです。

4/5

 INDEX

JavaScript×HTMLとJavaのシームレスな開発環境を体験してみよう
  Page1<Webサービスから結果セットを読み出して表示させるまで/RPCインターフェイスの定義とサービスメソッドの実装/検索結果セットのクラスを作成する/サービスインターフェイスの定義>
  Page2<サーバ側 サービスメソッドの実装/非同期インターフェイスの定義>
  Page3<クライアント側 検索機能の実装/ウィジェットへの値設定>
Page4<グリッドの利用/グリッドのバグ回避/スクロールに伴う自動読み込み>
  Page5<背景色変更と内部フレーム表示/今後のバージョンアップも期待>


 Ajax関連記事


Ajaxフレームワーク「Spry」で作る「リンク集2.0」
特集:AdobeのAjaxフレームワーク「Spry」を使ってみよう アドビのAjaxフレームワーク「Spry」。さっそく簡単なリンク集のサンプルを作成しながら、その機能を探ってみよう
リッチクライアント & 帳票」フォーラム 2006/6/21

古くて新しいAjaxの真実を見極める
「Webインターフェイスの新しい手法」「画期的なWebアプリケーションの仕組み」であるとして開発者たちの人気を集めるAjaxとは何なのか、その真実を見極めてみよう
最終更新 2005/8/2


HTML5 + UX フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日 月間