Jsf 2 为什么可以';设置f:selectItems in encodeBegin in composite component?

Jsf 2 为什么可以';设置f:selectItems in encodeBegin in composite component?,jsf-2,composite-component,Jsf 2,Composite Component,我试图理解如何编程复合组件,并遵循了balusc和其他人的优秀示例,但我遗漏了一些东西 <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" xmlns:c="http://java.sun.com/jst

我试图理解如何编程复合组件,并遵循了balusc和其他人的优秀示例,但我遗漏了一些东西

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite">

<cc:interface componentType="simpleComponent">
    <cc:attribute name="value" required="true" type="example.LanguageDefinition"/>
    <cc:attribute name="possibilities" default="de_DE" type="java.lang.String"/>
</cc:interface>

<cc:implementation>     
    <p:selectOneMenu binding="#{cc.inputComponent}" converter="omnifaces.SelectItemsConverter" var="l"
        value="#{cc.attrs.value}">
        <p:ajax update="@form"/>
        <f:selectItems value="#{cc.languages}" var="l" itemLabel="#{l.label}"
            itemValue="#{l}" />
        <p:column>#{l.label}</p:column>
        <p:column>
            <p:graphicImage name="#{l.imgPath}" />
        </p:column>
    </p:selectOneMenu>      
</cc:implementation>

#{l.label}

import java.io.IOException;
导入java.util.ArrayList;
导入java.util.List;
导入javax.faces.component.FacesComponent;
导入javax.faces.component.NamingContainer;
导入javax.faces.component.UIInput;
导入javax.faces.component.UINamingContainer;
导入javax.faces.context.FacesContext;
导入example.LanguageDefinition;
@FacesComponent(“simpleComponent”)
公共类SimpleComponent扩展UIInput实现NamingContainer{
专用UIInput组件;
公共UIInput getInputComponent(){
返回输入组件;
}
public void setInputComponent(UIInput inputComponent){
this.inputComponent=inputComponent;
}
@凌驾
公共对象getSubmittedValue(){
返回inputComponent.getSubmittedValue();
}
@凌驾
受保护对象getConvertedValue(FacesContext上下文,对象newSubmittedValue){
返回(字符串)newSubmittedValue;
}
@凌驾
公共字符串getFamily(){
返回UINamingContainer.COMPONENT_族;
}
@凌驾
public void encodeBegin(FacesContext上下文)引发IOException{
字符串可能性=getAttributeValue(“可能性”,“en_US”);
//理论上,基于传入的可能性构建,现在是硬代码
列表语言=新的ArrayList();
添加(新语言定义(“pt_pt”,
"images/flags/PT.gif","葡萄牙语",;
添加(新的语言定义(“cs_CZ”),
"images/flags/CZ.gif,"捷克(捷克共和国),;
getStateHelper().put(“语言”,语言);
super.encodeBegin(上下文);
}
@抑制警告(“未选中”)
公共列表getLanguages(){
return(List)getStateHelper().get(“语言”);
}
/**
*返回指定的属性值,如果为null,则返回指定的默认值。
*/
@抑制警告(“未选中”)
私有T getAttributeValue(字符串键,T defaultValue){
T value=(T)getAttributes().get(键);
返回值(value!=null)?值:defaultValue;
}
}
这样打电话不行:

一切都很好,但提交的值永远不会传递回我的“compBean”。但是,如果我在encodeBegin中设置selectItems“languages”以外的任何其他方式,它都会工作。。。作为具有getter和setter的成员变量,或使用以下代码:

结合这个简单得多的类:

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;

import example.LanguageDefinition;

@FacesComponent("simpleComponent")
public class SimpleComponent extends UIInput implements NamingContainer {

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

public void setPossibilities(String possibilities) {
    if (getStateHelper().get("possibilities") == null) {
        List<LanguageDefinition> languages = new ArrayList<LanguageDefinition>();
        languages.add(new LanguageDefinition("pt_PT",
                "images/flags/PT.gif", "Português (Portugal)"));
        languages.add(new LanguageDefinition("cs_CZ",
                "images/flags/CZ.gif", "Czech (Czech Republic)"));
        getStateHelper().put("languages", languages);
getStateHelper().put("possibilities", possibilities);
    }
}

public String getPossibilities() {
    return (String) getStateHelper().get("possibilities");
}

@SuppressWarnings("unchecked")
public List<LanguageDefinition> getLanguages() {
    return (List<LanguageDefinition>) getStateHelper().get("languages");
}
}
import java.util.ArrayList;
导入java.util.List;
导入javax.faces.component.FacesComponent;
导入javax.faces.component.NamingContainer;
导入javax.faces.component.UIInput;
导入javax.faces.component.UINamingContainer;
导入example.LanguageDefinition;
@FacesComponent(“simpleComponent”)
公共类SimpleComponent扩展UIInput实现NamingContainer{
@凌驾
公共字符串getFamily(){
返回UINamingContainer.COMPONENT_族;
}
公共空集合可能性(字符串可能性){
if(getStateHelper().get(“可能性”)==null){
列表语言=新的ArrayList();
添加(新语言定义(“pt_pt”,
"images/flags/PT.gif","葡萄牙语",;
添加(新的语言定义(“cs_CZ”),
"images/flags/CZ.gif,"捷克(捷克共和国),;
getStateHelper().put(“语言”,语言);
getStateHelper().put(“可能性”,可能性);
}
}
公共字符串{
返回(字符串)getStateHelper().get(“可能性”);
}
@抑制警告(“未选中”)
公共列表getLanguages(){
return(List)getStateHelper().get(“语言”);
}
}
但是,这样做似乎不对(不是巴卢斯克那样做的),所以我只是想理解。哪条路更好?假设第一个,为什么我的不起作用


谢谢

所以。。。这不起作用的原因是我忘记在自定义下拉列表值对象“example.LanguageDefinition”上实现Serializable

希望下一个人不必像我那样大海捞针:)

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;

import example.LanguageDefinition;

@FacesComponent("simpleComponent")
public class SimpleComponent extends UIInput implements NamingContainer {

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

public void setPossibilities(String possibilities) {
    if (getStateHelper().get("possibilities") == null) {
        List<LanguageDefinition> languages = new ArrayList<LanguageDefinition>();
        languages.add(new LanguageDefinition("pt_PT",
                "images/flags/PT.gif", "Português (Portugal)"));
        languages.add(new LanguageDefinition("cs_CZ",
                "images/flags/CZ.gif", "Czech (Czech Republic)"));
        getStateHelper().put("languages", languages);
getStateHelper().put("possibilities", possibilities);
    }
}

public String getPossibilities() {
    return (String) getStateHelper().get("possibilities");
}

@SuppressWarnings("unchecked")
public List<LanguageDefinition> getLanguages() {
    return (List<LanguageDefinition>) getStateHelper().get("languages");
}
}