logo
Home Tutorial

How To Create Your Own Java Server Faces Components



This step is devoted to adding attributes to our custom tag. As we mentioned for the first step, tag <div> does not provide any visible effect. So, in the second step, we will add attributes that make more visible results. Commonly, visual Java Server Faces tags define the tag style directly with style and styleClass attributes or indirectly by using the Cascading Style Sheet file.

Let’s start with the style attribute. Add it to the JSP page. The JSP page will look like this:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jsftutorials.com/" prefix="d" %>
<html>
	<head>
		<title>Show Custom Component</title>
	</head>
	<body>
	  <f:view>
	    <d:ticker style="border:1px solid darkblue;width:100px">
	      <f:verbatim>Hello JSF Component</f:verbatim>
	    </d:ticker>
	  </f:view>
	</body>	
</html>

Add the tag attribute to the ticker.tld file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
 <tlib-version>1.0</tlib-version>
 <jsp-version>1.2</jsp-version>
 <short-name>d</short-name>
 <uri>http://jsftutorials.com/</uri>
 <tag>
  <name>ticker</name>
  <tag-class>ticker.TickerTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>style</name>
  </attribute>
</tag>
</taglib>

Add the following code marked with bold to the TickerTag class:

package ticker;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;


public class TickerTag extends UIComponentTag{
	String style;
	
	public String getStyle() { 
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}


	public void release() {
		// the super class method should be called
		super.release();
		style = null ;
	}
	
	protected void setProperties(UIComponent component) {
		// the super class method should be called 
		super.setProperties(component);

		if(style != null)
			component.getAttributes().put("style", style);

	}

	public String getComponentType() {
		return "ticker";
	}

	public String getRendererType() {
		// null means the component renders itself
		return null;
	}

}

First, we have added a new property with the name style and provided the getter and setter for it. Then, we reset the property in the release() method. Finally, we have set the new value for the component property in the setProperties(UIComponent component) method. The last step is important. If you forget to do so, you cannot get to the value in the component type class later on.

Add the code marked with bold to the ticker.UITicker class:

package ticker;
import java.io.IOException;


import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;


public class UITicker extends UIOutput {
	
	public void encodeBegin(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
	    writer.startElement("div", this);

	    String style = (String)getAttributes().get("style");
	    if (style!=null)
	    	writer.writeAttribute("style", style, null);
	}

	public void encodeEnd(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
	    writer.endElement("div");
	}
}

In the first added line, we have taken the value of the style attribute, checked if it’s set, and then assigned the style attribute with the new value. Do not forget to check for null, otherwise you will get a NullPointer Exception when a tag without this attribute set is rendered.

Now, we are done with the style attribute. If you use JSF Studio just click the Run Web Application button to get a result. If you are using an Ant script, run it, deploy the result war file under the servlet container, then launch your browser and type the application URL.

The result page should see the box with dark blue border and the Hello JSF Component text inside this box.

Adding the styleClass component is very similar to what we did for style. Here is a bannerpage.jsp content:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jsftutorials.com/" prefix="d" %>
<html>
	<head>
		<title>Show Custom Component</title>
		<style>
		   .banner {
			   border: 1px solid darkblue;
			   padding: 5px 5px 5px 5px;
		   }
		</style>	
	</head>
	<body>
	  <f:view>
	    <d:ticker styleClass="banner" style="width:100px">
	      <f:verbatim>Hello JSF Component</f:verbatim>
	    </d:ticker>
	  </f:view>
	</body>	
</html>

This is the ticker.tld file content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
 <tlib-version>1.0</tlib-version>
 <jsp-version>1.2</jsp-version>
 <short-name>d</short-name>
 <uri>http://jsftutorials.com/</uri>
 <tag>
  <name>ticker</name>
  <tag-class>ticker.TickerTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>style</name>
  </attribute>
  <attribute>
   <name>styleClass</name>
  </attribute>
 </tag>
</taglib>

This is the TickerTag.java class content:

package ticker;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;


public class TickerTag extends UIComponentTag{
	String style;
	String styleClass;
	
	public String getStyle() { 
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}

	public String getStyleClass() {
		return styleClass;
	}

	public void setStyleClass(String styleClass) {
		this.styleClass = styleClass;
	}

	public void release() {
		// the super class method should be called
		super.release();
		style = null ;
		styleClass = null ;
	}
	
	protected void setProperties(UIComponent component) {
		// the super class method should be called 
		super.setProperties(component);

		if(style != null)
			component.getAttributes().put("style", style);

		if(styleClass != null)
			component.getAttributes().put("styleClass", styleClass);
		
	}

	public String getComponentType() {
		return "ticker";
	}

	public String getRendererType() {
		// null means the component renders itself
		return null;
	}

}

This is the UITicker.java file content:

package ticker;
import java.io.IOException;


import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;


public class UITicker extends UIOutput {
	
	
	public void encodeBegin(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
	    writer.startElement("div", this);

	    String style = (String)getAttributes().get("style");
	    if (style!=null)
	    	writer.writeAttribute("style", style, null);

	    String styleClass = (String)getAttributes().get("styleClass");
	    if (styleClass!=null)
	    	writer.writeAttribute("class", styleClass, null);
	}

	public void encodeEnd(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
	    writer.endElement("div");
	}
}

Now, step 2 is done. Run the resulting application. The browser window should show the bordered box with the Hello JSF Component text inside. Unlike the previous run, you will see 5 pixels of space between the text and the border.

See Also:

Guidelines for Designing Reusable Custom Components Using JavaServer Faces Technology


This article gives you some basic guidelines for designing
custom components using ChartComponent as an example.


Creating JSF Custom Components by Bill Dudney


This article illustrates how to build custom components for use
in web applications based on JavaServer Faces (JSF).