0
# Data Binding
1
2
Vaadin's data binding system provides two-way synchronization between UI components and Java objects (beans). It includes validation, conversion, and automatic form handling with comprehensive error management.
3
4
## Core Imports
5
6
```java
7
// Data binding core classes
8
import com.vaadin.flow.data.binder.Binder;
9
import com.vaadin.flow.data.binder.BeanBinder;
10
import com.vaadin.flow.data.binder.Binding;
11
import com.vaadin.flow.data.binder.BindingBuilder;
12
import com.vaadin.flow.data.binder.BindingValidationStatus;
13
import com.vaadin.flow.data.binder.BinderValidationStatus;
14
15
// Validation
16
import com.vaadin.flow.data.validator.Validator;
17
import com.vaadin.flow.data.validator.ValidationResult;
18
import com.vaadin.flow.data.validator.StringLengthValidator;
19
import com.vaadin.flow.data.validator.EmailValidator;
20
import com.vaadin.flow.data.validator.RegexpValidator;
21
import com.vaadin.flow.data.validator.RangeValidator;
22
import com.vaadin.flow.data.validator.DateRangeValidator;
23
import com.vaadin.flow.data.validator.BeanValidator;
24
25
// Conversion
26
import com.vaadin.flow.data.converter.Converter;
27
import com.vaadin.flow.data.converter.StringToIntegerConverter;
28
import com.vaadin.flow.data.converter.StringToDoubleConverter;
29
import com.vaadin.flow.data.converter.StringToBigDecimalConverter;
30
import com.vaadin.flow.data.converter.StringToDateConverter;
31
import com.vaadin.flow.data.converter.StringToBooleanConverter;
32
import com.vaadin.flow.data.converter.LocalDateToDateConverter;
33
import com.vaadin.flow.data.converter.DateToLocalDateConverter;
34
35
// Value providers and property access
36
import com.vaadin.flow.function.ValueProvider;
37
import com.vaadin.flow.function.SerializableFunction;
38
import com.vaadin.flow.function.SerializablePredicate;
39
import com.vaadin.flow.function.SerializableBiConsumer;
40
import com.vaadin.flow.data.binder.Setter;
41
import com.vaadin.flow.data.binder.PropertyDefinition;
42
43
// Result and context
44
import com.vaadin.flow.data.converter.Result;
45
import com.vaadin.flow.data.binder.ValueContext;
46
47
// Error handling
48
import com.vaadin.flow.data.binder.ErrorMessageProvider;
49
import com.vaadin.flow.data.binder.BindingValidationErrorHandler;
50
import com.vaadin.flow.data.binder.DefaultBindingValidationErrorHandler;
51
import com.vaadin.flow.data.binder.StatusChangeListener;
52
import com.vaadin.flow.data.binder.StatusChangeEvent;
53
54
// Required field configuration
55
import com.vaadin.flow.data.binder.RequiredFieldConfigurator;
56
import com.vaadin.flow.data.binder.DefaultRequiredFieldConfigurator;
57
58
// Component interfaces
59
import com.vaadin.flow.component.HasValue;
60
import com.vaadin.flow.component.HasValidation;
61
import com.vaadin.flow.component.Component;
62
import com.vaadin.flow.shared.Registration;
63
64
// Standard Java types
65
import java.math.BigDecimal;
66
import java.time.LocalDate;
67
import java.util.Date;
68
import java.util.Optional;
69
import java.util.List;
70
import java.util.Locale;
71
import java.text.DateFormat;
72
```
73
74
## Core Binding Classes
75
76
### Binder
77
78
Main class for binding form fields to bean properties with validation support.
79
80
```java { .api }
81
public class Binder<BEAN> {
82
public Binder();
83
public Binder(Class<BEAN> beanType);
84
85
// Field binding
86
public <FIELDVALUE> Binder.Binding<BEAN, FIELDVALUE> forField(HasValue<?, FIELDVALUE> field);
87
public <FIELDVALUE> Binder.BindingBuilder<BEAN, FIELDVALUE> forField(HasValue<?, FIELDVALUE> field);
88
89
// Bean operations
90
public void setBean(BEAN bean);
91
public BEAN getBean();
92
public void removeBean();
93
public void readBean(BEAN bean);
94
public boolean writeBeanIfValid(BEAN bean);
95
public BinderValidationStatus<BEAN> writeBeanAsDraft(BEAN bean);
96
97
// Validation
98
public boolean validate();
99
public BinderValidationStatus<BEAN> validate(boolean fireStatusChange);
100
public boolean isValid();
101
102
// Status change handling
103
public Registration addStatusChangeListener(StatusChangeListener listener);
104
public Registration addValueChangeListener(ValueChangeListener<HasValue.ValueChangeEvent<Object>> listener);
105
106
// Bean validation
107
public Binder<BEAN> withValidator(Validator<? super BEAN> validator);
108
public void setValidatorsDisabled(boolean validatorsDisabled);
109
public boolean isValidatorsDisabled();
110
111
// Required field handling
112
public void setRequiredConfigurator(RequiredFieldConfigurator requiredConfigurator);
113
114
// Conversion and validation error handling
115
public void setValidationErrorHandler(BindingValidationErrorHandler handler);
116
public void setStatusLabel(Label statusLabel);
117
}
118
```
119
120
### Binder.Binding
121
122
Individual field binding with conversion and validation.
123
124
```java { .api }
125
public static class Binding<BEAN, FIELDVALUE> {
126
// Validation
127
public Binding<BEAN, FIELDVALUE> withValidator(Validator<? super FIELDVALUE> validator);
128
public Binding<BEAN, FIELDVALUE> withValidator(SerializablePredicate<? super FIELDVALUE> predicate, String message);
129
public Binding<BEAN, FIELDVALUE> withValidator(SerializablePredicate<? super FIELDVALUE> predicate, ErrorMessageProvider errorMessageProvider);
130
131
// Null handling
132
public Binding<BEAN, FIELDVALUE> withNullRepresentation(FIELDVALUE nullRepresentation);
133
134
// Conversion
135
public <TARGET> Binder.BindingBuilder<BEAN, TARGET> withConverter(Converter<FIELDVALUE, TARGET> converter);
136
public <TARGET> Binder.BindingBuilder<BEAN, TARGET> withConverter(SerializableFunction<FIELDVALUE, TARGET> toModel,
137
SerializableFunction<TARGET, FIELDVALUE> toPresentation);
138
139
// Bean property binding
140
public Binding<BEAN, FIELDVALUE> bind(ValueProvider<BEAN, FIELDVALUE> getter, Setter<BEAN, FIELDVALUE> setter);
141
public Binding<BEAN, FIELDVALUE> bind(String propertyName);
142
143
// Status
144
public BindingValidationStatus<FIELDVALUE> validate();
145
public BindingValidationStatus<FIELDVALUE> validate(boolean fireStatusChange);
146
147
// Control
148
public void unbind();
149
public HasValue<?, FIELDVALUE> getField();
150
}
151
```
152
153
### BeanBinder
154
155
Extended binder with automatic bean property binding and JSR-303 validation support.
156
157
```java { .api }
158
public class BeanBinder<BEAN> extends Binder<BEAN> {
159
public BeanBinder(Class<BEAN> beanType);
160
161
// Automatic binding
162
public BeanBinder<BEAN> bindInstanceFields(Object objectWithMemberFields);
163
public BindingBuilder<BEAN, ?> forMemberField(HasValue<?, ?> field);
164
165
// Bean validation
166
public BeanBinder<BEAN> withValidator(Validator<? super BEAN> validator);
167
public void setBean(BEAN bean);
168
}
169
```
170
171
## Validation
172
173
### Validator Interface
174
175
Core validation interface for field and bean validation.
176
177
```java { .api }
178
public interface Validator<T> extends SerializableFunction<T, ValidationResult> {
179
ValidationResult apply(T value, ValueContext context);
180
181
// Static factory methods
182
static <T> Validator<T> from(SerializablePredicate<T> predicate, String errorMessage);
183
static <T> Validator<T> from(SerializablePredicate<T> predicate, ErrorMessageProvider errorMessageProvider);
184
}
185
```
186
187
### ValidationResult
188
189
Result of validation containing success/failure status and error messages.
190
191
```java { .api }
192
public class ValidationResult {
193
// Factory methods
194
public static ValidationResult ok();
195
public static ValidationResult error(String errorMessage);
196
public static ValidationResult create(String errorMessage, boolean isError);
197
198
// Status checking
199
public boolean isError();
200
public Optional<String> getErrorMessage();
201
202
// Combining results
203
public ValidationResult combine(ValidationResult other);
204
}
205
```
206
207
### Built-in Validators
208
209
Common validation implementations.
210
211
```java { .api }
212
public class StringLengthValidator implements Validator<String> {
213
public StringLengthValidator(String errorMessage, int minLength, int maxLength);
214
public StringLengthValidator(String errorMessage, Integer minLength, Integer maxLength);
215
}
216
217
public class EmailValidator implements Validator<String> {
218
public EmailValidator(String errorMessage);
219
}
220
221
public class RegexpValidator implements Validator<String> {
222
public RegexpValidator(String errorMessage, String regexp);
223
public RegexpValidator(String errorMessage, String regexp, boolean completeMatch);
224
}
225
226
public class RangeValidator<T extends Comparable<? super T>> implements Validator<T> {
227
public RangeValidator(String errorMessage, T minValue, T maxValue);
228
}
229
230
public class DateRangeValidator extends RangeValidator<LocalDate> {
231
public DateRangeValidator(String errorMessage, LocalDate minValue, LocalDate maxValue);
232
}
233
234
public class BeanValidator implements Validator<Object> {
235
public BeanValidator(Class<?> beanClass, String propertyName);
236
}
237
```
238
239
### ValidationStatus
240
241
Status information about validation results.
242
243
```java { .api }
244
public class BinderValidationStatus<BEAN> {
245
public List<BindingValidationStatus<?>> getFieldValidationStatuses();
246
public List<ValidationResult> getBeanValidationResults();
247
public boolean isOk();
248
public boolean hasErrors();
249
public List<BindingValidationStatus<?>> getFieldValidationErrors();
250
public List<ValidationResult> getBeanValidationErrors();
251
}
252
253
public class BindingValidationStatus<TARGET> {
254
public ValidationResult getResult();
255
public HasValue<?, ?> getField();
256
public boolean isError();
257
public Optional<String> getMessage();
258
}
259
```
260
261
## Conversion
262
263
### Converter Interface
264
265
Interface for converting between field values and bean property values.
266
267
```java { .api }
268
public interface Converter<PRESENTATION, MODEL> extends Serializable {
269
Result<MODEL> convertToModel(PRESENTATION value, ValueContext context);
270
PRESENTATION convertToPresentation(MODEL value, ValueContext context);
271
272
// Default methods
273
default <TARGET> Converter<PRESENTATION, TARGET> chain(Converter<MODEL, TARGET> other);
274
}
275
```
276
277
### Result Class
278
279
Container for conversion results with success/failure handling.
280
281
```java { .api }
282
public class Result<R> {
283
// Factory methods
284
public static <R> Result<R> ok(R value);
285
public static <R> Result<R> error(String message);
286
287
// Status checking
288
public boolean isError();
289
public R getOrThrow(SerializableFunction<String, RuntimeException> exceptionSupplier);
290
291
// Value handling
292
public <S> Result<S> map(SerializableFunction<R, S> mapper);
293
public <S> Result<S> flatMap(SerializableFunction<R, Result<S>> mapper);
294
public Optional<R> asOptional();
295
public Optional<String> getMessage();
296
}
297
```
298
299
### Built-in Converters
300
301
Common conversion implementations.
302
303
```java { .api }
304
public class StringToIntegerConverter implements Converter<String, Integer> {
305
public StringToIntegerConverter(String errorMessage);
306
public StringToIntegerConverter(Integer emptyValue, String errorMessage);
307
}
308
309
public class StringToDoubleConverter implements Converter<String, Double> {
310
public StringToDoubleConverter(String errorMessage);
311
public StringToDoubleConverter(Double emptyValue, String errorMessage);
312
}
313
314
public class StringToBigDecimalConverter implements Converter<String, BigDecimal> {
315
public StringToBigDecimalConverter(String errorMessage);
316
public StringToBigDecimalConverter(BigDecimal emptyValue, String errorMessage);
317
}
318
319
public class StringToDateConverter implements Converter<String, Date> {
320
public StringToDateConverter(String errorMessage);
321
public StringToDateConverter(DateFormat dateFormat, String errorMessage);
322
}
323
324
public class LocalDateToDateConverter implements Converter<LocalDate, Date> {
325
public LocalDateToDateConverter();
326
}
327
328
public class DateToLocalDateConverter implements Converter<Date, LocalDate> {
329
public DateToLocalDateConverter();
330
}
331
332
public class StringToBooleanConverter implements Converter<String, Boolean> {
333
public StringToBooleanConverter(String trueString, String falseString, String errorMessage);
334
}
335
```
336
337
## Value Context
338
339
### ValueContext
340
341
Context information for validation and conversion operations.
342
343
```java { .api }
344
public class ValueContext {
345
public ValueContext();
346
public ValueContext(Component component);
347
public ValueContext(Component component, HasValue<?, ?> hasValue);
348
349
public Optional<Component> getComponent();
350
public Optional<HasValue<?, ?>> getHasValue();
351
public Optional<Locale> getLocale();
352
353
// Builder methods
354
public ValueContext withLocale(Locale locale);
355
public ValueContext withComponent(Component component);
356
public ValueContext withHasValue(HasValue<?, ?> hasValue);
357
}
358
```
359
360
## Error Handling
361
362
### Error Message Providers
363
364
Interfaces for providing localized error messages.
365
366
```java { .api }
367
public interface ErrorMessageProvider extends SerializableFunction<ValueContext, String> {
368
String apply(ValueContext context);
369
}
370
371
public interface BindingValidationErrorHandler extends Serializable {
372
void handleError(HasValue<?, ?> field, ValidationResult result);
373
}
374
375
public class DefaultBindingValidationErrorHandler implements BindingValidationErrorHandler {
376
public void handleError(HasValue<?, ?> field, ValidationResult result);
377
}
378
```
379
380
### Status Change Events
381
382
Events for monitoring binding status changes.
383
384
```java { .api }
385
public interface StatusChangeListener extends SerializableEventListener {
386
void statusChange(StatusChangeEvent statusChangeEvent);
387
}
388
389
public class StatusChangeEvent extends EventObject {
390
public Binder<?> getBinder();
391
public boolean hasValidationErrors();
392
}
393
```
394
395
## Bean Property Utilities
396
397
### Property Access
398
399
Utilities for accessing bean properties in a type-safe manner.
400
401
```java { .api }
402
public interface ValueProvider<SOURCE, TARGET> extends SerializableFunction<SOURCE, TARGET> {
403
TARGET apply(SOURCE source);
404
405
// Default methods for nested properties
406
default <V> ValueProvider<SOURCE, V> andThen(ValueProvider<TARGET, V> after);
407
}
408
409
public interface Setter<BEAN, FIELDVALUE> extends SerializableBiConsumer<BEAN, FIELDVALUE> {
410
void accept(BEAN bean, FIELDVALUE fieldvalue);
411
}
412
413
// Property definition utilities
414
public class PropertyDefinition<T, V> {
415
public static <T, V> PropertyDefinition<T, V> create(ValueProvider<T, V> getter, Setter<T, V> setter);
416
public static <T, V> PropertyDefinition<T, V> create(ValueProvider<T, V> getter, Setter<T, V> setter, Class<V> type);
417
418
public ValueProvider<T, V> getGetter();
419
public Optional<Setter<T, V>> getSetter();
420
public Class<V> getType();
421
public String getName();
422
}
423
```
424
425
### Required Field Configuration
426
427
Configuration for marking fields as required.
428
429
```java { .api }
430
public interface RequiredFieldConfigurator extends Serializable {
431
void configure(HasValue<?, ?> field, boolean required, String caption);
432
}
433
434
public class DefaultRequiredFieldConfigurator implements RequiredFieldConfigurator {
435
public void configure(HasValue<?, ?> field, boolean required, String caption);
436
}
437
```
438
439
## Advanced Binding Features
440
441
### Buffered vs Non-buffered Binding
442
443
Control over when changes are applied to the bean.
444
445
```java { .api }
446
public class Binder<BEAN> {
447
// Buffered mode (default)
448
public boolean writeBeanIfValid(BEAN bean);
449
public BinderValidationStatus<BEAN> writeBeanAsDraft(BEAN bean);
450
451
// Non-buffered mode
452
public void setBean(BEAN bean); // Immediate binding
453
public void readBean(BEAN bean); // Read-only binding
454
}
455
```
456
457
### Cross-field Validation
458
459
Validation that depends on multiple field values.
460
461
```java { .api }
462
// Bean-level validator that can access all fields
463
binder.withValidator(bean -> {
464
if (bean.getEndDate().isBefore(bean.getStartDate())) {
465
return ValidationResult.error("End date must be after start date");
466
}
467
return ValidationResult.ok();
468
});
469
```
470
471
## Usage Examples
472
473
### Basic Field Binding
474
475
```java
476
public class PersonForm extends FormLayout {
477
private TextField firstName = new TextField("First Name");
478
private TextField lastName = new TextField("Last Name");
479
private EmailField email = new EmailField("Email");
480
private DatePicker birthDate = new DatePicker("Birth Date");
481
482
private Binder<Person> binder = new Binder<>(Person.class);
483
484
public PersonForm() {
485
// Simple property binding
486
binder.forField(firstName)
487
.asRequired("First name is required")
488
.withValidator(new StringLengthValidator("Name must be 2-50 characters", 2, 50))
489
.bind(Person::getFirstName, Person::setFirstName);
490
491
binder.forField(lastName)
492
.asRequired("Last name is required")
493
.bind(Person::getLastName, Person::setLastName);
494
495
binder.forField(email)
496
.withValidator(new EmailValidator("Invalid email address"))
497
.bind(Person::getEmail, Person::setEmail);
498
499
binder.forField(birthDate)
500
.withValidator(date -> date.isBefore(LocalDate.now()), "Birth date must be in the past")
501
.bind(Person::getBirthDate, Person::setBirthDate);
502
503
add(firstName, lastName, email, birthDate);
504
}
505
506
public void setPerson(Person person) {
507
binder.setBean(person);
508
}
509
510
public boolean save() {
511
return binder.writeBeanIfValid(binder.getBean());
512
}
513
}
514
```
515
516
### Conversion and Custom Validation
517
518
```java
519
TextField ageField = new TextField("Age");
520
521
binder.forField(ageField)
522
.withConverter(new StringToIntegerConverter("Age must be a number"))
523
.withValidator(age -> age >= 0 && age <= 150, "Age must be between 0 and 150")
524
.bind(Person::getAge, Person::setAge);
525
```
526
527
### Bean Validation Integration
528
529
```java
530
BeanBinder<Person> binder = new BeanBinder<>(Person.class);
531
532
// Automatic JSR-303 validation
533
binder.bindInstanceFields(this);
534
binder.setBean(new Person());
535
536
// The Person class should have JSR-303 annotations:
537
// @NotNull
538
539
// @Size(min = 2, max = 50)
540
```
541
542
### Custom Error Handling
543
544
```java
545
binder.setValidationErrorHandler(new BindingValidationErrorHandler() {
546
@Override
547
public void handleError(HasValue<?, ?> field, ValidationResult result) {
548
if (field instanceof HasValidation) {
549
((HasValidation) field).setErrorMessage(result.getErrorMessage().orElse(""));
550
((HasValidation) field).setInvalid(result.isError());
551
}
552
}
553
});
554
```
555
556
The data binding system provides robust form handling with automatic validation, conversion, and error management, significantly reducing boilerplate code for form development.