JSF - Creating a Custom Renderer as an output delegator of a Component

[Updated: Aug 24, 2017, Created: Aug 24, 2017]

This example demonstrates how to create and register a custom JSF Renderer.

A component class defines the state and behavior of a UI component, whereas a Renderer class separates the semantics of a component from its appearance. By keeping this separation, we can hook up different kind of rendering output without changing the UI components and the reset of the application logic.

Example

The Component

@FacesComponent(value = "GreetingComponent", createTag = true,
      tagName = "helloComponent", namespace = "http://example.com/tags")
public class HelloComponent extends UIComponentBase {

  public HelloComponent() {
      setRendererType("GreetingComponent");
  }

  @Override
  public String getFamily() {
      return "Greeting";
  }
}

The Renderer

@FacesRenderer(componentFamily = "Greeting", rendererType = "GreetingComponent")
public class GreetingRenderer extends Renderer {

  @Override
  public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
      Map<String, Object> attributes = component.getAttributes();
      String message = (String) attributes.get("message");
      LocalDateTime time = (LocalDateTime) attributes.get("time");
      String formattedTime = time.format(
              DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));

      ResponseWriter writer = context.getResponseWriter();
      writer.startElement("div", component);
      writer.write("Message: " + message);
      writer.endElement("div");

      writer.startElement("div", component);
      writer.write("Time: " + formattedTime);
      writer.endElement("div");
  }
}

View

src/main/webapp/index.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:t="http://example.com/tags">
<h:head></h:head>
<h:body>
    <h3>JSF Custom Component with Custom Renderer example</h3>
    <t:helloComponent message="#{helloBean.message}" time="#{helloBean.time}"/>
</h:body>
</html>

Managed Bean

@ManagedBean
@RequestScoped
public class HelloBean {

  public String getMessage() {
      return "Hi there!";
  }

  public LocalDateTime getTime() {
      return LocalDateTime.now();
  }
}

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

Example Project

Dependencies and Technologies Used :

  • jsf-api 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • jsf-impl 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • JDK 1.8
  • Maven 3.3.9

JSF Custom Component Select All Download
  • custom-component-and-renderer
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp

See Also