dataGrid

dataGrid - это таблица данных, которую можно редактировать, сортировать, фильтровать и агрегировать по столбцам. Для работы с большими объёмами данных используется отложенная загрузка при прокрутке, что обеспечивает высокую производительность.

XML-элемент

dataGrid

Java-класс

DataGrid

Атрибуты

General: id - aggregatable - columnReorderingAllowed - emptyStateText - enabled - selectionMode - visible

Привязка данных: dataContainer - metaClass

Размер: height - maxHeight - maxWidth - minHeight - minWidth - width

Положение: alignSelf - colspan

Внешний вид: classNames - css - themeNames

Прочее: aggregationPosition - allRowsVisible - ariaLabel - detailsVisibleOnClick - dropMode - editorBuffered - focusShortcut - multiSort - multiSortOnShiftClickOnly - multiSortPriority - nestedNullBehavior - pageSize - rowsDraggable - tabIndex

Обработчики

AttachEvent - BlurEvent - CellFocusEvent - ColumnReorderEvent - ColumnResizeEvent - DetachEvent - FocusEvent - GridDragEndEvent - GridDragStartEvent - GridDropEvent - ItemClickEvent - ItemDoubleClickEvent - SortEvent - dataGenerator - dragFilter - dropFilter enterPressHandler - itemSelectableProvider - tooltipGenerator

Элементы

actions - columns - column - contextMenu - emptyStateComponent

Основы

Для создания компонента используйте XML-элемент dataGrid и свяжите его с контейнером данных. Поддерживаются оба типа контейнеров: коллекции и KeyValue.

Затем укажите, какие атрибуты из контейнера вы хотите отобразить:

  • Чтобы показать все атрибуты, указанные в фетч-плане, добавьте элемент columns с атрибутом includeAll, установленным в true. Чтобы исключить ненужные атрибуты, перечислите их через запятую в атрибуте exclude.

  • Если нужно отобразить только определённые атрибуты, добавьте элемент columns и вложите в него отдельные элементы column для каждого нужного атрибута.

  • Если фетч-план содержит ссылочный атрибут, этот атрибут будет отображаться по имени его экземпляра. Чтобы отобразить конкретный атрибут, добавьте его явно как в фетч-план, так и в элемент column.

Ниже приведён пример создания базового компонента dataGrid:

<data readOnly="true">
    <collection id="usersDc"
                class="com.company.onboarding.entity.User">
        <fetchPlan extends="_base">
            <property name="department">
                <property name="name"/> (1)
            </property>
        </fetchPlan>
        <loader id="usersDl">
            <query>
                <![CDATA[select e from User e order by e.username]]>
            </query>
        </loader>
    </collection>
</data>
<layout>
    <dataGrid id="usersTable"
              width="100%"
              minHeight="20em"
              dataContainer="usersDc">
        <columns>
            <column property="username"/> (2)
            <column property="firstName"/>
            <column property="lastName"/>
            <column property="active"/>
            <column property="onboardingStatus"/>
            <column property="department.name"/> (3)
        </columns>
    </dataGrid>
</layout>
1 Ссылочный атрибут.
2 Колонка для отображения атрибута из корневой сущности.
3 Колонка для отображения ссылочного атрибута, к которому обращаются с помощью точечной нотации.
data grid basics

Привязка данных

Привязка данных - это связывание визуального компонента с контейнером данных. Компонент dataGrid может отображать данные, загруженные как в контейнер коллекции, так и в контейнер KeyValue.

Контейнер коллекции

Обычно dataGrid связывается с данными декларативно в XML-дескрипторе с помощью атрибута dataContainer. Этот атрибут должен ссылаться на контейнер коллекции, который содержит данные для отображения. Соответствующий пример приведён в предыдущем разделе.

Контейнер Key-Value

Также возможно привязать dataGrid к контейнеру Key-Value. Это позволяет отображать результаты запроса, возвращающего скалярные значения и/или агрегаты. Например:

<data readOnly="true">
    <keyValueCollection id="statusesDc">
        <loader id="statusesLoader">
            <query>
                <![CDATA[select o.department, o.onboardingStatus,
                count(o.onboardingStatus) from
                User o group by o.department, o.onboardingStatus]]>
            </query>
        </loader>
        <properties>
            <property name="department" datatype="string"/>
            <property name="onboardingStatus" datatype="int"/>
            <property name="count" datatype="int"/>
        </properties>
    </keyValueCollection>
</data>
<layout>
    <dataGrid width="100%" dataContainer="statusesDc">
        <columns>
            <column property="department"/>
            <column property="onboardingStatus"/>
            <column property="count"/>
        </columns>
    </dataGrid>
</layout>

Программная привязка

Если необходимо задать контейнер данных программно, используйте атрибут metaClass вместо dataContainer:

<dataGrid width="100%" id="dataGrid" metaClass="User">
    <columns>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="username"/>
        <column property="joiningDate"/>
        <column property="onboardingStatus"/>
    </columns>
</dataGrid>

После этого в контроллере экрана используйте класс ContainerDataGridItems для привязки dataGrid к контейнеру данных:

@ViewComponent
private DataGrid<User> dataGrid;

@ViewComponent
private CollectionContainer<User> usersDc;

@Subscribe
public void onInit(InitEvent event) {
    dataGrid.setItems(new ContainerDataGridItems<>(usersDc));
}

Программные колонки

Методы addColumn() и addComponentColumn() позволяют создавать колонки в Java вместо XML.

addColumn() удобно использовать вместе с рендерерами, например с LocalDateRenderer, показанным в разделе LocalDateRenderer. addComponentColumn() подходит, когда в каждой ячейке должен отображаться UI-компонент.

Следующий пример использует addComponentColumn(), чтобы добавить колонку с изображением пользователя:

import com.company.onboarding.entity.User;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.server.streams.DownloadHandler;
import com.vaadin.flow.server.streams.DownloadResponse;
import com.vaadin.flow.server.streams.InputStreamDownloadHandler;
import io.jmix.core.FileRef;
import io.jmix.core.FileStorageLocator;
import io.jmix.flowui.UiComponents;
import io.jmix.flowui.component.grid.DataGrid;
import java.io.InputStream;

