值变事件

如果使用者改变了JSF输入组件的值后送出窗体,就会发生值变事件(Value Change Event),这会丢出一个javax.faces.event.ValueChangeEvent对象,如果您想要处理这个事件,有两种方式,一是直接设定JSF输入组件的valueChangeListener属性,例如:
<h:selectOneMenu value="#{user.locale}"
                  onchange="this.form.submit();"
                  valueChangeListener="#{user.changeLocale}">

     <f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
     <f:selectItem itemValue="en" itemLabel="English"/>
 </h:selectOneMenu>

  为了仿真GUI中选择了选单项目之后就立即发生反应,我们在onchange属性中使用了JavaScript,其作用是在选项项目发生改变之后,立即送出窗体,而不用按下提交按钮;而valueChangeListener属性所绑定的user.changeLocale方法必须接受ValueChangeEvent对象,例如:

UserBean.java
package onlyfun.caterpillar;

 import javax.faces.event.ValueChangeEvent;

 public class UserBean {
    private String locale = "en";
    private String name;
    private String password;
    private String errMessage;

    public void changeLocale(ValueChangeEvent event) {
        if(locale.equals("en"))
            locale = "zh_TW";
        else
            locale = "en";
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

    public String getLocale() {
        if (locale == null) {
            locale = "en";
        }
        return locale;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public String verify() {
        if(!name.equals("justin") ||
           !password.equals("123456")) {
            errMessage = "名称或密码错误";
            return "failure";
        }
        else {
            return "success";
        }
    }
 }

  另一个方法是实作javax.faces.event.ValueChangeListener接口,并定义其processValueChange()方法,例如:

SomeListener.java
package onlyfun.caterpillar;
 ....
 public class SomeListener implements ValueChangeListener {
    public void processValueChange(ValueChangeEvent event) {
        ....
    }
    ....
 }


  然后在JSF页面上使用<f:valueChangeListener>卷标,并设定其type属性,例如:

{code:borderStyle=solid}
 <h:selectOneMenu value="#{user.locale}"
                  onchange="this.form.submit();">
     <f:valueChangeListener
              type="onlyfun.caterpillar.SomeListener"/>
     <f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>
     <f:selectItem itemValue="en" itemLabel="English"/>
 </h:selectOneMenu>

  下面这个页面是对 立即事件 中的范例程序作一个修改,将语言选项改以下拉式选单的选择方式呈现,这必须配合上面提供的UserBean类别来使用:

index.jsp
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
 <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
 <%@page contentType="text/html;charset=UTF8"%>

 <f:view locale="#{user.locale}">
 <f:loadBundle basename="messages" var="msgs"/>

 <html>
 <head>
 <title><h:outputText value="#{msgs.titleText}"/></title>
 </head>
 <body>

    <h:form>
        <h:selectOneMenu value="#{user.locale}"
                  immediate="true"
                  onchange="this.form.submit();"
                  valueChangeListener="#{user.changeLocale}">

            <f:selectItem itemValue="zh_TW"
                          itemLabel="Chinese"/>
            <f:selectItem itemValue="en"
                          itemLabel="English"/>
        </h:selectOneMenu>

        <h3><h:outputText value="#{msgs.hintText}"/></h3>
        <h:outputText value="#{msgs.nameText}"/>:
                <h:inputText value="#{user.name}"/><p>
        <h:outputText value="#{msgs.passText}"/>:
                <h:inputSecret value="#{user.password}"/><p>
        <h:commandButton value="#{msgs.commandText}"
                        action="#{user.verify}"/>
    </h:form>

 </body>
 </html>
	
 </f:view>