Combobox Vaadin组合框:字符串和POJO之间的转换

Combobox Vaadin组合框:字符串和POJO之间的转换,combobox,converter,vaadin7,Combobox,Converter,Vaadin7,使用FieldGroup,我有一个表单,使用BeanItem绑定Customer的所有属性,并将它们显示在FormLayout中 我的Customer类类似于: @Entity @Table(name="customer") public class Customer implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; privat

使用
FieldGroup
,我有一个表单,使用
BeanItem
绑定
Customer
的所有属性,并将它们显示在
FormLayout

我的
Customer
类类似于:

@Entity
@Table(name="customer")
public class Customer implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    private String description;
    (... other fields ...)

    private String language;
    (... getters and setters ...)
}
属性
language
是该语言的快捷方式。例如
“de”
“en”
“fr”
等等

此外,还有一个名为
Language
(代码简化)的POJO类

。。。以及实例的静态列表(简化代码):

我知道可以使用字段组上的提交处理程序手动更改CustomerBean对象。但我想避免这种情况

有没有一种方法可以“自动”在组合框、表单或bean项上实现转换器之类的东西

在查看(第18页到第21页)之后,我尝试使用
转换器的自定义实例。但这显然不起作用,因为绑定属性不能同时是语言集/语言列表和客户语言

如何做到这一点


注意:由于互操作性,我无法更改
客户
,我需要将构造与语言类一起使用。

您可以将快捷方式值作为值添加到
组合框中,并定义可选标题:

    cmbx.addContainerProperty("caption", String.class, "");
    cmbx.setItemCaptionPropertyId("caption");

    cmbx.addItem(languageEN.getLanguageShortCut()).getItemProperty("caption").setValue(languageEN.getLanguageLong());
    cmbx.addItem(languageFR.getLanguageShortCut()).getItemProperty("caption").setValue(languageFR.getLanguageLong());

如果您需要
ComboBox
作为值提供给您
Language
,您可以扩展ComboBox类:

class LanguageComboBox extends ComboBox {
    public LanguageComboBox(String caption, Collection<Language> languages) {
        super(caption, getShortcuts(languages));
    }

    @Override
    public Language getValue() {
       return new Language((String) super.getValue());
    }

    private static List<String> getShortcuts(Collection<Language> languages) {
       // extract shortcuts using java 1.8 
       return languages.stream()
            .map(language -> language.getShortcut())
            .collect(Collectors.toList());
    }
}
提交后,您的客户将拥有适当的语言价值


在我看来,您不应该在视图上使用实体-正如您所提到的,您不能更改
Customer
对象,并且这个类可能包含您需要添加到视图中的更多字段。我更愿意为这个视图创建单独的POJO类——这给了您更大的灵活性,并且不会出现像您报告的那样的问题。当然,最终您需要将视图对象转换为实体或更多实体,但在大多数情况下,承担该成本是值得的

你能澄清你的问题吗?从描述来看,不清楚您试图做什么,以及如果您只是试图绑定实体中的组合框和字段,为什么需要Conventer。更改了我的问题。我希望现在清楚多了。
// Assuming we have a combobox and our customer bean, both created before and elsewhere:
ComboBox cmbLanguage;
BeanItem<Customer> customer;

// Then, the language chosen by the user is:
Language lang = (Language)cmbLanguage.getValue();

// So this should actually happen upon saving the form:
customer.getItemProperty("language").setValue(lang.getShortcut());
    cmbx.addContainerProperty("caption", String.class, "");
    cmbx.setItemCaptionPropertyId("caption");

    cmbx.addItem(languageEN.getLanguageShortCut()).getItemProperty("caption").setValue(languageEN.getLanguageLong());
    cmbx.addItem(languageFR.getLanguageShortCut()).getItemProperty("caption").setValue(languageFR.getLanguageLong());
class LanguageComboBox extends ComboBox {
    public LanguageComboBox(String caption, Collection<Language> languages) {
        super(caption, getShortcuts(languages));
    }

    @Override
    public Language getValue() {
       return new Language((String) super.getValue());
    }

    private static List<String> getShortcuts(Collection<Language> languages) {
       // extract shortcuts using java 1.8 
       return languages.stream()
            .map(language -> language.getShortcut())
            .collect(Collectors.toList());
    }
}
    ComboBox comboBox = new LanguageComboBox("Language", LANGUAGES);
    fieldGroup.bind(comboBox,"language");