Extgwtとslim3gwt

とりあえず、やってみるとこんな感じでつながる。どこをどう最適化していけばいいかは少しずつ考えていこうかと思う。slim3のコードも少し変わっているようだし。この辺も少しずつ見ていくしかない。とりあえずなので汚いコードですが、少しずつ機能を増やして、リファクタリングを繰り返し、ネコ情報を的確に管理したいと思います。

public class CatManageGxt implements EntryPoint {
    
    private FormBinding formBindings;
  private final CatServiceAsync catservice = GWT.create(CatService.class);
  BaseListLoader<ListLoadResult<Cat>> loader;

    public void onModuleLoad() {
        ContentPanel cp = new ContentPanel();
        cp.setHeading("ネコ一覧");
        cp.setFrame(true);
        cp.setSize(800, 400);
        cp.setLayout(new RowLayout(Orientation.HORIZONTAL));

        final Grid<ModelData> grid = createGrid();
        grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        grid.getSelectionModel().addListener(
            Events.SelectionChange,
            new Listener<SelectionChangedEvent<ModelData>>() {
                public void handleEvent(SelectionChangedEvent<ModelData> be) {
                    if (be.getSelection().size() > 0) {
                        formBindings.bind((ModelData) be.getSelection().get(0));
                    } else {
                        formBindings.unbind();
                    }
                }
            });
        cp.add(grid, new RowData(.6, 1));

        final FormPanel panel = createForm(grid);
        formBindings = new FormBinding(panel, true);
        formBindings.setStore((Store) grid.getStore());

        cp.add(panel, new RowData(.4, 1));

        cp.setButtonAlign(HorizontalAlignment.LEFT);
        cp.addButton(new Button("Reset", new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                grid.getStore().rejectChanges();
            }
        }));

        Button updateButton = new Button("update");
        updateButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
            @Override
            public void componentSelected(ButtonEvent ce) {
                new MessageConfirmUtil() {
                    @Override
                    public void handling() {
                        executeUpdateCats(grid);
                    }
                }.execute();
            }
        });
        cp.addButton(updateButton);
        RootPanel.get().add(cp);
    }

    private void executeUpdateCat(Grid<ModelData> grid) {
        List<Record> commitingModels = grid.getStore().getModifiedRecords();
        for (Record record : commitingModels) {
            Cat cat = new Cat();
            cat.setName((String) record.get("name"));
            cat.setKey((String) record.get("key"));
            ModelData md = (ModelData) record.get("notpersistkind");
            String kindkey = md.get("key");
            catservice.updateCat(cat, kindkey, new AsyncCallback<Cat>() {
                public void onFailure(Throwable caught) {
                    Window.alert(caught.toString());
                }
                public void onSuccess(Cat result) {
                    loader.load();
                };
            });
        }
    }

    private FormPanel createForm(Grid<ModelData> grid) {
        FormPanel panel = new FormPanel();
        panel.setHeaderVisible(false);

        TextField<String> name = new TextField<String>();
        name.setName("name");
        name.setFieldLabel("お名前");
        panel.add(name);

        return panel;
    }

    private Grid<ModelData> createGrid() {
        List<ColumnConfig> configs = new ArrayList<ColumnConfig>();

        ColumnConfig column = new ColumnConfig();
        column.setId("name");
        column.setHeader("お名前");
        column.setWidth(100);
        configs.add(column);

        column = new ColumnConfig();
        column.setId("notpersistkind.name");
        column.setHeader("種類");
        column.setWidth(200);
        configs.add(column);

        loader =
            new BaseListLoader<ListLoadResult<Cat>>(new RpcProxy<List<Cat>>() {
                @Override
                protected void load(Object loadConfig,
                        AsyncCallback<List<Cat>> callback) {
                    catservice.searchAllCat(callback);
                }
            }, new BeanModelReader());

        ListStore<ModelData> store = new ListStore<ModelData>(loader);

        ColumnModel cm = new ColumnModel(configs);

        Grid<ModelData> grid = new Grid<ModelData>(store, cm);
        grid.getView().setEmptyText("sdfd");
        grid.setBorders(false);
        grid.setAutoExpandColumn("name");
        grid.setBorders(true);

        loader.load();
        return grid;
    }

}


slim3とつながっている。というかGWTのRPCを呼んでいる箇所は、executeUpdateCatの部分とはじめに一覧を読み込んでくる

loader =
        new BaseListLoader<ListLoadResult<Cat>>(new RpcProxy<List<Cat>>() {
             @Override
             protected void load(Object loadConfig,
                     AsyncCallback<List<Cat>> callback) {
                 catservice.searchAllCat(callback);
             }
        }, new BeanModelReader());

の部分になります。このRpcProxyは抽象クラスなので、loadを実装してあげます。ここでcatserviceからサーバ側のコードを呼んで、結果がcallbackされるのはRpcProxyのonSuccessになります。


RpcProxyクラス

public abstract class RpcProxy<D> implements DataProxy<D> {

  public void load(final DataReader<D> reader, final Object loadConfig,
      final AsyncCallback<D> callback) {
    load(loadConfig, new AsyncCallback<D>() {

      public void onFailure(Throwable caught) {
        callback.onFailure(caught);
      }

      @SuppressWarnings("unchecked")
      public void onSuccess(Object result) {
        try {
          D data = null;
          if (reader != null) {
            data = reader.read(loadConfig, result);
          } else {
            data = (D) result;
          }
          callback.onSuccess(data);
        } catch (Exception e) {
          callback.onFailure(e);
        }
      }

    });
  }

ここのreaderが先ほどのloadの第2引数のnew BeanModelReader()ですんで、ここでslim3で作ったCatがExtGwtのModelDataというものに変換されます。このModelDataになることにより、ExtGwtのGridに展開することができます。


slim3のmodelに

public class Cat implements Serializable , BeanModelTag{

こんな具合で、BeanModelTagインターフェースをimplしないと変換してくれません。


ExtGwtでは、ProxyやLoaderやReaderを組み合わせることにより様々なデータをリモートからとってきて、ExtGwtというかExt.jsが提供するUI部品にJavaオブジェクトであるModelDataを直接展開できるようになります。例えばXmlデータの場合ならば、XmlReaderとHttpProxyという組み合わせでデータをとってきて、ModelDataとしてUIに展開することが可能です。


つまり、全てがJavaで完結するのですが、エラーとか出た場合にはいろいろ面倒なのかとも思います。JavaScriptを知っておく必要の重要はあるかと思います。