Monday, August 18, 2008

JSF Renderers

After creating JSF components, it is also necessary for each component to be rendered to the client so that it can be visible to the client’s device. Each of the tag gives rise to an associated component. A renderer is a type of class that is responsible for encoding and decoding components. Encoding displays the component while decoding translates the user’s input into components value i.e. transform it into values the component can understand.

Now a days there are many devices that are web enabled. So application developers have challenge to develop components that can work across various platforms. For example, if we have an application that works on standard web browser and we want to extend it to make it enable to work on a WAP device. So, to handle this case we need components to be rendered in more than one way. Here JSF can help you . It is a simple task for JSF. Solution is to develop separate renderers for the component. JSF components use different renderers depending on the device used.

For example: Suppose we have used h:inputText tag . So the renderer of the component associated with this tag produces the following output:

This is called encoding. The encoded page is sent to the browser and displayed.

Now if fields in form are filled by user and page is submitted by clicking the button, the browser sends the form data to the web server as a “POST” request”. POST” request contains form data and URL of the form. This form data is placed in hash table and can be accessed by all components. Each component gets a chance to look that hash table to interpret the form data. This is called decoding.

Html output Tag handler asks each component to render itself. Tag handler call two rendering methods for each component :

1-encodeBegin() in doStartTag() and

2-encodeEnd() in doEndTag().

Opening tag, like

, is written by encodeBegin() method and closing tage
, is written by encodeEnd() method. Single tag, like , that dosen’t require separate opening and closing tag is also written by encodeEnd() method.

JSF tag handler may call third rendering method encodeChildren().if rendersChilden property of component is set to true i.e. if component has child components(compound component). For example: Html table component composed of input field components as column values for each row. So for a complex component tag handler calls encodeBegin(), then encodeChildren() and encodeEnd() on the component.If the child component also has its own children component then encodeChildren() method calls encodeBegin() and encodeEnd() on the child component.

Some components renders itself (Direct rendering) and some components uses renderer to render itself (Delegated rendering). So both are different. If component uses renderer, then JSF calls encoding methods of the renderer, not the encoding method of the component. Which renderer will be used is determined by getRenderer() method of the component. So rendering of UI components is separated out that makes it pluggable with other possible rendering i.e.if we want a new functionality, like a new look and feel or rendering output to different client types, then its easy to add or plug a new renderer.

Render kit :
Component classes generally transfer the task of generating output to the renderer. All JSF components follow it. Render kit is a set of related renderers. javax.faces.render.RenderKit is the class which represents the render kit.The default render kit contains renderers for html but it’s up to you to make it for other markup languages.Render kit can implement a skin (a look & feel).Render kit can target a specific device like phone, PC or markup language like HTML,WML, SVG. This is one of the best benefit of JSF because JSF doesn't limit to any device or markup.

Sometimes we may wish to customize the renderers of an existing RenderKit and sometimes create our own RenderKit. We typically create renderers for our custom components.In this case we have to register renderers with existing RenderKits in JSF configuration file faces-config.xml.This renderer should define renderer-type of the original component. Also, you should provide the renderer-class that points to your custom renderer. The renderer class should extend javax.faces.render.Renderer class.


The information mentioned in configuration file registers the renderer with the default html RenderKit. UI component's geRendererType() method is called that returns a string to identify the type of renderer that would be used by component and to see if it should delegate rendering to a renderer. If no matching render type is found then component renders itself without delegating to any renderer.



In this case, configuration file shows how to register the renderer (for ex. ButtonRenderer) specified in which renders a component (for ex. Button) specified in to a client (for ex. SVG) specified in .

Standard render kits:
JSF defines a standard RenderKit and set of associated Renderers that generate html markup. Renderer will be determined and handled automatically according to the tag used.


No comments: