logo
Home Tutorial

How To Create Your Own Java Server Faces Components



In this step, we set up our component with the look and feel we mentioned in the first step. Additionally, we assign a couple new attributes: width and height. It will be more convenient to define the value directly rather then use the style attribute. If you define width and height in the style and add width and height attributes for the custom tag at the same time, the attributes will overwrite the values defined with the style.

Add width and height attribute to the ticker.tld file. Here is the final version of it:

<?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>
  <attribute>
   <name>id</name>
  </attribute>
  <attribute>
   <name>rendered</name>
  </attribute>
  <attribute>
   <name>title</name>
  </attribute>
  <attribute>
   <name>binding</name>
  </attribute>
  <attribute>
   <name>width</name>
  </attribute>
  <attribute>
   <name>height</name>
  </attribute>
 </tag>
</taglib>

Add the code marked with bold to the TickerTag.java file:

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


public class TickerTag extends UIComponentTag{
	String style;
	String styleClass;
	String title;
	String width;
	String height;
	
	public String getHeight() {
		return height;
	}

	public void setHeight(String height) {
		this.height = height;
	}

	public String getWidth() {
		return width;
	}

	public void setWidth(String width) {
		this.width = width;
	}
	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 String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	
	public void release() {
		// the super class method should be called 
		super.release();
		style = null ;
		styleClass = null ;
		title = null;
		height = null;
		width = 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);

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

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

		if (title != null) {
			if (isValueReference(title)) {
				ValueBinding vb =
					getFacesContext().getApplication().
						createValueBinding(title);
					component.setValueBinding("title", vb);
			} else {
				component.getAttributes().put("title", title);
			}
		}
	}

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

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

}

This is a final version of the UITicker.java file:

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);

	    writer.writeAttribute("id", getClientId(context), null);
	    
	    String width = (String)getAttributes().get("width");
	    String height = (String)getAttributes().get("height");
	    
	    String style = (String)getAttributes().get("style");
	    
	    style= (style!=null) ? style + ";" : "";
	    
	    if (width  != null) style += "width:" + width + ";";
	    if (height != null) style += "height:" + height+ ";";
	    
	    writer.writeAttribute("style", style, null);

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

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

The HTML <div> tag itself does not have the width and height attributes. So, we use a little trick here. We add the width and height to the tail of the style attribute. If style attribute does not exist we create it.

This is a final version of the bannerpage.jsp file:

<%@ 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" %>
<f:loadBundle basename="demo.resources" var="bundle" />
<html>
  <head>
    <title>Show Custom Component</title>
    <style>
       .banner {
       border: 1px solid darkblue;
       padding: 5px 5px 5px 5px;
       overflow: auto;
       }
    </style>	
  </head>
  <body>
    <f:view>
      <h:form>
        <h:commandButton value="Turn Off" action="#{BannerPageBean.TurnOff}"/>
        <h:commandButton value="Turn On" action="#{BannerPageBean.TurnOn}"/>

        <d:ticker 	id="banner"
		width="300px"
         		height="200px"
         		styleClass="banner"
         		title="#{bundle.banner_title}"
         		binding="#{BannerPageBean.ticker}">

          <h:panelGrid columns="1">
            <h:outputText value="Introduction"/>
            <h:outputText value="Build Instruction"/>
            <h:outputText value="Building Components Tips"/>
            <h:outputText value="Step 1: Components Skeleton"/>
            <h:outputText value="Step 2: Adding Simple Attributes"/>
            <h:outputText value="Step 3: Adding JSF Support Attributes"/>
            <h:outputText value="Step 4: Attribute Binding"/>
            <h:outputText value="Step 5: Component Binding"/>
            <h:outputText value="Step 6: Final Version"/>
            <h:outputText value="Step 7: Creating Deployable jar File"/>
            <h:outputText value="What next?"/>	  	  
          </h:panelGrid>
			  
        </d:ticker>
      </h:form>
    </f:view>
  </body>	
</html>  

We have added the "overflow: auto" to the style class to make our text area scrollable, replaced a style attribute with the two size attributes and, finally, replaced the text greeting message with something new one. You can put any other code here if you want.

Run and test the application. It should show the scrollable text area with the dark blue border around it. If you see this, you have successfully passed the tutorial. We have only one more question to answer: How to distribute what we have done? We will dedicate the last step to this question.

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).