我有两个实体(项目和学生),具有很多对很多的关系,并且具有一个文本字段和两个元素列表的表单。
当我添加新学生时,出现两个元素列表。一个列表(左)具有所有可用的项目,另一个列表(右)具有将由学生选择的项目。
当我尝试绑定正确的列表时,问题就来了。我还有其他示例,但具有这样的简单元素:
getBinder().forField(tfDescription).withConverter(String::trim, String::trim).bind(Project::getDescription, Project::setDescription);
有人知道如何绑定或保存元素列表吗?
我要保存的一个示例是此示例,但在vaadin 10中:TwinCol
@Entity
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinTable(name="student_project", joinColumns=
{@JoinColumn(referencedColumnName="ID")}
, inverseJoinColumns=
{@JoinColumn(referencedColumnName="ID")})
private List<Student> students;
private String description;
public Project() {
}
public Project(String description) {
super();
this.description = description;
}
public Long getId() {
return id;
}
public String getDescription() {
return description;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "students")
@Fetch(value = FetchMode.SUBSELECT)
private List<Project> projects;
private String name;
public Student(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public List<Project> getProjects() {
return projects;
}
}
----------------------------------------------
@SpringComponent
@Scope("request")
public class ProjectEditorDialog extends AbstractEditorDialog<Student> {
private TextField tfName;
@Autowired
private ProjectRepository projectRepository;
private ListBox<Project> lbLeft; // List of projects to select
private Button bLeft;
private Button bRight;
private ListBox<Project> lbRight; // List of projects selected
private Project tempProject;
private List<Project> listLeftProjects = new ArrayList<Project>();
private List<Project> listRightProjects = new ArrayList<Project>();
@PostConstruct
private void init() {
createNameField();
createLeftColumn();
createCenterColumn();
createRightColumn();
checkButtons();
}
@Override
protected void confirmDelete() {
openConfirmationDialog("Delete Student",
String.format("Delete student: [%s]?", getCurrentItem().getName()));
}
private void createNameField() {
tfName = new TextField("Name");
tfName.setRequired(true);
getFormLayout().add(tfName);
getBinder().forField(tfName).withConverter(String::trim, String::trim).bind(Student::getName,
Student::setName);
}
private void createLeftColumn() {
VerticalLayout leftColumn = new VerticalLayout();
Label lTitle = new Label("Project availables");
leftColumn.add(lTitle);
lbLeft = new ListBox<Project>();
listLeftProjects = projectRepository.findAll();
lbLeft.setItems(listLeftProjects);
lbLeft.setRenderer(new ComponentRenderer<>(item -> {
Label label = new Label(item.getName());
label.getStyle().set("propertyDescription", "value");
return label;
}));
leftColumn.add(lbLeft);
getHorizontalLayout().add(leftColumn);
}
private void createCenterColumn() {
VerticalLayout centerColumn = new VerticalLayout();
bRight = new Button(">>");
bRight.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {
@Override
public void onComponentEvent(ClickEvent<Button> event) {
tempProject = lbLeft.getValue();
if (tempProject != null) {
listLeftProjects.remove(tempProject);
listRightProjects.add(tempProject);
lbLeft.setItems(listLeftProjects);
lbRight.setItems(listRightProjects);
checkButtons();
}
}
});
bLeft = new Button("<<");
bLeft.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {
@Override
public void onComponentEvent(ClickEvent<Button> event) {
tempProject = lbRight.getValue();
if (tempProject != null) {
listRightProjects.remove(tempProject);
listLeftProjects.add(tempProject);
lbLeft.setItems(listLeftProjects);
lbRight.setItems(listRightProjects);
checkButtons();
}
}
});
centerColumn.add(bRight);
centerColumn.add(bLeft);
getHorizontalLayout().add(centerColumn);
}
private void createRightColumn() {
VerticalLayout rightColumn = new VerticalLayout();
Label lTitle = new Label("Projects selected");
rightColumn.add(lTitle);
lbRight = new ListBox<Project>();
lbRight.setRenderer(new ComponentRenderer<>(item -> {
Label label = new Label(item.getDescription());
label.getStyle().set("propertyDescription", "value");
return label;
}));
rightColumn.add(lbRight);
getHorizontalLayout().add(rightColumn);
/*This doesn't work -- getBinder().forField(lbRight).bind(Student::getProjects, Student::setProjects);*/
}
private void checkButtons() {
if (listRightProjects.size() > 0)
bLeft.setEnabled(true);
else
bLeft.setEnabled(false);
if (listLeftProjects.size() > 0)
bRight.setEnabled(true);
else
bRight.setEnabled(false);
}
}