爪哇一角

共同探讨STRUTS#HIBERNATE#SPRING#EJB等技术
posts - 3, comments - 6, trackbacks - 0, articles - 99
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

八 JSF事件处理

Posted on 2009-01-20 14:49 非洲小白脸 阅读(387) 评论(0)  编辑  收藏 所属分类: JSF

1.JSF动作事件

前面的例子,我们直接将按钮的action绑定到一个Bean的方法上。实际上当按钮被触发时,JSF会自动产生一个Listener来处理事件。

如果您需要使用同一个方法来应付多种事件来源,并想要取得事件来源的相关讯息,您可以让处理事件的方法接收一个javax.faces.event.ActionEvent事件参数

如下jsp

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

</head>

<body>

<f:view>

<f:form>

       <h3>JSF动作事件--按钮触发的Listener事件,会在后台打出log。</h3>

       <h:commandButton value="#{msgs.commandText}">

              <f:actionListener type="test.LogHandler"/>

       </h:commandButton>

</f:form>

</f:view>

</body>

</html>

生成一个自定义的Listener

package test;

import javax.faces.event.ActionEvent;

import javax.faces.event.ActionListener;

public class LogHandler implements ActionListener{

       public void processAction(ActionEvent e) {

        System.out.println("++++++++LogHandler+++++++++");

    }

}

当按钮触发时,便会激活LogHandler这个Listener。你也可以同时指定多个Listener

http://localhost:8080/jsfTest/pages/jsfMyActionEvent.faces 就可以看到运行结果了。

具体程序参看示例程序。

 

2.JSF变量/值变事件

如果使用者改变了JSF输入元件的值后送出表单,就会发生值变事件(Value Change Event),这会丢出一个javax.faces.event.ValueChangeEvent物件

如果您想要处理这个事件,有两种方式,一是直接 设定JSF输入元件的valueChangeListener属性

jsfMyValueEvent.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=utf-8"%>

<f:view locale="#{valueEventBean.locale}">

<f:loadBundle basename="messages" var="msgs"/>

       <html>

       <head>

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

       </head>

       <body>

       <h:form>

              <h3><h:outputText value="#{msgs.hintText}"/></h3>

              <h:selectOneMenu value="#{valueEventBean.locale}"

                                onchange="this.form.submit();"

                                valueChangeListener="#{valueEventBean.changeLocale}">

                   <f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>

                   <f:selectItem itemValue="en" itemLabel="English"/>

               </h:selectOneMenu> 

       </h:form>

       </body>

       </html>

</f:view>

onchange属性中使用了JavaScript,其作用是在选项项目发生改变之后,立即送出表单,而不用按下提交按钮

valueChangeListener属性所绑定的user.changeLocale方法必须接受ValueChangeEvent物件

 

JsfMyValueEvent.java

package test;

import javax.faces.event.ValueChangeEvent;

public class JsfMyValueEvent {

       private String locale = "en";

    public String changeLocale(ValueChangeEvent e) {

        if(locale.equals("en"))

        locale = "zh_TW";

        else

        locale = "en";

        return locale;

    }

    public String getLocale() {

        if (locale == null) {

        locale = "en";

        }

        return locale;

    }

 }

别忘记在faces-config.xml中注册Bean

http://localhost:8080/jsfTest/pages/jsfMyValueEvent.faces 可以查看运行结果。

具体程序见示例程序。

 

另一个方法是实现javax.faces.event.ValueChangeListener接口,并实现processValueChange()方法

jsp中直接用标签<f:valueChangeListener 引用。见例:

<h:form>

              <h3><h:outputText value="#{msgs.hintText}"/></h3>

              <h:selectOneMenu value="#{valueEventBean.locale}"

                                onchange="this.form.submit();">

                   <f:valueChangeListener type="……"/>

                   <f:selectItem itemValue="zh_TW" itemLabel="Chinese"/>

                   <f:selectItem itemValue="en" itemLabel="English"/>

               </h:selectOneMenu> 

       </h:form>

与上面一种的写法有些区别,请注意。

这里就不再演示了。

 

对于动作事件(Action Event)来说,元件的动作事件是在套用请求值阶段就生成ActionEvent物件了,

但相关的事件处理并不是马上进行,ActionEvent会先被排入伫列,然后必须再通过验证、更新模式值阶段,之后才处理伫列中的事件。

可以设定元件的事件在套用请求值之后立即被处理,并跳过后续的阶段,直接进行画面绘制以回应请求,

对于JSF的input与command元件,都有一个immediate属性可以设定,只要将其设定为true,则指定的事件就成为立即事件。

 

3.JSF Phase 事件

JSF的请求执行到回应,完整的过程会经过六个阶段:

在每个阶段的前后会引发 javax.faces.event.PhaseEvent,如果您想尝试在每个阶段的前后捕捉这个事件,以进行一些处理,则可以实作 javax.faces.event.PhaseListener,并向javax.faces.lifecycle.Lifecycle登记这个 Listener,以有适当的时候通知事件的发生。

 

PhaseListener有三个必须实作的方法getPhaseId()、beforePhase()与afterPhase()

PhaseId.APPLY_REQUEST_VALUES

PhaseId.PROCESS_VALIDATIONS

PhaseId.UPDATE_MODEL_VALUES

PhaseId.INVOKE_APPLICATION

PhaseId.RENDER_RESPONSE

PhaseId.ANY_PHASE

其中PhaseId.ANY_PHASE指的是任何的阶段转换时,都进行监听。

如例:

package test;

import javax.faces.event.PhaseEvent;

import javax.faces.event.PhaseId;

import javax.faces.event.PhaseListener;

public class ShowPhaseListener implements PhaseListener {

       public void beforePhase(PhaseEvent event) {

        String phaseName = event.getPhaseId().toString();

        System.out.println("++++++++++++Before " + phaseName);

    }

    public void afterPhase(PhaseEvent event) {

        String phaseName = event.getPhaseId().toString();

        System.out.println("++++++++++++After " + phaseName);

    }

    public PhaseId getPhaseId() {

        return PhaseId.ANY_PHASE;

    }

}

faces-config.xml中向Lifecycle进行注册

<lifecycle>
<phase-listener>
 onlyfun.caterpillar.ShowPhaseListener
</phase-listener>

</lifecycle>

这样你就可以看到请求运行的每一个阶段前后都加上了Log

 

具体程序看示例程序。


只有注册用户登录后才能发表评论。


网站导航: