Vaadin Component Design Skill
Purpose
Create maintainable, responsive Vaadin UI components with proper lifecycle and data binding.
When to Use
-
✅ Creating new UI views
-
✅ Designing forms and data grids
-
✅ Implementing user interactions
-
✅ Building responsive layouts
Component Patterns
@SpringView(name = PoliticianView.NAME) @Secured({"ROLE_USER", "ROLE_ADMIN"}) public class PoliticianView extends VerticalLayout implements View { public static final String NAME = "politicians";
private final PoliticianService service;
private final Grid<Politician> grid = new Grid<>(Politician.class);
public PoliticianView(PoliticianService service) {
this.service = service;
setSizeFull();
configureGrid();
add(createToolbar(), grid);
updateList();
}
private void configureGrid() {
grid.setSizeFull();
grid.setColumns("firstName", "lastName", "party", "district");
grid.addColumn(p -> p.getVotingRecords().size())
.setCaption("Total Votes");
grid.getColumns().forEach(col -> col.setExpandRatio(1));
}
private Component createToolbar() {
TextField searchField = new TextField();
searchField.setPlaceholder("Search...");
searchField.addValueChangeListener(e -> updateList());
Button addButton = new Button("Add Politician");
addButton.addClickListener(e -> addPolitician());
return new HorizontalLayout(searchField, addButton);
}
}
Data Binding
public class PoliticianForm extends FormLayout { TextField firstName = new TextField("First Name"); TextField lastName = new TextField("Last Name"); ComboBox<Party> party = new ComboBox<>("Party");
Binder<Politician> binder = new Binder<>(Politician.class);
public PoliticianForm() {
binder.forField(firstName)
.asRequired("First name is required")
.withValidator(name -> name.length() >= 2, "Name too short")
.bind(Politician::getFirstName, Politician::setFirstName);
add(firstName, lastName, party);
}
}
References
-
Vaadin: https://vaadin.com/docs
-
citizen-intelligence-agency/src/main/java/com/hack23/cia/web/