CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-vaadin--vaadin

Comprehensive Java web application development framework that enables server-side Java development with modern web UI components and automatic client-server communication.

Overview
Eval results
Files

data-binding.mddocs/

Data Binding

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.

Core Imports

// Data binding core classes
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.BeanBinder;
import com.vaadin.flow.data.binder.Binding;
import com.vaadin.flow.data.binder.BindingBuilder;
import com.vaadin.flow.data.binder.BindingValidationStatus;
import com.vaadin.flow.data.binder.BinderValidationStatus;

// Validation
import com.vaadin.flow.data.validator.Validator;
import com.vaadin.flow.data.validator.ValidationResult;
import com.vaadin.flow.data.validator.StringLengthValidator;
import com.vaadin.flow.data.validator.EmailValidator;
import com.vaadin.flow.data.validator.RegexpValidator;
import com.vaadin.flow.data.validator.RangeValidator;
import com.vaadin.flow.data.validator.DateRangeValidator;
import com.vaadin.flow.data.validator.BeanValidator;

// Conversion
import com.vaadin.flow.data.converter.Converter;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.data.converter.StringToDoubleConverter;
import com.vaadin.flow.data.converter.StringToBigDecimalConverter;
import com.vaadin.flow.data.converter.StringToDateConverter;
import com.vaadin.flow.data.converter.StringToBooleanConverter;
import com.vaadin.flow.data.converter.LocalDateToDateConverter;
import com.vaadin.flow.data.converter.DateToLocalDateConverter;

// Value providers and property access
import com.vaadin.flow.function.ValueProvider;
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.function.SerializablePredicate;
import com.vaadin.flow.function.SerializableBiConsumer;
import com.vaadin.flow.data.binder.Setter;
import com.vaadin.flow.data.binder.PropertyDefinition;

// Result and context
import com.vaadin.flow.data.converter.Result;
import com.vaadin.flow.data.binder.ValueContext;

// Error handling
import com.vaadin.flow.data.binder.ErrorMessageProvider;
import com.vaadin.flow.data.binder.BindingValidationErrorHandler;
import com.vaadin.flow.data.binder.DefaultBindingValidationErrorHandler;
import com.vaadin.flow.data.binder.StatusChangeListener;
import com.vaadin.flow.data.binder.StatusChangeEvent;

// Required field configuration
import com.vaadin.flow.data.binder.RequiredFieldConfigurator;
import com.vaadin.flow.data.binder.DefaultRequiredFieldConfigurator;

// Component interfaces
import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.component.HasValidation;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.shared.Registration;

// Standard Java types
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.Optional;
import java.util.List;
import java.util.Locale;
import java.text.DateFormat;

Core Binding Classes

Binder

Main class for binding form fields to bean properties with validation support.

public class Binder<BEAN> {
    public Binder();
    public Binder(Class<BEAN> beanType);

    // Field binding
    public <FIELDVALUE> Binder.Binding<BEAN, FIELDVALUE> forField(HasValue<?, FIELDVALUE> field);
    public <FIELDVALUE> Binder.BindingBuilder<BEAN, FIELDVALUE> forField(HasValue<?, FIELDVALUE> field);

    // Bean operations
    public void setBean(BEAN bean);
    public BEAN getBean();
    public void removeBean();
    public void readBean(BEAN bean);
    public boolean writeBeanIfValid(BEAN bean);
    public BinderValidationStatus<BEAN> writeBeanAsDraft(BEAN bean);

    // Validation
    public boolean validate();
    public BinderValidationStatus<BEAN> validate(boolean fireStatusChange);
    public boolean isValid();

    // Status change handling
    public Registration addStatusChangeListener(StatusChangeListener listener);
    public Registration addValueChangeListener(ValueChangeListener<HasValue.ValueChangeEvent<Object>> listener);

    // Bean validation
    public Binder<BEAN> withValidator(Validator<? super BEAN> validator);
    public void setValidatorsDisabled(boolean validatorsDisabled);
    public boolean isValidatorsDisabled();

    // Required field handling
    public void setRequiredConfigurator(RequiredFieldConfigurator requiredConfigurator);

    // Conversion and validation error handling
    public void setValidationErrorHandler(BindingValidationErrorHandler handler);
    public void setStatusLabel(Label statusLabel);
}

Binder.Binding

Individual field binding with conversion and validation.

