Happy Man

mash-uppy

08 2008

ExtGWTでMVC (その5)

その4では、テスト用で作ったCarのリストをTableに表示した訳ですが
今回は、サーバからTable表示用の一覧を取得します。

新しくAppView2.javaを作成します。
AppView2は、PagingToolBarを持っていて
結果を1ページあたり10件ごと表示します。

まず、はじめに
新規にGWTリモートサービスを作成します。
#eclipse+cypal使っているだろうから。。。
AppRemoteService.java
AppRemoteServiceAsync.java
AppRemoteServiceImpl.java

作成したAppRemoteServiceに以下のインターフェースを追加します。
AppRemoteServiceAsyncには自動でメソッド追加されているはず。
このリターンやらパラメータが肝ですかね。
conditionは検索条件みたいなイメージです。

public PagingLoadResult<Car> getRemoteCars(Car condition, PagingLoadConfig config);

#とりあえずその2で作成したAppController.javaで使われている
#AppViewをAppView2に変更してください。

で、以下が、Remote+Paginationなテーブルです。
AppView2.java

package com.gethapp.sample.mvc.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.binder.TableBinder;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.TableEvent;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.PagingToolBar;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.table.DateTimeCellRenderer;
import com.extjs.gxt.ui.client.widget.table.Table;
import com.extjs.gxt.ui.client.widget.table.TableColumn;
import com.extjs.gxt.ui.client.widget.table.TableColumnModel;
import com.extjs.gxt.ui.client.widget.table.TableItem;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;

public class AppView2 extends View {
  //1ページあたりの表示数
  private static final int PAR_PAGE=10;

  private Viewport v;
  private ContentPanel cp;
  private Table table;
  private Text text;
  private Button button;

  // Carのstore
  private ListStore<Car> store;

  public AppView2(Controller controller) {
    super(controller);
  }

  protected void initialize() {
    v = new Viewport();
    cp = new ContentPanel();

    // テーブルを作る
    List<TableColumn> columns = getColumns();
    TableColumnModel cm = new TableColumnModel(columns);
    table = new Table(cm);
    table.setSelectionMode(SelectionMode.SINGLE);
    table.setWidth(400);
    table.setHeight(250);

    // テーブルの行選択時
    table.addListener(Events.SelectionChange, new Listener<TableEvent>() {
      public void handleEvent(TableEvent te) {
        List<TableItem> tiList = (List<TableItem>) te.selected;
        if (tiList.size() == 1) {
          TableItem ti = tiList.get(0);

          // 選択行の1カラム目は車名。これでOK?
          String name = (String) ti.getValue(0);

          // テーブルの下に配置したTextに車名を表示
          text.setText(name);
        }
      }
    });

    // 車名表示用
    text = new Text();

    //Paginationのツールバー
    final PagingToolBar toolBar = new PagingToolBar(PAR_PAGE);

    //Rpc呼び出し
    RpcProxy proxy = new RpcProxy() {
      @Override
      public void load(Object loadConfig, AsyncCallback callback) {
        AppRemoteServiceAsync service = AppRemoteService.Util.getInstance();
        service.getRemoteCars(new Car("KEYWORD", 100, new Date()),
          (PagingLoadConfig) loadConfig, callback);
      }
    };

    // loader
    final BasePagingLoader loader = new BasePagingLoader(proxy);

    // store
    store = new ListStore<Car>(loader);

    // binder
    // tableとstoreをTableBinderで結びつける
    TableBinder<Car> binder = new TableBinder<Car>(table, store);
    toolBar.bind(loader);

    // ボタンとクリックイベント
    button = new Button("load", new SelectionListener<ComponentEvent>() {
      @Override
      public void componentSelected(ComponentEvent ce) {
        table.removeAll();
        loader.load(0, PAR_PAGE);
      }
    });

    v.add(button);
    v.add(text);

    cp.setFrame(true);
    cp.setButtonAlign(HorizontalAlignment.CENTER);
    cp.setLayout(new FitLayout());
    cp.add(table);
    cp.setSize(400, 250);
    cp.setBottomComponent(toolBar);
    v.add(cp);
    RootPanel.get().add(v);
  }

  // このAppView2が処理する必要があるイベントごとにハンドラを記述する
  protected void handleEvent(AppEvent event) {
    switch (event.type) {
    case App.EVENT_INIT:
      break;
    }
  }

  private List<TableColumn> getColumns() {
    List<TableColumn> columns = new ArrayList<TableColumn>();

    TableColumn col = new TableColumn("name", "Name", 150);
    col.setAlignment(HorizontalAlignment.CENTER);
    col.setMinWidth(75);
    col.setMaxWidth(300);
    columns.add(col);

    col = new TableColumn("price", "Price", 50);
    col.setAlignment(HorizontalAlignment.RIGHT);
    columns.add(col);

    col = new TableColumn("mDate", "ManufacturingDate", 100);
    col.setAlignment(HorizontalAlignment.RIGHT);
    col.setRenderer(new DateTimeCellRenderer("yyyy"));
    columns.add(col);

    return columns;
  }

}

以下は、リモート側の実装です。
AppRemoteServiceImpl.java

package com.gethapp.sample.mvc.server;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.gethapp.sample.mvc.client.AppRemoteService;
import com.gethapp.sample.mvc.client.Car;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class AppRemoteServiceImpl extends RemoteServiceServlet implements AppRemoteService {

  /**
   *
   */
  private static final long serialVersionUID = -4266724257884001049L;

  /**
   * @param condition 検索条件
   * @param config ローダのコンフィグ
   * @return PagingToolBar用の検索結果リスト リストの要素はCarクラス
   */
  public PagingLoadResult<Car> getRemoteCars(Car condition,
      PagingLoadConfig config) {

    //conditionから検索条件を取り出す
    String name=condition.getName();
    int price=condition.getPrice();
    Date mDate=condition.getMDate();

    //本当は、CarにtoString実装してください
    System.out.println("クライアントから送られてきた検索条件"+condition.toString());

    //ここらで取り出した検索条件をゴニョゴニョやって。。。。

    //検索結果
    List<Car> l=new ArrayList<Car>();

    //適当に
    for (int i=0;i<25;i++) {
      Car c=new Car("SkyLine"+i,500+i,getManufacturingDate(2008-i));
      l.add(c);
    }
    int start = config.getOffset();
    int limit=l.size();

    //pagination用の結果リスト
    List<Car> sublist = new ArrayList<Car>();

    if (config.getLimit() > 0) {
      limit = Math.min(start + config.getLimit(), limit);
    }
    for (int i = config.getOffset(); i < limit; i++) {
      sublist.add(l.get(i));
    }

    return new BasePagingLoadResult<Car>(sublist, config.getOffset(), l.size());

  }

  //製造年のDateクラスを取り出す
  private synchronized Date getManufacturingDate(int year) {
    Calendar cal=Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    return cal.getTime();
  }

}

Leave a Reply

« GXTでMaps API よくみると。。。 »