JSF的一个核心就是事件与监听。JSF事件分为以下几种: 

1、Value-change events(值改变事件) 

<h:inputText valueChangeListener="#{myForm.processValueChanged}"/> 

<h:panelGrid binding="#{myForm.changePanel}" rendered="false"> 


</h:panelGrid> 

public void processValueChanged(ValueChangeEvent event) 

{ 

HtmlInputText sender = (HtmlInputText)event.getComponent(); 

sender.setReadonly(true); 

changePanel.setRendered(true); 

}当inputText的值改变的时候会触发processValueChanged事件,此事情内部通过参数,获取HtmlInputText的控件,然后设定readonly,同时设定panelGrid的模型changePanel的属性,因为panelGrid绑定了changePanel这个模型。 


2、Action events(动作事件) 

<h:commandButton type="submit" value="Login" action="success" 

immediate="true"/>上面这个是静态outcome事件,在faces-config.xml中配置相应的属性后,点击该按钮会转向相应的方法。 


<h:commandButton value = "Test Action Listener" actionListener = "#{testActionListener.doSomeAction}" />如果添加了actionListener属性的话,点击之后,在转向其他页面之前,会触发指定的事件,处理之后再转向。 

这里的doSomeAction方法的声明是void doSomeAction(ActionEvent actionEvent)。 


<h:commandButton type="submit" value="Login" 

action="#{loginForm.login}"/>上面这个是动态outcome事件,当点击该按钮之后会直接触发loginForm中的login事件,login事件返回的是一个字符串,在login处理完相应操作之后需要返回一个属性中已经配置过的字符串,例如success,然后JSF根据faces-config.xml中的配置,跳转到相应的页面。login的声明一般是String login(); 


当然也可以通过程序来添加监听器,不过监听器类需要实现ActionListener接口: 

UIComponent myComponent = new UIComponent(); 

myComponent.addActionListener(new TestActionListener()); 

myComponent.addActionListener(new CustomActionListener()); 



3、Data model events(数据模型事件) 

FacesContext facesContext = FacesContext.getCurrentInstance(); 

dataTable = (HtmlDataTable)facesContext.getApplication().createComponent( 

HtmlDataTable.COMPONENT_TYPE); 

DataModel myDataModel = new ResultSetDataModel(myResultSet); 

myDataModel.addDataModelListener(new DataModelListener() 

{ 

public void rowSelected(DataModelEvent e) 

{ 

FacesContext.getCurrentInstance().getExternalContext(). 

log("row selected:" + e.getRowIndex()); 

} 

}); 

dataTable.setValue(myDataModel);将上面的代码放入初始化程序中,当行的选择改变的时候就会触发相应的日志打印。 

这是因为这段代码给dataTable控件定义了一个数据模型,数据和相应的事件全部存在这个数据模型里面,然后将dataTable与这个模型进行绑定即可使用它所有的数据和事件。点击dataTable上面的一行自然也就会出发相应的行选择事件。 


4.Phase events(阶段事件) 


这个事件是为了捕捉一些阶段和过程而设定的,有以下几个阶段可以捕捉: 



ANY_PHASE 任一阶段 

APPLY_REQUEST_VALUES 请求处理阶段的应用请求值阶段 

INVOKE_APPLICATION 请求处理阶段的调用程序阶段 

PROCESS_VALIDATIONS 请求处理阶段的处理验证阶段 

RENDER_RESPONSE 请求处理阶段的描述响应阶段 

RESTORE_VIEW 请求处理阶段的恢复视图阶段 

UPDATE_MODEL_VALUES 请求处理阶段的更新模型值阶段 

具体可以参考http://java.sun.com/javaee/javaserverfaces/1.1_01/docs/api/javax/faces/event/PhaseId.html 


通过设定在实现类中设定相应的PhaseId以及添加到faces-config.xml中就可以捕捉相应阶段事件并添加响应的代码 


实现类 


import javax.faces.event.PhaseEvent; 

import javax.faces.event.PhaseId; 

import javax.faces.event.PhaseListener; 


public class CustomPhaseListener implements PhaseListener 

{ 

 public CustomPhaseListener() 

 { 

 } 


 public void afterPhase(PhaseEvent event) 

 { 

 System.out.println("After Phase->" + event.getPhaseId()); 

 } 


 public void beforePhase(PhaseEvent event) 

 { 

 System.out.println("Before Phase->" + event.getPhaseId()); 

 } 


 public PhaseId getPhaseId() 

 { 

 return PhaseId.ANY_PHASE;//选择事件标识的常量,此为任一阶段 

 } 

} 

在faces-config.xml中添加 

<lifecycle> 

 <phase-listener> 

 net.javabeat.articles.jsf.events.actions.TestActionListener 

 </phase-listener> 

</lifecycle> 

当然可以添加无限个的监听器 

<lifecycle> 

 <phase-listener>PhaseListener1</phase-listener> 

 <phase-listener>PhaseListener2</phase-listener> 

</lifecycle>