// class declaration and annotations omitted

    @ViewComponent
    private DataGrid<User> usersDtGr;

    @Autowired
    private UiComponents uiComponents;

    @Autowired
    private FileStorageLocator fileStorageLocator;

    @Subscribe
    public void onInit(InitEvent event) {
        Grid.Column<User> pictureColumn = usersDtGr.addComponentColumn(user -> { (1)
            FileRef fileRef = user.getPicture();
            if (fileRef != null) {
                Image image = uiComponents.create(Image.class); (2)
                image.setWidth("30px");
                image.setHeight("30px");
                image.setClassName("user-picture");
                InputStreamDownloadHandler handler = (3)
                        DownloadHandler.fromInputStream(e -> {
                            InputStream inputStream = fileStorageLocator.getByName(
                                    fileRef.getStorageName()).openStream(fileRef);
                            return new DownloadResponse(
                                    inputStream, fileRef.getFileName(), fileRef.getContentType(), -1);
                        });
                image.setSrc(handler); (4)

                return image; (5)
            } else {
                return new Span();
            }
        })
                .setHeader("Picture")
                .setAutoWidth(true)
                .setFlexGrow(0);
        usersDtGr.setColumnPosition(pictureColumn,0);
    }
1 Добавляет новую колонку, которая отображает компонент image.
2 Экземпляр компонента Image создается с помощью фабрики UiComponents.
3 Создает DownloadHandler, который открывает входной поток для файла, на который ссылается атрибут picture сущности User.
4 Устанавливает DownloadHandler в качестве источника компонента Image.
5 Метод addComponentColumn() возвращает визуальный компонент, который будет отображаться в ячейках столбца.

Множественный выбор

По умолчанию компонент работает в режиме одиночного выбора. Когда вы задаёте selectionMode значение MULTI, появляется колонка с чекбоксами, позволяющая выбрать любое количество строк. Чтобы выбрать все строки, щёлкните по чекбоксу в заголовке таблицы.

data grid multi select
Выбор диапазона с помощью Shift + click или других сочетаний клавиш в настоящее время не поддерживается.

Встроенное редактирование

Компонент поддерживает встроенное редактирование, позволяя пользователям переключаться между просмотром и редактированием данных таблицы. Встроенное редактирование можно активировать с помощью кнопок в колонке действий или двойным щелчком мыши.

Встроенное редактирование обновляет атрибуты сущностей в памяти. Для сохранения изменений в базе данных используйте следующие методы:

  • В экране деталей сущности объединяются в DataContext. Изменения сохраняются автоматически при нажатии OK, и происходит вызов метода DataContext.save().

  • В экране списка, где DataContext не используется, сохранение изменений выполняется с помощью DataManager, как описано ниже.

Колонка действий

Используйте editorActionsColumn для добавления кнопок Edit и Close рядом с каждой строкой. Они позволяют пользователям начать и завершить редактирование соответственно.

Колонка действий по умолчанию добавляется рядом с другими колонками. Если указано includeAll="true" - автоматически размещается крайней справа.
Показать код
<dataGrid width="100%" dataContainer="usersDc" id="editableUsersTable">
    <columns>
        <column property="username"/>
        <column property="firstName" editable="true"/> (1)
        <column property="lastName" editable="true"/>
        <column property="active" editable="true"/>
        <column property="onboardingStatus"/>
        <editorActionsColumn>
            <editButton text="Edit" icon="PENCIL"/> (2)
            <closeButton text="Close" icon="CLOSE"/> (3)
        </editorActionsColumn>
    </columns>
</dataGrid>
1 Сделайте нужные колонки редактируемыми.
2 Кнопка для начала редактирования.
3 Кнопка для завершения редактирования.

Буферизованный режим

При включённом буферизованном режиме пользователям необходимо подтверждать или отменять свои изменения, что снижает риск случайных правок. При переходе на другую строку внесённые изменения отменяются.

Показать код
<dataGrid width="100%" dataContainer="usersDc" editorBuffered="true"> (1)
    <columns>
        <column property="username"/>
        <column property="firstName" editable="true"/> (2)
        <column property="lastName" editable="true"/>
        <column property="active" editable="true"/>
        <column property="onboardingStatus"/>
        <editorActionsColumn>
            <editButton text="Edit" icon="PENCIL"/> (3)
            <saveButton icon="CHECK" themeNames="success"/> (4)
            <cancelButton icon="CLOSE" themeNames="error"/> (5)
        </editorActionsColumn>
    </columns>
</dataGrid>
1 Включить буферизованный режим.
2 Сделать соответствующие колонки редактируемыми.
3 Кнопка для начала редактирования.
4 Кнопка для подтверждения изменений.
5 Кнопка для отмены изменений.

Редактирование по двойному клику

Иногда удобнее начинать встроенное редактирование, дважды щёлкнув по элементу.

Показать код
<dataGrid width="100%" dataContainer="usersDc" id="dblClickTable">
    <columns>
        <column property="username"/>
        <column property="firstName" editable="true"/>
        <column property="lastName" editable="true"/>
        <column property="active" editable="true"/>
        <column property="onboardingStatus"/>
    </columns>
</dataGrid>
@ViewComponent
private DataGrid<User> dblClickTable;

@ViewComponent
private GridMenuItem<Object> emailItem;


@Subscribe
public void onInit(InitEvent event) {
    DataGridEditor<User> tableEditor = dblClickTable.getEditor();
    dblClickTable.addItemDoubleClickListener(e -> {
        tableEditor.editItem(e.getItem());
        Component editorComponent = e.getColumn().getEditorComponent();
        if (editorComponent instanceof Focusable) {
            ((Focusable) editorComponent).focus();
        }
    });
}

Автосохранение изменений

В стандартном экране списка загруженные сущности не объединяются в DataContext (если в XML-элементе загрузчика установлен атрибут readOnly="true"). Кроме того, в экранах списка обычно отсутствуют кнопки подтверждения, такие как OK или Save. Поэтому изменённые сущности необходимо явно сохранять в базе данных.

В небуферизованном режиме это можно сделать с помощью DataManager в обработчике события EditorCloseEvent следующим образом:

@ViewComponent
private CollectionContainer<User> usersDc;

@Install(to = "usersDataGrid.@editor", subject = "closeListener")
private void usersDataGridEditorCloseListener(final EditorCloseEvent<User> event) {
    User user = event.getItem();
    User savedUser = dataManager.save(user); (1)
    usersDc.replaceItem(savedUser); (2)
}
1 Сохранить сущность и получить сохранённый экземпляр.
2 Заменить текущий экземпляр сохранённым в контейнере данных. Все последующие изменения будут применяться к актуальной версии сущности.

В буферизованном режиме аналогичные действия выполняются в обработчике события EditorSaveEvent:

@Install(to = "usersDataGrid.@editor", subject = "saveListener")
private void usersDataGridEditorSaveListener(final EditorSaveEvent<User> event) {
    User user = event.getItem();
    User savedUser = dataManager.save(user);
    usersDc.replaceItem(savedUser);
}

Для генерации обработчиков в виде аннотированных методов используйте вкладку Handlers в Component Inspector Jmix студии, где обработчики событий редактора помечены префиксами [Editor].

Обработчики также можно добавить программно с помощью методов dataGrid.getEditor().addSaveListener() и аналогичных.

DataGridEditor

Интерфейс io.jmix.flowui.component.grid.editor.DataGridEditor предоставляет дополнительную функциональность редактора: настройку, открытие, сохранение и отмену редактирования строки, регистрацию обработчиков событий, а также служебные методы для определения компонентов редактирования колонок.

Для поддержки механизмов фреймворка, таких как контейнеры данных, источники значений и т.д., компонент редактирования колонки должен добавляться с использованием методов DataGridEditor (например, DataGridEditor#setColumnEditorComponent()), а не через прямое API колонки Column#setEditorComponent().

Пример использования:

@Autowired
private UiComponents uiComponents;

@ViewComponent
private DataGrid<User> editableUserTable;

@Subscribe
public void onInit(InitEvent event) {
    DataGridEditor<User> editor = editableUserTable.getEditor(); (1)

    editor.setColumnEditorComponent("timeZoneId", generationContext -> {
        //noinspection unchecked
        JmixComboBox<String> timeZoneField = uiComponents.create(JmixComboBox.class); (2)
        timeZoneField.setItems(List.of(TimeZone.getAvailableIDs()));
        timeZoneField.setValueSource(generationContext.getValueSourceProvider().getValueSource("timeZoneId"));
        timeZoneField.setWidthFull();
        timeZoneField.setClearButtonVisible(true);
        timeZoneField.setRequired(true);
        //noinspection unchecked,rawtypes
        timeZoneField.setStatusChangeHandler(((Consumer) generationContext.getStatusHandler())); (3)

        return timeZoneField; (4)
    });
}
1 Получить экземпляр DataGridEditor.
2 Экземпляр компонента JmixComboBox создается с помощью фабрики UiComponents.
3 Установить StatusChangeHandler.
4 Метод setColumnEditorComponent() возвращает визуальный компонент, который будет отображаться как редактор столбца.

SupportsStatusChangeHandler

По умолчанию компоненты ввода (например, textField, comboBox) отображают сообщения об ошибках в тексте над собой. Такое поведение имеет недостатки при ограниченной области ячейки редактирования. Интерфейс io.jmix.flowui.component.SupportsStatusChangeHandler позволяет определить альтернативный способ отображения сообщений об ошибках. Компоненты, реализующие этот интерфейс, поддерживают делегирование обработки ошибок.

По умолчанию встроенный редактор использует StatusChangeHandler для установки сообщения об ошибке компонента в качестве его title.

Компонент может включать секции заголовка (header) и подвала (footer) для отображения дополнительной информации. Каждая секция может содержать одну или несколько строк, которые можно добавить с помощью следующих методов:

Метод

Описание

appendHeaderRow()

Добавляет новую строку в нижнюю часть секции заголовка.

prependHeaderRow()

Добавляет новую строку в верхнюю часть секции заголовка.

appendFooterRow()

Добавляет новую строку в нижнюю часть секции подвала.

prependFooterRow()

Добавляет новую строку в верхнюю часть секции подвала.

Ниже приведён пример dataGrid, который содержит объединённые ячейки в заголовке и вычисляемое значение в подвале:

data grid header footer
Показать код
<dataGrid id="dataGrid"
          width="100%"
          dataContainer="usersDc"
          themeNames="column-borders">
    <columns>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="active"/>
    </columns>
</dataGrid>
@ViewComponent
private DataGrid<User> dataGrid;
@ViewComponent
private CollectionContainer<User> usersDc;
@ViewComponent
private CollectionLoader<User> usersDl;
@Autowired
private DataManager dataManager;
@Autowired
private UiComponents uiComponents;
@Autowired
private Notifications notifications;
@ViewComponent
private DataContext dataContext;

@Subscribe
protected void onInit(final InitEvent event) {
    usersDl.load();
    initHeader();
    initFooter();
}

protected void initHeader() {
    HeaderRow headerRow = dataGrid.prependHeaderRow();
    HeaderRow.HeaderCell headerCell = headerRow.join(
            dataGrid.getColumnByKey("firstName"),
            dataGrid.getColumnByKey("lastName")); (1)
    headerCell.setText("Full Name");
}

protected void initFooter() {
    FooterRow footerRow = dataGrid.appendFooterRow();
    FooterRow.FooterCell activeCell = footerRow.getCell(dataGrid.getColumnByKey("active"));
    activeCell.setText(getActiveCount() + "/" + usersDc.getItems().size());
}

protected int getActiveCount() {
    int activeCount = 0;
    Collection<User> items = dataGrid.getGenericDataView().getItems().toList();
    for (User user : items) {
        if (user.getActive()) {
            activeCount++;
        }
    }
    return activeCount;
}
1 Ячейки в заголовке могут быть объединены. Это позволяет представить общую информацию о связанных столбцах.
Как в заголовке, так и в подвале можно размещать сложное содержимое и компоненты. Смотрите интерактивный пример.

Фильтрация по заголовкам колонок

Это экспериментальная функция. Внешний вид и детали реализации могут существенно измениться в следующем релизе Jmix.

Данные в dataGrid можно фильтровать с помощью встроенных в заголовки колонок фильтров свойств.

Вы можете указать, для каких колонок должен быть доступен фильтр, используя XML-атрибут filterable. В фильтруемых колонках в заголовках отображается иконка фильтра (funnel). При клике на эту иконку появляется диалог с условием фильтрации по свойству. Если условие задано, иконка в соответствующей колонке подсвечивается.

Чтобы иконка фильтра всегда была видна, задайте колонке подходящую ширину с помощью атрибутов width или autoWidth. Не делайте колонку изменяемой по ширине, иначе пользователь сможет уменьшить её ширину и иконка фильтра станет невидимой.

Например:

<dataGrid dataContainer="usersDc"
          width="100%">
    <columns>
        <column property="firstName" filterable="true"
                width="15em"/>
        <column property="lastName" filterable="true"
                autoWidth="true"/>
        <column property="username"/>
        <column property="active"/>
        <column property="joiningDate"/>
        <column property="onboardingStatus"/>
    </columns>
</dataGrid>

Фильтры свойств в заголовках колонок работают так же, как отдельные фильтры по свойствам и как genericFilter - они добавляют условия к загрузчику данных. В стандартном режиме эти условия преобразуются в JPQL-запрос и фильтруют данные на уровне базы данных.

Фильтруемые колонки можно использовать совместно с компонентами propertyFilter и genericFilter. Условия всех фильтров объединяются логическим оператором AND.

В настоящее время условия фильтрации в столбцах не сохраняются в URL страницы. Это означает, что если пользователь применит фильтр, перейдёт в экран редактирования и затем вернётся обратно, фильтр будет сброшен.

Действия

Компонент dataGrid реализует интерфейс HasActions и может содержать как стандартные действия списка, так и пользовательские. Выполнение действий происходит при нажатии соответствующих кнопок или через контекстное меню, которое вызывается по правому клику.

data grid actions

Чтобы добавить action в Jmix Studio, выберите компонент в XML-дескрипторе экрана или в панели структуры Jmix UI, затем нажмите кнопку Add→Action в панели инспектора Jmix UI.

Показать код
<hbox id="buttonsPanel" classNames="buttons-panel"> (1)
    <button id="createBtn" action="usersDataGrid.create"/>
    <button id="editBtn" action="usersDataGrid.edit"/>
    <button id="removeBtn" action="usersDataGrid.remove"/>
    <button id="infoBtn" action="usersDataGrid.getInfo"/>
</hbox>
<dataGrid width="100%" dataContainer="usersDc" id="usersDataGrid">
    <columns>
        <column property="username"/>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="active"/>
        <column property="onboardingStatus"/>
        <column property="joiningDate"/>
    </columns>
    <actions>
        <action id="create" type="list_create"/> (2)
        <action id="edit" type="list_edit"/>
        <action id="remove" type="list_remove"/>
        <action id="getInfo" text="Get Info"/> (3)
    </actions>
</dataGrid>
1 Определите hbox для размещения кнопок действий.
2 Определите стандартное действие list_create.
3 Определите пользовательское действие getInfo. Значение его атрибута text используется как название действия в контекстном меню и как подпись кнопки.

Контекстное меню

Контекстное меню предоставляет альтернативный способ доступа к действиям через правую кнопку мыши. Каждое действие представлено отдельным пунктом меню.

Элемент contextMenu позволяет настроить список пунктов, организовав их с помощью разделителей и иерархической структуры.

data grid context menu
Показать код
<dataGrid width="100%" dataContainer="usersDc" id="menuDataGrid">
    <columns>
        <column property="username"/>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="active"/>
        <column property="onboardingStatus"/>
        <column property="joiningDate"/>
    </columns>
    <actions showInContextMenuEnabled="false"> (1)
        <action id="create" type="list_create"/>
        <action id="edit" type="list_edit"/>
        <action id="remove" type="list_remove"/>
        <action id="getInfo" text="View"/>
        <action id="sendMessage" text="Message"/>
    </actions>
    <contextMenu id="contextMenu">
        <item action="menuDataGrid.getInfo" icon="INFO_CIRCLE"/> (2)
        <separator/>
        <item text="Contact" icon="USER"> (3)
            <item action="menuDataGrid.sendMessage" icon="COMMENT"/>
            <item id="emailItem"/> (4)
        </item>
        <separator/>
        <item action="menuDataGrid.remove" icon="TRASH"/>
    </contextMenu>
</dataGrid>
1 Скрыть все действия из меню или скрыть конкретное действие, установив для него атрибут visible.
2 Явно добавить пункты меню для необходимых действий.
3 Вложить пункты друг в друга для создания иерархии.
4 Пункт с содержимым, добавленным динамически через dynamicContentHandler.
@ViewComponent
private GridMenuItem<Object> emailItem;

@Install(to = "contextMenu", subject = "dynamicContentHandler")
private boolean contextMenuDynamicContentHandler(final User user) {
    if (user == null) {
        return false;
    }
        emailItem.setText("Email: " + user.getEmail());
    return true;
}

Рендереры

Рендереры настраивают отображение ячеек колонок. В этом разделе описаны рендереры, специфичные для колонок dataGrid. Общие API рендереров, такие как ComponentRenderer, LitRenderer и FragmentRenderer, описаны в разделе Рендереры.

Рендереры можно определить следующими способами:

  • Декларативно в XML - используйте предопределенные рендереры numberRenderer, localDateRenderer, localDateTimeRenderer, detailLinkRenderer и detailButtonRenderer внутри элемента column.

  • С помощью аннотации @Supply - предоставляйте пользовательский рендерер из контроллера экрана.

  • С помощью fragmentRenderer - используйте общий механизм рендеринга на основе фрагментов, описанный в Рендерер фрагментов.

  • С помощью addColumn() и addComponentColumn() - создавайте колонки в Java и настраивайте рендереры программно. См. Программные колонки.

Чтобы добавить рендерер в Jmix Studio, выберите элемент column в XML-дескрипторе экрана или на панели структуры Jmix UI и нажмите Add→Renderer в панели инспектора Jmix UI.

LocalDateRenderer

LocalDateRenderer отвечает за отображение дат в формате значений типа LocalDate.

В элементе column таблицы присутствует вложенный элемент localDateRenderer, который содержит необязательный атрибут nullRepresentation и обязательный атрибут format для строки формата.

<column property="joiningDate">
    <localDateRenderer format="MMM dd, yyyy"/>
</column>

Атрибут nullRepresentation используется для задания текстового отображения значений null.

Ниже приведён пример использования LocalDateRenderer с методом addColumn():

@ViewComponent
private DataGrid<User> usersDtGr;

@Subscribe
public void onInit(InitEvent event) {
    usersDtGr.addColumn(new LocalDateRenderer<>(
                    User::getJoiningDate,
                    () -> DateTimeFormatter.ofLocalizedDate(
                            FormatStyle.MEDIUM)))
            .setHeader("Joining date");
}

LocalDateTimeRenderer

LocalDateTimeRenderer отвечает за отображение дат в формате значений типа LocalDateTime.

В элементе column таблицы присутствует вложенный элемент localDateTimeRenderer, который содержит необязательный атрибут nullRepresentation и обязательный атрибут format, задающий строку формата.

<column property="passwordExpiration">
    <localDateTimeRenderer format="dd/MM/YYYY HH:mm:ss"/>
</column>

Атрибут nullRepresentation используется для задания текстового отображения значений null.

Number Renderer

Отображает числовые значения в колонке.

<column property="factor">
    <numberRenderer numberFormat="#,#00.0000"/>
</column>

Укажите ровно один из атрибутов format или numberFormat. Если не указан ни один из них или указаны оба, фреймворк выбросит GuiDevelopmentException. Используйте необязательный атрибут nullRepresentation, чтобы задать отображение null. Атрибут numberFormat использует синтаксис java.text.DecimalFormat.

Отображает ссылку, открывающую экран редактирования текущей сущности.

<dataGrid width="100%" dataContainer="usersDc">
    <columns>
        <column property="username">
            <detailLinkRenderer viewId="User.detail"
                                target="BLANK"
                                classNames="detail-link"
                                css="font-weight: 600;"/>
        </column>
        <column property="firstName"/>
        <column property="lastName"/>
    </columns>
</dataGrid>

Поддерживаемые атрибуты:

  • viewClass, viewId задают целевой экран. Рендерер определяет экран в следующем порядке: viewClass, viewId, экран редактирования по умолчанию.

  • text задаёт текст ссылки. Если атрибут не указан, рендерер использует форматированное значение привязанного свойства колонки.

  • target задаёт цель ссылки.

  • classNames, css применяют стили.

Целевой экран должен иметь зарегистрированный маршрут ровно с одним параметром маршрута, а экземпляр сущности должен уже иметь ненулевой id. Для маршрутов без параметров или с несколькими параметрами настраивайте рендерер из Java-кода и передавайте собственный URL с помощью DetailLinkRenderer.withHrefProvider().

DetailButtonRenderer

Отображает кнопку, открывающую экран редактирования текущей сущности.

<dataGrid width="100%" dataContainer="stepsDc">
    <columns>
        <column property="name">
            <detailButtonRenderer viewId="Step.detail"
                                  icon="vaadin:edit"
                                  openMode="DIALOG"
                                  themeNames="tertiary-inline small"
                                  classNames="detail-button"
                                  css="color: var(--lumo-primary-text-color);"/>
        </column>
        <column property="duration"/>
        <column property="sortValue"/>
    </columns>
</dataGrid>

Поддерживаемые атрибуты:

  • viewClass, viewId задают целевой экран. Рендерер определяет экран в следующем порядке: viewClass, viewId, экран редактирования по умолчанию.

  • openMode управляет способом открытия экрана: NAVIGATION (по умолчанию) или DIALOG.

  • text задаёт текст кнопки. Если атрибут не указан, рендерер использует форматированное значение привязанного свойства колонки. Для колонок только с key задавайте его явно.

  • icon задаёт значок кнопки. Его можно определить через атрибут или вложенный элемент icon.

  • themeNames, classNames, css применяют стили.

Detail Renderers в колонках, не связанных со свойством

DetailLinkRenderer и DetailButtonRenderer можно использовать в колонках, которые задаются через атрибут key, а не привязываются к свойству сущности с помощью атрибута property.

<dataGrid width="100%" dataContainer="usersDc">
    <columns>
        <column property="username"/>
        <column key="openUser" header="Open">
            <detailButtonRenderer viewId="User.detail"
                                  text="Edit"
                                  openMode="DIALOG"/>
        </column>
    </columns>
</dataGrid>

В этом случае задайте text ссылки или кнопки явно, потому что привязанное значение свойства отсутствует.

TextRenderer

TextRenderer отображает обычный текст, переданный из Java-кода.

<column key="status" header="Status"/>
@Supply(to = "userStepsDataGrid.status", subject = "renderer")
private Renderer<UserStep> userStepsDataGridStatusRenderer() {
    return new TextRenderer<>(userStep ->
            isOverdue(userStep) ? "Overdue!" : "");
}

Обычно этот рендерер задается из Java-кода с помощью обработчика renderer или аннотации @Supply.

ComponentRenderer

Отображает в каждой ячейке пользовательский компонент. Используйте этот рендерер, когда ячейка должна содержать насыщенное или интерактивное содержимое, например чекбокс, изображение или кнопку.

Сведения о доступных конструкторах, общем поведении и особенностях производительности смотрите в разделе Рендерер компонентов.

Следующий пример отображает в колонке completed чекбокс только для чтения, в зависимости от того, задано ли значение completedDate.

<column key="completed" width="4em" flexGrow="0"/>
@Supply(to = "userStepsDataGrid.completed", subject = "renderer")
private Renderer<UserStep> userStepsDataGridCompletedRenderer() {
    return new ComponentRenderer<>(userStep -> {
        JmixCheckbox checkbox = uiComponents.create(JmixCheckbox.class);
        checkbox.setValue(userStep.getCompletedDate() != null);
        checkbox.addValueChangeListener(e -> {
            // ...
        });
        return checkbox;
    });
}

Детализация элементов

Компонент ItemDetails позволяет разворачивать строки для отображения дополнительной информации об элементе. Для реализации данной функциональности используйте метод setItemDetailsRenderer().

Метод принимает в качестве аргумента объект ComponentRenderer, который определяет способ отображения детализированной информации.

data grid items details

Атрибут detailsVisibleOnClick позволяет управлять отображением дополнительных сведений при клике на строку. Если необходимо, чтобы детализация появлялась по другому событию (не по клику), установите значение этого атрибута в false.

Сортировка

В этом разделе показана кастомизация сортировки для отдельного компонента dataGrid. О кастомизации сортировки для всего приложения см. Сортировка.

Любая колонка таблицы может использоваться для сортировки отображаемых данных. При нажатии на заголовок колонки в таблице активируется специальный индикатор, который показывает текущую колонку сортировки и направление сортировки (по возрастанию или убыванию). Последующие нажатия на тот же заголовок будут переключать направление сортировки на противоположное.

Атрибуты-перечисления сортируются по значениям id, а не по локализованным надписям, отображаемым в UI.

В результате порядок сортировки может отличаться от видимого порядка значений перечисления в dataGrid, особенно если значения перечисления локализованы.

Сортировка по нескольким столбцам

Данные можно сортировать одновременно по нескольким колонкам. В этом случае первая выбранная колонка определяет основной критерий сортировки, вторая колонка задаёт дополнительный критерий, а последующие колонки устанавливают второстепенные критерии сортировки.

Настройка осуществляется с помощью атрибутов multiSort, multiSortOnShiftClickOnly и multiSortPriority.

Пример:

<dataGrid width="100%"
          dataContainer="usersDc"
          multiSort="true"
          multiSortOnShiftClickOnly="true"
          multiSortPriority="APPEND">

Компаратор колонки

Используйте DataGridColumn#setComparator() для определения пользовательской логики сортировки конкретного столбца, когда сортировка выполняется в памяти. Сортировка в памяти используется, если у контейнера нет загрузчика, либо если загружена только первая страница и количество загруженных элементов меньше размера страницы.

В следующем примере атрибут Department.num сортируется как число, хотя тип этого атрибута - String:

<dataGrid id="inMemoryDepartmentsDataGrid"
          width="100%"
          dataContainer="inMemoryDepartmentsDc">
    <columns>
        <column property="name"/>
        <column property="num"/>
    </columns>
</dataGrid>
private void initInMemoryComparator() {
    inMemoryDepartmentsDc.setItems(dataManager.load(Department.class)
            .query("select e from Department e")
            .list());

    inMemoryDepartmentsDataGrid.getColumnByKey("num")
            .setComparator(Comparator.comparing(
                    department -> department.getNum() == null ? null : Integer.valueOf(department.getNum()),
                    Comparator.nullsFirst(Integer::compareTo)));
}

Делегат сортировки

Если таблица повторно загружает данные из базы данных, настройте делегат сортировки. Делегат получает инструкции по сортировке от таблицы и возвращает объект DataGridSort, что позволяет в одном месте переопределить сортировку в памяти, сортировку в базе данных или обе сразу.

Следующий пример настраивает сортировку так, чтобы значения Department.num сравнивались как числа, а не как строки:

<dataGrid id="delegateDepartmentsDataGrid"
          width="100%"
          dataContainer="delegateDepartmentsDc">
    <columns>
        <column property="name"/>
        <column property="num"/>
    </columns>
</dataGrid>
private void initBoundPropertySortBuilder() {
    delegateDepartmentsDataGrid.setSortBuilderDelegate(sortContext ->
            DataGridSortBuilder.create(sortContext)
                    .replaceSort("num", "CAST({E}.num BIGINT)", (1)
                            Comparator.comparing(
                                    department -> department.getNum() == null
                                            ? null
                                            : Integer.valueOf(department.getNum()),
                                    Comparator.nullsFirst(Integer::compareTo))) (2)
                    .build());
}
1 Если таблица повторно загружает данные из базы данных, в ORDER BY добавляется выражение CAST({E}.num BIGINT), поэтому база данных также выполняет числовую, а не лексикографическую сортировку.
2 Если таблица сортирует данные в памяти, компаратор преобразует num в Integer и сравнивает числовые значения.

Сортировка вычисляемой колонки

Делегат сортировки также полезен для колонок, которые не привязаны к атрибуту сущности. В следующем примере колонка fullName формируется из firstName и lastName, а делегат сортировки сопоставляет эту синтетическую колонку и с выражениями JPQL, и с компаратором для сортировки в памяти:

<dataGrid id="fullNameUsersDataGrid"
          width="100%"
          dataContainer="usersDc">
    <columns>
        <column key="fullName" header="Full name" sortable="true"/>
        <column property="username"/>
        <column property="department.name"/>
        <column property="onboardingStatus"/>
    </columns>
</dataGrid>
private void initComputedColumnSortBuilder() {
    fullNameUsersDataGrid.setSortBuilderDelegate(sortContext ->
            DataGridSortBuilder.create(sortContext)
                    .replaceSort("fullName",
                            List.of("{E}.firstName", "{E}.lastName"),
                            Comparator.comparing(User::getFirstName,
                                            Comparator.nullsFirst(String::compareTo))
                                    .thenComparing(User::getLastName,
                                            Comparator.nullsFirst(String::compareTo)))
                    .build());
}
@Supply(to = "fullNameUsersDataGrid.fullName", subject = "renderer")
protected Renderer<User> fullNameUsersDataGridFullNameRenderer() {
    return new TextRenderer<>(user ->
            ((user.getFirstName() == null ? "" : user.getFirstName()) + " "
                    + (user.getLastName() == null ? "" : user.getLastName())).trim());
}

Агрегация данных

Компонент поддерживает агрегацию значений в строках. При включении этой функции отображается дополнительная строка с агрегированными значениями.

Например:

<dataGrid width="100%"
          dataContainer="stepsDc"
          aggregatable="true"
          aggregationPosition="TOP"> (1)
    <columns>
        <column property="name"/>
        <column property="duration">
            <aggregation type="AVG"
                         cellTitle="msg://aggregation.cellTitle"/> (2)
        </column>
        <column property="sortValue"/>
        <column property="factor">
            <aggregation type="AVG">
                <formatter>
                    <number format="#,##0.00"/> (3)
                </formatter>
            </aggregation>
        </column>
    </columns>
</dataGrid>
1 Установите атрибут aggregatable в значение true.
2 Для каждого столбца, который нужно агрегировать, добавьте элемент aggregation. При необходимости укажите атрибут cellTitle для отображения подсказки при наведении на агрегированное значение.
3 Определите formatter для отображения значения в нестандартном формате.

Элемент aggregation позволяет задать пользовательскую логику вычисления агрегированных значений с помощью атрибута strategyClass:

<dataGrid width="100%"
          dataContainer="usersDc"
          aggregatable="true"
          aggregationPosition="TOP">
    <columns>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="onboardingStatus">
            <aggregation
                    strategyClass="com.company.onboarding.view.component.datagrid.DataGridUserStatusAggregation"/>
        </column>
    </columns>
</dataGrid>

Такой класс должен реализовывать интерфейс AggregationStrategy. Например:

public class DataGridUserStatusAggregation implements AggregationStrategy<OnboardingStatus, String> {

    @Autowired
    public Messages messages;

    @Override
    public String aggregate(Collection<OnboardingStatus> propertyValues) {
        OnboardingStatus mostFrequent = null;
        long max = 0;

        if (CollectionUtils.isNotEmpty(propertyValues)) {
            for (OnboardingStatus status : OnboardingStatus.values()) {
                long current = propertyValues.stream()
                        .filter(status :: equals)
                        .count();

                if (current > max) {
                    mostFrequent = status;
                    max = current;
                }
            }
        }

        if (mostFrequent != null) {
            String key = OnboardingStatus.class.getSimpleName() + "." + mostFrequent.name();
            return String.format("%s: %d/%d", messages.getMessage(OnboardingStatus.class, key), max, propertyValues.size());
        }

        return null;
    }

    @Override
    public Class<String> getResultClass() {
        return String.class;
    }
}

Отображение при отсутствии данных

Когда таблица данных не содержит информации для отображения, область между заголовком и подвалом по умолчанию остается пустой. Функция пустого состояния позволяет вывести сообщение или интерфейсный компонент, информирующий пользователя об отсутствии данных.

  • Используйте атрибут emptyStateText для определения текста, который будет отображаться при пустой таблице.

    <dataGrid id="dataGridEmptyState"
              dataContainer="customersDc"
              width="100%"
              emptyStateText="No customers found">
        <columns>
            <column property="firstName"/>
            <column property="lastName"/>
            <column property="age"/>
            <column property="martialStatus"/>
        </columns>
    </dataGrid>
    Данный атрибут имеет приоритет над компонентом пустого состояния, настроенным через метод setEmptyStateComponent(Component) в контроллере экрана и над элементом emptyStateComponent в XML-дескрипторе. Установка значения emptyStateText приведёт к удалению любого ранее заданного компонента.
  • Для отображения компонента при отсутствии данных используйте элемент emptyStateComponent.

    <dataGrid id="dataGridEmptyStateComp"
              dataContainer="customersDc"
              width="100%">
        <columns>
            <column property="firstName"/>
            <column property="lastName"/>
            <column property="age"/>
            <column property="martialStatus"/>
        </columns>
        <emptyStateComponent>
            <button id="newCustomerBtn"
                    text="Create customer" width="100%"/>
        </emptyStateComponent>
    </dataGrid>

    После настройки emptyStateComponent вы можете работать с вложенным компонентом как обычно, включая настройку его стилей и создание обработчиков событий.

    Установка этого компонента отменяет:

    • любой текст пустого состояния, заданный методом setEmptyStateText(String) в контроллере экрана;

    • атрибут emptyStateText в XML-дескрипторе экрана.

Варианты темы

Используйте атрибут themeNames для настройки темы компонента.

Вариант Описание Поддерживается в

column-borders

Добавляет вертикальные границы между столбцами.

Aura, Lumo

compact

Уменьшает высоту строк и интервалы.

Lumo

no-border

Удаляет внешнюю границу вокруг сетки.

Aura, Lumo

no-row-borders

Удаляет горизонтальные границы между строками.

Aura, Lumo

row-stripes

Чередует цвета фона строк для улучшения читаемости.

Aura, Lumo

wrap-cell-content

Позволяет содержимому ячеек переноситься на несколько строк вместо обрезки.

Aura, Lumo

Атрибуты

Атрибуты

В Jmix существует множество общих атрибутов, которые выполняют одинаковые функции для всех компонентов. Ниже перечислены атрибуты, специфичные для dataGrid:

Название

Описание

Значение по-умолчанию

allRowsVisible

Если значение равно true, таблица будет отображать все строки одновременно без полос прокрутки, фактически отключая виртуальную прокрутку. Это означает, что вместо рендеринга только видимых строк и подгрузки дополнительных при прокрутке пользователем, таблица будет отображать все строки в DOM одновременно.

Использование этой функции не рекомендуется при работе с большим количеством элементов, так как это может вызвать проблемы с производительностью.

false

aggregatable

Если значение true, активирует агрегацию колонок. Смотрите раздел Агрегация данных.

false

aggregationPosition

Определяет положение строки с агрегированными данными. Допустимые значения: TOP (вверху) или BOTTOM (внизу). Подробнее смотрите раздел Агрегация данных.

BOTTOM

columnReorderingAllowed

Если значение true, позволяет пользователям изменять порядок колонок.

false

detailsVisibleOnClick

Если значение true, позволяет раскрывать детализацию элементов по клику мыши.

true

dropMode

Определяет, в каких строках возможно выполнение операции перетаскивания (drop). Допустимые значения: BETWEEN, ON_TOP, ON_TOP_OR_BETWEEN, ON_GRID. Данная функция может использоваться, например, для изменения порядка строк и для перемещения строк в рамках таблицы.

editorBuffered

При значении true активируется буферизированный режим редактирования, который означает что:

- пользователь должен подтверждать изменения нажатием кнопки подтверждения;

- предусмотрена возможность отмены внесённых изменений.

В небуферизированном режиме (unbuffered mode) изменения применяются сразу без необходимости подтверждения.

false

emptyStateText

Определяет текст, отображаемый когда таблица данных пуста. Используйте null для удаления текущего содержимого пустого состояния. Подробнее смотрите раздел Отображение при отсутствии данных.

multiSort

При значении true активируется возможность сортировки данных по нескольким колонкам одновременно.

false

multiSortOnShiftClickOnly

При значении true множественная сортировка активируется только при одновременном нажатии и удержании клавиши Shift и клике на заголовке.

false

multiSortPriority

Определяет, добавляется ли выбранная колонка в начало или конец списка сортировки. Допустимые значения: PREPEND, APPEND.

PREPEND

nestedNullBehavior

Определяет поведение при обработке вложенных свойств, которые могут содержать значения null в цепочке свойств. Допустимые значения: THROW, ALLOW_NULLS.

THROW

pageSize

Определяет размер страницы (количество элементов, загружаемых из источника данных за один раз).

50

rowDraggable

Если значение true, пользователи могут перетаскивать строки в таблице.

false

selectionMode

Устанавливает режим выделения элементов. Допустимые значения: SINGLE, MULTI, NONE.

SINGLE

Обработчики

В Jmix существует множество общих обработчиков, которые настраиваются одинаково для всех компонентов. Ниже представлены обработчики, специфичные для dataGrid:

Чтобы сгенерировать заглушку обработчика в Jmix Studio, используйте вкладку Handlers панели инспектора Jmix UI, или команду Generate Handler, доступную на верхней панели контроллера экрана и через меню CodeGenerate (Alt+Insert / Cmd+N).

Название

Описание

CellFocusEvent

com.vaadin.flow.component.grid.CellFocusEvent - событие, которое возникает при фокусировке ячейки в таблице. Соответствует событию DOM grid-cell-focus.

ColumnReorderEvent

com.vaadin.flow.component.grid.ColumnReorderEvent - событие, которое возникает при изменении порядка колонок в таблице. Соответствует событию DOM column-reorder-all-columns.

ColumnResizeEvent

com.vaadin.flow.component.grid.ColumnResizeEvent - событие, которое возникает при изменении размера колонки в таблице данных пользователем. Соответствует событию DOM column-drag-resize.

GridDragEndEvent

com.vaadin.flow.component.grid.dnd.GridDragEndEvent - событие окончания перетаскивания строк в таблице данных. Соответствует событию DOM grid-dragend.

GridDragStartEvent

com.vaadin.flow.component.grid.dnd.GridDragStartEvent - событие начала перетаскивания строк в таблице данных. Соответствует событию DOM grid-dragstart.

GridDropEvent

com.vaadin.flow.component.grid.dnd.GridDropEvent - представляет событие перетаскивания (drop), которое возникает на самой таблице данных или на её строках. Соответствует событию DOM grid-drop.

ItemClickEvent

com.vaadin.flow.component.grid.ItemClickEvent - событие, которое возникает при клике на элемент таблицы данных. Соответствует событию DOM item-click.

ItemDoubleClickEvent

com.vaadin.flow.component.grid.ItemDoubleClickEvent - событие, которое возникает при двойном клике на элемент таблицы данных. Соответствует событию DOM item-double-click.

SortEvent

com.vaadin.flow.data.event.SortEvent - событие, описывающее изменение сортировки в DataProvider. Генерируется объектами, реализующими интерфейс SortNotifier. См. онлайн демо.

dataGenerator

Добавляет генератор данных для таблицы. Если генератор уже был добавлен, действие не выполняется. Подробнее см. в интерфейсе com.vaadin.flow.data.provider.HasDataGenerators.

dragFilter

Позволяет задавать, какие именно строки можно перетаскивать, вместо активации этой функции для всех строк через атрибут rowsDraggable.

dropFilter

Позволяет задавать, какие именно строки могут быть целями для операции перетаскивания (drop targets).

enterPressHandler

Обрабатывает событие нажатия пользователем клавиши Enter.

itemSelectableProvider

Устанавливает предикат, проверяющий, можно ли пользователю выбрать или снять выбор для конкретного элемента в таблице. Предикат получает экземпляр элемента и возвращает true, если пользователю разрешено изменить выбор для этого элемента, либо false в противном случае.

tooltipGenerator

Функция создает всплывающие подсказки (tooltip) для ячеек столбца на основе заданных условий. Смотрите рабочий пример в живой демонстрации.

Элементы

Элементы dataGrid предоставляют широкий набор возможностей для управления внешним видом, поведением и функциональностью колонок как в целом, так и по отдельности.

Чтобы добавить элемент в выбранный компонент, нажмите кнопку Add в панели инспектора Jmix UI.

columns

Элемент columns позволяет задать набор атрибутов для отображения и поведения для всех колонок.

XML-элемент

columns

Атрибуты

exclude - includeAll - resizable - sortable

Элементы

column - EditorActionsColumn

Table 1. Атрибуты

Название

Описание

Значение по-умолчанию

exclude

Исключает отображение определённых атрибутов. Несколько атрибутов следует перечислять через запятую. Например: exclude = "id, version, sortValue".

includeAll

Если значение равно true, включаются все атрибуты, указанные в фетч-плане соответствующего контейнера данных.

resizable

При значении true пользователь может изменять ширину всех колонок таблицы.

false

sortable

Если значение равно true, все колонки поддерживают сортировку пользователем.

true

column

Элемент column определяет отдельную колонку. Атрибуты, заданные для отдельной колонки, переопределяют атрибуты, установленные для всех колонок.

XML-элемент

column

Атрибуты

autowidth - editable - filterable - flexGrow - footer - frozen - header - key - property - resizable - sortable - textAlign - visible - width

Обработчики

AttachEvent - DataGridColumnVisibilityChangedEvent - DetachEvent - partNameGenerator - renderer - tooltipGenerator

Элементы

Aggregation - FragmentRenderer - LocalDateRenderer - LocalDateTimeRenderer - NumberRenderer - DetailLinkRenderer - DetailButtonRenderer

Table 2. Атрибуты

Название

Описание

Значение по-умолчанию

autoWidth

Если значение равно true, ширина колонки будет автоматически подстраиваться под её содержимое.

false

editable

Если значение равно true, колонку можно редактировать. Подробнее смотрите раздел Встроенное редактирование.

false

filterable

Если значение равно true, для этой колонки включается фильтрация. Подробнее смотрите раздел Фильтрация по заголовкам колонок.

false

flexGrow

Задаёт коэффициент расширения (flex grow) для данной колонки. При значении 0 ширина колонки фиксирована.

0

footer

Задаёт текст в нижней части колонки (футере). Значением атрибута может быть либо сам текст, либо ключ из пакета сообщений. В случае использования ключа значение должно начинаться с префикса msg://.

frozen

Если значение равно true, колонка фиксируется (закрепляется на месте) и остаётся видимой при горизонтальной прокрутке таблицы. Рекомендуется фиксировать колонки слева направо.

false

header

Задаёт текст заголовка колонки. Значением атрибута может быть либо сам текст, либо ключ из пакета сообщений. В случае использования ключа значение должно начинаться с префикса msg://.

key

Задаёт пользовательский идентификатор для привязки к этой колонке. Этот ключ можно использовать для последующего получения колонки с помощью метода getColumnByKey(String).

Ключ должен быть уникальным в пределах dataGrid и не может быть изменён после установки.

property

Указывает имя атрибута сущности, который будет отображаться в колонке. Это может быть атрибут корневой сущности, например, property = "user", или атрибут дочерней сущности, например, property = "user.department.name" (используйте точечную нотацию для перехода по объектному графу).

resizable

Если значение равно true, пользователь может изменять ширину колонки.

false

sortable

Если значение равно true, колонка поддерживает сортировку.

false

textAlign

Задает выравнивание текста с возможными значениями: START, CENTER, END.

START

visible

Если значение true, колонка видимая.

true

width

Задает ширину колонки в виде CSS-строки.

Table 3. Обработчики

Название

Описание

DataGridColumnVisibilityChangedEvent

Срабатывает при изменении видимости столбца через компонент gridColumnVisibility.

partNameGenerator

Генерирует части CSS-классов для этого столбца на основе заданных условий. Это позволяет настраивать внешний вид ячеек в зависимости от отображаемых данных. Смотрите живую демонстрацию.

renderer

Отображает содержимое столбца с использованием текста или компонентов. Смотрите TextRenderer и ComponentRenderer.

tooltipGenerator

Генерирует всплывающую подсказку для ячейки столбца на основе заданных условий. Смотрите живую демонстрацию.

contextMenu

Элемент contextMenu организует пункты контекстного меню (вызываемого правой кнопкой мыши) в порядке, отличном от стандартного. Смотрите пример.

XML-элемент

contextMenu

Атрибуты

id - classNames - css - enabled - visible

Обработчики

AttachEvent - DetachEvent - GridContextMenuOpenedEvent - openedChangeEvent - dynamicContentHandler

Элементы

item - separator

Table 4. Обработчики

Название

Описание

GridContextMenuOpenedEvent

Срабатывает при изменении состояния открытия контекстного меню. Может возвращать целевой элемент или идентификатор целевого столбца, позволяя меню отображать пункты в зависимости от выбранного элемента.

openedChangeEvent

Срабатывает при изменении состояния открытия контекстного меню.

dynamicContentHandler

Обрабатывает динамические обновления меню при его открытии, такие как добавление пунктов меню или их содержимого. Смотрите пример.

emptyStateComponent

Элемент emptyStateComponent определяет компонент для отображения при пустом состоянии таблицы. Используйте null, чтобы удалить текущее содержимое. Смотрите раздел Отображение при отсутствии данных.

Смотрите также

Смотрите документацию Vaadin для получения дополнительной информации.