级别: 初级 王 颖初 (wangychu@cn.ibm.com), 软件工程师, IBM 尹 雯 (yinwen@cn.ibm.com), 经理, IBM 冯 鑫 (fengxin@cn.ibm.com), 软件工程师, IBM 王 海成 (wanghc@cn.ibm.com), 资深软件工程师, IBM
2009 年 6 月 05 日 GWT-Ext 是基于 Google Web Toolkit(GWT)和 ExtJs 的功能强大的网页开发控件库。它非常适用于进行纯 Java 语言的富 Internet 应用的快速开发。本系列文章将详细讲解 GWT-Ext 的基本结构和功能特点,并通过代码示例来演示该技术的具体实现。本文是 GWT-Ext 体验之旅系列 的第 3 部分,我们将体验各种布局管理器的效果,了解我们常用的布局管理器的编程方式和一些经验总结。在对树的介绍中,我们将从树的同步和异步方式的初始化到树的一些特性进行详细介绍。
布局 Layout
(1) 水平布局
水平布局使在父容器面板中的所有子对象沿同一水平线依次顺序排列。
水平布局需要实现 com.gwtext.client.widgets.layout.HorizontalLayout 类。
当设定水平布局后,Panel 中新建的子对象将按照加入父容器的次序依次从左向右显示在父面板中。以下代码清单 1 将产生如图 1 的对象布局。
清单 1. 水平布局
Panel.setLayout(new HorizontalLayout(15));
panel.add(new Panel("Item 1", 100, 150));
panel.add(new Panel("Item 2", 75, 150));
panel.add(new Panel("Item 3", 100, 150));
panel.add(new Panel("Item 4", 150, 150)); |
图 1. 水平布局
(2) 垂直布局
垂直布局使在父容器面板中的所有子对象沿垂直方向依次顺序排列。
垂直布局需要实现 com.gwtext.client.widgets.layout.VerticalLayout 类。
当设定垂直布局后,所有的子对象将按照加入父容器的次序依次从上向下的显示在父面板中。下列代码清单 2 将产生如图 2 所示的垂直布局。
清单 2. 垂直布局
Panel panel = new Panel();
panel.setLayout(new VerticalLayout(15));
panel.add(new Panel("Item 1", 150, 100));
panel.add(new Panel("Item 2", 350, 75));
panel.add(new Panel("Item 3", 150, 100));
panel.add(new Panel("Item 3", 150, 150)); |
图 2. 垂直布局
(3) 边框布局
边框布局是一种高级的页面布局方式,它将整个的 UI 显示空间分为上、下、左、右、和中央五个部分,各个部分可以在各自所属的布局空间中随 UI 界面大小的变化自由缩放。当 UI 空间尺寸变化时,上、下两部分可以在水平方向上自由缩放,垂直高度固定不变,左、右两部分可以在垂直方向上自由缩放,水平宽度固定不变,当上、下、左、右四个部分布局尺寸确定后,中央部分会沿水平和垂直两个方向填充所有剩余空间。以下图 3 为一个边框布局的示例。
图 3. 边框布局
垂直布局需要实现 com.gwtext.client.widgets.layout.BorderLayout 类。
使用 com.gwtext.client.widgets.layout.BorderLayoutData 来定义各个子空间的显示属性,如最大尺寸、最小尺寸、空白等属性。 BorderLayoutData 用 setMargins 来定义各个子空间在边框布局中的位置。
public void setMinSize(int minSize)
public void setMaxSize(int maxSize)
public void setSplit(boolean split)
public void setMargins(int top,int left,int right,int bottom) |
使用类 com.gwtext.client.core.RegionPosition 来定义各个边框布局子空间的位置。 RegionPosition.NORTH 表示上部子空间,RegionPosition.SOUTH 表示下部子空间,RegionPosition.WEST 表示左侧子空间,RegionPosition.EAST 表示右侧子空间,RegionPosition.CENTER 则表示中央子空间。需要说明一下的是,上下左右这些相对位置都是针对 RegionPosition.CENTER 这个中央子空间来放置的。因此 GWT-Ext 如果发现使用边框布局,但是没有指定放置在中间的控件,会初始化失败。通过使用以下构造函数可定义各个子对象所属的空间布局。
public BorderLayoutData(RegionPosition region) |
代码清单 3 中 borderPanel 为具有边框布局的父面板,southPanel 为一个子对象面板。使用 add 方法将 southPanel 放在 borderPanel 面板的下部子空间中。其中参数 component 表示要添加的对象即 southPanel,layoutData 是 BorderLayoutData 类的实例对象。在这个例子里,我们使用 RegionPosition.SOUTH 构造了 southData,并设置了该空间的最大尺寸、最小尺寸、空白和位置等属性。
public void add(Component component, LayoutData layoutData) |
清单 3. 边框布局
Panel borderPanel = new Panel();
borderPanel.setLayout(new BorderLayout());
Panel southPanel = new Panel();
BorderLayoutData southData = new BorderLayoutData(RegionPosition.SOUTH);
southData.setMinSize(100);
southData.setMaxSize(200);
southData.setMargins(new Margins(0, 0, 0, 0));
southData.setSplit(true);
borderPanel.add(southPanel, southData); |
(4) 手风琴下拉布局
手风琴下拉布局是一个垂直的布局结构,位于手风琴下拉布局中的各个子界面成员共享公共的界面显示空间,当其中的任意一个成员对象处于激活状态时,其他的各个子成员对象会被自动隐藏。
手风琴下拉布局需要实现 com.gwtext.client.widgets.layout.AccordionLayout 类。
当设定手风琴下拉布局后,所有的子对象将按照加入父容器的次序依次从上向下的显示在父面板中。代码清单 4 将产生如图 4 所示的手风琴下拉布局。
清单 4. 手风琴下拉布局
Panel accordionPanel = new Panel();
accordionPanel.setLayout(new AccordionLayout(true));
Panel panelOne = new Panel("Panel 1", "<p> Panel1 content!</p>");
accordionPanel.add(panelOne);
Panel panelTwo = new Panel("Panel 2", "<p> Panel2 content!</p>");
accordionPanel.add(panelTwo);
Panel panelThree = new Panel("Panel 3", "<p> Panel3 content!</p>");
accordionPanel.add(panelThree); |
图 4. 手风琴下拉式布局
(5) 锚点式布局
锚点式布局是一种可以在水平和垂直方向上按照父容器的尺寸变换的布局方式。在锚点式布局中,子对象按照百分比或绝对像素数值在水平和垂直两个方向上指定它针对父容器的相对尺寸。当父容器的尺寸发生变化后,子对象会按照已经指定的相对尺寸改变自己的大小。
锚点式布局需要实现 com.gwtext.client.widgets.layout.AnchorLayout 类。
使用 com.gwtext.client.widgets.layout.AnchorLayoutData 对象来定义锚式布局所需要的数据。 AnchorLayoutData 对象的构造函数使用字符串定义需要的布局参数。参数 anchor 包括了水平和垂直方向的百分比或者绝对像素数值,以空格间隔。比如“ 100% 20% ”表示该对象相对于父容器,水平方向是 100%,垂直方向是父容器的 20% 。而“ -100 30% ”表示该对象水平放心相对于父容器少 100 像素,而垂直方向是父容器的 30% 。
public AnchorLayoutData(String anchor) |
使用 add 方法将对象放入父容器中。其中参数 component 表示要添加的对象,layoutData 是 AnchorLayoutData 类的实例对象。
public void add(Component component, LayoutData layoutData) |
代码清单 5 将产生如图 5 所示的锚点式布局。
清单 5. 锚点式布局
Panel wrapperPanel = new Panel();
wrapperPanel.setLayout(new AnchorLayout());
wrapperPanel.add(new Panel( "Item 1","Anchor : '100% 20%'
width is 100% of the containing element and 20% of its height"),
new AnchorLayoutData("100% 20%"));
wrapperPanel.add(new Panel("Item 2","Anchor : '50% 25%'
width is 50% of the containing element and 25% of its height"),
new AnchorLayoutData("50% 25%"));
wrapperPanel.add(new Panel("Item 3","Anchor : '-100 30%'
width is (100% of the containing element - 100px) and
height is 30% of containing element."),
new AnchorLayoutData("-100 30%"));
panel.add(wrapperPanel); |
图 5. 锚点式布局
(6) 列布局
在列布局中,各个子 UI 组件通过设定自己在水平方向上使用的宽度来共享父组件的宽度。
列布局需要实现 com.gwtext.client.widgets.layout. ColumnLayout 类。
使用 com.gwtext.client.widgets.layout.ColumnLayoutData 类对象来定义列布局所需要的数据.
public ColumnLayoutData(double columnWidth) |
使用 add 方法将对象放入父容器中。其中参数 component 表示要添加的对象,layoutData 是 ColumnLayoutData 类的实例对象。
public void add(Component component, LayoutData layoutData) |
代码清单 6 将产生如图 6 所示的列布局。
清单 6. 百分比列布局
Panel wrapperPanel = new Panel();
wrapperPanel.setLayout(new ColumnLayout());
wrapperPanel.add(new Panel("Column 1", "25% width"),new ColumnLayoutData(.25));
wrapperPanel.add(new Panel("Column 2", "60% width"),new ColumnLayoutData(.6));
wrapperPanel.add(new Panel("Column 3", "15% width"),new ColumnLayoutData(.15)); |
图 6. 百分比列布局
列布局管理器可以使用绝对像素数值,百分比或者两者的混合来定义宽度。
代码清单 7 将产生如图 7 所示的混合列布局。
清单 7. 混合列布局
Panel wrapperPanel = new Panel();
wrapperPanel.setLayout(new ColumnLayout());
Panel p1 = new Panel("Column 1", "120px width");
p1.setWidth(120);
wrapperPanel.add(p1);
wrapperPanel.add(new Panel("Column 2", "80% width"), new ColumnLayoutData(.8));
wrapperPanel.add(new Panel("Column 3", "20% width"), new ColumnLayoutData(.2)); |
图 7. 混合列布局
树 Tree
树是 UI 界面编程中经常使用的一种显示结构化的,具有继承关系的数据的方法。 GWT-Ext 在 JAVA 对象 API 的层面上提供对树状 UI 控件的支持,它内建了对树形控件中节点的编辑、排序、过滤,拖拽等功能的支持,同时提供了一个完善的 UI 事件监听和处理机制。综合使用树和 GWT-EXT 中的其他组件,可以构建出功能强大的表现层 UI 组件。
GWT-EXT 中对树型 UI 控件提供支持的接口和类位于 com.gwtext.client.widgets.tree 和 com.gwtext.client.widgets.tree.event 两个包中。前者包含了构建表现层的工具类,主要用于 HTML 页面的渲染。而后者则用于提供对树型控件的事件监听和处理功能。
(1) 构建树
在 GWT-EXT 中使用 com.gwtext.client.widgets.tree.TreePanel 构建包含树的面板。使用 com.gwtext.client.widgets.tree.TreeNode 构建树的各个节点。各个节点按照继承关系添加到树中的相应位置。 TreePanel 树面板对象是所有数中节点的父 UI 组件,它将作为容器来包含树中的所有节点对象。树中的每一个节点都是一个 TreeNode 类的实例对象,使用 TreeNode 类中的方法 appendChild 可以在当前节点下添加其下的子节点。其中参数 child 是 TreeNode 的实例对象。
public native void appendChild(Node child) |
构建树的步骤
a. 使用构造函数 public TreePanel() 构建 TreePanel 对象
TreePanel treePanel = new TreePanel(); |
b. 使用 TreeNode 的构造函数 public TreeNode() 构建一个树的根节点对象
TreeNode rootTreeNode = new TreeNode();
rootTreeNode.setText("root node"); |
c. 使用 TreeNode 的 public void setRootNode(Node node) 方法将这个 Node 对象作为根节点加入到 Tree 中。此时即可得到一个包含了一个根节点的树状 UI 组件。
treePanel.setRootNode(rootTreeNode); |
d. 为了得到更多的树节点,可以使用构造函数 public TreeNode() 生成更多的节点对象,并依次使用 TreeNode 对象的 appendChild(Node child) 方法将他们添加到根节点或其他字节点中即可。
TreeNode generation1childNodeA=new TreeNode("generation 1 child a");
rootTreeNode.appendChild(generation1childNodeA);
TreeNode generation2childNodeA=new TreeNode("generation 2 child a");
generation1childNodeA.appendChild(generation2childNodeA);
TreeNode generation2childNodeB=new TreeNode("generation 2 child b");
generation1childNodeA.appendChild(generation2childNodeB);
TreeNode generation3childNodeA=new TreeNode("generation 3 child a");
generation2childNodeB.appendChild(generation3childNodeA);
TreeNode generation1childNodeB=new TreeNode("generation 1 child b");
rootTreeNode.appendChild(generation1childNodeB); |
e. 调用 expand 方法展开节点。 TreeNode 对象的 expand() 方法是展开 TreeNode 的子节点。 TreePanel 的 expandAll() 方法是展开所以节点。
rootTreeNode.expand();
treePanel.expandAll(); |
综合以上示例代码,将产生一棵如图 8 的树:
图 8. 构建树
(2) Tree 的事件监听与处理
GWT-EXT 中提供了一套丰富,简便且易于使用的针对树控件的事件监听与处理机制和简便的 API 。这些 API 存在于包 com.gwtext.client.widgets.tree.event 中。 GWT-EXT 还定义了数个用于事件监听的接口,并且提供了实现了这些接口的类供用户使用,以下几个是编程中会经常用到的事件监听类:
com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter:监听所有 TreePanel 中对象的事件。
com.gwtext.client.widgets.tree.event.TreeNodeListenerAdapter:监听树中各个节点对象的事件。
com.gwtext.client.widgets.tree.event.AsyncTreeNodeListenerAdapter:监听树异步节点对象的事件。
com.gwtext.client.widgets.tree.event.TreeLoaderListenerAdapter:监听树的数据加载事件。
在事件监听类中定义了以下各种 UI 事件监听方法,当相关联的 UI 事件发生时,监听器方法中定义的程序逻辑会自动被 GWT-EXT 系统回调执行。
当在当前 Node 上添加了新的子节点时,onAppend 方法将自动被系统调用。
public void onAppend(Tree tree, TreeNode parent, TreeNode node, int index) |
当删除选定节点时 onRemove 方法自动被系统调用。
public void onRemove(Tree tree, TreeNode parent, TreeNode node): |
在选定的节点上单击鼠标左键时,onClick 方法将自动被系统调用。
public void onClick(TreeNode node, EventObject e): |
在选定的父节点上点击子树图标以收缩该节点的所有子节点的子树时,onCollapseNode 方法将自动被系统调用。
public void onCollapseNode(TreeNode node): |
在选定的节点上单击鼠标右键时,onContextMenu 方法将自动被系统调用。
public void onContextMenu(TreeNode node, EventObject e): |
在选定的节点上双击鼠标左键时,onContextMenu 方法将自动被系统调用。
public void onDblClick(TreeNode node, EventObject e): |
当选定的节点状态改变时(由禁用变为可用或由可用变为禁用),onDisabledChange 方法将自动被系统调用。
public void onDisabledChange(TreeNode node, boolean disabled): |
当在选定的节点上发生鼠标拖拽事件时,onDragDrop 方法将自动被系统调用。
public void onDragDrop(TreePanel treePanel, TreeNode node, DD dd): |
当在选定的节点上鼠标拖拽事件结束时,onEndDrag 方法将自动被系统调用。
public void onEndDrag(TreePanel treePanel, TreeNode node): |
在选定的父节点上点击子树图标以展开该节点的所有子节点的子树时,onExpandNode 方法将自动被系统调用。
public void onExpandNode(TreeNode node): |
当在选定的节点上发生数据加载事件时,onLoad 方法将自动被系统调用。
public void onLoad(TreeNode node): |
当选定的节点被删除时,onNodeDrop 方法将自动被系统调用。
public void onNodeDrop(TreePanel treePanel, TreeNode target,
DragData dragData, String point, DragDrop source, TreeNode dropNode): |
当选定的节点被移动到另一个位置时,onMoveNode 方法将自动被系统调用。
public void onMoveNode(Tree treePanel, TreeNode node,
TreeNode oldParent, TreeNode newParent, int index): |
当在选定的节点上开始一个鼠标拖拽事件时,onStartDrag 方法将自动被系统调用。
public void onStartDrag(TreePanel treePanel, TreeNode node): |
在代码中添加监听器支持非常简单,只需实例化一个监听器类,定义需要监听的事件方法,并将该监听器类的实例添加到 TreePanel 或 TreeNode 上即可。以下代码清单 8 向一个 TreePanel 添加了一个 TreePanelListenerAdapter 监听器实例,该监听器实例将监听树控件 panel 中对象的鼠标左键单击和右键单击事件,并在事件发生时弹出 GWT-EXT 的消息对话框。
清单 8. Tree 的事件监听和处理
TreePanelListenerAdapter tpla=new TreePanelListenerAdapter ()
{
public void onClick(TreeNode node, EventObject e)
{
MessageBox.alert("Bacis Tree Sample MessageBox",
node.getText()+" Clicked") ;
}
public void onContextMenu(TreeNode node, EventObject e)
{
MessageBox.alert("Bacis Tree Sample MessageBox",
node.getText()+" Right Clicked") ;
}
};
treePanel.addListener(tpla); |
(3) Tree 中对象的拖拽功能
GWT-EXT 中内建了对树控件的拖拽功能的支持。
下面的图 9,图 10 和图 11 是一个树控件之间的拖拽事例。左侧树中的“ Sent ”节点被拖拽到右侧树中“ ToDo ”节点上,成为“ ToDo ”节点的子节点。在 GWT-EXT 中,树中的节点可以被拖拽到任何支持拖拽功能的组件中。
图 9. Tree 中对象的拖拽功能 1
图 10. Tree 中对象的拖拽功能 2
图 11. Tree 中对象的拖拽功能 3
在 GWT-EXT 使用 TreePanel 的 setEnableDD(true) 方法启用拖拽功能支持,再使用 setDdGroup(String groupName) 方法设定对象所属的拖拽组。拖拽的目的和源必须属于同一个拖拽组。
public void setEnableDD(boolean enableDD)
public void setDdGroup(java.lang.String ddGroup) |
代码清单 9 生成了两个支持拖拽的树控件,并定义“ treeDD ”为它们所属的拖拽组。
清单 9. Tree 中对象的拖拽功能
TreePanel treePanel = getSampleTreePanel();
treePanel.setEnableDD(true);
treePanel.setDdGroup("treeDD");
TreePanel treePanel2 = getSampleTreePanel();
treePanel2.setEnableDD(true);
treePanel2.setDdGroup("treeDD");
private TreePanel getSampleTreePanel()
{
TreePanel treePanel = new TreePanel();
TreeNode root = new TreeNode("Mail");
root.setExpanded(true);
TreeNode inbox = new TreeNode("Inbox");
root.appendChild(inbox);
TreeNode drafts = new TreeNode("Drafts");
root.appendChild(drafts);
......
treePanel.setRootNode(root);
return treePanel;
} |
方法 getSampleTreePanel() 用来生成本节示例中的可拖拽树。
(4) Tree 的异步数据加载
树控件中各个节点的数据可以通过编程的方式初始化,也可以通过 XML,Json 等方式异步加载。下面我们将通过 Tree 异步提取 XML 这个比较常用的方式来介绍 Tree 的异步数据加载功能。
在前面的例子我们看到,一棵树是由一个根节点和若干个中间节点以及叶子节点组成的。和 XML 文件比较起来,树的根节点对应于 XML 的顶级标签,树的叶子节点对应于 XML 所有底级的标签,树的中间节点对应于其它的 XML 标签。因为 XML 的结构和树的结构的对应关系,我们可以应用 GWT-Ext 提供的接口轻易的将 XML 的信息转换为一棵树,并且显示出来。
清单 10. 待转换成 Tree 的 XML 文件
<countries>
<team id="team-a" title="Team A" icon="images/flag_yellow.gif" checked="true">
<country title="Australia" qtip="Captain - Rank 1" checked="true" rank="1"/>
<country title="Brazil" qtip="Rank 2" rank="2" checked="false"/>
<country title="Canada" qtip="Rank 3" rank="3" checked="false"/>
<country title="China" qtip="Rank 4" rank="4" checked="false"/>
</team>
<team title="Team B" icon="images/flag_blue.gif">
<country id="Germany" title="Germany" qtip="Captain" checked="true" rank="1"/>
<country title="France" qtip="Rank 2" rank="2" checked="false"/>
<country title="Canada" qtip="Rank 3" rank="3" checked="false"/>
<country title="India" qtip="Rank 4" rank="4" checked="false"/>
<country title="Seychelles" qtip="Rank 5" rank="5" checked="false"/>
</team>
<team title="Team C" icon="images/flag_green.gif">
<country title="United States" qtip="Captain - Rank 1" checked="true" rank="1"/>
<country title="Japan" qtip="Rank 2" rank="2" checked="false"/>
<country title="Italy" qtip="Rank 3" rank="3" checked="false"/>
<country title="Finland" qtip="Rank 4" rank="4" checked="false"/>
</team>
</countries> |
从 XML 中我们可以看到树的根节点对应于 XML 标签 <countries>, 根节点下的中间节点对应于 XML 标签 <team>, 叶子节点则对应了 XML 标签 <country> 。 在各个 XML 标签中有属性节点,GWT-Ext 可以取得这些节点值并且赋值于各个树中的各个节点。具体的实现介绍如下。
首先,新建一个负责异步通信的 XMLTreeLoader 的实例 loader,他的构造函数如下。
其次,XMLTreeLoader 提供了很多方法来映射 XML 的不同节点。代码清单 11 提供了具体的实例来解释。
清单 11. Tree 的异步数据加载
loader.setDataUrl("data/countries.xml");
loader.setMethod(Connection.GET);
loader.setRootTag("countries");
loader.setFolderIdMapping("@id");
loader.setLeafIdMapping("@id");
loader.setFolderTitleMapping("@title");
loader.setFolderTag("team");
loader.setLeafTitleMapping("@title");
loader.setLeafTag("country");
loader.setQtipMapping("@qtip");
loader.setCheckedMapping("@checked");
loader.setIconMapping("@icon");
loader.setAttributeMappings(new String[] { "@rank" }); |
方法 setDataUrl 用于设置 XML 映射文件的相对位置,参数 url 是相对于 com.ibm.developmentworks.demo.public 的路径。在本例中,我们在 public 目录下创建了新的 data 目录,同时在该目录下新建 countries.xml 文件。
public void setDataUrl(java.lang.String dataUrl) |
方法 setMethod 用于设置通信方法。由于 XMLTreeLoader 是建立在 HTTP 上的异步通信,因此这里有 Connection.GET 和 Connection.POST 两种通信方法。
public void setMethod(Connection.Method method) |
方法 setRootTag 用于指定 XML 文件中顶级标签的名字。在本例中,顶级标签是 countries 。对应于树的根节点。
public void setRootTag(java.lang.String rootTag) |
方法 setFolderTag(String tag)用于指定 XML 文件中非顶级和最底级标签的名字。在本例中,该标签是 team 。对于树中的目录节点。目录节点可以包含非根节点外的其它任何节点。
public void setFolderTag(java.lang.String folderTag) |
方法 setLeafTag 用于指定 XML 文件中最底级标签的名字。在本例中,该标签的名字是 country 。对应于树中的叶子节点。叶子节点下不能再包含其它节点。
public void setLeafTag(java.lang.String leafTag) |
方法 setFolderIdMapping 用于设置节点的标识 ID 。对于树的每个节点来说都有一个唯一 ID,这个 ID 在 XML 文件中出现在标签 <team> 的属性节点。如 id="team-a",GWT-Ext 取得属性节点值的方式是在属性名前加上 @ 符号,取得属性值。如果在 xml 的标签中没有该指定属性,GWT-Ext 会生成随机唯一 ID 。
public void setFolderIdMapping(java.lang.String folderIdMapping) |
方法 setLeafIdMapping(String id)用于设置叶子节点的标识 ID 。方式和 setFolderIdMapping 一样。
public void setLeafIdMapping(java.lang.String leafIdMapping) |
方法 setQtipMapping(String qTip)用于设置鼠标指到对应树节点后显示的提示信息。本例中对应于各个节点的 qtip 属性。在本例中,通过 @qtip 来获得提示。
public void setQtipMapping(java.lang.String qtipMapping) |
方法 setCheckedMapping 用于指定非根节点前的可选框是否被选择。他的获取值是 true 或者 false 。如果取得值是 true,则可选框被勾选,false 则没有被选择。在本例中,通过 @checked 取得 boolean 值。
public void setCheckedMapping(java.lang.String checkedMapping) |
方法 setIconMapping(String icon)用于指定各个节点的图标所对应的相对路径。在本例中,各国家被分成 3 组,每一组由一种颜色的旗子代替。我们将准备好的图标文件 flag_yellow.gif,flag_blue.gif 和 flag_green.gif 拷贝到 com.ibm.developmentworks.demo.public.images 目录下。参数值 icon 是相对于 public 目录的相对路径。在本例中,通过 @icon 取得相对路径。没有该属性的节点,GWT-Ext 用默认图标显示。
public void setIconMapping(java.lang.String iconMapping) |
方法 setAttributeMappings 用于存储属性对数组。对于每一个树节点,他拥有可显示的数据,也可以暂存一系列不可显示的属性。这给程序带来了极大的灵活性。在本例中,attributeMappings 数组中只有 @rank 一个属性对被存储到各个节点当中。
public void setAttributeMappings(java.lang.String[] attributeMappings) |
在正确设置上述方法之后,树和 XML 的关系就建立了起来。接下来需要建立一个 AsyncTreeNode 这样一个异步根节点来实现树显示。如下所示。
AsyncTreeNode root = new AsyncTreeNode("Countries", loader);
treePanel.setRootNode(root); |
此外在树被建立起来后为了让树自动展开,可以调用方法如下。
这样,显示的结果如图 12 所示。
图 12. Tree 的异步数据加载
结束语
本文主要介绍了各种常用的布局以及 Tree, 并重点对 Tree 的特性,比如事件监听处理,拖拽和异步数据加载进行了详细介绍和代码分析。接下来是我们体验之旅的最后一章,拖拽和通信。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| 本文用到的 GWT-Ext 控件演示平台工程 | GWTEXTDemo-all.zip | 1887KB | HTTP |
|---|
参考资料 学习
获得产品和技术
讨论
作者简介  | 
|  | 王颖初是 IBM 中国软件开发实验室(CSDL)CSDL ECM Build Team 的一名软件工程师,他从事使用 Java 技术的 Web 软件开发工作,同时对 Rational Clearcase 等软件配置管理系统有一定了解。 |
 | 
|  | 尹雯,ICC Development and FVT team 的经理。对 ECM 产品的 build 有着丰富的经验。熟悉软件测试与开发的流程。 |
 | 
|  | 冯鑫是 IBM 中国软件开发中心的一名软件工程师。他一直对 Java 开源社区的相关技术保持着极大的兴趣。如 Web2.0, 分布式计算(如 Hadoop)等等。除此之外,他的兴趣还包括一些自然语言处理方面的算法研究。 |
 | 
|  | 王海成是 IBM CDL 的软件工程师,主要从事 ECM 产品的开发工作, 目前负责 Client for Windows 产品的开发。 |
对本文的评价
|