JSF 扩展:Dynamic Faces(DynaFaces)

Sang Shin, sang.shin@sun.com, Sun Microsystems, www.javapassion.cn




在本实验室中,我们将探索各种使用 Dynamic Faces 的示例应用程序。示例应用程序来自于 Dynamic Faces 分发包。


预计时间:100 分钟(不包括课外练习)


前提条件

本动手实验室假定您拥有以下技术的基本知识或者具备相关编程经验:


软件需求

开始之前,需要在您的计算机中安装以下软件。


可以使用的操作系统平台

变更记录


未来计划(由 Sang Shin 完成)


实验室练习


练习 1:编译和运行 "dyna-blank-jsp" 示例应用程序


此示例是一个使用 JSP 的 Dynamic Faces 骨架应用程序。它只是定制的起点。您可以通过复制此项目创建一个新的 DynaFaces NetBeans 项目。

(1.1)打开、编译和运行 "dyna-blank-jsp" 示例应用程序

0. 启动 NetBeans IDE。
1. 打开 dyna-blank-jsp NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目。

2. 编译和运行 dyna-blank-jsp 项目。




(1.2)深入了解   "dyna-blank-jsp" 示例应用程序


1. web.xml

<?xml version='1.0' encoding='UTF-8'?>

<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>

    <context-param>
        <description>
            Set this flag to true if you want the JavaServer Faces
            Reference Implementation to validate the XML in your
            faces-config.xml resources against the DTD. Default
            value is false.
        </description>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>

    <!-- Faces Servlet -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <init-param>
          <param-name>javax.faces.LIFECYCLE_ID</param-name>
          <param-value>com.sun.faces.lifecycle.PARTIAL</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


    <!-- Faces Servlet Mapping -->
    <!--

         This mapping identifies a jsp page as having JSF content.  If a
         request comes to the server for foo.faces, the container will
         send the request to the FacesServlet, which will expect a
         corresponding foo.jsp page to exist containing the content.

    -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

</web-app>

2. index.html

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
    <head>
        <meta http-equiv="refresh" content="2;url=home.jsf">
    </head>
   
    <body>
       
    </body>
</html>

3. home.jsp

<%@ taglib uri="http://java.sun.com/jsf/core"  prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html"  prefix="h" %>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>

<f:view>
    <html>
        <head>
            <title>DynaFaces JSP Blank App</title>
            <jsfExt:scripts />
        </head>
        <body  bgcolor="white">
           
            <h:form id="form"> 
               
                <h1>DynaFaces JSP Blank App</h1>
               
               
            </h:form>
           
        </body>
    </html>
</f:view>



结束语

在此练习中, 您编译并运行了一个现成的 "dyna-blank-jsp" 示例应用程序,从而对应用程序的运行机制有所感触。

                                                                                                                        返回顶部



练习 2:编译和运行 "dyna-cardemo" 示例应用程序


Options 页面被修改,以使用 DynaFaces 提供 Ajax 行为。无需对整个页面进行刷新即更新了汽车的价格。

(2.1)打开、编译和运行 "dyna-cardemo" 示例应用程序

1. 打开 dyna-cardemo NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目中,正如 上面在练习 1 中所做

3. 编译和运行 dyna-cardemo 项目。






(2.2)深入了解  "dyna-cardemo" 示例应用程序


