Vaadin:将Enum值绑定到ComboBox(ConversionException)

时间:2016-09-07 08:54:30

标签: java data-binding combobox enums vaadin

我想将模型中的枚举值绑定到ComboBox。我尝试了什么:

型号:

public class Model{
public enum Status {
        Neu, Analyse, Pruefung, Freigabe, OnTheRoad, EOL, CANCELLED;
        public String getCaption() {
            return name();
        }

        public int getId() {
            return ordinal();
        }
    }

    private Status status;
}

形式:

public class MyForm extends CustomComponent{

private final BeanFieldGroup<Model> binder;

@PropertyId("status")
 private final ComboBox cStatus = new ComboBox("Status");

public MyForm (Model model) {
        final HorizontalLayout content = new HorizontalLayout();
        content.addComponent(buildContent());

        // Now use a binder to bind the members
        binder = new BeanFieldGroup<>(Model.class);

        // We need an item data source before we create the fields to be able to
        // find the properties, otherwise we have to specify them by hand
        final BeanItem bean = new BeanItem<>(model);
        binder.setItemDataSource(bean);
        binder.buildAndBindMemberFields(this);

        setCompositionRoot(content);
}

private buildContent(){
        final FormLayout basicContent = new FormLayout();

        final BeanContainer<Integer, Status> container = new BeanContainer<>(Status.class);
        container.setBeanIdProperty("id");
        container.addAll(EnumSet.allOf(Status.class));
        cStatus.setContainerDataSource(container);
        cStatus.setItemCaptionPropertyId("caption");
        basicContent.addComponent(cStatus);

        return basicContent;
}

public void commit() throws CommitException {
        binder.commit(); // This is what causes the error
}
}

当我调用commit()时,我收到此错误:

Caused by: com.vaadin.data.util.converter.Converter$ConversionException: Unable to convert value of type java.lang.Integer to model type class com.xx.test.entities.def.Model$Status. No converter is set and the types are not compatible.
    at com.vaadin.data.util.converter.ConverterUtil.convertToModel(ConverterUtil.java:181) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.ui.AbstractField.convertToModel(AbstractField.java:751) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.ui.AbstractField.convertToModel(AbstractField.java:731) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.ui.AbstractField.getConvertedValue(AbstractField.java:817) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.ui.AbstractField.commit(AbstractField.java:253) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.data.fieldgroup.FieldGroup.commitFields(FieldGroup.java:509) ~[vaadin-server-7.5.6.jar:7.5.6]
    at com.vaadin.data.fieldgroup.FieldGroup.commit(FieldGroup.java:481) ~[vaadin-server-7.5.6.jar:7.5.6]
    ... 49 more

有没有办法将模型的Enum绑定到ComboBox?

感谢您的帮助!

更新(AndréShild回答):

我想显示Enum值的String表示,所以我想我需要使用String而不是Integer?我发现实际上有一个“StringToEnumConverter”的版本。但是,我尝试使用StringToEnumConverter和我自己的“StringToStatusConverter”:

cStatus.setConverter((Converter) new StringToEnumConverter());
cStatus.addItems(EnumSet.allOf(Status.class));`
// cStatus.addItem(Status.CANCELLED); // Did not work
// cStatus.setConvertedValue(Status.EOL); // Did not work

现在我得到了:

java.lang.ClassCastException: xx.xxx.xxx.entities.modeldefdef.Model$Status cannot be cast to java.lang.String
    at com.vaadin.data.util.converter.StringToEnumConverter.convertToModel(StringToEnumConverter.java:32) ~[vaadin-server-7.5.6.jar:7.5.6]

...对于两个转换器。

2 个答案:

答案 0 :(得分:3)

在buildContent()方法中写:

// ...
final BeanItemContainer<Status> container = new BeanItemContainer<>(Status.class);
container.addAll(EnumSet.allOf(Status.class));
cStatus.setContainerDataSource(container);
cStatus.setItemCaptionPropertyId("caption");
basicContent.addComponent(cStatus);
// ...

为什么呢?您的ComboBox被FieldGroup绑定到Status类型的Property。但是您当前的Container BeanContainer具有Integer类型,即容器ID的类型。要解决此问题,容器的ID类型必须与属性的类型相匹配。这是通过使用BeanItemContainer完成的,BeanItemContainer使用Bean类型作为对象ID。 Here更详细地解释了这个问题。

答案 1 :(得分:1)

Vaadin有Converter的概念,它从内部表示转换为外部表示。

您需要实现Converter接口,然后指定使用它。

public class IntegerToModelStatusConverter implements Converter<Integer, Model$Status>

final ComboBox statusField = new ComboBox("Status");
statusField .setConverter(new IntegerToModelStatusConverter());

整数是相应枚举元素的int值。

有一个wiki条目更详细地描述了这一点。