I would like to know how to render a composite component, through Java,
I mean I have:
<myowntags:selectOneRadio>
<f:selectItem itemValue="value0" itemLabel="This is the value 0" />
<f:selectItem itemValue="value1" itemLabel="This is the value 1" />
<f:selectItem itemValue="value2" itemLabel="This is the value 2" />
</myowntags:selectOneRadio>
or
<myowntags:selectOneRadio>
<f:selectItems value="#{controller.items}" />
</myowntags:selectOneRadio>
and I would like to create a Java class to render it.
I know how to render a custom component without using composite, but since, to render a component I have to specify some values on the block:
<renderer>
<component-family>javax.faces.SelectBoolean</component-family>
<renderer-type>javax.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.CustomCheckboxRenderer</renderer-class>
</renderer>
then I get lost, because I don’t know the values of those parameters
inside the render tag for a composite component.
Thanks in advance,
Angel.
First, you need to have a backing component which implements
NamingContainerand returns"javax.faces.NamingContainer"as component family. This is required by composite components, you can’t change that part. TheUINamingContainerimplementation already does that, so if you can just extend from it.Or if you rather want to extend from
UISelectOne, then you’d have to implement theNamingContainerinterface and make sure that you returnUINamingContainer.COMPONENT_FAMILYin thegetFamily()override.Then, you need to specify it in
<cc:interface componentType>.Note that at this step you can already perform the rendering (encoding) through Java. Just override the
encodeChildren()method.Coming back to your concrete question, you’d thus like to have a standalone
Rendererclass for this. That’s fine. For that you need to extendRenderer:The backing component should be changed as follows in order to properly register this renderer as the default renderer (don’t override
getRendererType()method! otherwise you or anyone else would be unable to change this by<renderer>infaces-config.xml):Note that thanks to the
@FacesRenderer, you don’t need to hassle withfaces-config.xml.Whatever way you choose to encode the children, you can get component’s children just by
UIComponent#getChildren(). When you’re insideMySelectOneRadiocomponent:Or when you’re inside
MySelectOneRadioRendererrenderer:To delegate to the component’s own default rendering, invoke
super.encodeChildren()orcomponent.encodeChildren(). To delegate to child’s own default rendering, invokechild.encodeAll().See also: