SlideShare a Scribd company logo
B U S I N E S S D ATA B I N D I N G
FOR VAADIN (8) APPLICATIONPETER LEHTO
@peter_lehto
Session’s content
• The Good Ol’ Boy - Vaadin 7
• The Brand New Field Model of Vaadin 8
• CustomField<T>
• Where are my Items & Properties?
• Being Lazy & Happy without Containers
Session’s content
• The Good Ol’ Boy - Vaadin 7
• The Brand New Field Model of Vaadin 8
• CustomField<T>
• Where are my Items & Properties?
• Being Lazy & Happy without Containers
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
@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
No data binding
VAADIN 7
@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout();
TextField firstName = new TextField("Firstname");
TextField lastName = new TextField("Lastname");
CustomerDTO customer = new CustomerDTO();
No data binding
VAADIN 7
@Override
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());
}
});
No data binding
VAADIN 7
@Override
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());
}
});
No data binding
VAADIN 7
@Override
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());
}
});
layout.addComponents(firstName, lastName);
setContent(layout);
}
No data binding
VAADIN 7
@Override
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());
}
});
layout.addComponents(firstName, lastName);
setContent(layout);
}
• Setters used explicitly
• Every Field has a Listener
• No way to Save / Cancel
• Lots of code
• Prone to error and change
• Invalid values not prevented
WHAT’S WRONG?
@Override
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!
@Override
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());
}
});
layout.addComponents(firstName, lastName, save);
setContent(layout);
}
LET’S IMPROVE!
• Centralized value setting
• Validation could be added
BENEFITS? @Override
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());
}
});
layout.addComponents(firstName, lastName, save);
setContent(layout);
}
• Setters used explicitly
• Lots of code
• Prone to error and change
• Hard to Validate
@Override
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());
}
});
layout.addComponents(firstName, lastName, save);
setContent(layout);
}
WHAT’S WRONG?
@Override
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
@Override
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
With properties
VAADIN 7
@Override
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
@Override
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
}
}
});
BENEFITS?
• Not type safe
• Prone to error and change
• BeanItem boiler plate and
Checked CommitException
@Override
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?
# F F S
FIGHT FOR SIMPLICITY ;)
Session’s content
• The Good Ol’ Boy - Vaadin 7
• The Brand New Field Model of Vaadin 8
• CustomField<T>
• Where are my Items & Properties?
• Being Lazy & Happy without Containers
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 1 3 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 = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname);
With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname);
With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.readBean(customer);
With Binder
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.readBean(customer);
Commit / Discard?
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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));
Button discard = new Button("Discard" , e -> binder.removeBean());
Commit / Discard?
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname);
binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname);
binder.setBean(customer);
Without Buffering?
VAADIN 8
C o n v e r s i o n
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
.withConverter(Integer::valueOf, String::valueOf)
Conversion with
Binding
VAADIN 8
TextField yearOfBirth = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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 = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(firstName)
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(firstName)
.withValidator(Validator::notEmpty, "Mandatory field")
Validation with
Binding
VAADIN 8
TextField firstName = …
TextField lastName = …
CustomerDTO customer = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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 = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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 = …
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4, "Must have 4 characters")
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
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);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4, "Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value < 2000, "Must be before year 2000")
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4, "Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value < 2000, "Must be before year 2000")
.bind(CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth);
Validation with
Conversion
VAADIN 8
TextField yearOfBirth = …
Customer customer = …
customer.setYearOfBirth(1984);
BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);
binder.forField(yearOfBirth)
.withValidator(value -> value.length() == 4, "Must have 4 characters")
.withConverter(Integer::valueOf, String::valueOf)
.withValidator(value -> value < 2000, "Must be before 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
• The Good Ol’ Boy - Vaadin 7
• The Brand New Field Model of Vaadin 8
• CustomField<T>
• Where are my Items & Properties?
• Being Lazy & Happy without Containers
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
• The Good Ol’ Boy - Vaadin 7
• The Brand New Field Model of Vaadin 8
• CustomField<T>
• Where are my Items & Properties?
• Being Lazy & Happy without Containers
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<>();
countrySelector.setItems(getCountries());
ComboBox<Country> countrySelector = new ComboBox<>();
countrySelector.setItems(getCountries());
countrySelector.setItemCaptionGenerator(Country::getName);
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 < C o u n t r y, S t r i n g >
countrySelector.setDataProvider(DataProvider<Country, String> dataProvider)
countrySelector.setDataProvider(DataProvider<Country, String> dataProvider)
public interface DataProvider<Country, String> {
int size(Query<String> t);
Stream<Country> fetch(Query<String> query);
}
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 >
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 < F >
public class Query<F> {
int getOffset();
int getLimit();
List<SortOrder<String>> getSortOrders();
Optional<F> 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("firstName", customer -> customer.getFirstname());
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn("firstName", customer -> customer.getFirstname());
grid.addColumn("lastName", customer -> customer.getLastname());
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn("firstName", customer -> customer.getFirstname());
grid.addColumn("lastName", customer -> customer.getLastname());
grid.addColumn("yearsOld",
customer -> String.valueOf(LocalDate.now().getYear() -
customer.getYearOfBirth()));
Grid<CustomerDTO> grid = new Grid<>();
grid.addColumn("firstName", customer -> customer.getFirstname());
grid.addColumn("lastName", customer -> customer.getLastname());
grid.addColumn("yearsOld",
customer -> String.valueOf(LocalDate.now().getYear() -
customer.getYearOfBirth()));
grid.setDataProvider(DataProvider<CustomerDTO, F> customerDataProvider);
Lessons learned
• Vaadin 8 - built on Java 8
• Lambdas and Functional paradigm at large
• DataBinding completely redone
• Targets simplifications and flexibility
• Drops Containers, Items and Properties
• Gathers all DataBinding to Binder
T H A N K Y O U !
PLEASE RATE THE TALK
@
FLIP CHART BY THE DOOR!
@peter_lehto

More Related Content

What's hot

Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020
Jerry Liao
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
Michelangelo van Dam
 
Modern Android Architecture
Modern Android ArchitectureModern Android Architecture
Modern Android Architecture
Eric Maxwell
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
markstory
 
Autopsy Of A Widget
Autopsy Of A WidgetAutopsy Of A Widget
Autopsy Of A Widget
Fabian Jakobs
 
Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014
Paris Android User Group
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
Jana Karceska
 
Uma introdução ao framework Spring
Uma introdução ao framework SpringUma introdução ao framework Spring
Uma introdução ao framework Spring
elliando dias
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
Michelangelo van Dam
 
Why You Shouldn't Write OO
Why You Shouldn't Write OO Why You Shouldn't Write OO
Why You Shouldn't Write OO
Yehuda Katz
 
appengine java night #1
appengine java night #1appengine java night #1
appengine java night #1
Shinichi Ogawa
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
Clinton Dreisbach
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
DrupalCamp Kyiv
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Data20161007
Data20161007Data20161007
Data20161007
capegmail
 

What's hot (17)

Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Modern Android Architecture
Modern Android ArchitectureModern Android Architecture
Modern Android Architecture
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Autopsy Of A Widget
Autopsy Of A WidgetAutopsy Of A Widget
Autopsy Of A Widget
 
Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014Deep dive into android restoration - DroidCon Paris 2014
Deep dive into android restoration - DroidCon Paris 2014
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
 
Uma introdução ao framework Spring
Uma introdução ao framework SpringUma introdução ao framework Spring
Uma introdução ao framework Spring
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Why You Shouldn't Write OO
Why You Shouldn't Write OO Why You Shouldn't Write OO
Why You Shouldn't Write OO
 
appengine java night #1
appengine java night #1appengine java night #1
appengine java night #1
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICESONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Data20161007
Data20161007Data20161007
Data20161007
 

Viewers also liked

Vaadin 8 with Spring Framework
Vaadin 8 with Spring FrameworkVaadin 8 with Spring Framework
Vaadin 8 with Spring Framework
Peter Lehto
 
Building web apps with Vaadin 8
Building web apps with Vaadin 8 Building web apps with Vaadin 8
Building web apps with Vaadin 8
Marcus Hellberg
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin components
Peter Lehto
 
Techlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with VaadinTechlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with Vaadin
Peter Lehto
 
Building impressive layout systems with vaadin
Building impressive layout systems with vaadinBuilding impressive layout systems with vaadin
Building impressive layout systems with vaadin
Peter Lehto
 
GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
Peter Lehto
 
Vaadin with Java EE 7
Vaadin with Java EE 7Vaadin with Java EE 7
Vaadin with Java EE 7
Peter Lehto
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - Workshop
Peter Lehto
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
hezamu
 
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.createRemote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Peter Lehto
 
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
Peter Lehto
 
Vaadin 7 - Java Enterprise Edition integration
Vaadin 7 - Java Enterprise Edition integrationVaadin 7 - Java Enterprise Edition integration
Vaadin 7 - Java Enterprise Edition integration
Peter Lehto
 
Día internacional de la mujer. 2017. mujer y discapacidad.
Día internacional de la mujer. 2017. mujer y discapacidad.Día internacional de la mujer. 2017. mujer y discapacidad.
Día internacional de la mujer. 2017. mujer y discapacidad.
José María
 
Catalogo galleggianti idro stop
Catalogo galleggianti idro stopCatalogo galleggianti idro stop
Catalogo galleggianti idro stop
Autosystem Srl
 
Cosolvency
CosolvencyCosolvency
Cosolvency
Rajesh Raut
 
Learning Hub in Ambala ! Batra Computer Centre
Learning Hub in Ambala ! Batra Computer CentreLearning Hub in Ambala ! Batra Computer Centre
Learning Hub in Ambala ! Batra Computer Centre
jatin batra
 
Modul 8
Modul 8Modul 8
Modul 8
padlah1984
 
Social media is social business
Social media is social business  Social media is social business
Social media is social business
Intuit Inc.
 
Panel wim (2)
Panel wim (2)Panel wim (2)
Panel wim (2)
Camila Reed
 
Metolar-XR (Metoprolol Capsules)
Metolar-XR  (Metoprolol Capsules)Metolar-XR  (Metoprolol Capsules)
Metolar-XR (Metoprolol Capsules)
Clearsky Pharmacy
 

Viewers also liked (20)

Vaadin 8 with Spring Framework
Vaadin 8 with Spring FrameworkVaadin 8 with Spring Framework
Vaadin 8 with Spring Framework
 
Building web apps with Vaadin 8
Building web apps with Vaadin 8 Building web apps with Vaadin 8
Building web apps with Vaadin 8
 
Binding business data to vaadin components
Binding business data to vaadin componentsBinding business data to vaadin components
Binding business data to vaadin components
 
Techlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with VaadinTechlunch - Dependency Injection with Vaadin
Techlunch - Dependency Injection with Vaadin
 
Building impressive layout systems with vaadin
Building impressive layout systems with vaadinBuilding impressive layout systems with vaadin
Building impressive layout systems with vaadin
 
GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
 
Vaadin with Java EE 7
Vaadin with Java EE 7Vaadin with Java EE 7
Vaadin with Java EE 7
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - Workshop
 
Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014Functional UIs with Java 8 and Vaadin JavaOne2014
Functional UIs with Java 8 and Vaadin JavaOne2014
 
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.createRemote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
 
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
Remote controlling Parrot AR Drone with Spring Boot & Vaadin (JavaCro15)
 
Vaadin 7 - Java Enterprise Edition integration
Vaadin 7 - Java Enterprise Edition integrationVaadin 7 - Java Enterprise Edition integration
Vaadin 7 - Java Enterprise Edition integration
 
Día internacional de la mujer. 2017. mujer y discapacidad.
Día internacional de la mujer. 2017. mujer y discapacidad.Día internacional de la mujer. 2017. mujer y discapacidad.
Día internacional de la mujer. 2017. mujer y discapacidad.
 
Catalogo galleggianti idro stop
Catalogo galleggianti idro stopCatalogo galleggianti idro stop
Catalogo galleggianti idro stop
 
Cosolvency
CosolvencyCosolvency
Cosolvency
 
Learning Hub in Ambala ! Batra Computer Centre
Learning Hub in Ambala ! Batra Computer CentreLearning Hub in Ambala ! Batra Computer Centre
Learning Hub in Ambala ! Batra Computer Centre
 
Modul 8
Modul 8Modul 8
Modul 8
 
Social media is social business
Social media is social business  Social media is social business
Social media is social business
 
Panel wim (2)
Panel wim (2)Panel wim (2)
Panel wim (2)
 
Metolar-XR (Metoprolol Capsules)
Metolar-XR  (Metoprolol Capsules)Metolar-XR  (Metoprolol Capsules)
Metolar-XR (Metoprolol Capsules)
 

Similar to Vaadin 8 - Data Binding with Binder

Vaadin7
Vaadin7Vaadin7
Vaadin 7 FieldGroup & Converter
Vaadin 7 FieldGroup & ConverterVaadin 7 FieldGroup & Converter
Vaadin 7 FieldGroup & Converter
Nicolas Fränkel
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
Matteo Baglini
 
MaintainStaffTable
MaintainStaffTableMaintainStaffTable
MaintainStaffTable
William Rutherford
 
Easy Button
Easy ButtonEasy Button
Easy Button
Adam Dale
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1
Chris Huang
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
Darwin Durand
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
Andres Almiray
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
JavaDayUA
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
Joonas Lehtinen
 
An intro to cqrs
An intro to cqrsAn intro to cqrs
An intro to cqrs
Neil Robbins
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
sudhirchourasia86
 
ES2015 New Features
ES2015 New FeaturesES2015 New Features
ES2015 New Features
Giacomo Zinetti
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
stuq
 
Vaadin7
Vaadin7Vaadin7
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
Chris Weldon
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
Martijn Dashorst
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
Joonas Lehtinen
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
Mateusz Zalewski
 
Beautiful java script
Beautiful java scriptBeautiful java script
Beautiful java script
Ürgo Ringo
 

Similar to Vaadin 8 - Data Binding with Binder (20)

Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Vaadin 7 FieldGroup & Converter
Vaadin 7 FieldGroup & ConverterVaadin 7 FieldGroup & Converter
Vaadin 7 FieldGroup & Converter
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
 
MaintainStaffTable
MaintainStaffTableMaintainStaffTable
MaintainStaffTable
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1重構—改善既有程式的設計(chapter 8)part 1
重構—改善既有程式的設計(chapter 8)part 1
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
An intro to cqrs
An intro to cqrsAn intro to cqrs
An intro to cqrs
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
 
ES2015 New Features
ES2015 New FeaturesES2015 New Features
ES2015 New Features
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Apache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a treeApache Wicket and Java EE sitting in a tree
Apache Wicket and Java EE sitting in a tree
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
Beautiful java script
Beautiful java scriptBeautiful java script
Beautiful java script
 

Recently uploaded

Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
TaghreedAltamimi
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
VALiNTRY360
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
Rakesh Kumar R
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 

Recently uploaded (20)

Lecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptxLecture 2 - software testing SE 412.pptx
Lecture 2 - software testing SE 412.pptx
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
What next after learning python programming basics
What next after learning python programming basicsWhat next after learning python programming basics
What next after learning python programming basics
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 

Vaadin 8 - Data Binding with Binder

  • 1. B U S I N E S S D ATA B I N D I N G FOR VAADIN (8) APPLICATIONPETER LEHTO @peter_lehto
  • 2. Session’s content • The Good Ol’ Boy - Vaadin 7 • The Brand New Field Model of Vaadin 8 • CustomField<T> • Where are my Items & Properties? • Being Lazy & Happy without Containers
  • 3. Session’s content • The Good Ol’ Boy - Vaadin 7 • The Brand New Field Model of Vaadin 8 • CustomField<T> • Where are my Items & Properties? • Being Lazy & Happy without Containers
  • 4. 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
  • 5. @Override protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); No data binding VAADIN 7
  • 6. @Override protected void init(VaadinRequest vaadinRequest) { VerticalLayout layout = new VerticalLayout(); TextField firstName = new TextField("Firstname"); TextField lastName = new TextField("Lastname"); CustomerDTO customer = new CustomerDTO(); No data binding VAADIN 7
  • 7. @Override 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()); } }); No data binding VAADIN 7
  • 8. @Override 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()); } }); No data binding VAADIN 7
  • 9. @Override 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()); } }); layout.addComponents(firstName, lastName); setContent(layout); } No data binding VAADIN 7
  • 10. @Override 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()); } }); layout.addComponents(firstName, lastName); setContent(layout); } • Setters used explicitly • Every Field has a Listener • No way to Save / Cancel • Lots of code • Prone to error and change • Invalid values not prevented WHAT’S WRONG?
  • 11. @Override 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!
  • 12. @Override 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()); } }); layout.addComponents(firstName, lastName, save); setContent(layout); } LET’S IMPROVE!
  • 13. • Centralized value setting • Validation could be added BENEFITS? @Override 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()); } }); layout.addComponents(firstName, lastName, save); setContent(layout); }
  • 14. • Setters used explicitly • Lots of code • Prone to error and change • Hard to Validate @Override 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()); } }); layout.addComponents(firstName, lastName, save); setContent(layout); } WHAT’S WRONG?
  • 15. @Override 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
  • 16. @Override 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
  • 17. With properties VAADIN 7 @Override 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 } } });
  • 18. • No more explicit setters • Committable / Discardable • Validation part of Commit @Override 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 } } }); BENEFITS?
  • 19. • Not type safe • Prone to error and change • BeanItem boiler plate and Checked CommitException @Override 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?
  • 20. # F F S FIGHT FOR SIMPLICITY ;)
  • 21. Session’s content • The Good Ol’ Boy - Vaadin 7 • The Brand New Field Model of Vaadin 8 • CustomField<T> • Where are my Items & Properties? • Being Lazy & Happy without Containers
  • 22. 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 1 3 l o c VAADIN 8
  • 23. F i e l d G r o u p TO B i n d e r
  • 24. 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
  • 25. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);With Binder VAADIN 8
  • 26. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); With Binder VAADIN 8
  • 27. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); With Binder VAADIN 8
  • 28. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.readBean(customer); With Binder VAADIN 8
  • 29. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.readBean(customer); Commit / Discard? VAADIN 8
  • 30. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); 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)); Button discard = new Button("Discard" , e -> binder.removeBean()); Commit / Discard? VAADIN 8
  • 31. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.bind(firstName, CustomerDTO::getFirstname, CustomerDTO::setFirstname); binder.bind(lastName, CustomerDTO::getLastname, CustomerDTO::setLastname); binder.setBean(customer); Without Buffering? VAADIN 8
  • 32. C o n v e r s i o n
  • 33. TextField yearOfBirth = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); Conversion with Binding VAADIN 8
  • 34. TextField yearOfBirth = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) Conversion with Binding VAADIN 8
  • 35. TextField yearOfBirth = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withConverter(Integer::valueOf, String::valueOf) Conversion with Binding VAADIN 8
  • 36. TextField yearOfBirth = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withConverter(Integer::valueOf, String::valueOf) .bind(CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth); Conversion with Binding VAADIN 8
  • 37. Va l i d a t i o n
  • 38. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);Validation with Binding VAADIN 8
  • 39. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(firstName) Validation with Binding VAADIN 8
  • 40. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") Validation with Binding VAADIN 8
  • 41. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(firstName) .withValidator(Validator::notEmpty, "Mandatory field") .withValidator(value -> value.length() < 10, "Must be less than 10 chars") Validation with Binding VAADIN 8
  • 42. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); 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
  • 43. TextField firstName = … TextField lastName = … CustomerDTO customer = … BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); 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
  • 44. Va l i d a t i o n w i t h C o n v e r s i o n
  • 45. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class);Validation with Conversion VAADIN 8
  • 46. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) Validation with Conversion VAADIN 8
  • 47. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") Validation with Conversion VAADIN 8
  • 48. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) Validation with Conversion VAADIN 8
  • 49. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value < 2000, "Must be before year 2000") Validation with Conversion VAADIN 8
  • 50. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value < 2000, "Must be before year 2000") .bind(CustomerDTO::getYearOfBirth, CustomerDTO::setYearOfBirth); Validation with Conversion VAADIN 8
  • 51. TextField yearOfBirth = … Customer customer = … customer.setYearOfBirth(1984); BeanBinder<CustomerDTO> binder = new BeanBinder<>(CustomerDTO.class); binder.forField(yearOfBirth) .withValidator(value -> value.length() == 4, "Must have 4 characters") .withConverter(Integer::valueOf, String::valueOf) .withValidator(value -> value < 2000, "Must be before 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
  • 52. Session’s content • The Good Ol’ Boy - Vaadin 7 • The Brand New Field Model of Vaadin 8 • CustomField<T> • Where are my Items & Properties? • Being Lazy & Happy without Containers
  • 53. c . v. u i . C u s t o m F i e l d < T >
  • 54. 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
  • 55. CUSTOMFIELD public class MoneyField extends CustomField<Money> {
  • 56. CUSTOMFIELD public class MoneyField extends CustomField<Money> { private TextField textField; private Label currencyCode;
  • 57. 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 …; }
  • 58. 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; } }
  • 59. protected void doSetValue(Money value) { if (value == null) { textField.clear(); currencyCode.setValue(null); } else { textField.setValue(formatValue(value.getAmount())); currencyCode.setValue(value.getCurrencyCode()); } }
  • 60. Session’s content • The Good Ol’ Boy - Vaadin 7 • The Brand New Field Model of Vaadin 8 • CustomField<T> • Where are my Items & Properties? • Being Lazy & Happy without Containers
  • 61. c . v. d a t a . I t e m TO < T >
  • 62. C o m b o B o x C o m b o B o x < C o u n t r y > TO
  • 63. 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 ( )
  • 64. 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
  • 65. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class);
  • 66. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries());
  • 67. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox();
  • 68. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container);
  • 69. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container); countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY);
  • 70. BeanItemContainer<Country> container = new BeanItemContainer<>(Country.class); container.addAll(getCountries()); ComboBox countrySelector = new ComboBox(); countrySelector.setContainerDataSource(container); countrySelector.setItemCaptionMode(ItemCaptionMode.PROPERTY); countrySelector.setItemCaptionPropertyId("name");
  • 71. 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
  • 72. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItems(getCountries());
  • 73. ComboBox<Country> countrySelector = new ComboBox<>(); countrySelector.setItems(getCountries()); countrySelector.setItemCaptionGenerator(Country::getName);
  • 74. 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
  • 75.
  • 76. N e t h e r l a n d s , a n y o n e ?
  • 78. 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
  • 79. 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 >
  • 81. countrySelector.setDataProvider(DataProvider<Country, String> dataProvider) public interface DataProvider<Country, String> { int size(Query<String> t); Stream<Country> fetch(Query<String> query); }
  • 82. 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 >
  • 83. 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)
  • 84. 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 !
  • 85. Q u e r y < F >
  • 86. public class Query<F> { int getOffset(); int getLimit(); List<SortOrder<String>> getSortOrders(); Optional<F> getFilter(); }
  • 87. 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
  • 88. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld"); grid.setContainerDataSource( new BeanItemContainer<>(CustomerDTO.class));
  • 89. 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.
  • 90. # F F S
  • 91. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld");
  • 92. 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);
  • 93. HTTP Status 500 - com.vaadin.server.ServiceException: java.lang.UnsupportedOperationException: GeneratedPropertyContainer does not support adding properties.
  • 94. # F F S THIS ISN’T FUN ANYMORE…
  • 95. Grid grid = new Grid(); grid.addColumn("firstName"); grid.addColumn("lastName"); grid.addColumn("yearsOld"); GeneratedPropertyContainer generatedProps = new GeneratedPropertyContainer( new BeanItemContainer<>(CustomerDTO.class)); grid.setContainerDataSource(generatedProps);
  • 96. 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(); } });
  • 97. # F F S OH REALLY!?
  • 98. 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
  • 99. Grid<CustomerDTO> grid = new Grid<>();
  • 100. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn("firstName", customer -> customer.getFirstname());
  • 101. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn("firstName", customer -> customer.getFirstname()); grid.addColumn("lastName", customer -> customer.getLastname());
  • 102. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn("firstName", customer -> customer.getFirstname()); grid.addColumn("lastName", customer -> customer.getLastname()); grid.addColumn("yearsOld", customer -> String.valueOf(LocalDate.now().getYear() - customer.getYearOfBirth()));
  • 103. Grid<CustomerDTO> grid = new Grid<>(); grid.addColumn("firstName", customer -> customer.getFirstname()); grid.addColumn("lastName", customer -> customer.getLastname()); grid.addColumn("yearsOld", customer -> String.valueOf(LocalDate.now().getYear() - customer.getYearOfBirth())); grid.setDataProvider(DataProvider<CustomerDTO, F> customerDataProvider);
  • 104. Lessons learned • Vaadin 8 - built on Java 8 • Lambdas and Functional paradigm at large • DataBinding completely redone • Targets simplifications and flexibility • Drops Containers, Items and Properties • Gathers all DataBinding to Binder
  • 105. T H A N K Y O U ! PLEASE RATE THE TALK @ FLIP CHART BY THE DOOR! @peter_lehto