JSF事件监听器–动作,阶段,值更改

时间:2020-02-23 14:33:43  来源:igfitidea点击:

JSF事件和侦听器模型基于JavaBeans规范。
事件定义为基于用户操作(例如单击按钮,超链接,更改输入值等)触发的信号。
JSF告诉组件调用处理用户生成的事件的适当侦听器类。

现在让我们详细了解事件类和侦听器接口。

JSF事件类

与JSF事件相关的类在javax.faces.event包中定义。
在JSF中实现事件类时,必须扩展javax.faces.event包。
可以通过调用event.getComponent来获得生成的事件。

UIComponent ui = new UIComponent();
MyFacesEvent ev1 = new MyFacesEvent(ui); 
UIComponent sc1 = ev1.getComponent();

通过使用queue()方法,事件可以在请求处理生命周期结束时排队。
可以使用以下代码在特定阶段进行排队

MyFacesEvent ev1 = new MyFacesEvent();
ev1.setPhaseId(PhaseId.PROCESS_VALIDATIONS);

在上面的代码中,事件将在流程验证阶段结束时发生。

JSF侦听器类

事件与所有事件的侦听器类相关联。
例如,如果事件是一个valuechange事件,则将相应的侦听器类" ValueChangeListener"与其关联。
类似地," ActionListener"用于动作事件。

JavaBeans规范使方法成为注册事件的特定侦听器的必需方法。
例如,如果事件名称为" MyOwnEvent",侦听器类为" MyOwnListener",并希望在" MyOwnComponent"上调用此事件,则必须定义以下方法来注册侦听器类。

public void addMyOwnComponentListener(MyOwnListener l1)

public void removeMyOwnListener(MyOwnListener l1)

public void MyOwnListener[] getMyOwnListeners()

JSF活动

JSF事件属于以下三类之一:

  • 动作事件
  • 值变化事件
  • 阶段事件

JSF动作事件

动作事件是为ui组件(如命令按钮或者命令超链接)生成的事件。
一个事件可以附加任意数量的侦听器。

考虑提交表单的示例。

如下所示创建一个JSF视图页面" mobile.xhtml"。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html">
<h:head>
	<title>Text fields</title>
</h:head>
<h:body>
	<h3>Mobile details</h3>
	<h:form>
		<h:panelGrid columns="3">
			<h:outputLabel for="mname">Company Name:</h:outputLabel>
			<h:inputText id="mname"></h:inputText>
			<br 
			<br 

			<h:outputLabel for="model">Model Number:</h:outputLabel>
			<h:inputText id="model"></h:inputText>
			<br 
			<br 
			<h:outputLabel for="color">Color:</h:outputLabel>
			<h:inputText id="color"></h:inputText>
			<br 
			<br 
			<h:commandButton value="Mobile Action Listener"
				actionListener="#{mobileActionListener.processAction}" 

		</h:panelGrid>
	</h:form>
</h:body>
</html>

其中我们定义属性" actionListener",调用" MobileActionListener"类的processAction方法。

创建MobileActionListener.java类为;

package com.theitroad.jsf.beans;

import javax.faces.FactoryFinder;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;

@ManagedBean
@SessionScoped
public class MobileActionListener implements ActionListener {

	public MobileActionListener() {
	}

	@Override
	public void processAction(ActionEvent ae) throws AbortProcessingException {

		UIComponent ui = ae.getComponent();

		System.out.println("Event source is" + ui.getClass().getName());

	}

	public void listAllPhaseListeners() {
		LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
				.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
		Lifecycle applicationLifecycle = lifecycleFactory
				.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

		PhaseListener phaseListeners[] = applicationLifecycle
				.getPhaseListeners();
		for (PhaseListener phaseListener : phaseListeners) {
			System.out.println(phaseListener.getPhaseId());
		}
	}

}

其中我们实现了ActionListener类,并覆盖了processAction方法。
在此方法内部,我们仅打印由用户调用的事件。
ui.getClass()。
getName()方法输出触发的动作事件。

在" faces-config.xml"文件中进行以下输入,以调用actionlistener类。

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
            xmlns="https://xmlns.jcp.org/xml/ns/javaee"
            xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

  <managed-bean>
	    <managed-bean-name>mobileActionListener</managed-bean-name>
	        <managed-bean-class>
	            com.theitroad.jsf.beans.MobileActionListener
	        </managed-bean-class>
	    <managed-bean-scope>request</managed-bean-scope>
	</managed-bean>

  
  <lifecycle>
  <phase-listener>
      com.theitroad.jsf.beans.CustomPhaseListener
  </phase-listener>
  
</lifecycle>
</faces-config>

受管Bean Mobile Action Listener类路径在faces-config.xml文件中指定。