1. carDetails.jsp

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:jsp="http://java.sun.com/JSP/Page"
         xmlns:jsfExt="http://java.sun.com/jsf/extensions/dynafaces">
    <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>
   
    <html>
       
        <head>
            <meta http-equiv="Content-Type" content="text/html;CHARSET=UTF-8" />
            <title>CarStore</title>
            <link rel="stylesheet" type="text/css"
                  href="${pageContext.request.contextPath}/stylesheet.css" />
        </head>
       
        <f:loadBundle basename="carstore.bundles.Resources" var="bundle"/>
       
        <body bgcolor="white">
           
            <f:view>
               
                <h:form prependId="false">
                   
                   
                    <!-- non-option details -->

                    <h:panelGrid columns="1"
                                 summary="#{bundle.carDetails}"
                                 title="#{bundle.carDetails}">
                       
                        <h:graphicImage url="/images/cardemo.jpg"/>
                       
                        <h:graphicImage
                            binding="#{carstore.currentModel.components.image}"/>
                       
                        <h:outputText styleClass="subtitlebig"
                                      binding="#{carstore.currentModel.components.title}"/>
                       
                        <h:outputText
                            binding="#{carstore.currentModel.components.description}"/>
                       
                        <jsfExt:ajaxZone id="zone1">
                           
                            <h:panelGrid columns="2">
                               
                                <h:outputText styleClass="subtitle"
                                              value="#{bundle.basePriceLabel}"/>
                               
                                <h:outputText
                                    binding="#{carstore.currentModel.components.basePrice}"/>
                               
                                <h:outputText styleClass="subtitle"
                                              value="#{bundle.yourPriceLabel}"/>
                               
                                <h:outputText value="#{carstore.currentModel.currentPrice}"/>
                               
                            </h:panelGrid>
                           
                        </jsfExt:ajaxZone>
                       
                        <h:commandButton action="#{carstore.buyCurrentCar}"
                                         value="#{bundle.buy}"/>
                       
                    </h:panelGrid>
                   
                    <jsp:include page="optionsPanel.jsp"/>
                   
                    <h:commandButton action="#{carstore.buyCurrentCar}"
                                     value="#{bundle.buy}"/>
                   
                </h:form>
               
                <jsp:include page="bottomMatter.jsp"/>
               
            </f:view>
        </body>
       
    </html>
</jsp:root>


2. optionsPanel.jsp

<%@ page contentType="text/html" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces" %>

<jsfExt:ajaxZone id="zone2" render="zone1,zone2" execute="zone2"
                 action="#{carstore.currentModel.updatePricing}">
    <h:panelGrid>
       
        <h:outputText value="#{bundle.OptionsPackages}"/>
       
        <!-- options package chooser -->

        <h:panelGrid columns="4">
           
            <h:commandButton id="Custom" value="#{bundle.Custom}"
                             styleClass="#{carstore.customizers.Custom.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
            <h:commandLink id="Standard" value="#{bundle.Standard}"
                           styleClass="#{carstore.customizers.Standard.buttonStyle}"
                           actionListener="#{carstore.choosePackage}"/>
           
            <h:commandButton id="Performance" value="#{bundle.Performance}"
                             styleClass="#{carstore.customizers.Performance.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
            <h:commandButton id="Deluxe" value="#{bundle.Deluxe}"
                             styleClass="#{carstore.customizers.Deluxe.buttonStyle}"
                             actionListener="#{carstore.choosePackage}"/>
           
        </h:panelGrid>
       
    </h:panelGrid>
   
    <h:panelGrid columns="2">
       
        <h:outputText value="#{bundle.Engine}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.engine}"/>
       
        <h:outputText value="#{bundle.Brakes}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.brake}"/>
       
        <h:outputText value="#{bundle.Suspension}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.suspension}"/>
       
        <h:outputText value="#{bundle.Speakers}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.speaker}"/>
       
        <h:outputText value="#{bundle.Audio}"
                      styleClass="optionLabel"/>
       
        <h:selectOneRadio styleClass="optionValue"
                          binding="#{carstore.currentModel.components.audio}"/>
       
        <h:outputText value="#{bundle.Transmission}"
                      styleClass="optionLabel"/>
       
        <h:selectOneMenu styleClass="optionValue"
                         binding="#{carstore.currentModel.components.transmission}"/>
       
    </h:panelGrid>
   
    <h:outputText value="#{bundle.OtherOptions}"
                  styleClass="optionLabel"/>
   
    <h:panelGrid columns="6">
       
        <h:selectBooleanCheckbox title="#{bundle.sunroofLabel}"
                                 binding="#{carstore.currentModel.components.sunroof}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.sunroofLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.cruiseLabel}"
                                 binding="#{carstore.currentModel.components.cruisecontrol}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.cruiseLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.keylessLabel}"
                                 binding="#{carstore.currentModel.components.keylessentry}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.keylessLabel}"/>
       
        <h:selectBooleanCheckbox
            title="#{bundle.securityLabel}"
            binding="#{carstore.currentModel.components.securitySystem}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.securityLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.skiRackLabel}"
                                 binding="#{carstore.currentModel.components.skiRack}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.skiRackLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.towPkgLabel}"
                                 binding="#{carstore.currentModel.components.towPackage}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.towPkgLabel}"/>
       
        <h:selectBooleanCheckbox title="#{bundle.gpsLabel}"
                                 binding="#{carstore.currentModel.components.gps}">
        </h:selectBooleanCheckbox>
       
        <h:outputText value="#{bundle.gpsLabel}"/>
       
    </h:panelGrid>
   
