GXT之旅:第六章:Templates(1)——Template(1)
来源:互联网 发布:电子地图软件开发 编辑:程序博客网 时间:2024/05/18 04:22
第六章:Templates
本章我们要了解Templates,以及学习他们是如何方便我们去自定义数据的格式化和显示。我们也会详细了解XTemplates的丰富功能
本章,我们会涉及到如下GXt功能集
- Template
- XTemplate
- RowExpander
- ListView
- ModelProcessor
- CheckBoxListView
当然GXT会想到这样的问题,并且提供了连个解决方案。第一:ModelProcessor可以预加工ModelData,定义出一个新的列(以后会讲到)。第二种就是使用Template。
首先,我们要做一些准备工作,在Feed和Item类里面加入更多的fields,并在后端的server方法里面灌入数据——以供给Template使用。
- Feed类中,加入两个新的fields:imageUrl,存储图片的url;items用来存储Item集合。当然别忘了setter和getter方法
private String imageUrl;private List<Item> items = new ArrayList<Item>();
- Item类加入publication和thumbnailUrl。因为是直接继承的BaseModel,所以注意getter和setter方法的书写:
package com.danielvaughan.rssreader.shared.model;import java.util.Date;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 Date getPubDate() {return get("pubDate");}public String getThumbnailUrl() {return get("thumbnailUrl");}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 setPubDate(Date pubDate) {set("pubDate", pubDate);}public void setThumbnailUrl(String thumbnailUrl) {set("thumbnailUrl", thumbnailUrl);}public void setTitle(String title) {set("title", title);}}
- FeedService接口里修改原来无参数的loadFeedList()方法,为
List<Feed> loadFeedList(boolean loadItems);
- 别忘了在FeedServiceAsync修改对应的回调方法
void loadFeedList(boolean loadItems, AsyncCallback<List<Feed>>callback);
- FeedServiceImpl类里,通过修改loadFeedList()为loadFeedList(boolean loadItems),实现其抽象方法。
@Overridepublic List<Feed> loadFeedList(boolean loadItems)) {feeds.clear();Set<String> feedUrls = persistence.loadFeedList();for (String feedUrl : feedUrls) {feeds.put(feedUrl, loadFeed(feedUrl,loadItems)));}return new ArrayList<Feed>(feeds.values());}
- 修改FeedServiceImpl.loadFeed方法,加入新的loadItems参数。具体实现如下:
private Feed loadFeed(String feedUrl, boolean loadItems) {Feed feed = new Feed(feedUrl);try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");feed.setTitle(eleChannel.getChildText("title"));feed.setDescription(eleChannel.getChildText("description"));feed.setLink(eleChannel.getChildText("link"));Element eleImage = eleChannel.getChild("image");feed.setImageUrl("");if (eleImage != null) {Element eleUrl = eleImage.getChild("url");if (eleUrl != null) {feed.setImageUrl(eleUrl.getText());}}if (loadItems) {feed.setItems(loadItems(feedUrl));}return feed;} catch (IOException e) {LOGGER.log(Level.SEVERE, "IO Error loading feed", e);return feed;} catch (JDOMException e) {LOGGER.log(Level.SEVERE, "Error parsing feed", e);return feed;}}
- 牵扯到引用loadFeed方法的相关方法修改。
@Overridepublic void addExistingFeed(String feedUrl) {Feed loadResult = loadFeed(feedUrl, false);if (loadResult.getTitle() != null) {feeds.put(feedUrl, loadResult);persistence.saveFeedList(feeds.keySet());}}
- 相应的loadItems方法也要修改,
@Override@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"));Namespace ns = Namespace.getNamespace("media","http://search.yahoo.com/mrss/");Element eleThumbnail = eleItem.getChild("thumbnail", ns);if (eleThumbnail != null) {item.setThumbnailUrl(eleThumbnail.getAttributeValue("url"));}String pubDateStr = eleItem.getChildText("pubDate");if (pubDateStr != null) {try {DateFormat df = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z");item.setPubDate(df.parse(pubDateStr));} catch (ParseException e) {item.setPubDate(null);}}items.add(item);}return items;} catch (IOException e) {e.printStackTrace();return items;} catch (JDOMException e) {e.printStackTrace();return items;}}
- 最后,在FeedList的onRender方法里,修改为新的service方调用
protected void load(Object loadConfig, AsyncCallback<List<Feed>>callback) {feedService.loadFeedList(false, callback);}
- 目前为止,准备工作已经完成,下一章会在此数据结构的基础之上使用Template
- 修改后完整的FeedServiceImpl类如下:
package com.danielvaughan.rssreader.server.services;import java.io.IOException;import java.net.URL;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.UUID;import java.util.logging.Level;import java.util.logging.Logger;import org.jdom.Attribute;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.Namespace;import org.jdom.input.SAXBuilder;import com.danielvaughan.rssreader.client.services.FeedService;import com.danielvaughan.rssreader.server.utils.FilePersistence;import com.danielvaughan.rssreader.server.utils.Persistence;import com.danielvaughan.rssreader.shared.model.Category;import com.danielvaughan.rssreader.shared.model.Feed;import com.danielvaughan.rssreader.shared.model.Item;import com.extjs.gxt.ui.client.data.BasePagingLoadResult;import com.extjs.gxt.ui.client.data.ModelData;import com.extjs.gxt.ui.client.data.PagingLoadConfig;import com.extjs.gxt.ui.client.data.PagingLoadResult;import com.google.gwt.dev.util.collect.HashMap;import com.google.gwt.user.server.rpc.RemoteServiceServlet;@SuppressWarnings("serial")public class FeedServiceImpl extends RemoteServiceServlet implementsFeedService {private final static Logger LOGGER = Logger.getLogger(FeedServiceImpl.class.getName());private Map<String, Feed> feeds = new HashMap<String, Feed>();private final Persistence persistence = new FilePersistence();@Overridepublic void addExistingFeed(String feedUrl) {Feed loadResult = loadFeed(feedUrl, false);if (loadResult.getTitle() != null) {feeds.put(feedUrl, loadResult);persistence.saveFeedList(feeds.keySet());}}@Overridepublic Feed createNewFeed() {UUID uuid = UUID.randomUUID();return new Feed(uuid.toString());}private PagingLoadResult<Item> getPagingLoadResult(List<Item> items,PagingLoadConfig config) {List<Item> pageItems = new ArrayList<Item>();int offset = config.getOffset();int limit = items.size();if (config.getLimit() > 0) {limit = Math.min(offset + config.getLimit(), limit);}for (int i = config.getOffset(); i < limit; i++) {pageItems.add(items.get(i));}return new BasePagingLoadResult<Item>(pageItems, offset, items.size());}@Overridepublic List<ModelData> loadCategorisedItems(String feedUrl,Category category) {List<Item> items = loadItems(feedUrl);Map<String, List<Item>> categorisedItems = new HashMap<String, List<Item>>();for (Item item : items) {String itemCategoryStr = item.getCategory();if (itemCategoryStr == null) {itemCategoryStr = "Uncategorised";}List<Item> categoryItems = categorisedItems.get(itemCategoryStr);if (categoryItems == null) {categoryItems = new ArrayList<Item>();}categoryItems.add(item);categorisedItems.put(itemCategoryStr, categoryItems);}if (category == null) {List<ModelData> categoryList = new ArrayList<ModelData>();for (String key : categorisedItems.keySet()) {categoryList.add(new Category(key));}return categoryList;} else {return new ArrayList<ModelData>(categorisedItems.get(category.getTitle()));}}private Feed loadFeed(String feedUrl, boolean loadItems) {Feed feed = new Feed(feedUrl);try {SAXBuilder parser = new SAXBuilder();Document document = parser.build(new URL(feedUrl));Element eleRoot = document.getRootElement();Element eleChannel = eleRoot.getChild("channel");feed.setTitle(eleChannel.getChildText("title"));feed.setDescription(eleChannel.getChildText("description"));feed.setLink(eleChannel.getChildText("link"));Element eleImage = eleChannel.getChild("image");feed.setImageUrl("");if (eleImage != null) {Element eleUrl = eleImage.getChild("url");if (eleUrl != null) {feed.setImageUrl(eleUrl.getText());}}if (loadItems) {feed.setItems(loadItems(feedUrl));}return feed;} catch (IOException e) {LOGGER.log(Level.SEVERE, "IO Error loading feed", e);return feed;} catch (JDOMException e) {LOGGER.log(Level.SEVERE, "Error parsing feed", e);return feed;}}@Overridepublic List<Feed> loadFeedList(boolean loadItems) {feeds.clear();Set<String> feedUrls = persistence.loadFeedList();for (String feedUrl : feedUrls) {feeds.put(feedUrl, loadFeed(feedUrl, loadItems));}return new ArrayList<Feed>(feeds.values());}@Override@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"));Namespace ns = Namespace.getNamespace("media","http://search.yahoo.com/mrss/");Element eleThumbnail = eleItem.getChild("thumbnail", ns);if (eleThumbnail != null) {item.setThumbnailUrl(eleThumbnail.getAttributeValue("url"));}String pubDateStr = eleItem.getChildText("pubDate");if (pubDateStr != null) {try {DateFormat df = new SimpleDateFormat("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z");item.setPubDate(df.parse(pubDateStr));} catch (ParseException e) {item.setPubDate(null);}}items.add(item);}return items;} catch (IOException e) {e.printStackTrace();return items;} catch (JDOMException e) {e.printStackTrace();return items;}}@Overridepublic PagingLoadResult<Item> loadItems(String feedUrl,PagingLoadConfig config) {List<Item> items = loadItems(feedUrl);return getPagingLoadResult(items, config);}@Overridepublic void saveFeed(Feed feed) {Element eleRoot = new Element("rss");eleRoot.setAttribute(new Attribute("version", "2.0"));// Create a document from the feed objectDocument document = new Document(eleRoot);Element eleChannel = new Element("channel");Element eleTitle = new Element("title");Element eleDescription = new Element("description");Element eleLink = new Element("link");eleTitle.setText(feed.getTitle());eleDescription.setText(feed.getDescription());eleLink.setText(feed.getLink());eleChannel.addContent(eleTitle);eleChannel.addContent(eleDescription);eleChannel.addContent(eleLink);eleRoot.addContent(eleChannel);persistence.saveFeedXml(feed.getUuid(), document);addExistingFeed(persistence.getUrl(feed.getUuid()));}}
- GXT之旅:第六章:Templates(1)——Template(1)
- GXT之旅:第六章:Templates(1)——Template(2)
- GXT之旅:第六章:Templates(2)——XTemplate(1)
- GXT之旅:第六章:Templates(2)——XTemplate(2)
- GXT之旅:第二章:GXT组件(1)——组件层次结构
- GXT之旅:第一章:初识ExtGWT(1)——简介
- GXT之旅:第二章:GXT组件(2)——渲染和容器
- GXT之旅:第二章:GXT组件(3)——事件和监听
- GXT之旅:第二章:GXT组件(4)——容器的布局
- GXT之旅:第二章:GXT组件(5)——加载消息
- GXT之旅:第二章:GXT组件(6)——定制组件
- GXT之旅:第二章:GXT组件(7)——Button和Tooltip
- GXT之旅:第二章:GXT组件(8)——Popup
- GXT之旅:第二章:GXT组件(9)——Popup位置
- GXT之旅:第七章:MVC——标准的MVC与GXT MVC
- GXT之旅:第七章:MVC——GXT MVC的相关类
- GXT之旅:第五章:高级Components(1)——Trees和TreeGrid(1)
- GXT之旅:第四章:Data与Components(1)——ModelData
- Java反射机制剖析(二)-功能以及举例
- 在jsp上显示pdf||网页直接打开PDF 在IE中显示pdf文档的方法及参数设置
- 一些常用的PCB 设计工具
- Qt4.7在ARM开发板上如何设置中文显示
- web.xml中load-on-startup标签的含义
- GXT之旅:第六章:Templates(1)——Template(1)
- DIV实现隐藏、显示、移动效果
- Deb打包
- 计算文件MD5值 应用层篇
- 机房收费系统之组合查询的传参问题
- Android 悬浮拖到窗口例子
- 实战:监控sqlserver 2008 R2群集状态
- 关于javascript模块和命名空间(Module and namespace)
- 飞鸽出现传送文件失败?