« Previous | 1 | 2 | 3 | Next »

Event Handling


When a user clicks a JSF button or link or changes any value in text field, JSF UI component fires event which will be handled by the the application code.
  • To handle such JSF event, event handler are to be registered in the application code or managed bean.
  • When a UI component checks that a user event has happened, it creates an instance of the corresponding event class and adds it to an event list.
  • Then, Component fires the event, i.e., checks the list of listeners for that event and call the event notification method on each listener or handler.
  • JSF also provide system level event handlers which can be used to do some tasks when application starts or is stopping.
Following are important Event Handler in JSF 2.0:
S.N.Event Handlers & Description
1valueChangeListene
Value change events get fired when user make changes in input components.
2actionListener
Action events get fired when user clicks on a button or link component.
3Application Events
Events firing during JSF lifecycle: PostConstructApplicationEvent, PreDestroyApplicationEvent , PreRenderViewEvent.
(1) valueChangeListener

When user interacts with input components, such as h:inputText or h:selectOneMenu, the JSF fires a valueChangeEvent which can be handled in two ways.
TechniqueDescription
Method BindingPass the name of the managed bean method in valueChangeListenerattribute of UI Component.
ValueChangeListenerImplement ValueChangeListener interface and pass the implementation class name to valueChangeListener attribute of UI Component.
Method Binding

Define a method

public void localeChanged(ValueChangeEvent e){
//assign new value to country
selectedCountry = e.getNewValue().toString();
}

Use above method

<h:selectOneMenu value="#{userData.selectedCountry}" onchange="submit()"
valueChangeListener="#{userData.localeChanged}" >
<f:selectItems value="#{userData.countries}" />
</h:selectOneMenu>

ValueChangeListener

Implement ValueChangeListener

public class LocaleChangeListener implements ValueChangeListener {
@Override
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
//access country bean directly
UserData userData = (UserData) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("userData");
userData.setSelectedCountry(event.getNewValue().toString());
}
}

Use listener method

<h:selectOneMenu value="#{userData.selectedCountry}" onchange="submit()">
<f:valueChangeListener type="com.javatechnologycenter.test.LocaleChangeListener"
/>
<f:selectItems value="#{userData.countries}" />
</h:selectOneMenu>

Example Application

Let us create a test JSF application to test the valueChangeListener in JSF.
StepDescription
1Create a project with a name helloworld under a package com.javatechnologycenter.test as explained in the JSF - First Application chapter.
2Modify UserData.java file as explained below.
3Create LocaleChangeListener.java file under a package com.javatechnologycenter.test.Modify it as explained below
4Modify home.xhtml as explained below. Keep rest of the files unchanged.
5Compile and run the application to make sure business logic is working as per the requirements.
6Finally, build the application in the form of war file and deploy it in Apache Tomcat Webserver.
7Launch your web application using appropriate URL as explained below in the last step.

UserData.java

package com.javatechnologycenter.test;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
private static final long serialVersionUID = 1L;
private static Map<String,String> countryMap;
private String selectedCountry = "United Kingdom"; //default value
static{
countryMap = new LinkedHashMap<String,String>();
countryMap.put("en", "United Kingdom"); //locale, country name
countryMap.put("fr", "French");
countryMap.put("de", "German");
}
public void localeChanged(ValueChangeEvent e){
//assign new value to country

selectedCountry = e.getNewValue().toString();
}
public Map<String, String> getCountries() {
return countryMap;
}
public String getSelectedCountry() {
return selectedCountry;
}
public void setSelectedCountry(String selectedCountry) {
this.selectedCountry = selectedCountry;
}
}

LocaleChangeListener.java

package com.javatechnologycenter.test;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
public class LocaleChangeListener implements ValueChangeListener {
@Override
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
//access country bean directly
UserData userData = (UserData) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("userData");
userData.setSelectedCountry(event.getNewValue().toString());
}
}

home.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSF tutorial</title>
</h:head>
<h:body>
<h2>valueChangeListener Examples</h2>
<h:form>
<h2>Method Binding</h2>
<hr/>
<h:panelGrid columns="2">
Selected locale :
<h:selectOneMenu value="#{userData.selectedCountry}"
onchange="submit()"
valueChangeListener="#{userData.localeChanged}" >
<f:selectItems value="#{userData.countries}" />
</h:selectOneMenu>
Country Name:
<h:outputText id="country" value="#{userData.selectedCountry}"
size="20" />
</h:panelGrid>
</h:form>
</h:body>
</html>

Once you are ready with all the changes done, let us compile and run the application as we did in JSF - First Application chapter. If everything is fine with your application, this will produce following result:

Select locale. You will see the following result.

Modify home.xhtml again in deployed directory where you've deployed the application as explained below. Keep rest of the files unchanged.

home.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSF tutorial</title>
</h:head>
<h:body>
<h2>valueChangeListener Examples</h2>
<h:form>
<h2>ValueChangeListener interface</h2>
<hr/>
<h:panelGrid columns="2">
Selected locale :
<h:selectOneMenu value="#{userData.selectedCountry}"
onchange="submit()">
<f:valueChangeListener
type="com.javatechnologycenter.test.LocaleChangeListener" />
<f:selectItems value="#{userData.countries}" />
</h:selectOneMenu>
Country Name:
<h:outputText id="country1" value="#{userData.selectedCountry}"
size="20" />
</h:panelGrid>
</h:form>
</h:body>
</html>

Once you are ready with all the changes done, refresh the page in browser. If everything is fine with your application, this will produce following result:

Select locale. You will see the following result.

(2) actionListener

When user interacts with components, such as h:commandButton or h:link, the JSF fires a action events which can be handled in two ways.
TechniqueDescription
Method BindingPass the name of the managed bean method in actionListener attribute of UI Component.
ActionListenerImplement ActionListener interface and pass the implementation class name to actionListener attribute of UI Component.
Method Binding

Define a method

public void updateData(ActionEvent e){
data="Hello World";
}

Use above method

<h:commandButton id="submitButton"
value="Submit" action="#{userData.showResult}"
actionListener="#{userData.updateData}" />
</h:commandButton>

ActionListener

Implement ActionListener

public class UserActionListener implements ActionListener{
@Override
public void processAction(ActionEvent arg0)
throws AbortProcessingException {
//access userData bean directly
UserData userData = (UserData) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("userData");
userData.setData("Hello World");
}
}

Use listener method

<h:commandButton id="submitButton1"
value="Submit" action="#{userData.showResult}" >
<f:actionListener type="com.javatechnologycenter.test.UserActionListener" />
</h:commandButton>

Example Application

Let us create a test JSF application to test the actionListener in JSF.

StepDescription
1Create a project with a name helloworld under a package com.javatechnologycenter.test as explained in the JSF - First Application chapter.
2Modify UserData.java file as explained below.
3Create UserActionListener.java file under a package com.javatechnologycenter.test.Modify it as explained below
4Modify home.xhtml as explained below. Keep rest of the files unchanged.
5Modify result.xhtml as explained below. Keep rest of the files unchanged.
6Compile and run the application to make sure business logic is working as per the requirements.
7Finally, build the application in the form of war file and deploy it in Apache Tomcat Webserver.
8Launch your web application using appropriate URL as explained below in the last step.

UserData.java

package com.javatechnologycenter.test;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
private static final long serialVersionUID = 1L;
private static Map<String,String> countryMap;
private String data = "sample data";
public String showResult(){
return "result";
}
public void updateData(ActionEvent e){
data="Hello World";
}
public String getData() {
return data; }
public void setData(String data) {
this.data = data;
}
}

UserActionListener.java

package com.javatechnologycenter.test;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class UserActionListener implements ActionListener{
@Override
public void processAction(ActionEvent arg0)
throws AbortProcessingException {
//access userData bean directly
UserData userData = (UserData) FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().get("userData");
userData.setData("Hello World");
}
}

home.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSF tutorial</title>
</h:head>
<h:body>
<h2>actionListener Examples</h2>
<h:form>
<h2>Method Binding</h2>
<hr/>
<h:commandButton id="submitButton"
value="Submit" action="#{userData.showResult}"
actionListener="#{userData.updateData}" />
</h:commandButton>
<h2>ActionListener interface</h2>
<hr/>
<h:commandButton id="submitButton1"
value="Submit" action="#{userData.showResult}" >
<f:actionListener
type="com.javatechnologycenter.test.UserActionListener" />
</h:commandButton>
</h:form>
</h:body>
</html>

result.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>JSF Tutorial!</title>
</h:head>
<h:body>
<h2>Result</h2>
<hr />
#{userData.data}
</h:body>
</html>

Once you are ready with all the changes done, let us compile and run the application as we did in JSF - First Application chapter. If everything is fine with your application, this will produce following result:

Click on any submit button. You will see the following result.

(3) Application Events

JSF provides system event listeners to do application specific tasks during JSF application Life Cycle.
System EventDescription
PostConstructApplicationEventFires when application starts.Can be used to perform initialization tasks after application has started.
PreDestroyApplicationEventFires when application is about to shut down.Can be used to perform a cleanup tasks before application is about to be shut down.
PreRenderViewEventFires before a JSF page is to be displayed. Can be used to authenticate user and provide restricted access to JSF View.
System Events which can be handled in following manner.
TechniqueDescription
SystemEventListenerImplement SystemEventListener interface and register the system-event-listener class in faces-config.xml
Method BindingPass the name of the managed bean method in listener attribute of f:event.
SystemEventListener

Implement SystemEventListener Interface

public class CustomSystemEventListener implements SystemEventListener {
@Override
public void processEvent(SystemEvent event) throws
AbortProcessingException {
if(event instanceof PostConstructApplicationEvent){
System.out.println("Application Started.
PostConstructApplicationEvent occurred!");
}
}
}

Register custom system event listener for system event in faces-config.xml

<system-event-listener>
<system-event-listener-class>
com.javatechnologycenter.test.CustomSystemEventListener
</system-event-listener-class>
<system-event-class>
javax.faces.event.PostConstructApplicationEvent
</system-event-class>
</system-event-listener>

Method Binding

Define a method

public void handleEvent(ComponentSystemEvent event){
data="Hello World";
}

Use above method

<f:event listener="#{user.handleEvent}" type="preRenderView" />
Example Application

Let us create a test JSF application to test the system events in JSF.
StepDescription
1Create a project with a name helloworld under a package com.javatechnologycenter.test as explained in the JSF - First Application chapter.
2Modify UserData.java file as explained below.
3Create CustomSystemEventListener.java file under a package com.javatechnologycenter.test.Modify it as explained below
4Modify home.xhtml as explained below.
5Create faces-config.xml in WEB-INF folder.Modify it as explained below. Keep rest of the files unchanged.
6Compile and run the application to make sure business logic is working as per the requirements.
7Finally, build the application in the form of war file and deploy it in Apache Tomcat Webserver.
8Launch your web application using appropriate URL as explained below in the last step.
UserData.java

package com.javatechnologycenter.test;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ComponentSystemEvent;
@ManagedBean(name = "userData", eager = true)
@SessionScoped
public class UserData implements Serializable {
private static final long serialVersionUID = 1L;
private String data = "sample data";
public void handleEvent(ComponentSystemEvent event){
data="Hello World";
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

CustomSystemEventListener.java

package com.javatechnologycenter.test;
import javax.faces.application.Application;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PostConstructApplicationEvent;
import javax.faces.event.PreDestroyApplicationEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
public class CustomSystemEventListener implements SystemEventListener {
@Override
public boolean isListenerForSource(Object value) {
//only for Application
return (value instanceof Application);
}
@Override
public void processEvent(SystemEvent event)
throws AbortProcessingException {
if(event instanceof PostConstructApplicationEvent){
System.out.println("Application Started.
PostConstructApplicationEvent occurred!");
}
if(event instanceof PreDestroyApplicationEvent){
System.out.println("PreDestroyApplicationEvent occurred.
Application is stopping.");
}
}
}

home.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>JSF tutorial</title>
</h:head>
<h:body>
<h2>Application Events Examples</h2>
<f:event listener="#{userData.handleEvent}" type="preRenderView" />
#{userData.data}
</h:body>
</html>

faces-config.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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-facesconfig_2_0.xsd"
version="2.0">
<application>
<!-- Application Startup -->
<system-event-listener>
<system-event-listener-class>
com.javatechnologycenter.test.CustomSystemEventListener
</system-event-listener-class>
<system-event-class>
javax.faces.event.PostConstructApplicationEvent
</system-event-class>
</system-event-listener>
<!-- Before Application is to shut down -->
<system-event-listener>
<system-event-listener-class>
com.javatechnologycenter.test.CustomSystemEventListener
</system-event-listener-class>
<system-event-class>
javax.faces.event.PreDestroyApplicationEvent
</system-event-class>
</system-event-listener>
</application>
</faces-config>

Once you are ready with all the changes done, let us compile and run the application as we did in JSF - First Application chapter. If everything is fine with your application, this will produce following result:

Look into your web-server console output. You will see the following result.

INFO: Deploying web application archive helloworld.war
Dec 6, 2012 8:21:44 AM com.sun.faces.config.ConfigureListener contextInitialized
INFO: Initializing Mojarra 2.1.7 (SNAPSHOT 20120206) for context '/helloworld'
Application Started. PostConstructApplicationEvent occurred!
Dec 6, 2012 8:21:46 AM com.sun.faces.config.ConfigureListener
$WebConfigResourceMonitor$Monitor <init>
INFO: Monitoring jndi:/localhost/helloworld/WEB-INF/faces-config.xml
for modifications
Dec 6, 2012 8:21:46 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Dec 6, 2012 8:21:46 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Dec 6, 2012 8:21:46 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/24 config=null
Dec 6, 2012 8:21:46 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 44272 ms
« Previous | 1 | 2 | 3 | Next »


copyright © 2014 - all rights riserved by javatechnologycenter.com