</jsfExt:ajaxZone>

结束语

在此练习中, 您编译并运行了一个现成的 "dyna-cardemo" 示例应用程序,从而对该应用程序的运行机制有所感触。

                                                                                                                        返回顶部


练习 3:编译和运行 "dyna-jmaki" 示例应用程序


这个例子显示了将 DynaFaces 和 jMaki 以及定制 JSF 组件联合起来的一些可能性。注意我们使 AJAX 激活了 Blueprints Scroller 组件而未对其做任何修改。此组件完全是一个 "开架" 组件。

这个例子也显示了 jMaki dojo FishEye 组件是如何与 JSF 紧密集成在一起的。该页面有两个消息区域,通过 Ajax 对选择 fishEye 中的一个条目这一选择作出响应从而进行更新。jMaki FishEye 部件在请求域托管 bean 上有一个绑定到 int 属性的值。它还在同一个托管 bean 上有一个指向方法的 valueChangeListener 方法绑定。选择列表中其中一项条目既会导致组件的当前值发生更新,其类型转为 int,也会导致调用 valueChangeListener,它在请求域内存储一条由 outputText 输出的消息,只有在两个 outputText 组件都呈现出来的时候,outputText 才输出这条消息。选定的消息字符串都被从托管 bean 中拿出来。

(3.1)打开、编译和运行 "dyna-jmaki" 示例应用程序的第一部分

1. 打开 dyna-jmaki NetBeans 项目。

2. 删除断开的引用,并将 DynaFaces 库文件添加到项目,如 以上练习 1 中所做

3. 编译和运行 dyna-jmaki 项目。






(3.2)深入了解  "dyna-jmaki" 示例应用程序的第一部分


1. CustomerBean.java

package com.sun.faces.run_time_test.model;


import java.io.Serializable;


/**
 * <p>JavaBean represented the data for an individual customer.</p>
 */

public class CustomerBean implements Serializable {
   
   
    public CustomerBean() {
        this(null, null, null, 0.0);
    }
   
   
    public CustomerBean(String accountId, String name,
            String symbol, double totalSales) {
        this.accountId = accountId;
        this.name = name;
        this.symbol = symbol;
        this.totalSales = totalSales;
    }
   
   
    private String accountId = null;
   
   
    public String getAccountId() {
        return (this.accountId);
    }
   
   
    public void setAccountId(String accountId) {
        this.accountId = accountId;
    }
   
   
    private String name = null;
   
   
    public String getName() {
        return (this.name);
    }
   
   
    public void setName(String name) {
        this.name = name;
    }
   
   
    private String symbol = null;
   
   
    public String getSymbol() {
        return (this.symbol);
    }
   
   
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
   
   
    private double totalSales = 0.0;
   
   
    public double getTotalSales() {
        return (this.totalSales);
    }
   
   
    public void setTotalSales(double totalSales) {
        this.totalSales = totalSales;
    }
   
   
    public String toString() {
        StringBuffer sb = new StringBuffer("CustomerBean[accountId=");
        sb.append(accountId);
        sb.append(",name=");
        sb.append(name);
        sb.append(",symbol=");
        sb.append(symbol);
        sb.append(",totalSales=");
        sb.append(totalSales);
        sb.append("]");
        return (sb.toString());
    }
   
   
}

2. ResultSetBean.java

package com.sun.faces.run_time_test.model;

import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>Backing file bean for <code>ResultSet</code> com.sun.javaee.blueprints.simpleuicomponents.onents.</p>
 */

public class ResultSetBean {
   
