Home | Download | PDF | API | FAQ | Search | Feedback | History

> ## Implementing an Event Listener

> As explained in Event and Listener Model (page 290), JavaServer Faces technology supports action events and value-change events.

> Action events occur when the user activates a component that implements `ActionSource`. These events are represented by the `javax.faces.event.ActionEvent` class.

> Value-change events occur when the user changes the value of a component that implements `EditableValueHolder`. These events are represented by the `javax.faces.event.ValueChangeEvent` class.

> One way to handle these events is to implement the appropriate listener classes. Listener classes that handle the action events in an application must implement `javax.faces.event.ActionListener`. Similarly, listeners that handle the value-change events must implement `javax.faces.event.ValueChangeListener`.

> This section explains how to implement the two listener classes.

> If you need to handle events generated by custom components, you must implement an event handler and manually queue the event on the component as well as implement an event listener. See Handling Events for Custom Components (page 439) for more information.

> Note: You need not create an `ActionListener` implementation to handle an event that results solely in navigating to a page and does not perform any other application-specific processing. See Writing a Method to Handle Navigation for information on how to manage page navigation.

> ### Implementing Value-Change Listeners

> A `ValueChangeListener` implementation must include a `processValueChange(ValueChangeEvent)` method. This method processes the specified value-change event and is invoked by the JavaServer Faces implementation when the value-change event occurs. The `ValueChangeEvent` instance stores the old and the new values of the component that fired the event.

> The `NameChanged` listener implementation is registered on the `name` `UIInput` component on the `bookcashier.jsp` page. This listener stores into session scope the name the user entered in the text field corresponding to the `name` component. When the `bookreceipt.jsp` page is loaded, it displays the first name inside the message:

>     "Thank you, {0} for purchasing your books from us."

> Here is part of the `NameChanged` listener implementation:

>     ...
>     public class NameChanged extends Object implements
>       ValueChangeListener {

>        public void processValueChange(ValueChangeEvent event)
>         throws AbortProcessingException {

>         if (null != event.getNewValue()) {
>             FacesContext.getCurrentInstance().
>             getExternalContext().getSessionMap().
>               put("name", event.getNewValue());
>         }
>       }
>     }

> When the user enters the name in the text field, a value-change event is generated, and the `processValueChange(ValueChangeEvent)` method of the `NameChanged` listener implementation is invoked. This method first gets the ID of the component that fired the event from the `ValueChangeEvent` object. Next, it puts the value, along with an attribute name, into the session map of the `FacesContext` instance.

> Registering a Value-Change Listener on a Component (page 356) explains how to register this listener onto a component.

> ### Implementing Action Listeners

> An `ActionListener` implementation must include a `processAction(ActionEvent)` method. The `processAction(ActionEvent)` method processes the specified action event. The JavaServer Faces implementation invokes the `processAction(ActionEvent)` method when the `ActionEvent` occurs.

> The Duke's Bookstore application does not use any `ActionListener` implementations. Instead, it uses method expressions from `actionListener` attributes to refer to backing bean methods that handle events. This section explains how to turn one of these methods into an `ActionListener` implementation.

> The `chooselocale.jsp` page allows the user to select a locale for the application by clicking on one of a set of hyperlinks. When the user clicks one of the hyperlinks, an action event is generated, and the `chooseLocaleFromLink(ActionEvent)` method of `LocaleBean` is invoked. Instead of implementing a bean method to handle this event, you can create a listener implementation to handle it. To do this, you do the following:

> - Move the `chooseLocaleFromLink(ActionEvent)` method to a class that implements `ActionListener`
> - Rename the method to `processAction(ActionEvent)`

> The listener implementation would look something like this:

>     ...
>     public class LocaleChangeListener extends Object implements
>       ActionListener {

>       private HashMap<String, Locale> locales = null;

>       public LocaleChangeListener() {
>         locales = new HashMap<String, Locale>(4);
>         locales.put("NAmerica", new Locale("en", "US"));
>         locales.put("SAmerica", new Locale("es", "MX"));
>         locales.put("Germany", new Locale("de", "DE"));
>         locales.put("France", new Locale("fr", "FR"));
>       }

>       public void processAction(ActionEvent event)
>         throws AbortProcessingException {

>         String current = event.getComponent().getId();
>         FacesContext context = FacesContext.getCurrentInstance();
>         context.getViewRoot().setLocale((Locale)
>         locales.get(current));
>       }
>     }

> Registering an Action Listener on a Component (page 357) explains how to register this listener onto a component.