richfaces 经典记录

2009-08-10
缩略显示
<rich:fileUpload>批量上传
关键字: 批量上传

public class FileUploadBean {
    public void uploadListener(UploadEvent event) {
        //获取传过来的items,3.2.2之前版本不支持getUploadItems方法
        List itemList = event.getUploadItems();
        for(int i=0 ; i<itemList.size() ; i++){
            try {           
                UploadItem item = (UploadItem) itemList.get(i);
                File file = new File("d:\\"+UUID.randomUUID().toString()+".jpg");
                //大小不能超过4M
                if(item.getFileSize() <= 4000000){
                    FileInputStream fis = new FileInputStream(item.getFile());  
                    FileOutputStream out = new FileOutputStream(file);  
                    int bytes = 0;  
                    byte[] bteFile = new byte[1024];  
                    while ((bytes = fis.read(bteFile)) != -1) {  
                        out.write(bteFile, 0, bytes);  
                    }
                    fis.close();
                    out.close();                   
                }
            } catch (Exception e) { 

            }            
        }
    }
}

<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <f:view>
            <h:form>
<h:panelGroup>  
<h:outputText value="上传头像"></h:outputText>  
<rich:spacer height="3" />
   <rich:fileUpload   fileUploadListener="#{fileUploadBean.uploadListener}"
                   maxFilesQuantity="5"
                   autoclear="false"
                   addControlLabel="添加图片"
                   uploadControlLabel="上传"
                   clearAllControlLabel="清除所有"
                   clearControlLabel="清除"
                   cancelEntryControlLabel="取消"
                   stopControlLabel="停止"
                   stopEntryControlLabel="停止" noDuplicate="true"
                   listHeight="400"
                   listWidth="515"
                   style="height:100;"
                   id="upload"
                   acceptedTypes="jpg, gif, png, bmp">       
               </rich:fileUpload>  

       <h:outputText value="支持 JPG、JPEG、GIF、BMP 和 PNG 文件格式,最大4M。">  
                </h:outputText>  
           </h:panelGroup>
            </h:form>
        </f:view>
    </body>
</html>

    * 18:54
    * 浏览 (140)
    * 评论 (0)
    * 分类: richfaces

2009-07-29
缩略显示
优化JSF Richfaces应用
关键字: 优化
使用Richfaces开发基于JSF的RIA应用是非常通用、自然和稳定的选择。实际上,Richfaces用于实现Ajax是非常自然的技术,它使得使用JSF来创建富用户交互变得非常容易。这里我共享一些优化JSF Richfaces应用的常见的最佳实践。

XML/HTML代码
<context-param> 
        <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name> 
        <param-value>true</param-value> 
</context-param> 

该配置将强制容器在发送到客户端之前压缩所有的Richfaces资源,包括图片、样式表、JavaScript等。它将大大的减少页面的加载时间。

XML/HTML代码
<filter> 
    <filter-name>richfaces</filter-name> 
    <display-name>RichFaces Filter</display-name> 
    <filter-class>org.ajax4jsf.Filter</filter-class> 
    <init-param>   
        <param-name>forceparser</param-name> 
        <param-value>false</param-value> 
    </init-param> 
</filter>  

这可以通过设置forceparser设置为false来最小化。在仅仅有AJAX响应的情况下,它将变得很干净。在其他情况下,所有的JSF响应都是干净的。这时因为该filter映射到FacesServlet上:这可以用于部分页面显示。

XML/HTML代码
<context-param> 
    <param-name>org.richfaces.LoadStyleStrategy</param-name> 
    <param-value>all</param-value> 
</context-param> 

该配置将保证所有和样式相关的文件在第一次访问Richfaces应用的请求到达时全部加载到客户端。

XML/HTML代码
<context-param> 
    <param-name>org.richfaces.LoadScriptStrategy</param-name> 
    <param-value>all</param-value> 
</context-param> 

JSF优化技巧将保证所有和Richfaces相关的JavaScript、文件、库等在第一次请求到达时被下载到客户端。

XML/HTML代码
<filter> 
    <display-name>RichFaces Filter</display-name> 
    <filter-name>richfaces</filter-name> 
    <filter-class>org.ajax4jsf.Filter</filter-class> 
    <init-param>   
        <param-name>enable-cache</param-name> 
        <param-value>true</param-value>   
    </init-param> 
</filter> 

JSF Richfaces优化将启用Richfaces组件的缓存,并将组件缓存到客户端来提高应用的性能。

Richfaces内置了几个解析器。默认的是Tidy,但是它非常慢。Neko解析器是最快的,它可以通过如下的配置来启用。

XML/HTML代码
<context-param> 
        <param-name>org.ajax4jsf.xmlparser.ORDER</param-name> 
        <param-value>NEKO</param-value> 
    </context-param> 
    <context-param> 
        <param-name>org.ajax4jsf.xmlparser.NEKO</param-name> 
        <param-value>.*\..*</param-value> 
    </context-param> 

这里,我们配置只适用NEKO过滤器,它会被应用到所有的URL上。

和Ajax相关的几个技巧
ajaxSingle = true
对任何Ajax组件来说,如果它的值仅仅在服务器器端使用,那么ajaxSingle应该设置为true,以便不会提交整个Ajax请求Map到服务器。
limitToList = ture
this attribute should be true for any ajax compoenent who will reRender only the components specified in its reRender attribute list. All other components not specified in the reRender list will no longer reRender upon request complition.
immediate = true
This trick should be used by setting extra effort. This property will submit the value and skips validation phase and set the value immediatly into backing bean

    * 21:43
    * 浏览 (105)
    * 评论 (0)
    * 分类: richfaces

2009-07-29
缩略显示
动态改变RichFaces的皮肤
关键字: skin
给RichFaces设置一个皮肤很简单,只要在web.xml文件中写以下这一段就可以了:



Xml代码
<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>ruby</param-value>
</context-param>

<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>ruby</param-value>
</context-param>

但是,有时候你也许会要在程序运行的时候去动态改变RichFaces的皮肤。甚至你可能会想让每个用户保存自己喜欢的皮肤。那该怎么做呢?



首先,我们需要将硬编码到web.xml中的皮肤设置改变为一个EL表达式:

Xml代码
<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>#{skinBean.skin}</param-value>
</context-param>

<context-param>
  <param-name>org.richfaces.SKIN</param-name>
  <param-value>#{skinBean.skin}</param-value>
</context-param>

skinBean是一个JSF managed Bean,类似这样:

Java代码
public class SkinBean { 
  
   private String skin; 
  
   public String getSkin() { 
    return skin; 
   } 
   public void setSkin(String skin) { 
    this.skin = skin; 
   } 
}

public class SkinBean {

   private String skin;

   public String getSkin() {
return skin;
   }
   public void setSkin(String skin) {
this.skin = skin;
   }
}

当然,你需要在JSF的配置文件里面注册一下这个Bean:

Xml代码
<managed-bean>
  <managed-bean-name>skinBean</managed-bean-name>
  <managed-bean-class>demo.SkinBean</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
  <managed-property>
   <property-name>skin</property-name>
   <value>ruby</value>
  </managed-property>
</managed-bean>

<managed-bean>
  <managed-bean-name>skinBean</managed-bean-name>
  <managed-bean-class>demo.SkinBean</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
  <managed-property>
   <property-name>skin</property-name>
   <value>ruby</value>
  </managed-property>
</managed-bean>

我们会想要设置一个默认的皮肤,同时我们需要将这个Bean的声明周期为Session。之所以不放到request中,是因为如果放到 request中,那么每次请求到达的时候,都会去刷新并将皮肤恢复成默认的,而我们希望看到的效果是,用户每次登录的整个过程,皮肤是一直不变的(除非用户主动去改变它)。



通过下面的页面,我们立刻就能看到效果了。

Xml代码
<h:form>
   <rich:panel header="I can change skins" style="width: 300px">
    <h:panelGrid columns="2">
       <h:selectOneListbox id="select" value="#{skinBean.skin}" onchange="submit()">
        <f:selectItem itemLabel="plain" itemValue="plain" />
        <f:selectItem itemLabel="emeraldTown" itemValue="emeraldTown" />
        <f:selectItem itemLabel="blueSky" itemValue="blueSky" />
        <f:selectItem itemLabel="wine" itemValue="wine" />
        <f:selectItem itemLabel="japanCherry" itemValue="japanCherry" />
        <f:selectItem itemLabel="ruby" itemValue="ruby" />
        <f:selectItem itemLabel="classic" itemValue="classic" />
        <f:selectItem itemLabel="laguna" itemValue="laguna" />
        <f:selectItem itemLabel="deepMarine" itemValue="deepMarine" />
       </h:selectOneListbox>
           <rich:tabPanel>
        <rich:tab label="Tab 1">Tabs also change color</rich:tab>
        <rich:tab label="Tab 2">...</rich:tab>
       </rich:tabPanel>
        </h:panelGrid>
   </rich:panel>
</h:form>

<h:form>
   <rich:panel header="I can change skins" style="width: 300px">
<h:panelGrid columns="2">
   <h:selectOneListbox id="select" value="#{skinBean.skin}" onchange="submit()">
<f:selectItem itemLabel="plain" itemValue="plain" />
<f:selectItem itemLabel="emeraldTown" itemValue="emeraldTown" />
<f:selectItem itemLabel="blueSky" itemValue="blueSky" />
<f:selectItem itemLabel="wine" itemValue="wine" />
<f:selectItem itemLabel="japanCherry" itemValue="japanCherry" />
<f:selectItem itemLabel="ruby" itemValue="ruby" />
<f:selectItem itemLabel="classic" itemValue="classic" />
<f:selectItem itemLabel="laguna" itemValue="laguna" />
<f:selectItem itemLabel="deepMarine" itemValue="deepMarine" />
   </h:selectOneListbox>
           <rich:tabPanel>
<rich:tab label="Tab 1">Tabs also change color</rich:tab>
<rich:tab label="Tab 2">...</rich:tab>
   </rich:tabPanel>
        </h:panelGrid>
   </rich:panel>
</h:form>

这里放一个tab组件,其实是为了让你看到外观上的改变效果的,没有功能上的实际作用。你还可以放几个其他组件上去,看看效果的变化。



如果你想要学习如何编写自己的皮肤,请参考这篇文章XXX(稍后放出:)



其他你可以尝试一下的,就是改变一下标准组件的样式,我们的例子中为h:selectOneListbox:

Xml代码
<context-param>
   <param-name>org.richfaces.CONTROL_SKINNING</param-name>
   <param-value>enable</param-value>
</context-param>

    * 02:58
    * 浏览 (147)
    * 评论 (1)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter11
关键字: 使用内建的 skins
1.      使用内建的 Skins

1)      基本的内建 Skin 都在 richfaces-impl-3.3.1.jar 文件中,包括: DEFAULT 、 plain 、 emeraldTown 、 blueSky 、 wine 、 japanCherry 、 ruby 、 classic 、 deepMarine 、 NULL 。

2)      新增的三个 Skins 在各自单独的 jar 文件中: laguna 、 darkX 、 glassX 。

3)      要使用内建的 Skins ,就要在 web.xml 文件中加入 org.richfaces.SKIN context 参数:

<context-param>

<param-name>org.richfaces.SKIN</param-name>

<param-value>ruby</param-value>

</context-param>

4)      对于每一个 Skins 主题,在对应的 jar 文件的 META-INF/skins 路径下,都有对应的 properties 文件。 properties 文件里定义着不同 skins 的外观参数。





2.      创建自定义 Skins

1)      最简单的方法就是将现成 skin 的 properties 文件,复制到应用的 classpath 中,即 META-INF/skins 或 WEB-INF/classes 中,然后以自定义的名称命名文件,并修改其中的参数。

2)      另一种方式就是自己创建 properties 文件,并在其中声明从哪个现有 skin 进行扩展。如:

baseSkin=ruby

generalSizeFont=16px

headerSizeFont=16px

3)      通过查阅文档,可以得知需要修改哪些参数属性,以实现想要的外观效果。





3.      使用换肤和 CSS

三种使用途径:

l            使用 skin 生成的 CSS ;

l            重新定义 skin 插入的 CSS 类;

l            用控件的 style 或 styleClass 类的属性,添加自定义的 style 。





4.      其他应用

对于我来说,内建的 skin 基本已经足够使用了,等到真正需要的时候,再来学习这部分知识吧。

只有真正需要的,才能学完记得住,呵呵 ~



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/17/4277583.aspx

    * 04:03
    * 浏览 (50)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter10
关键字: rich:scrollabledatatable
1.      <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>

    * 04:02
    * 浏览 (121)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter09
关键字: rich:dropdownmenu
1.      <rich:dropDownMenu>

1)      <rich:dropDownMenu> 生成下拉菜单。

2)      每一个 menu item 都可以设定 action 或 actionListener 以供 Ajax 调用。 reRender 属性定义需要被刷新的控件。

3)      <rich:toolBar> 是装载下拉菜单的容器。

4)      <rich:dropDownMenu> 不提供其自己的 form ,所以必须置于 form 里才能使用。

5)      可以使用 <rich:dropDownMenu> 的 value 属性或者 <f:facet name=”label”> 来指定菜单的名称。

6)      submitMode 属性控制提交模式,三种选择:

l        Server (默认):使用常规的表单提交 Request ;

l        Ajax :使用 Ajax 提交;

l        None : action 和 actionListener 都被忽略掉, menu item 不触发任何提交,所有行为都取决于嵌于 item 内部的控件。

如果在 <rich:dropDownMenu> 设置该属性,则其内部的所有 menuItem 也将继承其属性值。

7)      <rich:menuItem> 也提供了 onXXXX 属性,例如 onselect 、 onclick 、 oncomplete 等,用于调用自定义 JavaScript 代码(如显示 modalPanel 等)。





2.      <rich:contextMenu>

1)      event 属性用于设定引起 contextMenu 弹出的事件,比如 oncontextmenu 、 onclick 等,主要还是要看 <rich:contextMenu> 所服务的控件支持哪些 onXXXX 事件。

2)      submitMode 属性控制提交模式,三种选择:

l        Server (默认):使用常规的表单提交 Request ;

l        Ajax :使用 Ajax 提交;

l        None : action 和 actionListener 都被忽略掉, menu item 不触发任何提交,所有行为都取决于嵌于 item 内部的控件。

如果在 <rich:contextMenu> 设置该属性,则其内部的所有 menuItem 也将继承其属性值。

3)      attachTo 属性用于指定将 contextMenu 指定给哪个控件。

4)      或是将 <rich:contextMenu> 直接置于某个控件体内,并将 attached 属性设为 true ,也可以实现以上效果。比如在表格中使用时,可以将 <rich:contextMenu> 直接放在 <rich:column> 中。

但应注意,根据用户指南提示, <rich:contextMenu> 应该放在 <h:outputText> 外面,或者为 <h:outputText> 设置 ID ,已实现正常使用。

5)      disableDefaultMenu 属性可以彻底禁用页面的默认右键菜单。

6)      可以在 menuItem 体内,使用 <f:setPropertyActionListener> 或 <a4j:actionparam> ,传递参数。





3.      <rich:contextMenu> 与 <rich:componentControl>

1)      可以用 <rich:componentControl> 来调用显示 contextMenu ,并传递参数,例如:

<rich:componentControl event="onRowClick" for="menu" operation="show">

<f:param value="#{air.name}" name="airlineName" />

</rich:componentControl>

2)      这时 <rich:contextMenu> 的 attached 属性应该设为 false 。

3)      通过 <f:param> 传递的参数,可以在 contextMenu 中使用,比如:

<rich:menuItem value="Select {airlineName} " actionListener="#{airlinesBean.select}">

</rich:menuItem>

              注意,这里用的是 {paramName} ,而 #{paramName} ,没有“ # ”。





4.      <rich:contextMenu> 与 <a4j:support>

1)      当需要动态的向 <rich:contextMenu> 传递参数的时候,尤其是在 dataTable 中的时候,有两种方法:

l      将 <rich:contextMenu> 放在 dataTable 体内,则 <rich:contextMenu> 可以直接使用 dataTable 的 var 属性;但局限性就是,必须置于 dataTable 体内;

l      另方法就是使用 <a4j:support> 。

2)      具体方法就是通过设定 <a4j:support> 的 event 属性,指定父控件的什么样的事件会弹出 contextMenu 。例如:

<a4j:form>

<rich:dataTable id="dtTable" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="15">



<rich:column>

<f:facet name="header">

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

</f:facet>

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

</rich:column>



<rich:column>

<f:facet name="header">

<h:outputText value="Market Name"></h:outputText>

</f:facet>

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

</rich:column>



<a4j:support event="onRowContextMenu" reRender="ctxMenu" oncomplete=" #{rich:component('ctxMenu')}.doShow(event,{}) " >

<f:setPropertyActionListener value="#{xcvr}" target="#{dataTableTestBean.selectedXcvr}"/>

</a4j:support>



</rich:dataTable>



<rich:contextMenu id="ctxMenu" submitMode="ajax" attached="false" disableDefaultMenu="true">

<rich:menuItem value="View #{dataTableTestBean.selectedXcvr.itemCode}" reRender="detailPanel" ajaxSingle="true" actionListener="#{dataTableTestBean.menuClicked}" oncomplete="#{rich:component('detailPanel')}.show()">

</rich:menuItem>

</rich:contextMenu>

</a4j:form>





5.      尚存疑问

1)      在使用 contextMenu 时,我曾想通过点击 menuItem 来弹出 modalPanel ,也确实成功了。但是问题是,只是隔次成功,换句话说,就是第一次成功、第二次失败、第三次成功、第四次失败……但奇怪的是,如果只是弹出菜单,而没有点击,则再次右键弹出时,就又成功了。

2)      失败的时候,连 actionListener 都不会执行, modalPanel 更是没有弹出。我换了好几种方法, dataTable 内外都试过了,均是如此。但如果去除要弹出modalPanel的代码,则一切恢复正常,actionListener每次也能正常运行。

3)      我在 JavaRanch 的论坛上,发了帖子,还在等待解答。

http://www.coderanch.com/t/449548/JSF/java/Trouble-with-ContextMenu-ModalPanel-RichFaces



Hi all,

I met some trouble when I used the RichFaces contextMenu and modalPanel together.

I hope to show the modalPanel by clicking the context menu item.

For the first time I clicked the menu item, the modal was showed. However, the second time, the menu item even didn't execute. Then the third time, everything went well again. And then 4th time failed, 5th time succeeded, 6th time failed..., alternately.

Thus, 50% succeeded and 50% failed. It's too weird.



1.               <f:view> 

2.                   <a4j:form> 

3.                       <h:panelGroup id="panelGroup" > 

4.                           <h:outputText value="Right Click Me!" ></h:outputText> 

5.                       </h:panelGroup> 

6.        

7.                       <rich:contextMenu attachTo="panelGroup"  event="oncontextmenu"  

8.                           submitMode="ajax"  disableDefaultMenu="true" > 

9.                           <rich:menuItem value="try"  

10.                           oncomplete="#{rich:component('modalPanel')}.show()"  

11.                           actionListener="#{contextMenuTestBean.menuClicked}" ></rich:menuItem> 

12.                   </rich:contextMenu> 

13.               </a4j:form> 