    private List list = null;
   
   
    public ResultSetBean() {
    }
   
   
    public List getList() {
        // Construct a preconfigured customer list lazily.
        if (list == null) {
            list = new ArrayList();
            for (int i = 0; i < 1000; i++) {
                list.add(new CustomerBean(Integer.toString(i),
                        "name_" + Integer.toString(i),
                        "symbol_" + Integer.toString(i), i));
            }
        }
        return list;
    }
   
   
    public void setList(List newlist) {
        this.list = newlist;
    }
   
    // -------------------------------------------------------- Bound Components
   
    /**
     * <p>The <code>UIData</code> component representing the entire table.</p>
     */
    private UIData data = null;
   
   
    public UIData getData() {
        return data;
    }
   
   
    public void setData(UIData data) {
        this.data = data;
    }
   
   
    // ---------------------------------------------------------- Action Methods
   
   
    /**
     * <p>Scroll directly to the first page.</p>
     */
    public String first() {
        scroll(0);
        return (null);
       
    }
   
   
    /**
     * <p>Scroll directly to the last page.</p>
     */
    public String last() {
        scroll(data.getRowCount() - 1);
        return (null);
       
    }
   
   
    /**
     * <p>Scroll forwards to the next page.</p>
     */
    public String next() {
        int first = data.getFirst();
        scroll(first + data.getRows());
        return (null);
       
    }
   
   
    /**
     * <p>Scroll backwards to the previous page.</p>
     */
    public String previous() {
        int first = data.getFirst();
        scroll(first - data.getRows());
        return (null);
       
    }
   
   
    /**
     * <p>Scroll to the page that contains the specified row number.</p>
     *
     * @param row Desired row number
     */
    public void scroll(int row) {
       
        int rows = data.getRows();
        if (rows < 1) {
            return; // Showing entire table already
        }
        if (row < 0) {
            data.setFirst(0);
        } else if (row >= data.getRowCount()) {
            data.setFirst(data.getRowCount() - 1);
        } else {
            data.setFirst(row - (row % rows));
        }
       
    }
   
   
    /**
     * Handles the ActionEvent generated as a result of clicking on a
     * link that points a particular page in the result-set.
     */
    public void processScrollEvent(ActionEvent event) {
        int currentRow = 1;
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent component = event.getComponent();
        Integer curRow = (Integer) component.getAttributes().get("currentRow");
        if (curRow != null) {
            currentRow = curRow.intValue();
        }
        // scroll to the appropriate page in the ResultSet.
        scroll(currentRow);
    }
   
   
}


(3.3)运行 "dyna-jmaki" 示例应用程序的第二部分





(3.4)深入了解  "dyna-jmaki" 示例应用程序的第二部分


1. FishEyeBean.java

package com.sun.faces.run_time_test.model;

import com.sun.faces.extensions.avatar.lifecycle.AsyncResponse;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

/**
 *
 * @author edburns
 */
public class FishEyeBean {
   
    /** Creates a new instance of FishEyeBean */
    public FishEyeBean() {
    }
   
    public void valueChanged(ValueChangeEvent e) {
        FacesContext context = FacesContext.getCurrentInstance();
        AsyncResponse async = AsyncResponse.getInstance();
        String message = " oldValue: " +
                e.getOldValue() + " newValue: " + e.getNewValue();
        context.getExternalContext().getRequestMap().put("fishEyeMessage", message);
        // Request DynaFaces to re-render only the fishEyeMessage.
        List<String> renderSubtrees = async.getRenderSubtrees();
        renderSubtrees.clear();
        renderSubtrees.add("fishEyeMessage");
        renderSubtrees.add("personMessage");
        renderSubtrees.add(e.getComponent().getClientId(context));
    }

    /**
     * Holds value of property selectedIndex.
     */
    private int selectedIndex;

    /**
     * Getter for property selectedIndex.
     * @return Value of property selectedIndex.
     */
    public int getSelectedIndex() {
        return this.selectedIndex;
    }

    /**
     * Setter for property selectedIndex.
     * @param selectedIndex New value of property selectedIndex.
     */
    public void setSelectedIndex(int selectedIndex) {
        this.selectedIndex = selectedIndex;
    }

    /**
     * Holds value of property personMessages.
     */
    private String [] personMessages;

    /**
     * Getter for property personMessages.
     * @return Value of property personMessages.
     */
    public String [] getPersonMessages() {
        return this.personMessages;
    }

    /**
     * Setter for property personMessages.
     * @param personMessages New value of property personMessages.
     */
    public void setPersonMessages(String [] personMessages) {
        this.personMessages = personMessages;
    }

    /**
     * Getter for property personMessage.
     * @return Value of property personMessage.
     */
    public String getPersonMessage() {
        return personMessages[getSelectedIndex()];
    }
   
}

2. fisheye.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%>

<f:view>
   
    <html>
        <head>
            <title><%@ include file="title.jsp" %></title>
           
            <link rel="stylesheet" href="css/default_developer.css" />
            <link rel="stylesheet" href="css/default.css" />
            <link rel="stylesheet" href="css/homepage.css" />   
            <jsfExt:scripts/>
            <%@ include file="extraHeadContent.jsp" %>
        </head>
       
        <%@ page contentType="text/html" %>
       
        <body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" rightmargin="0" bgcolor="#ffffff" class="vaa2v0">
           
            <a name="top"></a>
           
            <%@ include file="masthead.jsp" %>
           
            <!-- BEGIN PAGETITLE -->
            <div class="pagetitle"><%@ include file="title.jsp" %></div>
            <!-- END PAGETITLE -->
           
            <%@ include file="topPanelFishEye.jsp" %>
           
           
            <!-- BEGIN WRAPPER TABLE, 2 COLUMN, MAIN/RIGHT -->
            <table border="0" cellpadding="0" cellspacing="10" width="100%">
                <tr valign="top"><td>
                       
                        <!-- BEGIN MAIN COLUMN -->
                       
                        <%@ include file="mainColumnFishEye.jsp" %>
                       
                    </td>
                   
                    <!-- BEGIN RIGHT COLUMN -->
                    <td>
                       
                        <div class="e15"><div class="e15v0">
                                <div class="cornerTL"><div class="cornerTR"></div></div>
                                <div class="pad">
                                   
                                    <%@ include file="rightColumnFishEye.jsp" %>
                                   
                                </div>
                                <div class="cornerBL"><div class="cornerBR"></div></div>
                               
                        </div></div>
                       
                    </td>
                   
                </tr>
               
               
                <tr>
                    <td class="headerbar3">
                       
                        <div class="headerpadding2"><span style="color:#fff;">Running the Demo</span></div>
                       
                    </td>
                   
                </tr>
                <tr>
                   
                    <td>
                       
                        <%@ include file="bottomPanelFishEye.jsp" %>
                       
                    </td>
                </tr>
               
            </table>
           
        </body>
    </html>
</f:view>

2. mainColumnFishEye.jsp

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/blueprints/ui" prefix="d" %>
<%@ taglib prefix="a" uri="http://java.sun.com/jmaki-jsf" %>
<%@taglib prefix="jsfExt" uri="http://java.sun.com/jsf/extensions/dynafaces"%>

<jsfExt:scripts/>

<h:form id="form" prependId="false">
   
   
    <table bgcolor="#eeeeee" border="0" cellpadding="2" cellspacing="0" width="100%" class="vtop">
        <colgroup>
            <col width="100%" />
        </colgroup>
       
        <tr>
            <td class="headerbar3" colspan="2">
                <div class="headerpadding2"><span style="color:#fff;">JSF, Dynamic Faces, and the Dojo FishEye widget.</span></div>
               
            </td>
        </tr>
       
        <tr>
           
            <td colspan="2">
               
                <a:ajax name="dojo.fisheye"
                        value="#{fishEyeBean.selectedIndex}"
                        valueChangeListener="#{fishEyeBean.valueChanged}"
                        args="{items:[
                        {iconSrc:'images/3_Galbraith_small.jpg',caption:'Ben',index:0},
                        {iconSrc:'images/2_Almaer_small.jpg',caption:'Dion',index:1},
                        {iconSrc:'images/1255_Raskin_small.jpg',caption:'Aza',index:2},
                        {iconSrc:'images/1254_Lewis_Ship_small.jpg',caption:'Howard',index:3}
                        ]}"

                />
               
               
            </td>
        </tr>
       
        <tr>
           
            <td colspan="2">
               
                <p>This example shows how the jMaki dojo FishEye component is fully
                    integrated with JSF.  The page has two message areas that are updated
                    via Ajax in response to the selection of one of the items in the
                    fishEye.  The jMaki FishEye widget has a value binding to an
                    <code>int</code> property on a request scoped managed bean.  It also has
                    a <code>valueChangeListener</code> method binding pointing to a method
                    on that same managed bean.  Choosing one of the items in the list both
                    causes the current value of the component to be updated, with type
                    conversion to <code>int</code>, and the <code>valueChangeListener</code>
                    to be called, which stores a message in request scope which is output by
                    an <code>outputText</code> as well as making it so only the two
                    <code>outputText</code> components are rendered.  The selected message
                strings are all pulled from the managed bean.</p>
               
            </td>
           
        </tr>
       
       
        <tr>
           
            <td>Selected Person <h:outputText id="personMessage" value="#{fishEyeBean.personMessage}" />
            </td>
           
            <td>Message from ValueChangeListener <h:outputText id="fishEyeMessage" value="#{requestScope.fishEyeMessage}" />
               
            </td>
           
        </tr>
       
    </table>
   