public static class Binding<BEAN, FIELDVALUE> {
    // Validation
    public Binding<BEAN, FIELDVALUE> withValidator(Validator<? super FIELDVALUE> validator);
    public Binding<BEAN, FIELDVALUE> withValidator(SerializablePredicate<? super FIELDVALUE> predicate, String message);
    public Binding<BEAN, FIELDVALUE> withValidator(SerializablePredicate<? super FIELDVALUE> predicate, ErrorMessageProvider errorMessageProvider);

    // Null handling
    public Binding<BEAN, FIELDVALUE> withNullRepresentation(FIELDVALUE nullRepresentation);

    // Conversion
    public <TARGET> Binder.BindingBuilder<BEAN, TARGET> withConverter(Converter<FIELDVALUE, TARGET> converter);
    public <TARGET> Binder.BindingBuilder<BEAN, TARGET> withConverter(SerializableFunction<FIELDVALUE, TARGET> toModel,
                                                                      SerializableFunction<TARGET, FIELDVALUE> toPresentation);

    // Bean property binding
    public Binding<BEAN, FIELDVALUE> bind(ValueProvider<BEAN, FIELDVALUE> getter, Setter<BEAN, FIELDVALUE> setter);
    public Binding<BEAN, FIELDVALUE> bind(String propertyName);

    // Status
    public BindingValidationStatus<FIELDVALUE> validate();
    public BindingValidationStatus<FIELDVALUE> validate(boolean fireStatusChange);

    // Control
    public void unbind();
    public HasValue<?, FIELDVALUE> getField();
}

BeanBinder

Extended binder with automatic bean property binding and JSR-303 validation support.

public class BeanBinder<BEAN> extends Binder<BEAN> {
    public BeanBinder(Class<BEAN> beanType);

    // Automatic binding
    public BeanBinder<BEAN> bindInstanceFields(Object objectWithMemberFields);
    public BindingBuilder<BEAN, ?> forMemberField(HasValue<?, ?> field);

    // Bean validation
    public BeanBinder<BEAN> withValidator(Validator<? super BEAN> validator);
    public void setBean(BEAN bean);
}

Validation

Validator Interface

Core validation interface for field and bean validation.

public interface Validator<T> extends SerializableFunction<T, ValidationResult> {
    ValidationResult apply(T value, ValueContext context);

    // Static factory methods
    static <T> Validator<T> from(SerializablePredicate<T> predicate, String errorMessage);
    static <T> Validator<T> from(SerializablePredicate<T> predicate, ErrorMessageProvider errorMessageProvider);
}

ValidationResult

Result of validation containing success/failure status and error messages.

public class ValidationResult {
    // Factory methods
    public static ValidationResult ok();
    public static ValidationResult error(String errorMessage);
    public static ValidationResult create(String errorMessage, boolean isError);

    // Status checking
    public boolean isError();
    public Optional<String> getErrorMessage();

    // Combining results
    public ValidationResult combine(ValidationResult other);
}

Built-in Validators

Common validation implementations.

public class StringLengthValidator implements Validator<String> {
    public StringLengthValidator(String errorMessage, int minLength, int maxLength);
    public StringLengthValidator(String errorMessage, Integer minLength, Integer maxLength);
}

public class EmailValidator implements Validator<String> {
    public EmailValidator(String errorMessage);
}

public class RegexpValidator implements Validator<String> {
    public RegexpValidator(String errorMessage, String regexp);
    public RegexpValidator(String errorMessage, String regexp, boolean completeMatch);
}

public class RangeValidator<T extends Comparable<? super T>> implements Validator<T> {
    public RangeValidator(String errorMessage, T minValue, T maxValue);
}

public class DateRangeValidator extends RangeValidator<LocalDate> {
    public DateRangeValidator(String errorMessage, LocalDate minValue, LocalDate maxValue);
}

public class BeanValidator implements Validator<Object> {
    public BeanValidator(Class<?> beanClass, String propertyName);
}

ValidationStatus

Status information about validation results.

public class BinderValidationStatus<BEAN> {
    public List<BindingValidationStatus<?>> getFieldValidationStatuses();
    public List<ValidationResult> getBeanValidationResults();
    public boolean isOk();
    public boolean hasErrors();
    public List<BindingValidationStatus<?>> getFieldValidationErrors();
    public List<ValidationResult> getBeanValidationErrors();
}

public class BindingValidationStatus<TARGET> {
    public ValidationResult getResult();
    public HasValue<?, ?> getField();
    public boolean isError();
    public Optional<String> getMessage();
}

Conversion

Converter Interface

Interface for converting between field values and bean property values.

public interface Converter<PRESENTATION, MODEL> extends Serializable {
    Result<MODEL> convertToModel(PRESENTATION value, ValueContext context);
    PRESENTATION convertToPresentation(MODEL value, ValueContext context);

    // Default methods
    default <TARGET> Converter<PRESENTATION, TARGET> chain(Converter<MODEL, TARGET> other);
}

Result Class

Container for conversion results with success/failure handling.

public class Result<R> {
    // Factory methods
    public static <R> Result<R> ok(R value);
    public static <R> Result<R> error(String message);

    // Status checking
    public boolean isError();
    public R getOrThrow(SerializableFunction<String, RuntimeException> exceptionSupplier);

    // Value handling
    public <S> Result<S> map(SerializableFunction<R, S> mapper);
    public <S> Result<S> flatMap(SerializableFunction<R, Result<S>> mapper);
    public Optional<R> asOptional();
    public Optional<String> getMessage();
}

Built-in Converters

Common conversion implementations.

public class StringToIntegerConverter implements Converter<String, Integer> {
    public StringToIntegerConverter(String errorMessage);
    public StringToIntegerConverter(Integer emptyValue, String errorMessage);
}

public class StringToDoubleConverter implements Converter<String, Double> {
    public StringToDoubleConverter(String errorMessage);
    public StringToDoubleConverter(Double emptyValue, String errorMessage);
}

public class StringToBigDecimalConverter implements Converter<String, BigDecimal> {
    public StringToBigDecimalConverter(String errorMessage);
    public StringToBigDecimalConverter(BigDecimal emptyValue, String errorMessage);
}

public class StringToDateConverter implements Converter<String, Date> {
    public StringToDateConverter(String errorMessage);
    public StringToDateConverter(DateFormat dateFormat, String errorMessage);
}

public class LocalDateToDateConverter implements Converter<LocalDate, Date> {
    public LocalDateToDateConverter();
}

public class DateToLocalDateConverter implements Converter<Date, LocalDate> {
    public DateToLocalDateConverter();
}

public class StringToBooleanConverter implements Converter<String, Boolean> {
    public StringToBooleanConverter(String trueString, String falseString, String errorMessage);
}

Value Context

ValueContext

Context information for validation and conversion operations.

public class ValueContext {
    public ValueContext();
    public ValueContext(Component component);
    public ValueContext(Component component, HasValue<?, ?> hasValue);

    public Optional<Component> getComponent();
    public Optional<HasValue<?, ?>> getHasValue();
    public Optional<Locale> getLocale();

    // Builder methods
    public ValueContext withLocale(Locale locale);
    public ValueContext withComponent(Component component);
    public ValueContext withHasValue(HasValue<?, ?> hasValue);
}

Error Handling

Error Message Providers

Interfaces for providing localized error messages.

public interface ErrorMessageProvider extends SerializableFunction<ValueContext, String> {
    String apply(ValueContext context);
}

public interface BindingValidationErrorHandler extends Serializable {
    void handleError(HasValue<?, ?> field, ValidationResult result);
}

public class DefaultBindingValidationErrorHandler implements BindingValidationErrorHandler {
    public void handleError(HasValue<?, ?> field, ValidationResult result);
}

Status Change Events

Events for monitoring binding status changes.

public interface StatusChangeListener extends SerializableEventListener {
    void statusChange(StatusChangeEvent statusChangeEvent);
}

public class StatusChangeEvent extends EventObject {
    public Binder<?> getBinder();
    public boolean hasValidationErrors();
}

Bean Property Utilities

Property Access

Utilities for accessing bean properties in a type-safe manner.

public interface ValueProvider<SOURCE, TARGET> extends SerializableFunction<SOURCE, TARGET> {
    TARGET apply(SOURCE source);

    // Default methods for nested properties
    default <V> ValueProvider<SOURCE, V> andThen(ValueProvider<TARGET, V> after);
}

public interface Setter<BEAN, FIELDVALUE> extends SerializableBiConsumer<BEAN, FIELDVALUE> {
    void accept(BEAN bean, FIELDVALUE fieldvalue);
}

