+ All Categories
Home > Software > Vaadin DevDay 2017 - Data Binding in Vaadin 8

Vaadin DevDay 2017 - Data Binding in Vaadin 8

Date post: 22-Jan-2018
Category:
Upload: peter-lehto
View: 313 times
Download: 10 times
Share this document with a friend
141
BINDING DATA TO UI COMPONENTS @peter_lehto
Transcript

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 pTO

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 8TextField 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 8Save 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 8TextField 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 withBinding

VAADIN 8

TextField yearOfBirth = …

customer.setYearOfBirth(1984);

Binder<CustomerDTO> binder = new Binder<>();

binder.forField(yearOfBirth)

Conversion withBinding

VAADIN 8

TextField yearOfBirth = …

customer.setYearOfBirth(1984);

Binder<CustomerDTO> binder = new Binder<>();

binder.forField(yearOfBirth) .withConverter(Integer::valueOf, String::valueOf)

Conversion withBinding

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 withBinding

VAADIN 8

Va l i d a t i o n

TextField firstName = …TextField lastName = …

CustomerDTO customer = …

Binder<CustomerDTO> binder = new Binder<>();Validation withBinding

VAADIN 8

TextField firstName = …TextField lastName = …

CustomerDTO customer = …

Binder<CustomerDTO> binder = new Binder<>();

binder.forField(firstName)

Validation withBinding

VAADIN 8

TextField firstName = …TextField lastName = …

CustomerDTO customer = …

Binder<CustomerDTO> binder = new Binder<>();

binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field")

Validation withBinding

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 withBinding

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 withBinding

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 withBinding

VAADIN 8

Va l i d a t i o nw 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 withConversion

VAADIN 8

TextField yearOfBirth = …Customer customer = …

customer.setYearOfBirth(1984);

Binder<CustomerDTO> binder = new Binder<>();

binder.forField(yearOfBirth)

Validation withConversion

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 withConversion

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 withConversion

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 withConversion

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 withConversion

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 withConversion

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 rb u s i n e s s t y p e s

CUSTOMFIELDpublic class MoneyField extends CustomField<Money> {

CUSTOMFIELDpublic class MoneyField extends CustomField<Money> {

private TextField textField; private Label currencyCode;

CUSTOMFIELDpublic class MoneyField extends CustomField<Money> {

private TextField textField; private Label currencyCode;

private BigDecimal parseValue() throws ParseException { return …; }

private String formatValue(BigDecimal parsedValue) { return …; }

CUSTOMFIELDpublic 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 mTO

< 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 STHIS 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 SOH 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 !


Recommended