The Grid component
Grid is the Vaadin table. It shows a list of objects: each row is one object, each column is one of its properties. The grid scrolls through thousands of rows, sorts on a header click and highlights rows by itself. You only say which columns you need and where the data comes from.
The first grid
Let us replace the paragraphs in the posts view with a grid:
// src/main/java/com/example/blog/views/PostListView.java
package com.example.blog.views;
import com.example.blog.Post;
import com.example.blog.PostService;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
@Route("")
@PageTitle("Posts")
public class PostListView extends VerticalLayout {
public PostListView(PostService service) {
Grid<Post> grid = new Grid<>(Post.class, false);
grid.addColumn(Post::getTitle).setHeader("Title");
grid.addColumn(Post::getAuthor).setHeader("Author");
grid.addColumn(Post::getPublishedOn).setHeader("Date");
grid.addColumn(post -> post.isPublished() ? "Published" : "Draft").setHeader("Status");
grid.setItems(service.findAll());
add(grid);
setSizeFull();
}
}http://localhost:8080/ shows a grid with three rows and four columns. setSizeFull() stretches the view over the whole window, and the grid takes the free height.
new Grid<>(Post.class, false) creates an empty grid, and you add columns by hand. Without false Vaadin creates columns for all properties, including id and the long content — usually not what you want.
Sorting
Columns made from lambdas are not sortable by default. setComparator turns sorting on and says which value to compare rows by:
// src/main/java/com/example/blog/views/PostListView.java (part of the constructor)
grid.addColumn(Post::getTitle).setHeader("Title").setComparator(Post::getTitle);
grid.addColumn(Post::getPublishedOn).setHeader("Date").setComparator(Post::getPublishedOn);The headers get arrows: one click sorts ascending, a second one descending. This kind of sorting works while all rows are already in memory; large grids are covered in the next lesson.
Components in cells
A cell can hold any component, for example a button:
// src/main/java/com/example/blog/views/PostListView.java (part of the constructor)
grid.addComponentColumn(post -> new Button("Open",
event -> Notification.show("Opening: " + post.getTitle())))
.setHeader("Actions").setAutoWidth(true);Each row gets an "Open" button. setAutoWidth(true) fits the column width to its content.
Selecting a row
// src/main/java/com/example/blog/views/PostListView.java (part of the constructor)
grid.addItemClickListener(event -> Notification.show("Selected post: " + event.getItem().getTitle()));
grid.asSingleSelect().addValueChangeListener(event -> {
Post selected = event.getValue();
});The first listener fires on every row click. The second fires when the selected row changes; when the selection is cleared, event.getValue() returns null.
| Column method | What it does |
|---|---|
setHeader("...") | Column header |
setComparator(...) | In-memory sorting |
setAutoWidth(true) | Width from content |
setFlexGrow(2) | Share of the free width |
setResizable(true) | Width can be changed with the mouse |
setFrozen(true) | The column stays put when scrolling sideways |
Common mistake
A grid with automatic columns and a typo in a property name:
// src/main/java/com/example/blog/views/PostListView.java (wrong)
Grid<Post> grid = new Grid<>(Post.class);
grid.setColumns("titel", "author");The view does not open:
java.lang.IllegalArgumentException: Can't resolve property name 'titel' from 'Property set for bean com.example.blog.Post'Property names come from getters: getTitle gives title. The compiler checks method references like Post::getTitle, so they cannot cause this error.