Tuesday, February 17, 2015

Creating a java based custom component in JSF 2.2 - Simple example

In JSF 2.2 it is very easy to create java based custom components. In this tutorial I will show you how to do that.
The component which I am going to create can format the date you enter in to a given pattern.
After creating the component I hope to use it in my xhtml page as below.

<tl:date date="#{myBean.date}" pattern="yyyy-MM-dd">

This component has two attributes. The attribute "date" accepts java.util.Date type value. What my component does is it formats the date using the given pattern(the value entered in to the "pattern" attribute) and displays it on the page.
First I create a java class by extending javax.faces.component.UIComponentBase class. My java class represents the custom date component that I am going to create. This is the code of the class.

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

@FacesComponent(createTag=true, tagName="date", namespace="http://tech-lead.blogspot.com/tags")
public class Date extends UIComponentBase {

  @Override
  public String getFamily() {
    return "custom.component";
  }

  @Override
  public void encodeBegin(FacesContext context) throws IOException {
    java.util.Date date = (java.util.Date) getAttributes().get("date");
    if(date == null) return;
    
    String pattern = (String) getAttributes().get("pattern");
    ResponseWriter writer = context.getResponseWriter();
    
    if(pattern == null || pattern.isEmpty()) {
      writer.write(date.toString());
    } else {
      DateFormat dateFormat = new SimpleDateFormat(pattern);
      writer.write(dateFormat.format(date));
    }
  }
}

Most important points are described below.
@FacesComponent - This annotation is mandatory. This is needed to identify this class as a JSF component.
createTag - Without setting this as 'true' you can't use this component as a tag in xhtml page
tagName - This is the tag name of this component.(The name you use in xhtml page to refer to this component)
namespace - This is the namespace URI you used to import the tag lib which contains this component.
getFamily() - A family name for your components. You can return an arbitrary string here. Returning null may throws runtime exceptions in some JSF implementations.

That is all. The component is created. Now lets use it in our xhtml page.

This is my index.xhtml page.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:tl="http://tech-lead.blogspot.com/tags">

<h:head>
</h:head>
<body>
The date is <tl:date date="#{test.date}" pattern="yyyy-MM-dd" />.
</body>
</html>

This is my managed bean, MyBean.java
import java.util.Date;
import javax.faces.bean.ManagedBean;

@ManagedBean(name="myBean")
public class MyBean {
  private Date date = new Date();

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }
}

Start the application and point to index.jsf page. You will see the formatted date displayed on page.

1 comment:

  1. How do you create documentation for attributes in JSF 2.2 ?

    ReplyDelete