У меня есть две сущности (Project и Student), с множественными отношениями и формой с одним текстовым полем и двумя списками элементов.
Когда я добавляю нового ученика, появляются два списка элементов. Один список (слева), в котором есть все доступные проекты, и другой список (справа), в котором проект будет выбран студентом.
Проблема возникает, когда я пытаюсь связать правильный список. У меня есть другие примеры, но с такими простыми элементами, как это:
getBinder().forField(tfDescription).withConverter(String::trim, String::trim).bind(Project::getDescription, Project::setDescription);
Кто-нибудь знает, как связать или сохранить список элементов?
Один из примеров того, что я хотел бы сохранить, это ваадин 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);
}
}