我想知道如何通过Java渲染复合组件, 我是说我有:
<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>
或
<myowntags:selectOneRadio>
<f:selectItems value="#{controller.items}" />
</myowntags:selectOneRadio>
我想创建一个Java类来渲染它。
我知道如何在不使用复合的情况下渲染自定义组件,但是因为要渲染组件,我必须在块上指定一些值:
<renderer>
<component-family>javax.faces.SelectBoolean</component-family>
<renderer-type>javax.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.CustomCheckboxRenderer</renderer-class>
</renderer>
然后我迷路了,因为我不知道那些参数的值 在复合组件的render标签内。
提前致谢, 天使。
答案 0 :(得分:12)
首先,您需要一个支持组件来实现NamingContainer
并返回"javax.faces.NamingContainer"
作为组件系列。这是复合组件所必需的,您无法更改该组件。 UINamingContainer
实现已经这样做了,所以如果你可以从中扩展它。
@FacesComponent("mySelectOneRadio")
public class MySelectOneRadio extends UINamingContainer {
// ...
}
或者如果您想要从UISelectOne
扩展,那么您必须实现NamingContainer
界面,并确保在getFamily()
覆盖中返回UINamingContainer.COMPONENT_FAMILY
然后,您需要在<cc:interface componentType>
中指定它。
<cc:interface componentType="mySelectOneRadio">
请注意,在此步骤中,您已经可以通过Java执行呈现(编码)。只需覆盖encodeChildren()
方法。
@FacesComponent("mySelectOneRadio")
public class MySelectOneRadio extends UINamingContainer {
@Override
public void encodeChildren(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", this);
writer.writeText("hello world", null);
writer.endElement("div");
}
}
回到你的具体问题,你希望有一个独立的Renderer
类。没关系。为此,您需要扩展Renderer
:
@FacesRenderer(componentFamily=UINamingContainer.COMPONENT_FAMILY, rendererType=MySelectOneRadioRenderer.RENDERER_TYPE)
public class MySelectOneRadioRenderer extends Renderer {
public static final String RENDERER_TYPE = "com.example.MySelectOneRadio";
@Override
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeText("hello world", null);
writer.endElement("div");
}
}
应该按如下方式更改支持组件,以便将此渲染器正确注册为默认渲染器(不要覆盖getRendererType()
方法!否则您或其他任何人将无法通过{{1}更改此设置在<renderer>
):
faces-config.xml
请注意,感谢@FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {
public MyComposite() {
// Set default renderer.
setRendererType(MySelectOneRadioRenderer.RENDERER_TYPE);
}
}
,您无需为@FacesRenderer
而烦恼。
无论您选择哪种方式对孩子进行编码,您都可以通过faces-config.xml
获得组件的子项。当你在UIComponent#getChildren()
组件内时:
MySelectOneRadio
或者当你在if (getChildCount() > 0) {
for (UICompnent child : getChildren()) {
// ...
}
}
渲染器内时:
MySelectOneRadioRenderer
要委派组件自己的默认呈现,请调用if (component.getChildCount() > 0) {
for (UICompnent child : component.getChildren()) {
// ...
}
}
或super.encodeChildren()
。要委托子级自己的默认呈现,请调用component.encodeChildren()
。