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.
Encoding:
For example: Suppose we have used h:inputText tag . So the renderer of the
component associated with this tag produces the following output:
<input type=”text” name=”ID”
value=”current_value”/>
This is called encoding. The encoded
page is sent to the browser and displayed.
Decoding:
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 <form> , is
written by encodeBegin() method and closing tage </form>,
is written by encodeEnd() method. Single tag, like <input>, 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.
<render-kit>
<renderer>
<renderer-type>........</renderer-type>
<renderer-class>........</renderer-class>
</renderer>
</render-kit>
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.
<render-kit>
<render-kit-id>...........</render-kit-id>
<render-kit-class>........</render-kit-class>
<renderer>
<renderer-type>.........</renderer-type>
<renderer-class>........</renderer-class>
</renderer>
</render-kit>
In this case, configuration file shows
how to register the renderer (for ex. ButtonRenderer) specified in <renderer-class>
which renders a component (for ex. Button) specified in <renderer-type>
to a client (for ex. SVG) specified in <render-kit-id>.
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.

|
Current Comments
1 comments so far (post your own) View All Comments Latest 10 Comments:In case you do not know the depth of the children components, rendering is tricky.
For example, You have a role and permissions inside it. One permission can be dependant on another and it may be on another.
You can recursively call the child components as:
encodeRecursive( context, childComp )
in the for loop where you are iterating the child components in your encodeBegin method of your ABCRenderer class.
I got this solution after lot of difficulties.
Hope this would help.
Posted by Gaurav Ashwin on Wednesday, 06.18.08 @ 11:20am | #63695