我有一个遗留的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存储到这一个选择公司。
答案 0 :(得分:0)
<击>
您可以使用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。产生的用户界面
<强> 6。按保存按钮
击> <击> Setting actual company name to [myNewCompany]
击>