JSF无法获得自定义复合输入组件的渲染器

时间:2016-09-07 10:49:04

标签: jsf jsf-2 composite-component

我正在构建自定义JSF复合组件以输入周期性。我有这个型号:

public class Periodicity implements Serializable {

    private PeriodicityType type;

    private Integer value = 0;

    public PeriodicityExchange() {
        super();
    }

    /**Getter and setters**/

}

其中PeriodicityType是包含DAYWEEKMONTHYEAR的枚举。

此模型的输入组件包含用于选择数值的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.InputrendererTypejavax.faces.Composite

我使用的是Mojarra 2.2.12。我在这里缺少什么?

1 个答案:

答案 0 :(得分:3)

  

家庭评估为javax.faces.Input

这不正确。它应该是javax.faces.NamingContainerUINamingContainer.COMPONENT_FAMILY的常量值。

下面的COMPONENT_FAMILY可能在使用静态导入进行重构时搞砸了:

@Override
public String getFamily() {
    return COMPONENT_FAMILY;
}

上述内容实际上是从UIInput继承的,但必须是UINamingContainer。最好用FQN指定它。

@Override
public String getFamily() {
    return UINamingContainer.COMPONENT_FAMILY;
}