14.    

15.               <rich:modalPanel id="modalPanel" > 

16.                   <f:facet name="header" > 

17.                       <h:outputText value="Modal Panel"  /> 

18.                   </f:facet> 

19.                   <h:outputText value="Hello!"  /> 

20.                   <a4j:commandLink value="Close"  

21.                       onclick="#{rich:component('modalPanel')}.hide()" ></a4j:commandLink> 

22.               </rich:modalPanel> 

23.           </f:view>    


When I remove the code on line 10.

oncomplete="#{rich:component('modalPanel')}.show()"    


The actionListener of menuItem can be executed successfully every time.

Can anybody help to advise the reason?

Thanks in advance!



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/14/4269014.aspx

    * 03:59
    * 浏览 (86)
    * 评论 (1)
    * 分类: richfaces

2009-07-27
缩略显示
[置顶] Practical_RichFaces要点Chapter08
关键字: rich:picklist
1.      <rich:pickList>

1)      实际上,这个控件与 <h:selectManyMenu> 和 <h:selectManyListbox> 本质上是一样的,都允许选择一到多个值,存于 List 中。

2)      可以使用 <f:selectItem> 和 <f:selectItems> 为其添加选项,这些选项会显示在左侧框体里;

【注意】

l            当 SelectItem 的值是自定义类对象的时候,应该为其创建自定义 Converter ,并 Override 该自定义类的 equals 方法(这一步可以借助 Eclipse 自动生成)。

l            应当使用 converter 属性指定在 faces-config.xml 中注册的自定义 Converter 的 ID ;我曾想将 Converter 注册默认为一类对象做转换,但这种方法对 <rich:pickList> 的 <f:selectItems> 里面的自定义类无效。

3)      value 属性必须绑定到一个可以接受多个值的对象上去,比如 List 、数组等。如果 value 对应的 List 或数组里默认有元素,则说明这些元素在初始阶段就被选中了,它们会一开始就自动出现在右侧框体里。

4)      可以修改 copyAllControlLabel 、 copyControlLabel 、 removeControlLabel 、 removeAllControlLabel 四个属性的值,指定按钮上的显示 Label 。

5)      可以用名为 copyAllControl 、 copyAllControlDisabled 、 removeAllControl 、 removeAllControlDisabled 、 copyControl 、 copyControlDisabled 、 removeControl 、 removeControlDisabled 的 <f:facet> 自定义控制按钮的外观。每一个按钮都需要定义 enabled 和 disabled 两种状态时的外观。

6)      showButtonsLabel 属性默认为 true ,当设为 false 时,控制按钮不显示 Label 文字。

7)      默认情况下,通过双击 Item 可以实现左右增删;当 switchByClick 属性设为 true 时,则单击即可完成以上操作。

8)      除了支持 onclick 、 onchange 等基本 JavaScript 事件以外,还支持如 onlistchanged 等额外事件。可以使用 <a4j:support> 来指定 onlistchanged 等事件到 event 属性,已触发 Ajax Request ,刷新 reRender 中的控件。

9)      例如:

<h:panelGrid>

<a4j:form>

<rich:dataTable id="xcvrTable" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="10">

<f:facet name="header">

<h:outputText value="DataTable"></h:outputText>

</f:facet>

<rich:columns value="#{dataTableTestBean.selectedFields}" var="field">

<f:facet name="header">

<h:outputText value="#{field.fieldName}"></h:outputText>

</f:facet>

<h:outputText value="#{xcvr[field.fieldName]}"></h:outputText>

</rich:columns>

<f:facet name="footer">

<rich:datascroller></rich:datascroller>

</f:facet>

</rich:dataTable>

</a4j:form>



<a4j:form>

<rich:pickList converter="fieldConverter" value="#{dataTableTestBean.selectedFields}" copyAllControlLabel="Add All" copyControlLabel="Add" removeAllControlLabel="Del All" removeControlLabel="Del" showButtonsLabel="false">

<f:selectItems value="#{dataTableTestBean.allFieldOptions}" />

<a4j:support event="onlistchanged" reRender="xcvrTable" actionListener="#{dataTableTestBean.listChanged}">

</a4j:support>

</rich:pickList>

</a4j:form>

</h:panelGrid>





2.      <rich:orderingList>

1)      <rich:orderingList> 的形式很像 dataTable 类控件,只是增加了一些额外功能;可以像使用 <h:dataTable> 或 <rich:dataTable> 一样使用它。

2)      value 属性接受 List 之类的值。通过 var 属性指定的行变量进行遍历。

3)      value 的 List 中,如果使用的是自定义类对象,则也要提供自定义 Converter ,并用 converter 属性指定 faces-config.xml 中的注册名;同时,还要 Override 自定义类的 equals 和 hashCode 方法(这个也可以由 Eclipse 代劳)。

4)      注意,通过右侧按钮实现的顺序调整,是 Client 端的。只有通过提交(如 commandButton 或者 <a4j:support> ),才能更新 managed bean 内的值。

5)      可以使用 <h:column> 、 <rich:column> 、 <rich:columns> 来定义其内容,就像使用 dataTable 一样。

6)      selection 属性用来定义哪些元素是一开始就已经处于选中状态的了,该属性接受 Set 类型的值。

7)      可以使用 <f:facet name="caption"> 为控件添加一个标题。

8)      可以修改 topControlLabel 、 bottomControlLabel 、 upControlLabel 、 downControlLabel 四个属性的值,指定按钮上的显示 Label 。

9)      可以用名为 topControl 、 topControlDisabled 、 bottomControl 、 bottomControlDisabled 、 upControl 、 upControlDisabled 、 downControl 、 downControlDisabled 的 <f:facet> 自定义控制按钮的外观。每一个按钮都需要定义 enabled 和 disabled 两种状态时的外观。

10)  再次提醒,通过右侧按钮调整的顺序,仅限于 Client 端。要想调整 managed bean 中的顺序,可以使用 <a4j:commandButton> 或者 <a4j:commandLink> 来提交 Ajax Request 以更新模型值并刷新页面;或者干脆省掉按钮或链接,直接使用 <a4j:support event=”onorderchange”> ,当顺序改变时, JavaScript 事件会通过 <a4j:support> 触发 Ajax Request 以更新模型值并刷新页面。

11)  例如:

<a4j:form>

<rich:dataTable id="xcvrTable" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="10">

<f:facet name="header">

<h:outputText value="DataTable"></h:outputText>

</f:facet>

<rich:columns value="#{dataTableTestBean.selectedFields}" var="field">

