Hi, I have a requirement to represent a model field in different component views. So I did a test, creating two texfields and binding both of them to a bean object Person ‘name’ field, but it seems not working properly.
Person.java
public class Person implements Serializable{
private String title;
private String name;
public Person() {
}
public Person(final String title, final String name) {
this.title = title;
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
System.out.println("Title : " + this.title);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
System.out.println("Name : " + this.name);
}
}
PersonForm.java
public class PersonForm<T extends Person> extends HorizontalLayout{
private TextField nameField1;
private TextField nameField2;
private T person;
private Binder<T> binder;
public PersonForm() {
nameField1 = new TextField("Name1");
nameField2 = new TextField("Name2");
addComponents(nameField1, nameField2);
binder = new Binder<>();
binder.forField(nameField1).bind(Person::getName, Person::setName);
binder.forField(nameField2).bind(Person::getName, Person::setName);
}
public void setPerson(T person) {
this.person = person;
this.binder.setBean(this.person);
}
}
MyUI.java
public class MyUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
PersonForm<Person> form = new PersonForm<>();
form.setPerson(new Person("Mr", "Hai Chan"));
setContent(form);
}
@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}
I was expecting if one textfield value changed, another one value will be changed as well. But it does not work. I am wondering is there any way to use binder to do the consistent update or I have to implement value changed listener.
Think of each binding as an independent thing when using the
Binder class. When the user changes the value of an input field, the
Binder class helps with the binding for that input field only. So you need to update the input fields programmatically. This is pretty straightforward to do. You can add a
ValueChangeListener to all the fields in the form and update their values using the
Binder.
setBean method. Binder has an
addValueChangeListener method for that, so you just need to add one more line to your code:
Hi, Alejandro,
Thanks for your reply. It seems vaadin does not have “two-way binding”. When I update the data model, it does not refresh the view automatically, need to invoke
readBean or
setBean every time the data change. But the view changes will be reflected to the model object by using
setBean .
PS: I also want to thank Alejandro for the video, I really appreciate those - especially when you explain a little deeper what’s actually happening (3:00 in this video)!