ComboBox和原始值作为数组

时间:2015-10-14 11:37:50

标签: vaadin vaadin7

我有一个遗留的MongoDB数据库(集合),其中有一个值存储为数组List。但在使用ComboBox选择的UI中,它只有一个必须的值。所以我有一个模型bean

class Project {
   List<Company> companies;
}

我想绑定它并使用VAADIN ComboBox进行编辑。最初我以为我可以为ComboBox使用一些客户转换器,但无法使其工作。组合应编辑List(公司bean)中的第一个值,并作为数组存储回公司字段以保持兼容。是否有可能做到这一点,如果可以,你能给我一些提示如何实现这个目标吗?

编辑:增强解释

MongoDB模型:

 class Project {
       List<Company> companies;
    }

Vaadin UI:

ComboBox companies;

......&#39;公司&#39; ComboBox附加到BeanItemContainer,它是List ...因此,选择是唯一的一个公司bean,但出于兼容性原因,应该存储为仅包含一个项目的List。所以基本上ComboBox应该能够将现有的List值作为单个公司读取,允许选择并将其作为List存储到这一个选择公司。

1 个答案:

答案 0 :(得分:0)

在最后一次更新问题后,下面的答案可能不正确。等待OP提供详细信息,以便更正答案。

<击> 您可以使用ProjectDelegator包装器使用某种delegation approach。这将允许您将表单绑定到Project名称(使用项目字段)以及Company名称(使用 getCompany() getter)

<强> 1。 UI类

@PreserveOnRefresh
@SpringUI
public class MyVaadinUI extends UI {

    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        // add the form to the UI
        layout.addComponent(new MyForm(new ProjectDelegator(new Project("myProject", new Company("myCompany")))));
    }
}

<强> 2。表格

// "wrapping" the form in a custom component. not really needed but a nice touch
public class MyForm extends CustomComponent {
    public MyForm(ProjectDelegator projectDelegator) {
        FormLayout layout = new FormLayout();

        // use a binder to create fields and bind the members using reflection
        BeanFieldGroup<ProjectDelegator> binder = new BeanFieldGroup<>(ProjectDelegator.class);

        // bind the project name using the "project" field
        layout.addComponent(binder.buildAndBind("Project", "project.name"));

        // bind the company name using the "getCompany" method
        layout.addComponent(binder.buildAndBind("Company", "company.name"));

        // add a "save" button
        layout.addComponent(new Button("Save", new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent clickEvent) {
                try {
                    // commit changes
                    binder.commit();
                } catch (FieldGroup.CommitException e) {
                    // didn't expect this! what gives?!
                    System.out.println("Could not save data: [" + e.getMessage() + "]");
                }
            }
        }));

        // set the delegator as the binder data source
        binder.setItemDataSource(projectDelegator);

        setCompositionRoot(layout);
    }
}

第3。 “委托人”

// delegator class to adapt from/to list with only 1 item
public class ProjectDelegator {
    // nice constant to express the intent as clearly as possible
    private static final int MY_ONLY_COMPANY = 0;

    // our delegate
    private Project project;

    public ProjectDelegator(Project project) {
        this.project = project;
    }

    // BeanFieldGroup will use this by reflection to bind the "company.name" field
    public Company getCompany() {
        // delegate the accessing to the origina product 
        return project.getCompanies().get(MY_ONLY_COMPANY);
    }

    // accessor; can if not required at a later time
    public Project getProject() {
        return project;
    }
}

<强> 4。遗留模型类

// our problem class
public class Project {
    private String name;
    private List<Company> companies = new ArrayList<>();

    public Project(String name, Company company) {
        this.name = name;
        companies.add(company);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Company> getCompanies() {
        return companies;
    }

    public void setCompanies(List<Company> companies) {
        this.companies = companies;
    }
}
// the "indirect" problem :)
public class Company {
    private String name;

    public Company(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("Setting actual company name to [" + name + "]");
        this.name = name;
    }
}

<强> 5。产生的用户界面

Resulting interface

<强> 6。按保存按钮

<击> Setting actual company name to [myNewCompany]