</h:form>


练习 4:编译和运行 "dyna-simple-events" 示例应用程序


本例显示了如何通过 AJAX 将 JavaScript 中的 jsf ValueChangeEvent 直接分发给 JSF 生命同期。此事务中遍历到的任何安装在组件上的 valueChangeListeners 都被正常触发。

本例也显示了如何通过 AJAX 将 JavaScript 中的 jsf ActionEvent 直接分发给 JSF 生命同期。此事务中遍历到的任何安装在组件上的 actionListeners 都被正常触发。

(4.1)打开、编译和运行 "dyna-simple-events" 示例应用程序

1. 打开 dyna-simple-events NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-simple-events 项目。







(4.2)深入了解  "dyna-simple-events" 示例应用程序


<即将添加will be added later>

练习 5:编译和运行 "dyna-simple-partial-update" 示例应用程序



(5.1)打开、编译和运行 "dyna-simple-partial-update" 示例应用程序

1. 打开 dyna-simple-partial-update NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-simple-partial-update 项目。



(5.2)深入了解  "core-flags-with-fparam" 示例应用程序


<即将添加>

练习 6:编译和运行 "dyna-flash" 示例应用程序

本示例应用程序中的系列页面演示了来自于 Ruby On Rails 中的 flash 概念的用法。

在 JSF 中,很自然地使用新的 Unified Expression Language in Java EE 5 来展示 flash。它通过一个定制的 ELResolver 来实现,其引入一个名称为 "flash" 的隐式对象。我考虑过将其称为 "dhhIsMyHero",但是选择了更为简单的 "flash"。

使用 flash 很简单,并且从语义上与其在 Rails 中的运行方式一样。它是一张图。放入图中的成分在 "下一张" 显示给用户的视图中是可访问的。在向用户显示了 "下一张" 视图后,该图将清空。


(6.1)打开、编译和运行 "dyna-flash" 示例应用程序

1. 打开 dyna-flash NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-flash 项目。



(6.2)深入了解  "dyna-flash" 示例应用程序


<即将添加will be added later>


练习 7:编译和运行 "dyna-fire-ajax-transaction"示例应用程序


本示例介绍了 DynaFaces.fireAjaxTransaction 方法的行为,特别是其执行和呈现选项的行为。可在项目首页找到这些选项完整的引用材料。

View 区域是一个有关 PanelGrid 和 CommandButton 组件的视图。最初,每个组件都有一个绿色边界,意味着所有这些组件已经度过了其生命周期中最初的呈现阶段。

每个 fireAjaxTransaction 按钮都会引发一个不同的 DynaFaces.fireAjaxTransaction 事件,对视图中一个或多个组件产生影响。组件颜色会随着其所处的生命周期阶段的不同而发生改变。

Options 区域显示了用于 fireAjaxTransaction 命令的选项。在触发新命令前按下 Reset 按钮。

(7.1)打开、编译和运行 "dyna-fire-ajax-transaction" 示例应用程序

1. 打开 dyna-fire-ajax-transaction NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-fire-ajax-transaction 项目。



(7.2)深入了解  "dyna-fire-ajax-transaction" 示例应用程序


