如何在f中使用枚举值:selectItem(s)

我想做一个selectOneMenu下拉菜单,这样我就可以在我的问题上select一个状态。 是否有可能使f:selectItem更灵活考虑如果枚举的顺序改变,如果列表很大,会发生什么? 我能做得更好吗? 是否有可能自动“select”该问题的项目?

枚举类

public enum Status { SUBMITTED, REJECTED, APPROVED } 

问题实体

 @Enumerated(EnumType.STRING) private Status status; 

JSF

 <div class="field"> <h:outputLabel for="questionStatus" value="Status" /> <h:selectOneMenu id="questionStatus" value="#{bean.question.status}" > <f:selectItem itemLabel="Submitted" itemValue="0" /> <f:selectItem itemLabel="Rejected" itemValue="1" /> <f:selectItem itemLabel="Approved" itemValue="2" /> </h:selectOneMenu> <hr /> </div> 

JSF有一个内置的enum转换器,所以应该这样做:

 @ManagedBean @ApplicationScoped public class Data { public Status[] getStatuses() { return Status.values(); } } 

 <h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{data.statuses}" /> </h:selectOneMenu> 

(注意:因为JSF 2.0不再需要提供SelectItem[]List<SelectItem> ,所以T[]List<T>也被接受,并且您可以通过var属性来访问当前项目)

如果碰巧使用JSF实用程序库OmniFaces ,那么可以使用<o:importConstants>而不是bean。

 <o:importConstants type="com.example.Status" /> <h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{Status}" /> </h:selectOneMenu> 

如果您打算控制标签,也可以将它们添加到Status枚举中:

 public enum Status { SUBMITTED("Submitted"), REJECTED("Rejected"), APPROVED("Approved"); private String label; private Status(String label) { this.label = label; } public String getLabel() { return label; } } 

 <f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{status.label}" /> 

或者,更好的做法是使枚举值成为本地化资源包的属性键(需要EL 3.0):

 <f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{text['data.status.' += status]}" /> 

在与资源包#{text}关联的属性文件中,

 data.status.SUBMITTED = Submitted data.status.REJECTED = Rejected data.status.APPROVED = Approved 

对于本地化我们可以使用这个解决scheme:

 public enum Status { SUBMITTED, REJECTED, APPROVED } data.status.SUBMITTED=Submitted data.status.REJECTED=Rejected data.status.APPROVED=Approved <h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{text['data.status.'.concat(status)]}" /> </h:selectOneMenu> 

所以本地化string的资源path在Enum中不是硬编码的。

您可以使用<f:selectItems value="#{carBean.carList}" />并返回一个SelectItem实例的列表,这些实例包含枚举(使用Status.values()来获取所有可能的值)。

您可以使用下面的实用程序el函数来获取枚举值,并在SelectOneMenu使用它们。 不需要创buildbean和样板方法。

 public final class ElEnumUtils { private ElEnumUtils() { } /** * Cached Enumerations, key equals full class name of an enum */ private final static Map<String, Enum<?>[]> ENTITY_ENUMS = new HashMap<>();; /** * Retrieves all Enumerations of the given Enumeration defined by the * given class name. * * @param enumClassName Class name of the given Enum. * * @return * * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") public static Enum<?>[] getEnumValues(final String enumClassName) throws ClassNotFoundException { // check if already cached - use classname as key for performance reason if (ElEnumUtils.ENTITY_ENUMS.containsKey(enumClassName)) return ElEnumUtils.ENTITY_ENUMS.get(enumClassName); final Class<Enum<?>> enumClass = (Class<Enum<?>>) Class.forName(enumClassName); final Enum<?>[] enumConstants = enumClass.getEnumConstants(); // add to cache ElEnumUtils.ENTITY_ENUMS.put(enumClassName, enumConstants); return enumConstants; } } 

将其注册为taglib文件中的一个el函数:

 <function> <description>Retrieves all Enumerations of the given Enumeration defined by the given class name.</description> <function-name>getEnumValues</function-name> <function-class> package.ElEnumUtils </function-class> <function-signature> java.lang.Enum[] getEnumValues(java.lang.String) </function-signature> </function> 

最后称之为:

 <p:selectOneMenu value="#{bean.type}"> <f:selectItems value="#{el:getEnumValues('package.BeanType')}" var="varEnum" itemLabel="#{el:getEnumLabel(varEnum)}" itemValue="#{varEnum}"/> </p:selectOneMenu> 

熟悉BalusC的答案,你应该使用本地化的枚举标签的资源包,并为更干净的代码,你也可以创build一个函数,如getEnumLabel(enum)