我正在构建自定义JSF复合组件以输入周期性。我有这个型号:
public class Periodicity implements Serializable {
private PeriodicityType type;
private Integer value = 0;
public PeriodicityExchange() {
super();
}
/**Getter and setters**/
}
其中PeriodicityType
是包含DAY
,WEEK
,MONTH
,YEAR
的枚举。
此模型的输入组件包含用于选择数值的p:spinner
元素和用于选择周期类型的h:selectOneMenu
。该组件运行良好,但现在我想要一个支持它的java类,所以我修改了我的facelet文件:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<composite:interface componentType="periodicityInput">
<composite:attribute name="value" type="model.Periodicity" />
</composite:interface>
<composite:implementation>
<div class="col-xs-2">
<p:spinner binding="#{cc.periodicityValue}"
value="#{cc.attrs.value.value}" min="0" />
</div>
<div class="col-xs-3">
<h:selectOneMenu binding="#{cc.periodicityType}"
value="#{cc.attrs.value.type}" styleClass="form-control">
<f:selectItem itemLabel="No periodicity" noSelectionOption="true" />
<f:selectItem itemLabel="Days" itemValue="DAY" />
<f:selectItem itemLabel="Weeks" itemValue="WEEK" />
<f:selectItem itemLabel="Months" itemValue="MONTH" />
<f:selectItem itemLabel="Years" itemValue="YEAR" />
</h:selectOneMenu>
</div>
</composite:implementation>
</html>
那是我的java类(基于this BalusC's tutorial)。它使用faces-config.xml文件注册为组件:
public class PeriodicityInput extends UIInput implements NamingContainer {
private UIInput periodicityValue;
private UIInput periodicityType;
@Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
}
@Override
protected Object getConvertedValue(FacesContext context, Object newSubmittedValue)
throws ConverterException {
try {
return new PeriodicityExchange(
Integer.parseInt(newSubmittedValue.toString().split("-")[0]),
newSubmittedValue.toString().split("-")[1]);
} catch (Exception ex) {
throw new ConverterException(ex);
}
}
public String getFamily() {
return COMPONENT_FAMILY;
}
public UIInput getPeriodicityType() {
return periodicityType;
}
public UIInput getPeriodicityValue() {
return periodicityValue;
}
@Override
public Object getSubmittedValue() {
return periodicityValue.getSubmittedValue() + "-" + periodicityType.getSubmittedValue();
}
public void setPeriodicityType(UIInput periodicityType) {
this.periodicityType = periodicityType;
}
public void setPeriodicityValue(UIInput periodicityValue) {
this.periodicityValue = periodicityValue;
}
}
问题是,只要我使用componentType
属性将我的组件绑定到java类,组件就会停止渲染。 encodeBegin
被调用,但进行了一些进一步的调试,我注意到当JSF尝试获取复合组件的渲染器时,它返回null。 getRenderer(FacesContext)
课程中的方法UIComponentBase
尝试访问context.getRenderKit().getRenderer(getFamily(), rendererType)
,其中家庭评估为javax.faces.Input
和rendererType
至javax.faces.Composite
。
我使用的是Mojarra 2.2.12。我在这里缺少什么?
答案 0 :(得分:3)
家庭评估为
javax.faces.Input
这不正确。它应该是javax.faces.NamingContainer
,UINamingContainer.COMPONENT_FAMILY
的常量值。
下面的COMPONENT_FAMILY
可能在使用静态导入进行重构时搞砸了:
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
上述内容实际上是从UIInput
继承的,但必须是UINamingContainer
。最好用FQN指定它。
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}