Event HandlingWhen 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.
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.
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.
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.
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.
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.
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 ApplicationLet us create a test JSF application to test the system events in JSF.
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 |