GXT之旅:第五章:高级Components(1)——Trees和TreeGrid(1)

第五章:高级Components

本章我们要基于前几章内容,更深入的学习data-backed components。我们会学习Tree以及如何优化和改进数据的加载和显示等内容。学习如何将Tree的概念应用与Grid。会涉及到Grid的一些高级功能。最后我们要学习menus和toolbars


本章,我们会涉及到如下GXt功能集

  • Trees
  • BaseTreeModel
    • TreeStore
    • TreePanel
    • TreeGrid
    • TreeGridCellRenderer
  • Advanced grid features
    • Column grouping
      • HeaderGroupConfig
    • Aggregation rows
      • AggregationRowConfig
      • SummaryType
    • Paging
      • PagingListResult
      • PagingLoadConfig
        • PagingModelMemoryProxy
        • PagingLoader
        • PagingToolBar
  • ImageBundle
  • Toolbars and menus
    • Menu
    • MenuItem
    • CheckMenuItem
    • MenuBar
    • MenuBarItem
    • MenuEvent
    • ToolBar
    • Status

Trees

上一章,我们所涉及的components只是使用ListData。现在我们要学习那些使用TreesData的components。

GXT所提供的有关tree的components和list的components是很类似的。不同的是,对于tree来说,要使用其专门的ModelData—Store, DataReader, 和Loader。

BaseTreeModel

BaseTreeModel 继承 BaseModel 实现了TreeModel接口,自然添加了关于tree的功能方法——有关于管理父子关系的功能方法。为了让ModelData可以被TreePanel或者TreeGrid使用,javaBean就需要继承BaseTreeModel而不是BaseModel。

在RSSReader项目里,我们准备让一个feed的url的items集合存在一个树的分类上。为了实现此功能,我们需要创建一个Category class继承BaseTreeModel

  • 在com.danielvaughan.rssreader.shared.model包下,新建类Category,继承BaseTreeModel。
public class Category extends BaseTreeModel {}
  • 新建一个静态的ID属性,用来做自增序列。新建一个构造函数,其参数是String类型的title,并且让ID自增
	private static int ID = 0;

	public Category(String title) {
		set("id", ID++);
		set("title", title);
	}
  • 再添加一个无参数的构造函数,只是让ID自增
	public Category() {
		set("id", ID++);
	}
  • 在加入get方法,整个Category类的定义如下:
package com.danielvaughan.rssreader.shared.model;

import com.extjs.gxt.ui.client.data.BaseTreeModel;

@SuppressWarnings("serial")
public class Category extends BaseTreeModel {
	private static int ID = 0;

	public Category() {
		set("id", ID++);
	}

	public Category(String title) {
		set("id", ID++);
		set("title", title);
	}

	public Integer getId() {
		return (Integer) get("id");
	}

	public String getTitle() {
		return (String) get("title");
	}
}

接下来,需要在FeedService接口里,定义新的方法,用来根据给定的category获得属于该category内的items集合。

  • FeedService接口内定义loadCategorisedItems方法
List<ModelData> loadCategorisedItems(String feedUrl, Category category);

  • 同样的,异步回调方法
void loadCategorisedItems(String feedUrl, Category category,
AsyncCallback<List<ModelData>> callback);
  • 在FeedServiceImpl类里,实现其抽象方法
@Override
	public 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) {
			// 0:get each item 's category
			String itemCategoryStr = item.getCategory();
			if (itemCategoryStr == null) {
				itemCategoryStr = "Uncategorised";
			}
			// 1: get categoryItems by itemCategoryStr
			List<Item> categoryItems = categorisedItems.get(itemCategoryStr);
			if (categoryItems == null) {
				categoryItems = new ArrayList<Item>();
			}
			// 2: add current item into categoryItems
			categoryItems.add(item);

			// 3: put categoryItems into categorisedItems(hashMap) named as
			// itemCategoryStr
			categorisedItems.put(itemCategoryStr, categoryItems);
		}
		// 4: if category is null, return the whole categoryList
		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()));
		}
	}

TreeStore

TreeStore 是另外一个Store的实现类。其不同点在于,使用TreeStore来存储ListStore,用来表示层级的数据,而不是普通的数据集合。

我们可以将TreeModel添加到TreeStore里面,不需要使用TreeModel去管理父子层级关系,不需要复杂的编码,系统内部会自动的管理其关系。对于如何通过add方法,将TreeModel添加到TreeStore中并同时设置之间的层级关系,之后会介绍。

TreePanel

TreePanel是一个真正的可视化树控件。使用起来也很简单,掌握起来也很容易。

当通过构造函数创建TreePanel的时候,其必须传入TreeStore的参数。通过setDisplayProperty方法,来设置显示TreeStore里面的哪一列内容。

默认情况下,当一个节点有子节点的时候,显示的图标是文件夹;如果是叶子节点的时候(就是该节点没有子节点),显示的图标是白色文件图片。当然可以通过setLeafIcon来设置叶子节点的图标(需要以GWT的AbstractImagePrototype类作为参数)。

ImageBundle

Tree components 使用 GWT提供的ImageBundle 功能,用来作为tree节点的图标的初始化加载过程。如果想要在我们RSSReader项目里,让tree components使用自定义的图标的话,就需要我们定义一个ImageBundle。尽管ImageBundle是GWT的内容并未GXT的内容,但是我们要注意的是:虽然ImageBundle的出现是用来替换ClientBundle,但是他还是不推荐被直接使用的(deprecation)。我们需要自加工一个Icons。

  • 新建包:com.danielvaughan.rssreader.client.resources,在其包下新建Icons接口,继承ImageBundle

@SuppressWarnings("deprecation")
public interface Icons extends ImageBundle {}

  • 每个被添加到ImageBundle的图片,都需要一个无参的方法返回AbstractImagePrototype。使用@Resource注解图片的位置,相对于当前package的路径
package com.danielvaughan.rssreader.client.resources;

import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.ImageBundle;

@SuppressWarnings("deprecation")
public interface Icons extends ImageBundle {
	@Resource("rss.png")
	AbstractImagePrototype rss();
}

  • 在同样的package下,新建Resources类,用来静态引用刚才生成的Icons。
package com.danielvaughan.rssreader.client.resources;

import com.google.gwt.core.client.GWT;

public class Resources {
	public static final Icons ICONS = GWT.create(Icons.class);
}
  • 最后,我们RSSReader项目的package层级关系如下:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值