Таблица Grid
Grid — таблица Vaadin. Она показывает список объектов: каждая строка — один объект, каждая колонка — одно его свойство. Таблица сама умеет прокручивать тысячи строк, сортировать по клику на заголовок и выделять строки. Вы только говорите, какие колонки нужны и откуда брать данные.
Первая таблица
Заменим абзацы в экране статей на таблицу:
// 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("Статьи")
public class PostListView extends VerticalLayout {
public PostListView(PostService service) {
Grid<Post> grid = new Grid<>(Post.class, false);
grid.addColumn(Post::getTitle).setHeader("Заголовок");
grid.addColumn(Post::getAuthor).setHeader("Автор");
grid.addColumn(Post::getPublishedOn).setHeader("Дата");
grid.addColumn(post -> post.isPublished() ? "Опубликована" : "Черновик").setHeader("Статус");
grid.setItems(service.findAll());
add(grid);
setSizeFull();
}
}На http://localhost:8080/ таблица из трёх строк и четырёх колонок. setSizeFull() растягивает экран на всё окно, и таблица занимает свободную высоту.
new Grid<>(Post.class, false) создаёт пустую таблицу, а колонки добавляются вручную. Без false Vaadin сам сделает колонки для всех свойств, включая id и длинный content, — обычно это не то, что нужно.
Сортировка
Колонки из лямбд по умолчанию не сортируются. setComparator включает сортировку и говорит, по какому значению сравнивать строки:
// src/main/java/com/example/blog/views/PostListView.java (фрагмент конструктора)
grid.addColumn(Post::getTitle).setHeader("Заголовок").setComparator(Post::getTitle);
grid.addColumn(Post::getPublishedOn).setHeader("Дата").setComparator(Post::getPublishedOn);У заголовков появляются стрелки: клик сортирует по возрастанию, второй — по убыванию. Так сортировка работает, пока все строки уже в памяти; для больших таблиц — следующий урок.
Компоненты в ячейках
В ячейку можно положить любой компонент — например, кнопку:
// src/main/java/com/example/blog/views/PostListView.java (фрагмент конструктора)
grid.addComponentColumn(post -> new Button("Открыть",
event -> Notification.show("Открываем: " + post.getTitle())))
.setHeader("Действия").setAutoWidth(true);В каждой строке появляется кнопка «Открыть». setAutoWidth(true) подбирает ширину колонки по содержимому.
Выбор строки
// src/main/java/com/example/blog/views/PostListView.java (фрагмент конструктора)
grid.addItemClickListener(event -> Notification.show("Выбрана статья: " + event.getItem().getTitle()));
grid.asSingleSelect().addValueChangeListener(event -> {
Post selected = event.getValue();
});Первый обработчик срабатывает на каждый клик по строке. Второй — на смену выделенной строки; при снятии выделения event.getValue() вернёт null.
| Метод колонки | Что делает |
|---|---|
setHeader("...") | Заголовок колонки |
setComparator(...) | Сортировка в памяти |
setAutoWidth(true) | Ширина по содержимому |
setFlexGrow(2) | Доля свободной ширины |
setResizable(true) | Ширину можно менять мышью |
setFrozen(true) | Колонка не уезжает при прокрутке вбок |
Частая ошибка
Таблица с автоматическими колонками и опечатка в имени свойства:
// src/main/java/com/example/blog/views/PostListView.java (неправильно)
Grid<Post> grid = new Grid<>(Post.class);
grid.setColumns("titel", "author");Экран не открывается:
java.lang.IllegalArgumentException: Can't resolve property name 'titel' from 'Property set for bean com.example.blog.Post'Имена свойств берутся из геттеров: getTitle даёт title. Ссылки на методы вроде Post::getTitle проверяет компилятор, поэтому с ними такой ошибки не бывает.