`
wangzl2222
  • 浏览: 148007 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

JSF Chapter10

阅读更多
.      <rich:scrollableDataTable>

1)      <rich:scrollableDataTable> 也是一个 dataTable 类的控件。不过,它提供了一些额外的附加功能:

l      当表格滚动时,通过 Ajax 从 Server 取得数据行;

l      可以一次性选中多个行;

l      可以任意调整列的宽度;

l      可以设定冻结列;

l      可以轻易的实现排序;

2)      Ajax 滚动数据表格

l      通过 width 和 height 属性定义表格外观尺寸;

l      通过 rows 属性,定义一次性用 Ajax 取回的行数;

l      <rich:scrollableDataTable> 需要在 form 里,才能实现 Ajax 取回数据行;

l      另外,根据我的实验,最好把 sortMode 、 rowKeyVar 等属性设置齐全一些,否则有时外观刷新不正常,比如调整列宽时。

3)      调整列宽度

不用做额外的操作,只是调整 column 的 header 宽度就好,在每次 Request 之间,系统会自动记住列宽。

4)      设定冻结列

使用 frozenColCount 属性,可以定义表格最左边多少列会被冻结,在横向滚动的时候,不会运动。

5)      选中多行

l      需要用到 selection 属性和 binding ;

l      selection 属性应该指向 managed bean 中的一个实现了 org.richfaces.model.selection.Selection 接口的对象,通常可以直接使用 org.richfaces.model.selection.SimpleSelection 类对象( SimpleSelection 实现了 Selection 接口)。

l      binding 应该指向 managed bean 中的 UIScrollableDataTable 对象。

l      基本原理:在 browser 端,用户选定多行数据,通过提交( Ajax 或 Server ), Server 端更新 Selection 的值,再解析 Selection 的值,查看每一个 rowKey 在 table 中是否可用,从而取得 table 对应行中的数据。

l      具体实现:

<rich:scrollableDataTable value="#{dataTableScrollerBean.xcvrList}" var="xcvr" rows="20" height="300px" width="400px" sortMode="single" rowKeyVar="rkv" frozenColCount="1" binding="#{dataTableScrollerBean.table}" selection="#{dataTableScrollerBean.selection}" >

 

<a4j:support event="onselectionchange " reRender="out1" actionListener="#{dataTableScrollerBean.takeSelection}" ></a4j:support>

 

<rich:column id="itemCode">

<f:facet name="header">

<h:outputText value="Item Code" />

</f:facet>

<h:outputText value="#{xcvr.itemCode}"></h:outputText>

</rich:column>

……

</rich:scrollableDataTable>

 

<h:outputText id="out1" value="#{dataTableScrollerBean.selectedXcvrs}">

 

 

private UIScrollableDataTable table;

private SimpleSelection selection;

private List<Xcvr> selectedXcvrs = new ArrayList<Xcvr>();

 

// Getter and Setter for above 3 member variables.

……

 

public void takeSelection(ActionEvent evt) {

selectedXcvrs.clear();

 

Iterator<Object> it = selection.getKeys();

 

while(it.hasNext()) {

table.setRowKey(it.next());

if(table.isRowAvailable() ) {

selectedXcvrs.add((Xcvr)table.getRowData() );

}

}

}

在 JSP 页面里通过 <a4j:support> ,在发生 onselectionchange 事件的时候,发起提交,调用 managed bean 的 actionListener 方法 takeSelection() 。
在 managed bean 的 takeSelection 方法里,首先使用 Selection 的 getKeys 方法,返回一个 Iterator<Object> ;然后遍历,将这个 Iterator<Object> 中的每一个 Key ,通过 UIScrollableDataTable 的 setRowKey 方法设为当前 Key ;如果 UIScrollableDataTable 的 isRowAvailable() 方法为真,即当前行数据可用,则通过 getRowData() 方法加 Casting 操作,获得对应的数据对象。

 

6)      实现排序

l      设定 sortMode 属性,两种选择: single 或 multy ;

l      <rich:column> 的 id 必须与 column 中的数据对象的属性名相对应,即:

<rich:column id="itemCode ">

<f:facet name="header">

<h:outputText value="Item Code" />

</f:facet>

<h:outputText value="#{xcvr.itemCode }"></h:outputText>

</rich:column>

l      如果无法实现对应(如 column 中包含多个属性值的联合),则必须给 <rich:column> 加上 sortBy 属性,如:

<rich:column id="c1" sortBy=”#{xcvr.itemCode}” >

<f:facet name="header">

<h:outputText value="Item Code / Tech" />

</f:facet>

<h:outputText value="#{xcvr.itemCode}, #{xcvr.tech} "></h:outputText>

</rich:column>

 

 

2.      关于 dataTable 的 sort 和 filter

我曾在第 7 章,对于数据表的排序、筛选留有疑问。通过上面的排序实现和用户指南,大致有了了解:

1)      在 <rich:dataTable> 中设定好 sortMode ;

2)      在 <rich:column> 中设置好 sortBy 和 filterBy 属性:

<rich:column id="itemCode" sortBy="#{xcvr.itemCode}" filterBy="#{xcvr.itemCode}" >

<f:facet name="header">

<h:outputText value="Item Code"></h:outputText>

</f:facet>

<h:outputText id="out1" value="#{xcvr.itemCode}"></h:outputText>

</rich:column>

3)      用户指南在 <rich:column> 的章节有详细的介绍。

 

 

3.      <rich:tree>

1)      <rich:tree> 控件用来显示具有层级关系的内容。它的 value 属性接受的是 TreeNode ( org.richfaces.model.TreeNode )接口的对象,当然也可以直接使用 TreeNode 的实现类 org.richfaces.model.TreeNodeImpl 。

2)      TreeNode 与 TreeNodeImpl 的主要 API 方法:

l      public void addChild (java.lang.Object identifier, TreeNode <T > child)

此方法用于为 Node 节点添加子节点,参数 identifier 用于标识符,区分子节点;

l      public void setData(T  data)

此方法用于设置 Node 节点自身所包含的数据。可以是任意类型的。

3)      通常可以使用递归的方法,生成节点树,比如文件树等。

public void createTree() {

FacesContext context = FacesContext.getCurrentInstance();

ExternalContext externalContext = context.getExternalContext();

File rootDir = new File(((ServletContext) externalContext.getContext()).getRealPath("/"));

 

root = new TreeNodeImpl<File>();

addNodes(rootDir, root);

}

 

public void addNodes(File file, TreeNode<File> node) {

int count = 1;

 

// 为当前节点设置 Data ,即将当前目录设为当前节点的数据内容

node.setData(file);

 

// 遍历子文件和子目录

for (File childFile : file.listFiles()) {

TreeNodeImpl<File> childNode = new TreeNodeImpl<File>();

       
if (childFile.isFile()) {

        // 如果为单个文件,则作为子节点数据内容
childNode.setData(childFile);

} else {

        // 如果为目录,则递归生成子节点树

addNodes(childFile, childNode);

}

 

        // 将子节点或字节点树加入当前节点

node.addChild(count++, childNode);

}

}

 

4)      将整个节点树的根节点,传入 <rich:tree> 的 value 属性。

<rich:tree value="#{treeTestBean.root}" />

 

5)      <rich:tree> 应置于 form 中使用,并且有三种切换模式 switchType :

l      Ajax (默认):通过 Ajax 提交实现,每次展开闭合都会引起 Ajax Request ;

l      Server :引起常规提交;

l      Client : 所有操作只基于 Client 端 , 与 Server 没有交互。

6)      关于处理选择节点事件:

l      ajaxSubmitSelection 属性为 true 的话,选择节点时,提交方式为 Ajax 。

l      managed bean 中应该定义一个型为

public void selectionListener(NodeSelectedEvent event) 的方法。

l      <rich:tree> 的 nodeSelectListener 属性应该指向这个 Listener 方法。

l      例如:

public void selectionListener(NodeSelectedEvent evt ) throws IOException {

UITree tree = (UITree) evt.getComponent();

File file = (File) tree.getRowData();

nodeTitle = file.getName();

}

通过 NodeSelectedEvent 的 getComponent 方法获得产生该节点选择事件的 Tree 控件(这与 ActionEvent 的 getComponent 方法类似)。通过 UITree 的 getRowData 方法,返回当前节点自身包含的数据内容。

7)      关于处理展开闭合事件:

l      managed bean 中应该定义一个型为

public void expansionListener(NodeExpandedEvent evt) 。

l      <rich:tree> 的 changeExpandListener 属性应该指向这个 Listener 方法。

l      例如:

<rich:tree value="#{treeTestBean2.root}" nodeSelectListener="#{treeTestBean2.selectionListener}" changeExpandListener="#{treeTestBean2.expansionListener}" ajaxSubmitSelection="true" reRender=”out1” />

 

8)      可以使用 icon, iconCollapsed, iconExpanded, iconLeaf 属性修改不同节点不同状态下的图标样式。

9)      使用 <rich:treeNode>

l      <rich:treeNode> 控件可以为不同类型的节点,提供不同类型的外观;

l      主要用法是: <rich:tree> 具有 nodeFaces 属性,这个属性可以指向 bean 中的某个 property 。可以根据这个 property 的可能取值,在 <rich:treeNode> 中定义不同的外观。不同的 property 取值之间,通过 <rich:treeNode> 的 type 区分。当有一个节点树的时候,系统遍历每个节点,将该节点的数据内容的该 property 值与多个 <rich:treeNode> 的 type 属性值进行比较,匹配上哪个,就使用哪个 <rich:treeNode> 定义的外观。

l      例如:

<rich:tree value="#{treeTestBean2.root}" nodeSelectListener="#{treeTestBean2.selectionListener}" changeExpandListener="#{treeTestBean2.expansionListener}" ajaxSubmitSelection="true" var="file" nodeFace="#{file.directory}" >

 

<rich:treeNode type="true" >

<h:outputText value="[DIR]#{file.name}" />

</rich:treeNode>

 

<rich:treeNode type="false" >

<h:outputText value="[FILE]#{file.name}" />

</rich:treeNode>

 

</rich:tree>

在这个例子中, file 本身是一个 File 对象,具有 isDirectory() 方法用于判断该 File 对象是一个目录还是一个单独文件。我将它作为 bean 的 property 传给 nodeFaces 属性。当得到一个节点时,查看该节点内容( File 对象)的该 property 值,如果值为 true ,则应用第一个 treeNode 的外观;如果为 false ,则用第二个。

l      <rich:treeNode> 除了 markup 重定义了以外,其他 <rich:tree> 的属性,它基本都支持。因此也可以为 treeNode 设置用于外观自定义、选择或展开事件处理 Listener 等等方面的属性。

 

 

4.      <rich:treeNodeAdaptor> 和 <rich:recursiveTreeNodesAdaptor>

大致看了一下,似乎不难,只是非常简单的递归。基本思路就是:

1)      定义一个 MyNode 类,其中包含一个可以返回其子节点数组的 getter 方法,返回类型为 MyNode[] 。例如:

public class MyNode {

private MyNode[] children;

 

public MyNode[] getChildren() {

……

return children;

}

}

 

2)      假设 managed bean 中定义一个名为 myRoots 的 MyNode 数组对象,代表多个主节点;

3)      在 <rich:recursiveTreeNodesAdaptor> 中,按如下设置:

<rich:tree style="width:300px" switchType="ajax">

<rich:recursiveTreeNodesAdaptor roots="#{testBean.myRoots}" var="item" nodes="#{item.children}" />

</rich:tree>
from:http://blog.csdn.net/gengv/archive/2009/06/16/4274672.aspx
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics