I'm using the binder.addStatusChangeListener( ... )
part of the code at Binding Data to Forms, Checking a return value in my webapp. MCVE derived from that is:
public class Person implements Serializable {
private String name;
public Person() {}
public Person( final String name ) {
this.name = name;
}
public String getName() {
return name;
}
public void setName( final String name ) {
this.name = name;
}
}
public class PersonView extends VerticalLayout {
private final Person person = new Person( "Gerold Broser" );
private final TextField name = new TextField( "Name:" );
private final BeanValidationBinder<Person> binder =
new BeanValidationBinder<>( Person.class );
private final Button button = new Button( "Button" );
public PersonView() {
super();
binder.bindInstanceFields( this );
binder.setBean( person );
addComponent( name );
addComponent( button );
binder.addStatusChangeListener( event -> {
final boolean hasChanges, isValid;
out.println( "hasChanges=" + (hasChanges = event.getBinder().hasChanges()) );
out.println( "isValid=" + (isValid = event.getBinder().isValid()) );
button.setEnabled( hasChanges && isValid );
} );
}
}
As soon as I change the TextField
's content in my browser I get the following output:
hasChanges=false
isValid=true
Is this a bug or do I miss something?
From the javadoc:
public boolean hasChanges()
Check whether any of the bound fields' have uncommitted changes since last explicit call to
readBean(Object)
,removeBean()
,writeBean(Object)
orwriteBeanIfValid(Object)
. Unsuccessful writeoperations will not affect this value.Note that if you use
setBean(Object)
method, Binder tries to commit changes as soon as all validators have passed. Thus, when using this method with it seldom makes sense and almost always returns false.Return values for each case are compiled into the following table:
╔════════════╦════════════╦═════════╦═════════╦══════════════════╦════════════════════╗
║ ║ After ║ After ║ After ║ After successful ║ After unsuccessful ║
║ ║ readBean, ║ valid ║ invalid ║ writeBean or ║ writeBean or ║
║ ║ setBean or ║ user ║ user ║ writeBeanIfValid ║ writeBeanIfValid ║
║ ║ removeBean ║ changes ║ changes ║ ║ ║
╠════════════╬════════════╬═════════╬═════════╬══════════════════╬════════════════════╣
║ A bean is ║ ║ ║ ║ ║ ║
║ currently ║ false ║ false ║ true ║ false ║ no change ║
║ bound ║ ║ ║ ║ ║ ║
╟────────────╫────────────╫─────────╫─────────╫──────────────────╫────────────────────╢
║ No bean is ║ ║ ║ ║ ║ ║
║ currently ║ false ║ true ║ true ║ false ║ no change ║
║ bound ║ ║ ║ ║ ║ ║
╚════════════╩════════════╩═════════╩═════════╩══════════════════╩════════════════════╝
Returns:
whether any bound field's value has changed since last call to setBean, readBean, writeBean or writeBeanIfValid
In conclusion, using setBean(myBean)
will trigger automatic commits. Thus, if you want to manually commit changes, use binder.readBean(myBean)
& binder.writeBean(myBean)
.