现在运行该应用程序,并在浏览器中转到mobile.xhtml页面,然后单击提交按钮,这将在控制台中产生以下输出

Event source is javax.faces.component.html.HtmlCommandButton

由于提交按钮是触发的事件,因此该事件是CommandButton标记,与提交按钮相对应。

JSF价值变更事件

值更改事件是指UI组件的文本字段,单选按钮,列表框等。
值更改事件将在UI组件中更改后立即触发。
此事件的侦听器通常根据要求在字段上执行验证,以检查输入的值是否有效。

考虑下面的示例,该示例在列表框中更改值并显示新值

创建mobilevalue.xhtml为;

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html"
	xmlns:f="https://java.sun.com/jsf/core">
<h:head>
	<title>Value Change Event</title>
</h:head>
<h:body>
	<h3>Value Change Event Example</h3>
	<h:form>
		<h:panelGrid columns="3">

			<h:selectOneMenu id="name" value="#{mobileValueChangeListener.name}"
				onchange="submit()"
				valueChangeListener="#{mobileValueChangeListener.onSelectNames}">
				<f:selectItem itemValue="Nokia" itemLabel="Nokia" 
				<f:selectItem itemValue="Samsung" itemLabel="Samsung" 
				<f:selectItem itemValue="Blackberry" itemLabel="Blackberry" 
				<f:selectItem itemValue="Sony" itemLabel="Sony" 
				<f:selectItem itemValue="Mi3" itemLabel="Mi3" 

			</h:selectOneMenu>

		</h:panelGrid>
	</h:form>
	<br 
	<br 
	<h:outputText value="#{mobileValueChangeListener.result}"></h:outputText>
</h:body>
</html>

其中我们调用valueChangeListener属性,并调用MobileValueChangeListener bean的onSelectNames方法。

创建MobileValueChangeListener.javabean为;

package com.theitroad.jsf.beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;

@ManagedBean
@SessionScoped
public class MobileValueChangeListener {

	private String name;
	private String result;

	public String getName() {
		return name;
	}

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

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public MobileValueChangeListener() {
	}

	public void onSelectNames(ValueChangeEvent vc) {

		Object oval = vc.getOldValue();
		Object nval = vc.getNewValue();

		System.out.println("oval" + oval);
		System.out.println("nval" + nval);

		if (nval != null) {
			result = "Newly changed value is:" + (String) nval;

		}
	}

}

在onSelectNames方法中,我们通过getOldValue和getNewValue方法获取新值和旧值,并检查新值是否不等于null,如果为true,则将新值存储到结果变量中,并在JSF视图上显示此变量的值。
页。

现在,运行在更改列表框中的值时产生以下输出的应用程序。

JSF阶段事件

这种类型的事件涉及在每个阶段的开始或者结束时在JSF生命周期的六个阶段之一中触发的事件。

考虑一个通过创建CustomPhaseListener.java来捕获阶段事件的示例;

package com.theitroad.jsf.beans;

import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

public class CustomPhaseListener implements PhaseListener {

	private static final long serialVersionUID = -1395570878923714114L;

	@Override
	public void afterPhase(PhaseEvent pe) {
		System.out.println("After phase" + pe.getPhaseId());
	}

	@Override
	public void beforePhase(PhaseEvent pe) {

		System.out.println("Before phase" + pe.getPhaseId());
	}

	@Override
	public PhaseId getPhaseId() {

		return PhaseId.ANY_PHASE;
	}

}

创建一个JSF视图页面" phaseListener.xhtml"为;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:f="https://java.sun.com/jsf/core"
	xmlns:h="https://java.sun.com/jsf/html">

<h:head>
	<title>Phase Listener example</title>
</h:head>
<h:body>
	<h3>Phase Listener example</h3>
	<h:form>
		<h:inputText id="mname" 

		<h:commandButton id="button" value="Submit" 

		<h:messages 

	</h:form>
</h:body>
</html>

现在运行该应用程序,并在phaseListener页面上输入一些文本,然后单击Submit按钮。
检查服务器日志,并产生以下输出。

Before phase RESTORE_VIEW 1
After phase RESTORE_VIEW 1
Before phase APPLY_REQUEST_VALUES 2
After phase APPLY_REQUEST_VALUES 2
Before phase PROCESS_VALIDATIONS 3
After phase PROCESS_VALIDATIONS 3
Before phase UPDATE_MODEL_VALUES 4
After phase UPDATE_MODEL_VALUES 4
Before phase INVOKE_APPLICATION 5
After phase INVOKE_APPLICATION 5
Before phase RENDER_RESPONSE 6
After phase RENDER_RESPONSE 6

每个阶段的事件ID都打印在控制台中。