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.