<f:facet name="header">

<h:outputText value="#{field.fieldName}"></h:outputText>

</f:facet>

<h:outputText value="#{xcvr[field.fieldName]}"></h:outputText>

</rich:columns>

</rich:dataTable>

</a4j:form>



<a4j:form>

<rich:orderingList id="fieldOrderList" value="#{dataTableTestBean.selectedFields}" var="row" converter="fieldConverter" >



<a4j:support event="onorderchanged" reRender="xcvrTable, fieldPickList" ajaxSingle="true" ></a4j:support>



<rich:column>

<f:facet name="header">

<h:outputText value="Field Name"></h:outputText>

</f:facet>

<h:outputText value="#{row.fieldName}"></h:outputText>

</rich:column>

</rich:orderingList>



<rich:pickList id="fieldPickList" converter="fieldConverter" value="#{dataTableTestBean.selectedFields}">

<f:selectItems value="#{dataTableTestBean.allFieldOptions}" />

<a4j:support event="onlistchanged" reRender="xcvrTable, fieldOrderList" actionListener="#{dataTableTestBean.listChanged}" ajaxSingle="true" ></a4j:support>

</rich:pickList>

</a4j:form>





3.      <rich:listShuttle>

1)      <rich:listShuttle> 基本上来说就是 <rich:orderingList> 和 <rich:pickList> 的组合体。既可以选择一到多个值,又可以调整它们的顺序。可以在左右两个框体内显示任意多列。

2)      可以将左侧框体内的值选择到到右侧框体,然后在右侧框体内调整顺序。而这种调整顺序,仍然是 Client 端的调整,仍然需要提交 Ajax Request 才能更新模型值。

3)      对于自定义类对象,仍然需要提供自定义 Converter ,设置 <rich:listShuttle> 的 converter 属性; Override 自定义类的 equals 和 hashCode 方法。

4)      sourceValue 属性用于设定左侧框体内的值,也即整体范围 List ; targetValue 属性用于设定右侧框体内的值,也即选出项 List 。二者都接受集合类( List ),并且共用一个 var 属性指定变量名称。

5)      sourceCaptionLabel 和 targetCaptionLabel 属性分别设定左右侧框体的标题。

6)      对于按钮外观的自定义修改与前面两个控件大同小异。

7)      可以通过 onlistchanged 或 onorderchanged 事件,使用 <a4j:support> 分别触发 Ajax Request 。

8)      sourceRequired 或 targetRequired 分别设为 true 的时候,表示左框体或右框体不能为空。

9)      例如:

<a4j:form>

<rich:dataTable id="xcvrTable" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="10">

<f:facet name="header">

<h:outputText value="DataTable"></h:outputText>

</f:facet>

<rich:columns value="#{dataTableTestBean.selectedFields}" var="field">

<f:facet name="header">

<h:outputText value="#{field.fieldName}"></h:outputText>

</f:facet>

<h:outputText value="#{xcvr[field.fieldName]}"></h:outputText>

</rich:columns>

</rich:dataTable>

</a4j:form>



<a4j:form>

<rich:listShuttle var="row" targetValue="#{dataTableTestBean.selectedFields}" sourceValue="#{dataTableTestBean.fields}" converter="fieldConverter" >



<a4j:support event="onlistchanged" reRender="xcvrTable"></a4j:support>

<a4j:support event="onorderchanged" reRender="xcvrTable"></a4j:support>



<rich:column>

<f:facet name="header">

<h:outputText value="Field Name"></h:outputText>

</f:facet>

<h:outputText value="#{row.fieldName}"></h:outputText>

</rich:column>

</rich:listShuttle>

</a4j:form>



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/13/4265338.aspx

    * 03:58
    * 浏览 (170)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter07
关键字: rich:datatable
1.      常用的 dataTable 类的控件有:

l            <rich:dataTable>

l            <rich:dataDefinitionList>

l            <rich:dataOrderedList>

l            <rich:dataList>

l            <rich:dataGrid>





2.      <rich:dataTable>

1)      <rich:dataTable> 具有 <h:dataTable> 的所有基本功能,此外还具有换肤、部分行刷新、合并行或列的功能。

2)      在其内部仍然可以使用 <h:column>.





3.      <rich:dataDefinitionList>

1)      <rich:dataDefinitionList> 可以创建一个 HTML 定义列表;

2)      可以使用 <f:facet name=”term”> 来设定特定的数据格式,例如:

<rich:dataDefinitionList value="#{airlinesBean.airlines}" var="air">

<f:facet name="term">

<h:outputText value=”#{air.code}” />

</f:facet>

<h:outputText value=”#{air.name}, #{air.code}” />

</rich:dataDefinitionList>





4.      <rich:dataOrderedList>

1)      <rich:dataOrderedList> 可以生成列表,并在每一行开头添加上行号,从 1 开始。

2)      例如:

<rich:dataOrderedList value="#{airlinesBean.airlines}" var="air">

<h:outputText value=”#{air.name}, #{air.code}” />

</rich:dataOrderedList>





5.      <rich:dataList>

1)      <rich:dataList > 可以生成列表,并在每一行开头添加一个圆点。

2)      例如:

<rich:dataList value="#{airlinesBean.airlines}" var="air">

<h:outputText value=”#{air.name}, #{air.code}” />

</rich:dataList>





6.      <rich:dataGrid>

1)      <rich:dataGrid> 是 <rich:dataTable> 和 <h:panelGrid> 的混合体。

2)      仍然遍历数据集合,但是通过 columns 属性控制每一行容纳多少条记录。例如:

<rich:dataGrid value="#{airlinesBean.airlines}" var="air" border="1" columns="2">

<h:outputText value=”#{air.name}, #{air.code}” />

</rich:dataGrid>





7.      除以上几种之外,还有之前讲过的 <a4j:repeat> ,它本身并不产生任何 HTML 标记

<a4j:repeat value="#{airlinesBean.airlines}" var="air" rowKeyVar="i">

#{air.name} -

#{air.code}

<h:outputText value="," rendered="#{i lt (airlinesBean.size-1)}"/>

</a4j:repeat>





8.      添加滚动条 <rich:datascroller>

1)      对于要使用 <rich:datascroller> 作为滚动条的 dataTable 类控件,应该将它们的 rows 属性设置好,设为每页需要显示的数据行数。

2)      对于 <rich:dataTable> 只需要将 <rich:datascroller> 置于 <f:facet name=”footer”> 中就可以了;

而对于其他 dataTable 类控件,则应该将 <rich:datascroller> 置于控件外,并将 <rich:datascroller> 的 for 属性设置为 dataTable 类控件的 ID 。

3)      <rich:datascroller> 需要在 form 中使用。

4)      <rich:datascroller> 的前后翻页等样式可以通过属性,任意定于。

5)      pageIndexVar 属性,指定代表当前页码的变量名称; pagesVar 属性,指定代表总页码数的变量名称。例如:

<rich:datascroller maxPages="4" selectedStyle="font-weight:bold"

pageIndexVar="currentPage" pagesVar="totalPages">

<f:facet name="pages">

<h:outputText value="#{currentPage}/#{totalPages}” />

</f:facet>

...

</rich:datascroller>

6)      maxPages 属性设定滚动条中,每次最多能同时显示的页码数。





9.      使用 JavaScript 事件

1)      <rich:dataTable> 等控件定义了许多 onXXXX 属性,对应 JavaScript 事件,以调用自定义 JavaScript 代码。如: onclick 、 ondblclick 、 onRowClick 、 onRowDblClick 等。

2)      可以与 <a4j:support> 和 <f:setPropertyActionListener> 等一起使用,用来触发 Ajax Request 。例如:

<rich:dataTable id="dtTabel" border="1" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="10" onRowContextMenu="#{rich:component('detail')}.show()" >



<a4j:support event="onRowDblClick" reRender="grid1" action="#{dataTableTestBean.rowDblClickedAction}" oncomplete="#{rich:component('detailModalPanel')}.show()" >

<f:setPropertyActionListener target="#{dataTableTestBean.selectedXcvr}" value="#{xcvr}" />

</a4j:support>

……

</rich:dataTable>

       【注意】

这段代码是希望通过双击或右键,弹出 modalPanel ,里面显示行的详细信息。但是 <rich:dataTable> 的 onRowContextMenu 所调用弹出的 modalPanel 里面一开始是不会有值的,因为页面从未提交 dataTableTestBean.selectedXcvr 里面还没有值;而 <a4j:support> 的 oncomplete 属性调用弹出的 modalPanel 里面就有值,因为 <a4j:support> 的 event 属性根据 <rich:dataTable> 的 onRowDblClick 事件引发了 Ajax Request ,这一切完成之后( oncomplete ),才调用弹出的 modalPanel ,自然就能找到值了。





10.  实现部分控件的数据刷新

1)      基本思路就是要确定哪一行 的哪一个控件 要刷新。

2)      联想到之前 <a4j:repeat> 里面的定位方法, ajaxKeys 用来定义哪些行需要被局部刷新。 ajaxKeys 属性接受 EL 表达式。

3)      至于哪些列(控件)需要局部更新,那就需要在将这些列(控件 ID )放在引发刷新的控件的 reRender 属性里面。

4)      具体例子如下:

<a4j:form>

<rich:dataTable id="dtTabel" border="1" value="#{dataTableTestBean.xcvrList}" var="xcvr" rows="10" ajaxKeys="#{dataTableTestBean.rowsToUpdate}" onRowContextMenu="#{rich:component('detail')}.show()">



<a4j:support event="onRowDblClick" reRender="grid1" action="#{dataTableTestBean.rowDblClickedAction}" oncomplete="#{rich:component('detail')}.show()">

<f:setPropertyActionListener target="#{dataTableTestBean.selectedXcvr}" value="#{xcvr}" />

</a4j:support>



<h:column id="column1">

<f:facet name="header">

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

</f:facet>

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

</h:column>



<h:column id="column2">

<f:facet name="header">

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

</f:facet>

<h:outputText id="out2" value="#{xcvr.tech}"></h:outputText>

</h:column>

……

</rich:dataTable>

</a4j:form>



<rich:modalPanel id="detail">

<f:facet name="header">

<h:outputText value="Xcvr Detail"></h:outputText>

</f:facet>

<f:facet name="controls">

<h:panelGroup>

<a4j:commandLink id="closeLink" value="Close"></a4j:commandLink>

<rich:componentControl for="detail" attachTo="closeLink" event="onclick" operation="hide" />

</h:panelGroup>

</f:facet>

<a4j:form>

<h:panelGrid id="grid" columns="2">

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

<h:inputText value="#{dataTableTestBean.selectedXcvr.itemCode}"></h:inputText>

<h:outputText value="Technology"></h:outputText>

<h:inputText value="#{dataTableTestBean.selectedXcvr.tech}"></h:inputText>

</h:panelGrid>

<h:panelGroup>

<a4j:commandButton value="Save" actionListener="#{dataTableTestBean.editXcvr}" onclick="#{rich:component('detail')}.hide()" reRender="out1,out2" />

<a4j:commandButton value="Cancel" immediate="true" onclick="#{rich:component('detail')}.hide()" />

</h:panelGroup>

</a4j:form>

</rich:modalPanel>



       【注意】

根据书上的代码, modalPanel 中用于保存修改的按钮的 reRender 属性,里面放的是, <rich:dataGrid> 的元素一个 <h:panelGrid> 的 ID ;于是我开始以为我的这个例子就应该放置 column1 和 column2 。但结果证明我错了,没有任何刷新。

于是我想,难道是防止整个 dataTable 的 ID ?试了一下,倒是刷新了。但我担心并不是 dataTable 局部刷新,而是整个表都刷新了。于是略一测试,果然是整个 dataTable 都被刷新了。

再次调整思路,我把需要刷新的两列的 <h:outputText> 的 ID out1 、 out2 放入按钮的 reRender 属性,测试结果成功,表格被局部刷新了。

现在反思一下,感觉因为 <h:column> 是被当作列来对待的,它并不像 <h:panelGrid> 那样充当一个纯粹的容器,因此将 <h:panelGrid> 的 ID 放入 reRender 时,其内部的内容都可以被刷新,而 <h:column> 就不行。





11.  创建行或列 span

1)      <rich:column> 属性与 <h:column> 基本功能相同,但提供了我行或列合并的功能。

2)      colspan 属性用于设定某一单元格实际占用多少列的值。

3)      <rich:columnGroup> 控件可以绑定多个列,并形成新的一行。

4)      <rich:column breakBefore="true"> 可以替代 <rich:columnGroup> 产生新的一行。

5)      rowspan 属性用于设定某一单元格实际占用多少行的值。

6)      要想知道具体结果是什么,最好亲自写一下试试看。





12.  <rich:columns>

1)      虽然这一章并没有讲到 <rich:columns> ,我还是查看了用户指南,简单学习了一下。感觉某些方面还是很有用的。

2)      整体思路就是 <rich:columns> 在 <rich:dataTable> 中,将 <rich:columns> 自己的 value 属性传进来的 Collection 进行遍历。为了帮助理解,可以这么认为:

l        通常, <rich:dataTable> 的 value 属性传进来的 Collection ,包含的是整个数据表,含有很多行;而 <rich:columns> 传进来的 Collection ,是对于每一行来说都相同的多个“列信息”。

l        <rich:dataTable> 是遍历每一行,但是需要逐列设置每一列现实的内容;而 <rich:columns> 则“更进一步”,将逐列设置每一列内容也省了,通过遍历每一列,设置列信息。

例如:

<rich:dataTable id="dtTabel" border="1" value="#{dataTableTestBean.xcvrList}" var="xcvr">

<rich:columns var="field" index="index" value="#{dataTableTestBean.fields}" >

<f:facet name="header">

<h:outputText value="#{field.fieldName}" />

</f:facet>



<h:outputText value="#{xcvr[field.fieldName]} " />

</rich:columns>

</rich:dataTable>

3)      value 属性,可以接受 List 类型的值, List 的元素可以是任意类型的。上面例子里, #{dataTableTestBean.fields} 是一个 Field 的 List ( Field 是一个自定义类,具有 fieldName 成员变量)。这个 Field List 里可以包括需要显示在表格里的 Xcvr 类的属性名。

在 <rich:columns> 的体里, #{xcvr[field.fieldName]} 就是要取每一行 xcvr 对象的名称为 field.fieldName 的值的属性。

4)      在 <rich:dataTable> 内 <rich:columns> 和 <rich:column> 、 <h:columns> 任然可以混合使用,互不干扰。

5)      columns 属性定义显示出来的列数;

begin 属性定义从哪一列开始显示;

end 属性定义到哪一列结束。

6)      还有一些关于 sort 、 filter 的属性,用户指南上也写得不太清楚,等到 Practical RichFaces 在第 10 章讲到 scrollableDataTable 的时候可能会涉及到。到时再仔细研究吧。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/12/4263633.aspx

    * 03:57
    * 浏览 (139)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter01
关键字: richfaces
1.       JSF’s View = UIComponent + Renderer

2.       验证只在 rendered 设置为 true 的时候才会发生。

3.       JSF 是基于 Server-Side 的,所有的事件处理都在 Server 上完成。

Browser 可以被认为仅仅是一个 Component Tree 的映像,或者被认为是 Component Tree 的可读的 View 。

4.       RichFaces 并不是标准 JSF 的替代实现,而是基于标准 JSF 的组件库。

5.       RichFaces 包括 2 个库: a4j 和 rich :

a4j :提供页面级( Page-Level ) Ajax 支持,主要是基础性的控制,比如如何发送 request 请求,把什么发送到 Server ,以及需要更新什么。

rich :提供组件级( Component-Level )的 Ajax 支持,提供各种现成的功能。换言之, rich 组件通常用在不需要决定如何发送 request ,或者需要更新什么的场合。

6.       换肤功能( Skinnability )

7.       组件开发工具箱( CDK , Component Development Kit )


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/05/4246221.aspx

    * 03:53
    * 浏览 (56)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter02
关键字: 配置 richfaces
1.       配置 RichFaces



1)        添加 lib 到 CLASSPATH

• richfaces-api-3.2.x.jar

• richfaces-impl-3.2.x.jar

• richfaces-ui-3.2.x.jar



2)        配置 web.xml 文件

• 主要是添加 ajax4jsf 的 Filter

<filter>

<display-name>RichFaces Filter</display-name>

<filter-name>richfaces</filter-name>

<filter-class>org.ajax4jsf.Filter</filter-class>

</filter>



<filter-mapping>

<filter-name>richfaces</filter-name>

<servlet-name>Faces Servlet</servlet-name>

<dispatcher>REQUEST</dispatcher>

<dispatcher>FORWARD</dispatcher>

<dispatcher>INCLUDE</dispatcher>

</filter-mapping>



• 可以选择性的设置 SKIN 参数

<context-param>

<param-name>org.richfaces.SKIN</param-name>

<param-value>blueSky</param-value>

</context-param>



3)        在页面中添加 taglib 声明

<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>

<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>





2.       部分页面更新( Partial-Page Update )



指定的控件将会在 Server 上被 render 出来, Browser 接收到 response ,一部分页面就会被更新。换句话说,就是一部分 DOM 会被更新。





3.       使用 <a4j:support>



1)      onkeyup 事件是标准的 DHTML 事件



2)      如何使用 < a4j:support>

• <a4j:support> 可以添加到任何标准 JSF 控件内部 ;

• 将 <a4j:support> 作为 Child 控件添加到 JSF 控件内 , 并指定一个将要触发 request 的 DHTML 事件 , 比如 onkeyup ;

• 用 actionListener 属性指定 ActionListener (方法)来应对 DHTML 事件;

• reRender 属性用来指定哪些控件将要被更新。



在这种情况下,每次 onkeyup 事件都会触发一次 Ajax Request 。 Server 得到 Request ,进入正常的 JSF 生命周期。然后 Ajax 得到 Response 并刷新部分页面。



【注意】

对于通常的 <f:message> ,如果不做特别操作,即使把这个 <f:message> 的 ID 加入触发 Ajax Request 的控件的 reRender 属性,当验证出错的时候, <f:message> 也不会被刷新到页面上来。

原因在于, Ajax Request 是根据 ID 在 DOM Tree 中查找控件位置,进行部分刷新的。当第一次载入页面的时候,因为没有错误信息,所以 <f:message> 不会被 render 。但当 Ajax Request 提交的值验证失败产生错误信息的时候, Server 发回的 Response 被 Ajax 接收到, Ajax 按照 ID 去查找控件的 DOM Tree 位置。这是它将无法定位 <f:message> ,因而也就无法刷新出来了。

解决办法有两种:

• 将 <f:message> 放在 <h:panelGroup> 或 <a4j:outputPanel> 中,将 <h:panelGroup> 或 <a4j:outputPanel> 的 ID 放到触发 Ajax Request 的控件的 reRender 中。

• 直接使用 <rich:message> 以代替 <f:message> , <rich:message> 实际上就是将 <f:message> 放进 <a4j:outputPanel ajaxRendered=”true”> 中( <a4j:outputPanel ajaxRendered=”true”> 中的控件总是会被刷新的)。





4.       使用 <a4j:log>



将 <a4j:log> 加入页面,当运行时按下 Ctrl+Shift+L 的时候会弹出一个信息页面窗口,根据你的操作,会自动刷新出 Debug 信息。

可以更改热键,比如: <a4j:log hotkey="D"/>



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/05/4246303.aspx

    * 03:51
    * 浏览 (71)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter03
关键字: a4j:commandlink
本章主要包括三方面内容:

· 发送 Ajax Request

· 实现 Partial-Page 更新

· 了解什么数据将会被 process





1.       发送 Ajax Request



1)  四个 RichFaces 控件可以发送 Ajax Request 并允许 Partial-Page 更新

• <a4j:commandLink>

• <a4j:commandButton>

• <a4j:support>

• <a4j:poll>



2)  <a4j:commandLink> 与 <a4j:commandButton>

与标准的 <h:commandLink> 与 <h:commandButton> 非常相似,增加的功能:

• reRender 属性,用于指定哪些控件需要 Partial-Page 更新;

• 对于 Partial-Page 更新, action 方法的返回值应为 null 。 Response 将被用来更新 Browser 的 DOM 。



3)  <a4j: support>

• <a4j: support> 应该作为标准 JSF 控件的直接子控件( Direct Child )来使用。

• 关键属性 event ,用来指定哪个 DHTML event 将会引发 Ajax Request 。(实际上, <a4j:commandLink> 与 <a4j:commandButton> 是使用了“ onClick ” DHTML event 来引发 Ajax Request 。

• 至于能够指定哪些 DHTML 事件,取决于父控件能够支持哪些。

• 当在页面上混合使用 <a4j: support> 和 JavaScript 代码时,有可能导致不确定的结果,因为 JavaScript 代码有可能比 <a4j: support> “抢占先机”。

• 可以同时组合使用多个 <a4j:support> 以分别应对不同的 DHTML event ,比如 onClick 、 onkeyup 、 onkeydown 等。



4)  <a4j:poll>

• interval          指定多长时间向 Server 发送一次 Ajax Request ;

• enabled          是否启动自动发送 Ajax Request 功能;

• reRender              页面的哪些控件(部分)要被刷新;

将 <a4j:poll> 放置在一个独立的 form 里,这样在发送 Request 的时候,其他 form 里面的 Field 将不会被发送。



5)  limitToList 属性

• 能够引发 Ajax Request 的四种控件都有 limitToList 这个属性;

• 当 limitToList 设为 true 的时候,只有当前控件的 reRender 里面的控件会被刷新;

• 即使 <a4j:outputPanel ajaxRendered=”true”> 也不会被刷新。





2.       实现 Partial-Page 更新



1)  两种方法:

• reRender 属性

• <a4j:outputPanel ajaxRendered=”true”>



2)  使用 reRender 属性

• 通常是逗号分隔的 ID 列表;

• 当 reRender 指向一个容器类控件的时候,该容器控件中的子控件也将被刷新;

• 接受 EL 表达式,如 #{profile.renderList} ,以实现 reRender 控件列表的动态刷新;

• 接受 4 种格式: Set 、 List 、 String[] 、 String (逗号分隔 ID 列表)。



【注意】

EL 表达式只在 Render Response 阶段之前被解析,也就意味着,可以在 action 或 actionListener 里更新 reRender 控件列表。

通常情况下,页面里的 EL 表达式应该在 Update Model Value 阶段被解析( Update Model Value 阶段在 Invoke Application 阶段之前)。而此处, EL 表达式只在 Render Response 阶段之前被解析( Render Response 阶段在 Invoke Application 阶段之后),也就留给我们机会在 Invoke Application 阶段的 action 或 actionListener 里对 reRender 控件列表进行修改。如修改 #{profile.renderList} 里面的的 renderList 集合对象。



3)  使用 <a4j:outputPanel>

• <a4j:outputPanel> 与 <h:panelGroup> 很相似,是一个容器类的控件;它的 ID 也可以被添加到其他控件的 reRender 属性里。

• 当 <a4j:outputPanel> 的 ajaxRendered 属性被设为 true ,则其内部的控件总会被刷新。





3.       了解什么数据将会被 process



1)  使用 <a4j:region>

• 可以使用 <a4j:region> 来指定哪些控件将被 process ( Process 包括解码 decoding 、转换 conversion 、验证 validation 、更新模型值 model updating );

• 请注意,整个 Form 还是会被提交,只是在 region 中的控件会被 process ;

• 如果未指定 region ,则整个页面将作为一个 region ,也就意味着整个 form 被 process ;

• 对于嵌套 region ,当外部 region 里的 ajax 控件引发 Request 的时候,内部 region 里的控件也将一起被 process ;而当内部 region 里的 ajax 控件引发 Request 的时候,外部 region 里的控件则不会随之一起 process ;



【注意】切勿将 process 和 reRender 相混淆

<a4j:region> 只是表明哪些控件被 process (解码 decoding 、转换 conversion 、验证 validation 、更新模型值 model updating );而 Partial-Page 刷新还是得靠 reRender 和 <a4j:outputPanel> 负责。两者之间,概念不同。



2)  使用 ajaxSingle 属性

• 将 ajaxSingle 属性设为 true ,等同于将单个控件包装在 <a4j:region> 中。如:

<h:inputText value="#{profile.age}">

<a4j:support event="onblur" reRender="userInfo" ajaxSingle="true">

</h:inputText>

等同于

<a4j:region>

<h:inputText value=”#{profile.age}”>

<a4j:support event=”onblur” reRender=”userInfo”>

</h:inputText>

</a4j:region>



• 对于单独的 <a4j:commandButton> 或 <a4j:commandLink> , ajaxSingle 也可以设为 true ,也就是只有这个控件被 process 。



3)  使用 process 属性

• process 属性用于设置 region 外的控件随 region 内的控件一起 process ;

• 接受 4 种格式: Set 、 List 、 String[] 、 String (逗号分隔 ID 列表)。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/06/05/4246420.aspx

    * 03:50
    * 浏览 (120)
    * 评论 (0)
    * 分类: richfaces

2009-07-27
缩略显示
Practical_RichFaces要点Chapter04
关键字: eventsqueue
1.       用队列控制 Event Traffic


1)  以下两个属性用来避免由频繁的 DHTML 事件所引发大量的 request 请求。

· eventsQueue

· requestDelay



2)  对于能够引发 Ajax Request 的 4 种控件来说,以上两种属性都是可用的。



3)  eventQueue 属性

· 将 eventQueue 属性指定一个对列名,则在当前一个 Request

你可能感兴趣的:(JavaScript,Ajax,bean,Richfaces,JSF)