GXT之旅:第四章:Data与Components(5)——Grid

来源:互联网 发布:gtx970 gpuz数据 编辑:程序博客网 时间:2024/05/16 08:07

准备工作——Item

正如我们所知,一个feed的信息,里面会包含多组Item的信息,也就是一对多的概念。如果想将这些items都显示出来,我们需要有另外的model bean class来存储他们。整个处理过程如下:

  • 新建Item modalData类,其属性用来存储对应的信息(在这里为了简单起见,直接使用之前提到的第一种方法,让Item成为ModalData类。):
package com.danielvaughan.rssreader.shared.model;import com.extjs.gxt.ui.client.data.BaseModel;@SuppressWarnings("serial")public class Item extends BaseModel {public Item() {}public String getCategory() {return get("category");}public String getDescription() {return get("description");}public String getLink() {return get("link");}public String getTitle() {return get("title");}public void setCategory(String category) {set("category", category);}public void setDescription(String description) {set("description", description);}public void setLink(String link) {set("link", link);}public void setTitle(String title) {set("title", title);}}
  • 在FeedService接口里,定义loadItems方法,根据url,返回Item List
package com.danielvaughan.rssreader.client.services;import java.util.List;import com.danielvaughan.rssreader.shared.model.Feed;import com.danielvaughan.rssreader.shared.model.Item;import com.google.gwt.user.client.rpc.RemoteService;import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;@RemoteServiceRelativePath("feed-service")public interface FeedService extends RemoteService {void addExistingFeed(String feedUrl);Feed createNewFeed();List<Feed> loadFeedList();List<Item> loadItems(String feedUrl);void saveFeed(Feed feed);}

  • 同样的FeedServiceAsync 异步回调类,添加对应的回调方法
package com.danielvaughan.rssreader.client.services;import java.util.List;import com.danielvaughan.rssreader.shared.model.Feed;import com.danielvaughan.rssreader.shared.model.Item;import com.google.gwt.user.client.rpc.AsyncCallback;public interface FeedServiceAsync {void addExistingFeed(String feedUrl, AsyncCallback<Void> callback);void createNewFeed(AsyncCallback<Feed> callback);void loadFeedList(AsyncCallback<List<Feed>> asyncCallback);void loadItems(String feedUrl, AsyncCallback<List<Item>> callback);void saveFeed(Feed feed, AsyncCallback<Void> callback);}

  • 在FeedServiceImpl实现类,实现抽象方法loadItems
@SuppressWarnings("unchecked")public List<Item> loadItems(String feedUrl) {List<Item> items = new ArrayList<Item>();try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");List<Element> itemElements = eleChannel.getChildren("item");for (Element eleItem : itemElements) {Item item = new Item();item.setTitle(eleItem.getChildText("title"));item.setDescription(eleItem.getChildText("description"));item.setLink(eleItem.getChildText("link"));item.setCategory(eleItem.getChildText("category"));items.add(item);}return items;} catch (IOException e) {e.printStackTrace();return items;} catch (JDOMException e) {e.printStackTrace();return items;}}

Grid

Grid很类似与flex的datagrid。GXT的Grid component 拥有这许多不同的功能。现在,我们就从最基本的功能——如何的让Grid显示数据开始。当通过Grid的构造函数创建实例的之后,需要指定两方面的内容:ListStore和ColumnModel

Grid<ModelData> grid = new Grid<ModelData>(itemStore, columnModel);

ColumnConfig

Columnconfig定义了Grid在显示的时候每一列。具体点说就是指明了:1.使用了列数据;2.数据是如何被渲染出来的。

Conlumnconfig和ColumnModel之间的关系,查看源码的构造函数一看便知:

  public ColumnModel(List<ColumnConfig> columns) {    this.configs = new ArrayList<ColumnConfig>(columns);  }

Columnconfig可以有很多组,存入list里,然后传入到ColumnModel的构造函数中去,生成ColumnModel的实例。

那么将上面提到所有内容加入到我们的RSSReader项目里——让应用程序在启动的时候,自动的读取一个RSS url 将读取的items信息显示到Grid中:

  • 创建新package:com.danielvaughan.rssreader.client.grids,在新包内加入ItemGrid内的自定义组件。我们将在这个ItemGrid 内加入Grid的代码
  • 为了让Grid能够自适应浏览器窗口的大小,ItemGrid类要继承LayoutContainer
  • 习惯上,构造函数里,设置其LayOut
public ItemGrid() {setLayout(new FitLayout());}
  • 当然了,必须要override onRender方法。首先,定义ColumnConfigs 他是一个List<ColumnConfig>
final List<ColumnConfig> columns = new ArrayList<ColumnConfig>();columns.add(new ColumnConfig("title", "Title", 200));columns.add(new ColumnConfig("description", "Description", 200));
  • 将定义好的columns传入ColumnModel的构造函数
final ColumnModel columnModel = new ColumnModel(columns);

  • 定义测试的RSS url,为了保证定义的url一定好用:
final String TEST_DATA_FILE = "http://127.0.0.1:8888/rss2sample.xml";

  • 从Registry里拿feedService

final FeedServiceAsync feedService = Registry.get(RSSReaderConstants.FEED_SERVICE);

  • 还是按照之前的远程调用,RpcProxy去调用FeedService的loadItems方法。通过

final FeedServiceAsync feedService = Registry.get(RSSReaderConstants.FEED_SERVICE);RpcProxy<List<Item>> proxy = new RpcProxy<List<Item>>() {@Overrideprotected void load(Object loadConfig,AsyncCallback<List<Item>> callback) {feedService.loadItems(TEST_DATA_FILE, callback);}};

  • 因为Item是使用的一种方法实现的modelData——直接继承了BaseModel(其属性都是用get/set写的),因此不需要reader进行转换。loader可以直接通过proxy获得
ListLoader<ListLoadResult<Item>> loader = new BaseListLoader<ListLoadResult<Item>>(proxy);
  • 通过loader,获得store数据
ListStore<ModelData> itemStore = new ListStore<ModelData>(loader);

  • ListStore和ColumnModel都准备完毕之后,开始创建Grid,将两个对象传入Grid的构造函数当中。设置description列可以自动伸展,填充空白区域。

Grid<ModelData> grid = new Grid<ModelData>(itemStore,columnModel);grid.setBorders(true);grid.setAutoExpandColumn("description");

  • 调用load方法,让Grid装载store

loader.load();

  • 将Grid添加到LayoutContainer内显示
add(grid);
  • 最后编辑com.danielvaughan.rssreader.client.components.RssMainPanel,添加ItemGrid
package com.danielvaughan.rssreader.client.components;import com.danielvaughan.rssreader.client.grids.ItemGrid;import com.extjs.gxt.ui.client.widget.ContentPanel;import com.extjs.gxt.ui.client.widget.layout.FitLayout;public class RssMainPanel extends ContentPanel {public RssMainPanel() {setHeading("Main");setLayout(new FitLayout());add(new ItemGrid());}}








原创粉丝点击