1. home.jsp

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:jsp="http://java.sun.com/JSP/Page"
         xmlns:jsfExt="http://java.sun.com/jsf/extensions/dynafaces">
    <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>

    <f:view>  
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html;CHARSET=UTF-8" />
                <title>Dynamic Faces fireAjaxTransaction</title>
                <link rel="stylesheet" type="text/css"
                      href="${pageContext.request.contextPath}/stylesheet.css" />
                <jsfExt:scripts />
            </head>
            <body  bgcolor="white">
                <h:form id="form" prependId="false"> 
                   
                    <h1>Dynamic Faces fireAjaxTransaction</h1>
                   
                    <jsp:include page="colorKey.jsp"/>
                   
                    <h:panelGrid columns="2" cellspacing="30">    
                        <jsp:include page="fireajax.jsp"/>            
                        <jsp:include page="componentMap.jsp"/>            
                    </h:panelGrid>
                   
                    <h:panelGrid border="1" columns="2" cellspacing="40">
                        <h:commandButton id="reset"
                                         value="reset"
                                         onclick="DynaFaces.fireAjaxTransaction(this,
                                         {execute:'reset'}); return false;"
                                         actionListener="#{bean.reset}"/>
                        <h:panelGrid columns="2">
                            <h:panelGrid id="optionsTitle">
                                <h:outputText value="Options: " styleClass="options-prompt"/>
                            </h:panelGrid>
                            <h:panelGrid id="fireOptions">                        
                                <h:outputText value="#{bean.fireOptions}" styleClass="options"/>                       
                            </h:panelGrid>
                        </h:panelGrid>
                    </h:panelGrid>             
                   
                </h:form> 
               
            </body>
        </html>
    </f:view>
   
</jsp:root>

2. fireajax.jsp

<%@ page contentType="text/html" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="g" uri="http://java.sun.com/jsf/fireAjaxTrans" %>

<h:panelGrid border="1" columns="2" cellspacing="10" headerClass="keytitle">
    <f:facet name="header">
        <h:outputText value="Command"/>
    </f:facet>
    <h:commandButton id="ajax1"
                     value="fireAjaxTransaction [ajax1]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax1,_1'}); return false;"
                     actionListener="#{bean.getOptions}"/> 
    <h:commandButton id="ajax2"
                     value="fireAjaxTransaction [ajax2]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax2,_6,_10'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax3"
                     value="fireAjaxTransaction [ajax3]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax3,_5'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax4"
                     value="fireAjaxTransaction [ajax4]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax4,_4,_9'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax5"
                     value="fireAjaxTransaction [ajax5]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax5',render:'_1,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax6"
                     value="fireAjaxTransaction [ajax6]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax6',render:'_6,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax7"
                     value="fireAjaxTransaction [ajax7]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax7,_10',render:'_5,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
    <h:commandButton id="ajax8"
                     value="fireAjaxTransaction [ajax8]"
                     onclick="DynaFaces.fireAjaxTransaction(this,
                     {execute:'ajax8,_1,_2,_3,_4',render:'_1,_2,_3,_4,optionsTitle,fireOptions'}); return false;"
                     actionListener="#{bean.getOptions}"/>
</h:panelGrid>


练习 8:编译和运行 "dyna-tictactoe" 示例应用程序


(8.1)打开、编译和运行 "dyna-tictactoe" 示例应用程序

1. 打开 dyna-tictactoe NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-tictactoe项目。



(8.2)深入了解  "dyna-tictactoe" 示例应用程序


<即将添加>


练习 9:编译和运行 "dyna-blank-facelets" 示例应用程序


(9.1)打开、编译和运行 "dyna-blank-facelets" 示例应用程序

1. 打开 dyna-blank-facelets NetBeans 项目。

2. 删除断开的引用并将 DynaFaces 库文件添加到项目,正如 您在以上练习 1 中所做

3. 编译和运行 dyna-blank-facelets 项目。



(9.2)深入了解  "dyna-blank-facelets" 示例应用程序


<即将添加>

课外练习(针对 Sang Shin“Java EE 编程在线课程”的学习者)


<尚未添加>

                                                                                                                    返回顶部





原文链接: http://www.javapassion.com/handsonlabs/jsfdynafaces/