// Property definition utilities
public class PropertyDefinition<T, V> {
    public static <T, V> PropertyDefinition<T, V> create(ValueProvider<T, V> getter, Setter<T, V> setter);
    public static <T, V> PropertyDefinition<T, V> create(ValueProvider<T, V> getter, Setter<T, V> setter, Class<V> type);

    public ValueProvider<T, V> getGetter();
    public Optional<Setter<T, V>> getSetter();
    public Class<V> getType();
    public String getName();
}

Required Field Configuration

Configuration for marking fields as required.

public interface RequiredFieldConfigurator extends Serializable {
    void configure(HasValue<?, ?> field, boolean required, String caption);
}

public class DefaultRequiredFieldConfigurator implements RequiredFieldConfigurator {
    public void configure(HasValue<?, ?> field, boolean required, String caption);
}

Advanced Binding Features

Buffered vs Non-buffered Binding

Control over when changes are applied to the bean.

public class Binder<BEAN> {
    // Buffered mode (default)
    public boolean writeBeanIfValid(BEAN bean);
    public BinderValidationStatus<BEAN> writeBeanAsDraft(BEAN bean);

    // Non-buffered mode
    public void setBean(BEAN bean);  // Immediate binding
    public void readBean(BEAN bean); // Read-only binding
}

Cross-field Validation

Validation that depends on multiple field values.

// Bean-level validator that can access all fields
binder.withValidator(bean -> {
    if (bean.getEndDate().isBefore(bean.getStartDate())) {
        return ValidationResult.error("End date must be after start date");
    }
    return ValidationResult.ok();
});

Usage Examples

Basic Field Binding

public class PersonForm extends FormLayout {
    private TextField firstName = new TextField("First Name");
    private TextField lastName = new TextField("Last Name");
    private EmailField email = new EmailField("Email");
    private DatePicker birthDate = new DatePicker("Birth Date");

    private Binder<Person> binder = new Binder<>(Person.class);

    public PersonForm() {
        // Simple property binding
        binder.forField(firstName)
              .asRequired("First name is required")
              .withValidator(new StringLengthValidator("Name must be 2-50 characters", 2, 50))
              .bind(Person::getFirstName, Person::setFirstName);

        binder.forField(lastName)
              .asRequired("Last name is required")
              .bind(Person::getLastName, Person::setLastName);

        binder.forField(email)
              .withValidator(new EmailValidator("Invalid email address"))
              .bind(Person::getEmail, Person::setEmail);

        binder.forField(birthDate)
              .withValidator(date -> date.isBefore(LocalDate.now()), "Birth date must be in the past")
              .bind(Person::getBirthDate, Person::setBirthDate);

        add(firstName, lastName, email, birthDate);
    }

    public void setPerson(Person person) {
        binder.setBean(person);
    }

    public boolean save() {
        return binder.writeBeanIfValid(binder.getBean());
    }
}

Conversion and Custom Validation

TextField ageField = new TextField("Age");

binder.forField(ageField)
      .withConverter(new StringToIntegerConverter("Age must be a number"))
      .withValidator(age -> age >= 0 && age <= 150, "Age must be between 0 and 150")
      .bind(Person::getAge, Person::setAge);

Bean Validation Integration

BeanBinder<Person> binder = new BeanBinder<>(Person.class);

// Automatic JSR-303 validation
binder.bindInstanceFields(this);
binder.setBean(new Person());

// The Person class should have JSR-303 annotations:
// @NotNull
// @Email
// @Size(min = 2, max = 50)

Custom Error Handling

binder.setValidationErrorHandler(new BindingValidationErrorHandler() {
    @Override
    public void handleError(HasValue<?, ?> field, ValidationResult result) {
        if (field instanceof HasValidation) {
            ((HasValidation) field).setErrorMessage(result.getErrorMessage().orElse(""));
            ((HasValidation) field).setInvalid(result.isError());
        }
    }
});

The data binding system provides robust form handling with automatic validation, conversion, and error management, significantly reducing boilerplate code for form development.

Install with Tessl CLI

npx tessl i tessl/maven-com-vaadin--vaadin

docs

components.md

data-binding.md

data-components.md

index.md

layouts.md

routing.md

security.md

server-communication.md

theming.md

tile.json