JSF Component listener with @ListenerFor

This tutorial shows how to add a listener to a component using the @ListenerFor and @ListenersFor annotation. The @ListenerFor annotation allows a component to subscribe to particular events with the component itself being the listener. For this we need to do the following:

  1. Implement the ComponentSystemEventListener interface. The UIComponent implements this interface, so all components that extend from UIComponent are automatically eligible for receiving component system events.
  2. Override the processEvent method. We can use this method to process the incoming event.
  3. Use the @ListenerFor and/or @ListenersFor annotations to indicate the event that the component will listen for (by registering the source class of the event).

Component Listener with @ListenersFor and @ListenerFor

Our MyOutput component extends from UIOutput, which extends from UIComponent. This makes our class eligible for handling ComponentSystemEvents. We register two system events by annotating the class with the wrapper @ListenersFor annotation, which has 2 @ListenerFor annotations describing which system events to listen for. We listen for a PostAddToViewEvent and the PostConstructViewMapEvent. Finally, we simply process the event by printing some standard text to the console.

package com.memorynotfound.jsf;

import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.*;
import java.io.IOException;

@FacesComponent(value = "com.memorynotfound.myOutput", createTag = true,
        tagName = "myOutput", namespace = "http://memorynotfound.com/component-listener")
@ListenersFor({
        @ListenerFor(systemEventClass=PostAddToViewEvent.class),
        @ListenerFor(systemEventClass=PostConstructViewMapEvent.class)
})
public class MyOutput extends UIOutput {

    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
        super.processEvent(event);
        System.out.println("process event - " + event.toString());
    }

    @Override
    public void encodeEnd(FacesContext context) throws IOException {
        ResponseWriter responseWriter = context.getResponseWriter();
        responseWriter.write((String)getValue());
    }

}

Using JSF Component with the listener

We can use our component in the HTML.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:custom="http://memorynotfound.com/component-listener">
<h:body>

    <h2>JSF Custom Component Event Listener</h2>
    <custom:myOutput value="JSF Custom Component Event Listener"/>

</h:body>
</html>

Generated Output

When the page is accessed, the following output is printed to the console.

process event - javax.faces.event.PostAddToViewEvent[[email protected]]
process event - javax.faces.event.PostAddToViewEvent[[email protected]]

Demo

URL: http://localhost:8081/jsf-component-listener/

jsf component listener @ListenersFor

References

Download

You may also like...