SlideShare uma empresa Scribd logo
B I N D I N G D ATA T O U I C O M P O N E N T S
5
S T O R Y A N D P H I L O S O P H Y
Software is eating the world and what most of us see of it is the user interface. The user
interface has become the key component of how the users experience the business
behind it. Competition is lost or won due to user experience. Simplicity is king and the
users get frustrated by anything ugly, slow or not working on the device they happen to
use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight.
Together we want to build a user interface that puts a smile on the user’s face.
Vaadin is the technology that empowers developers to build the best web-apps for
business purposes. Our priority over everything else is developer productivity because
we believe that by simplifying the developer experience and saving the developer’s
time, they are best able to focus on building great user interfaces.
Our brand is what we want everyone to think about us. When everyone - both us and
the people around us - have a consistent understanding of what Vaadin is and what we
stand for, it enables that image to spread and amplify. This book defines what we want
that image to be. It defines what the Vaadin brand is.
I hope that You are as excited and proud of living and breathing the Vaadin brand as
I am. You are the one who is shaping what everyone thinks about Vaadin - using this
brand as a tool and a guideline every day.
Let’s fight for simplicity for both the users and the developers!
Joonas Lehtinen
Founder & CEO
Vaadin
I N T R O D U C T I O N
@peter_lehto
Session’s content
Session’s content
• Average day with Vaadin 7
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
H o w w o u l d y o u e d i t
c u s t o m e r r e c o r d s ?
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
Setters and Getters
VAADIN 7
Setters and Getters
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Setters and Getters
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
Setters and Getters
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
• Every Field has a Listener
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
• Every Field has a Listener
• Implicit save, cannot discard
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
• Every Field has a Listener
• Implicit save, cannot discard
• Lots of code
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
• Every Field has a Listener
• Implicit save, cannot discard
• Lots of code
• Prone to error and change
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
firstName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setFirstName(firstName.getValue());
}
});
lastName.addValueChangeListener(
new ValueChangeListener() {
@Override
public void valueChange(ValueChangeEvent event) {
customer.setLastName(lastName.getValue());
}
});
• Setters used explicitly
• Every Field has a Listener
• Implicit save, cannot discard
• Lots of code
• Prone to error and change
• Invalid values not prevented
WHAT’S WRONG?
LET’S IMPROVE!
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
LET’S IMPROVE!
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
BENEFITS?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
BENEFITS?
• Centralized value setting
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
BENEFITS?
• Centralized value setting
• Validation could be added
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
• Setters used explicitly
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
• Setters used explicitly
• Lots of code
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
• Setters used explicitly
• Lots of code
• Prone to error and change
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
customer.setFirstName(firstName.getValue());
customer.setLastName(lastName.getValue());
}
});
}
• Setters used explicitly
• Lots of code
• Prone to error and change
• Hard to Validate
WHAT’S WRONG?
With properties
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
With properties
VAADIN 7
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(
new BeanItem<CustomerDTO>(customer));
With properties
VAADIN 7
fieldGroup.setItemDataSource(
new BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
BENEFITS?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• No more explicit setters
BENEFITS?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• No more explicit setters
• Committable / Discardable
BENEFITS?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• No more explicit setters
• Committable / Discardable
• Validation part of Commit
BENEFITS?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• Not type safe
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• Not type safe
• Prone to error and change
WHAT’S WRONG?
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
FieldGroup fieldGroup = new FieldGroup();
fieldGroup.bind(firstName, "firstName");
fieldGroup.bind(lastName, "lastName");
fieldGroup.setItemDataSource(new
BeanItem<CustomerDTO>(customer));
Button save = new Button("Save",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
try {
fieldGroup.commit();
}
catch(CommitException e) {
// show errors
}
}
});
• Not type safe
• Prone to error and change
• BeanItem boiler plate and
checked CommitException
WHAT’S WRONG?
# F F S
FIGHT FOR SIMPLICITY
FIGHT FOR SIMPLICITY
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
c . v. u i . A b s t r a c t F i e l d < T >
VAADIN 7
1 8 5 3 l o c 2 2 8 l o c
VAADIN 8
F i e l d G r o u p
TO
B i n d e r
H o w w o u l d y o u e d i t
c u s t o m e r r e c o r d s ?
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
Read Data?
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.readBean(customer);
Read Data
VAADIN 8
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.readBean(customer);
Save Data?
VAADIN 8
Save Data
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.readBean(customer);
Button save = new Button("Save" ,
e -> binder.writeBeanIfValid(customer));
Write directly
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.bind(firstName,
CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName,
CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.setBean(customer);
C o n v e r s i o n
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withConverter(Integer::valueOf, String::valueOf)
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withConverter(Integer::valueOf, String::valueOf)
.bind(
CustomerDTO::getYearOfBirth,
CustomerDTO::setYearOfBirth);
Conversion with
Binding
VAADIN 8
Va l i d a t i o n
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(firstName)
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(firstName)
.withValidator(Validator::notEmpty, "Mandatory field")
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(firstName)
.withValidator(Validator::notEmpty, "Mandatory field")
.withValidator(value -> value.length() < 10,
"Must be less than 10 chars")
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(firstName)
.withValidator(Validator::notEmpty, "Mandatory field")
.withValidator(value -> value.length() < 10,
"Must be less than 10 chars")
.bind(
CustomerDTO::getFirstname,
CustomerDTO::setFirstname);
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(firstName)
.withValidator(Validator::notEmpty, "Mandatory field")
.withValidator(value -> value.length() < 10,
"Must be less than 10 chars")
.bind(
CustomerDTO::getFirstname,
CustomerDTO::setFirstname);
Button save = new Button(“Save",
e -> binder.writeBeanIfValid(customer));
Validation with
Binding
VAADIN 8
Va l i d a t i o n
w i t h
C o n v e r s i o n
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4,
"Must have 4 characters")
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4,
"Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4,
"Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value > 2000,
"Must be after year 2000")
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4,
"Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value > 2000,
"Must be after year 2000")
.bind(CustomerDTO::getYearOfBirth,
CustomerDTO::setYearOfBirth);
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
Binder<CustomerDTO> binder = new Binder<>();
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4,
"Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value > 2000,
"Must be after year 2000")
.bind(CustomerDTO::getYearOfBirth,
CustomerDTO::setYearOfBirth);
Button save = new Button("Save", e -> {
try {
binder.writeBean(customer);
} catch (ValidationException ve) {
ve.getFieldValidationErrors().forEach(error -> …);
}
});
Validation with
Conversion
VAADIN 8
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
c . v. u i . C u s t o m F i e l d < T >
c . v. u i . C u s t o m F i e l d < T >
F o r m a k i n g F i e l d s f o r y o u r
b u s i n e s s t y p e s
CUSTOMFIELD
public class MoneyField extends CustomField<Money> {
CUSTOMFIELD
public class MoneyField extends CustomField<Money> {
private TextField textField;
private Label currencyCode;
CUSTOMFIELD
public class MoneyField extends CustomField<Money> {
private TextField textField;
private Label currencyCode;
private BigDecimal parseValue() throws ParseException {
return …;
}
private String formatValue(BigDecimal parsedValue) {
return …;
}
CUSTOMFIELD
public class MoneyField extends CustomField<Money> {
private TextField textField;
private Label currencyCode;
private BigDecimal parseValue() throws ParseException {
return …;
}
private String formatValue(BigDecimal parsedValue) {
return …;
}
public Money getValue() {
if (StringUtils.isEmpty(textField.getValue())) {
return null;
}
try {
return Money.of(currencyCode.getValue(), parseValue());
} catch (ParseException e) {
textField.setComponentError(new UserError("Invalid format”));
return null;
}
}
protected void doSetValue(Money value) {
if (value == null) {
textField.clear();
currencyCode.setValue(null);
} else {
textField.setValue(formatValue(value.getAmount()));
currencyCode.setValue(value.getCurrencyCode());
}
}
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
c . v. d a t a . I t e m
TO
< T >
C o m b o B o x
C o m b o B o x < C o u n t r y >
TO
C o u n t r y c = ( C o u n t r y )
c o m b o B o x . g e t V a l u e ( )
TO
C o u n t r y c = c o m b o B o x . g e t V a l u e ( )
H o w w o u l d y o u m a k e
a d r o p d o w n o f c o u n t r i e s ?
VAADIN 7
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
container.addAll(getCountries());
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
container.addAll(getCountries());
ComboBox countrySelector = new ComboBox();
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
container.addAll(getCountries());
ComboBox countrySelector = new ComboBox();
countrySelector.setContainerDataSource(container);
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
container.addAll(getCountries());
ComboBox countrySelector = new ComboBox();
countrySelector.setContainerDataSource(container);
countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY);
BeanItemContainer<Country> container =
new BeanItemContainer<>(Country.class);
container.addAll(getCountries());
ComboBox countrySelector = new ComboBox();
countrySelector.setContainerDataSource(container);
countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY);
countrySelector.setItemCaptionPropertyId("name");
H o w w o u l d y o u m a k e
a d r o p d o w n o f c o u n t r i e s ?
VAADIN 8
ComboBox<Country> countrySelector = new ComboBox<>();
ComboBox<Country> countrySelector = new ComboBox<>();
countrySelector.setItemCaptionGenerator(Country::getName);
countrySelector.setItems(getCountries());
H o w w o u l d y o u f i l t e r
e n t r i e s i n a d r o p d o w n ?
VAADIN 7
N e t h e r l a n d s , a n y o n e ?
countrySelector.setFilteringMode(FilteringMode.CONTAINS);
countrySelector.setFilteringMode(FilteringMode.STARTSWITH);
OR
H o w w o u l d y o u f i l t e r
e n t r i e s i n a d r o p d o w n ?
VAADIN 8
D a t a P r o v i d e r < T Y P E , F I LT E R >
Session’s content
• Average day with Vaadin 7
• Binder, Java 8 and Functions
• Binding custom data types with CustomField<T>
• Where are my Items & Properties?
• How to be as Lazy as possible?
D a t a P r o v i d e r < C o u n t r y, S t r i n g >
public interface DataProvider<T, F> {
int size(Query<T, F> query);
Stream<T> fetch(Query<T, F> query);
}
ComboBox<Country> countrySelector = new ComboBox<>();
countrySelector.setItemCaptionGenerator(Country::getName);
countrySelector.setDataProvider(
ComboBox<Country> countrySelector = new ComboBox<>();
countrySelector.setItemCaptionGenerator(Country::getName);
countrySelector.setDataProvider(
(filter, offset, limit) ->
countryService.getCountries(filter, offset, limit),
ComboBox<Country> countrySelector = new ComboBox<>();
countrySelector.setItemCaptionGenerator(Country::getName);
countrySelector.setDataProvider(
(filter, offset, limit) ->
countryService.getCountries(filter, offset, limit),
(filter) -> countryService.size(filter));
D a t a P r o v i d e r < C o u n t r y, S t r i n g >
java.util.function.Predicate<T>
CriteriaQuery.where(...)
Service.findCountries(String)
P l u g i n t o a n y d a t a s o u r c e l a z i l y !
Q u e r y < T Y P E , F I LT E R >
public class Query<TYPE, FILTER> {
int getOffset();
int getLimit();
}
public class Query<TYPE, FILTER> {
int getOffset();
int getLimit();
List<QuerySortOrder> getSortOrders();
}
public class Query<TYPE, FILTER> {
int getOffset();
int getLimit();
List<QuerySortOrder> getSortOrders();
Comparator<TYPE> getInMemorySorting();
}
public class Query<TYPE, FILTER> {
int getOffset();
int getLimit();
List<QuerySortOrder> getSortOrders();
Comparator<TYPE> getInMemorySorting();
Optional<FILTER> getFilter();
}
T h e c l a s s i c C o n t a i n e r d i s c r e p a n c y
VAADIN 7
Grid grid = new Grid();
grid.addColumn("firstName");
grid.addColumn("lastName");
grid.addColumn("yearsOld");
grid.setContainerDataSource(
new BeanItemContainer<>(CustomerDTO.class));
HTTP Status 500 - com.vaadin.server.ServiceException:
java.lang.IllegalStateException:
Found at least one column in Grid that does not exist
in the given container: yearsOld with the header “Years
Old”.
Call removeAllColumns() before setContainerDataSource()
if you want to reconfigure the columns based on the new
container.
# F F S
Grid grid = new Grid();
grid.addColumn("firstName");
grid.addColumn("lastName");
grid.addColumn("yearsOld");
Grid grid = new Grid();
grid.addColumn("firstName");
grid.addColumn("lastName");
grid.addColumn("yearsOld");
GeneratedPropertyContainer generatedProps =
new GeneratedPropertyContainer(
new BeanItemContainer<>(CustomerDTO.class));
generatedProps.addContainerProperty("yearsOld", Integer.class, null);
grid.setContainerDataSource(generatedProps);
HTTP Status 500 - com.vaadin.server.ServiceException: java.lang.UnsupportedOperationException:
GeneratedPropertyContainer does not support adding properties.
# F F S
THIS ISN’T FUN ANYMORE…
Grid grid = new Grid();
grid.addColumn("firstName");
grid.addColumn("lastName");
grid.addColumn("yearsOld");
GeneratedPropertyContainer generatedProps =
new GeneratedPropertyContainer(
new BeanItemContainer<>(CustomerDTO.class));
grid.setContainerDataSource(generatedProps);
generatedProps.addGeneratedProperty("yearsOld", new
PropertyValueGenerator<Integer>() {
@Override
public Class<Integer> getType() {
return Integer.class;
}
@Override
public Integer getValue(Item item, Object itemId,
Object propertyId) {
return LocalDate.now().getYear() -
((CustomerDTO)itemId).getYearOfBirth();
}
});
# F F S
OH REALLY!?
B y e B y e C o n t a i n e r s ;
w e ’ v e h a d e n o u g h !
VAADIN 8
Grid<CustomerDTO> grid = new Grid<>();
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn(Customer::getFirstName);
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn(Customer::getFirstName);
grid.addColumn(Customer::getLastName);
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn(Customer::getFirstName);
grid.addColumn(Customer::getLastName);
grid.addColumn(customer ->
String.valueOf(LocalDate.now().getYear() - customer.getYearOfBirth()));
Lessons learned
Lessons learned
• Vaadin 8 - built on Java 8
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
• Data binding completely redone
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
• Data binding completely redone
• Targets simplifications and flexibility, #FFS
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
• Data binding completely redone
• Targets simplifications and flexibility, #FFS
• Drops Containers, Items and Properties
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
• Data binding completely redone
• Targets simplifications and flexibility, #FFS
• Drops Containers, Items and Properties
• Gathers all data binding to Binder, simplifies Fields
@peter_lehto
T H A N K Y O U !

Mais conteúdo relacionado

Mais procurados

Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfaces
deimos
 
Frank Mantek Google G Data
Frank Mantek Google G DataFrank Mantek Google G Data
Frank Mantek Google G Data
deimos
 
Evolving The Java Language
Evolving The Java LanguageEvolving The Java Language
Evolving The Java Language
QConLondon2008
 

Mais procurados (19)

Vaadin 8 with Spring Framework
Vaadin 8 with Spring FrameworkVaadin 8 with Spring Framework
Vaadin 8 with Spring Framework
 
Vaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfigurationVaadin 8 with Spring Frameworks AutoConfiguration
Vaadin 8 with Spring Frameworks AutoConfiguration
 
GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
 
What's new in Vaadin 8, how do you upgrade, and what's next?
What's new in Vaadin 8, how do you upgrade, and what's next?What's new in Vaadin 8, how do you upgrade, and what's next?
What's new in Vaadin 8, how do you upgrade, and what's next?
 
Building web apps with Vaadin 8
Building web apps with Vaadin 8 Building web apps with Vaadin 8
Building web apps with Vaadin 8
 
Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfaces
 
Vaadin with Java EE 7
Vaadin with Java EE 7Vaadin with Java EE 7
Vaadin with Java EE 7
 
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
TDC2017 | São Paulo - Trilha Java EE How we figured out we had a SRE team at ...
 
MVVM & Data Binding Library
MVVM & Data Binding Library MVVM & Data Binding Library
MVVM & Data Binding Library
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Data binding
Data bindingData binding
Data binding
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
Frank Mantek Google G Data
Frank Mantek Google G DataFrank Mantek Google G Data
Frank Mantek Google G Data
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google Guice
 
Evolving The Java Language
Evolving The Java LanguageEvolving The Java Language
Evolving The Java Language
 
MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2MVC and Razor - Doc. v1.2
MVC and Razor - Doc. v1.2
 
Mvc & java script
Mvc & java scriptMvc & java script
Mvc & java script
 
MongoDB Stitch Tutorial
MongoDB Stitch TutorialMongoDB Stitch Tutorial
MongoDB Stitch Tutorial
 
Google Guice
Google GuiceGoogle Guice
Google Guice
 

Semelhante a Vaadin DevDay 2017 - Data Binding in Vaadin 8

Semelhante a Vaadin DevDay 2017 - Data Binding in Vaadin 8 (20)

Building web apps with vaadin 8
Building web apps with vaadin 8Building web apps with vaadin 8
Building web apps with vaadin 8
 
Going web native
Going web nativeGoing web native
Going web native
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter LehtoJavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
JavaCro'14 - Building interactive web applications with Vaadin – Peter Lehto
 
Vaadin 7 by Joonas Lehtinen
Vaadin 7 by Joonas LehtinenVaadin 7 by Joonas Lehtinen
Vaadin 7 by Joonas Lehtinen
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
 
How to separate the f2 e and sde in web development for_taobao
How to separate the f2 e and sde in web development for_taobaoHow to separate the f2 e and sde in web development for_taobao
How to separate the f2 e and sde in web development for_taobao
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdf
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 
Lerman Vvs14 Ef Tips And Tricks
Lerman Vvs14  Ef Tips And TricksLerman Vvs14  Ef Tips And Tricks
Lerman Vvs14 Ef Tips And Tricks
 
Dependency rejection and TDD without Mocks
Dependency rejection and TDD without MocksDependency rejection and TDD without Mocks
Dependency rejection and TDD without Mocks
 
Dependency Rejection and TDD without Mocks
Dependency Rejection and TDD without MocksDependency Rejection and TDD without Mocks
Dependency Rejection and TDD without Mocks
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTech
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 

Último

JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
Max Lee
 

Último (20)

How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Benefits of Employee Monitoring Software
Benefits of  Employee Monitoring SoftwareBenefits of  Employee Monitoring Software
Benefits of Employee Monitoring Software
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with StrimziStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
 
OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfImplementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
CompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdfCompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdf
 
INGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignINGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by Design
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 

Vaadin DevDay 2017 - Data Binding in Vaadin 8

  • 1. B I N D I N G D ATA T O U I C O M P O N E N T S 5 S T O R Y A N D P H I L O S O P H Y Software is eating the world and what most of us see of it is the user interface. The user interface has become the key component of how the users experience the business behind it. Competition is lost or won due to user experience. Simplicity is king and the users get frustrated by anything ugly, slow or not working on the device they happen to use at the time. We at Vaadin fight for simplicity and invite everyone to join this fight. Together we want to build a user interface that puts a smile on the user’s face. Vaadin is the technology that empowers developers to build the best web-apps for business purposes. Our priority over everything else is developer productivity because we believe that by simplifying the developer experience and saving the developer’s time, they are best able to focus on building great user interfaces. Our brand is what we want everyone to think about us. When everyone - both us and the people around us - have a consistent understanding of what Vaadin is and what we stand for, it enables that image to spread and amplify. This book defines what we want that image to be. It defines what the Vaadin brand is. I hope that You are as excited and proud of living and breathing the Vaadin brand as I am. You are the one who is shaping what everyone thinks about Vaadin - using this brand as a tool and a guideline every day. Let’s fight for simplicity for both the users and the developers! Joonas Lehtinen Founder & CEO Vaadin I N T R O D U C T I O N @peter_lehto
  • 4. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions
  • 5. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T>
  • 6. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties?
  • 7. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 8. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 9. H o w w o u l d y o u e d i t c u s t o m e r r e c o r d s ? VAADIN 7
  • 10. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); Setters and Getters VAADIN 7
  • 11. Setters and Getters VAADIN 7 protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO();
  • 12. Setters and Getters VAADIN 7 protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } });
  • 13. Setters and Getters VAADIN 7 protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } });
  • 14. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); WHAT’S WRONG?
  • 15. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly WHAT’S WRONG?
  • 16. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly • Every Field has a Listener WHAT’S WRONG?
  • 17. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly • Every Field has a Listener • Implicit save, cannot discard WHAT’S WRONG?
  • 18. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly • Every Field has a Listener • Implicit save, cannot discard • Lots of code WHAT’S WRONG?
  • 19. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly • Every Field has a Listener • Implicit save, cannot discard • Lots of code • Prone to error and change WHAT’S WRONG?
  • 20. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); firstName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setFirstName(firstName.getValue()); } }); lastName.addValueChangeListener( new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { customer.setLastName(lastName.getValue()); } }); • Setters used explicitly • Every Field has a Listener • Implicit save, cannot discard • Lots of code • Prone to error and change • Invalid values not prevented WHAT’S WRONG?
  • 21. LET’S IMPROVE! protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO();
  • 22. LET’S IMPROVE! protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); }
  • 23. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } BENEFITS?
  • 24. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } BENEFITS? • Centralized value setting
  • 25. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } BENEFITS? • Centralized value setting • Validation could be added
  • 26. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } WHAT’S WRONG?
  • 27. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } • Setters used explicitly WHAT’S WRONG?
  • 28. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } • Setters used explicitly • Lots of code WHAT’S WRONG?
  • 29. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } • Setters used explicitly • Lots of code • Prone to error and change WHAT’S WRONG?
  • 30. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { customer.setFirstName(firstName.getValue()); customer.setLastName(lastName.getValue()); } }); } • Setters used explicitly • Lots of code • Prone to error and change • Hard to Validate WHAT’S WRONG?
  • 31. With properties VAADIN 7 protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO();
  • 32. With properties VAADIN 7 protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource( new BeanItem<CustomerDTO>(customer));
  • 33. With properties VAADIN 7 fieldGroup.setItemDataSource( new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } });
  • 34. BENEFITS? protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } });
  • 35. • No more explicit setters BENEFITS? protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } });
  • 36. • No more explicit setters • Committable / Discardable BENEFITS? protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } });
  • 37. • No more explicit setters • Committable / Discardable • Validation part of Commit BENEFITS? protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } });
  • 38. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } }); WHAT’S WRONG?
  • 39. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } }); • Not type safe WHAT’S WRONG?
  • 40. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } }); • Not type safe • Prone to error and change WHAT’S WRONG?
  • 41. protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); FieldGroup fieldGroup = new FieldGroup(); fieldGroup.bind(firstName, "firstName"); fieldGroup.bind(lastName, "lastName"); fieldGroup.setItemDataSource(new BeanItem<CustomerDTO>(customer)); Button save = new Button("Save", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { try { fieldGroup.commit(); } catch(CommitException e) { // show errors } } }); • Not type safe • Prone to error and change • BeanItem boiler plate and checked CommitException WHAT’S WRONG?
  • 42. # F F S
  • 45. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 46. c . v. u i . A b s t r a c t F i e l d < T > VAADIN 7 1 8 5 3 l o c 2 2 8 l o c VAADIN 8
  • 47. F i e l d G r o u p TO B i n d e r
  • 48. H o w w o u l d y o u e d i t c u s t o m e r r e c o r d s ? VAADIN 8
  • 49. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>();With Binder VAADIN 8
  • 50. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); With Binder VAADIN 8
  • 51. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); With Binder VAADIN 8
  • 52. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); Read Data? VAADIN 8
  • 53. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.readBean(customer); Read Data VAADIN 8
  • 54. VAADIN 8 TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.readBean(customer); Save Data?
  • 55. VAADIN 8 Save Data TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.readBean(customer); Button save = new Button("Save" , e -> binder.writeBeanIfValid(customer));
  • 56. Write directly VAADIN 8 TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.setBean(customer);
  • 57. C o n v e r s i o n
  • 58. TextField yearOfBirth = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); Conversion with Binding VAADIN 8
  • 59. TextField yearOfBirth = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) Conversion with Binding VAADIN 8
  • 60. TextField yearOfBirth = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withConverter(Integer::valueOf, String::valueOf) Conversion with Binding VAADIN 8
  • 61. TextField yearOfBirth = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withConverter(Integer::valueOf, String::valueOf) .bind( CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth); Conversion with Binding VAADIN 8
  • 62. Va l i d a t i o n
  • 63. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>();Validation with Binding VAADIN 8
  • 64. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.forField(firstName) Validation with Binding VAADIN 8
  • 65. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") Validation with Binding VAADIN 8
  • 66. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") .withValidator(value -> value.length() < 10, "Must be less than 10 chars") Validation with Binding VAADIN 8
  • 67. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") .withValidator(value -> value.length() < 10, "Must be less than 10 chars") .bind( CustomerDTO::getFirstname, CustomerDTO::setFirstname); Validation with Binding VAADIN 8
  • 68. TextField firstName = … TextField lastName = … CustomerDTO customer = … Binder<CustomerDTO> binder = new Binder<>(); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") .withValidator(value -> value.length() < 10, "Must be less than 10 chars") .bind( CustomerDTO::getFirstname, CustomerDTO::setFirstname); Button save = new Button(“Save", e -> binder.writeBeanIfValid(customer)); Validation with Binding VAADIN 8
  • 69. Va l i d a t i o n w i t h C o n v e r s i o n
  • 70. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>();Validation with Conversion VAADIN 8
  • 71. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) Validation with Conversion VAADIN 8
  • 72. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") Validation with Conversion VAADIN 8
  • 73. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) Validation with Conversion VAADIN 8
  • 74. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value > 2000, "Must be after year 2000") Validation with Conversion VAADIN 8
  • 75. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value > 2000, "Must be after year 2000") .bind(CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth); Validation with Conversion VAADIN 8
  • 76. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); Binder<CustomerDTO> binder = new Binder<>(); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value > 2000, "Must be after year 2000") .bind(CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth); Button save = new Button("Save", e -> { try { binder.writeBean(customer); } catch (ValidationException ve) { ve.getFieldValidationErrors().forEach(error -> …); } }); Validation with Conversion VAADIN 8
  • 77. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 78. c . v. u i . C u s t o m F i e l d < T >
  • 79. c . v. u i . C u s t o m F i e l d < T > F o r m a k i n g F i e l d s f o r y o u r b u s i n e s s t y p e s
  • 80. CUSTOMFIELD public class MoneyField extends CustomField<Money> {
  • 81. CUSTOMFIELD public class MoneyField extends CustomField<Money> { private TextField textField; private Label currencyCode;
  • 82. CUSTOMFIELD public class MoneyField extends CustomField<Money> { private TextField textField; private Label currencyCode; private BigDecimal parseValue() throws ParseException { return …; } private String formatValue(BigDecimal parsedValue) { return …; }
  • 83. CUSTOMFIELD public class MoneyField extends CustomField<Money> { private TextField textField; private Label currencyCode; private BigDecimal parseValue() throws ParseException { return …; } private String formatValue(BigDecimal parsedValue) { return …; } public Money getValue() { if (StringUtils.isEmpty(textField.getValue())) { return null; } try { return Money.of(currencyCode.getValue(), parseValue()); } catch (ParseException e) { textField.setComponentError(new UserError("Invalid format”)); return null; } }
  • 84. protected void doSetValue(Money value) { if (value == null) { textField.clear(); currencyCode.setValue(null); } else { textField.setValue(formatValue(value.getAmount())); currencyCode.setValue(value.getCurrencyCode()); } }
  • 85. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 86. c . v. d a t a . I t e m TO < T >
  • 87. C o m b o B o x C o m b o B o x < C o u n t r y > TO
  • 88. C o u n t r y c = ( C o u n t r y ) c o m b o B o x . g e t V a l u e ( ) TO C o u n t r y c = c o m b o B o x . g e t V a l u e ( )
  • 89. H o w w o u l d y o u m a k e a d r o p d o w n o f c o u n t r i e s ? VAADIN 7
  • 90. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class);
  • 91. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries());
  • 92. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox();
  • 93. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container);
  • 94. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container); countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY);
  • 95. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container); countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY); countrySelector.setItemCaptionPropertyId("name");
  • 96. H o w w o u l d y o u m a k e a d r o p d o w n o f c o u n t r i e s ? VAADIN 8
  • 98. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItemCaptionGenerator(Country::getName); countrySelector.setItems(getCountries());
  • 99. H o w w o u l d y o u f i l t e r e n t r i e s i n a d r o p d o w n ? VAADIN 7
  • 100.
  • 101. N e t h e r l a n d s , a n y o n e ?
  • 103. H o w w o u l d y o u f i l t e r e n t r i e s i n a d r o p d o w n ? VAADIN 8
  • 104. D a t a P r o v i d e r < T Y P E , F I LT E R >
  • 105. Session’s content • Average day with Vaadin 7 • Binder, Java 8 and Functions • Binding custom data types with CustomField<T> • Where are my Items & Properties? • How to be as Lazy as possible?
  • 106. D a t a P r o v i d e r < C o u n t r y, S t r i n g >
  • 107. public interface DataProvider<T, F> { int size(Query<T, F> query); Stream<T> fetch(Query<T, F> query); }
  • 108. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItemCaptionGenerator(Country::getName); countrySelector.setDataProvider(
  • 109. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItemCaptionGenerator(Country::getName); countrySelector.setDataProvider( (filter, offset, limit) -> countryService.getCountries(filter, offset, limit),
  • 110. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItemCaptionGenerator(Country::getName); countrySelector.setDataProvider( (filter, offset, limit) -> countryService.getCountries(filter, offset, limit), (filter) -> countryService.size(filter));
  • 111. D a t a P r o v i d e r < C o u n t r y, S t r i n g > java.util.function.Predicate<T> CriteriaQuery.where(...) Service.findCountries(String)
  • 112. P l u g i n t o a n y d a t a s o u r c e l a z i l y !
  • 113. Q u e r y < T Y P E , F I LT E R >
  • 114. public class Query<TYPE, FILTER> { int getOffset(); int getLimit(); }
  • 115. public class Query<TYPE, FILTER> { int getOffset(); int getLimit(); List<QuerySortOrder> getSortOrders(); }
  • 116. public class Query<TYPE, FILTER> { int getOffset(); int getLimit(); List<QuerySortOrder> getSortOrders(); Comparator<TYPE> getInMemorySorting(); }
  • 117. public class Query<TYPE, FILTER> { int getOffset(); int getLimit(); List<QuerySortOrder> getSortOrders(); Comparator<TYPE> getInMemorySorting(); Optional<FILTER> getFilter(); }
  • 118. T h e c l a s s i c C o n t a i n e r d i s c r e p a n c y VAADIN 7
  • 119. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld"); grid.setContainerDataSource( new BeanItemContainer<>(CustomerDTO.class));
  • 120. HTTP Status 500 - com.vaadin.server.ServiceException: java.lang.IllegalStateException: Found at least one column in Grid that does not exist in the given container: yearsOld with the header “Years Old”. Call removeAllColumns() before setContainerDataSource() if you want to reconfigure the columns based on the new container.
  • 121. # F F S
  • 122. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld");
  • 123. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld"); GeneratedPropertyContainer generatedProps = new GeneratedPropertyContainer( new BeanItemContainer<>(CustomerDTO.class)); generatedProps.addContainerProperty("yearsOld", Integer.class, null); grid.setContainerDataSource(generatedProps);
  • 124. HTTP Status 500 - com.vaadin.server.ServiceException: java.lang.UnsupportedOperationException: GeneratedPropertyContainer does not support adding properties.
  • 125. # F F S THIS ISN’T FUN ANYMORE…
  • 126. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld"); GeneratedPropertyContainer generatedProps = new GeneratedPropertyContainer( new BeanItemContainer<>(CustomerDTO.class)); grid.setContainerDataSource(generatedProps);
  • 127. generatedProps.addGeneratedProperty("yearsOld", new PropertyValueGenerator<Integer>() { @Override public Class<Integer> getType() { return Integer.class; } @Override public Integer getValue(Item item, Object itemId, Object propertyId) { return LocalDate.now().getYear() - ((CustomerDTO)itemId).getYearOfBirth(); } });
  • 128. # F F S OH REALLY!?
  • 129. B y e B y e C o n t a i n e r s ; w e ’ v e h a d e n o u g h ! VAADIN 8
  • 130. Grid<CustomerDTO> grid = new Grid<>();
  • 131. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn(Customer::getFirstName);
  • 132. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn(Customer::getFirstName); grid.addColumn(Customer::getLastName);
  • 133. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn(Customer::getFirstName); grid.addColumn(Customer::getLastName); grid.addColumn(customer -> String.valueOf(LocalDate.now().getYear() - customer.getYearOfBirth()));
  • 135. Lessons learned • Vaadin 8 - built on Java 8
  • 136. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large
  • 137. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large • Data binding completely redone
  • 138. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large • Data binding completely redone • Targets simplifications and flexibility, #FFS
  • 139. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large • Data binding completely redone • Targets simplifications and flexibility, #FFS • Drops Containers, Items and Properties
  • 140. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large • Data binding completely redone • Targets simplifications and flexibility, #FFS • Drops Containers, Items and Properties • Gathers all data binding to Binder, simplifies Fields
  • 141. @peter_lehto T H A N K Y O U !