dataGrid
dataGrid
- это таблица данных, которую можно редактировать, сортировать, фильтровать и агрегировать по столбцам. Для работы с большими объёмами данных используется отложенная загрузка при прокрутке, что обеспечивает высокую производительность.
XML-элемент |
|
---|---|
Java-класс |
|
Атрибуты |
id - aggregatable - aggregationPosition - alignSelf - allRowsVisible - classNames - colspan - columnReorderingAllowed - css - dataContainer - detailsVisibleOnClick - dropMode - editorBuffered - emptyStateText - enabled - focusShortcut - height - maxHeight - maxWidth - metaClass - minHeight - minWidth - multiSort - multiSortOnShiftClickOnly - multiSortPriority - nestedNullBehavior - pageSize - rowDraggable - selectionMode - tabIndex - themeNames - visible - width |
Обработчики |
AttachEvent - BlurEvent - CellFocusEvent - ColumnReorderEvent - ColumnResizeEvent - DetachEvent - FocusEvent - GridDragEndEvent - GridDragStartEvent - GridDropEvent - ItemClickEvent - ItemDoubleClickEvent - SortEvent - dataGenerator - dragFilter - dropFilter enterPressHandler - 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 | Столбец для отображения ссылочного атрибута, к которому обращаются с помощью точечной нотации. |

Привязка данных
Привязка данных - это связывание визуального компонента с контейнером данных. Компонент 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));
}
Встроенное редактирование
Компонент поддерживает встроенное редактирование, позволяя пользователям переключаться между просмотром и редактированием данных таблицы. Встроенное редактирование можно активировать с помощью кнопок в колонке действий или двойным щелчком мыши.
Встроенное редактирование обновляет атрибуты сущностей в памяти. Для сохранения изменений в базе данных используйте следующие методы:
|
Колонка действий
Используйте 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 студии, где обработчики событий редактора помечены префиксами Обработчики также можно добавить программно с помощью методов |
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) для отображения дополнительной информации. Каждая секция может содержать одну или несколько строк, которые можно добавить с помощью следующих методов:
Метод |
Описание |
---|---|
|
Добавляет новую строку в нижнюю часть секции заголовка. |
|
Добавляет новую строку в верхнюю часть секции заголовка. |
|
Добавляет новую строку в нижнюю часть секции подвала. |
|
Добавляет новую строку в верхнюю часть секции подвала. |
Ниже приведён пример dataGrid
, который содержит объединённые ячейки в заголовке и вычисляемое значение в подвале:

Показать код
<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
. В фильтруемых столбцах в заголовках отображается иконка фильтра (). При клике на эту иконку появляется диалог с условием фильтрации по свойству. Если условие задано, иконка в соответствующем столбце подсвечивается.
Чтобы иконка фильтра всегда была видна, задайте столбцу подходящую ширину с помощью атрибутов 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
и может содержать как стандартные действия списка, так и пользовательские. Выполнение действий происходит при нажатии соответствующих кнопок или через контекстное меню, которое вызывается по правому клику.

Чтобы добавить |
Показать код
<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
позволяет настроить список пунктов, организовав их с помощью разделителей и иерархической структуры.

Показать код
<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;
}
Рендереры
Рендереры используются для настройки отображения данных в таблице. Например, с помощью рендерера можно:
-
Форматировать даты или числа.
-
Отображать пользовательские иконки или изображения.
-
Создавать интерактивные элементы, такие как кнопки или ссылки.
-
Показывать разное содержимое в зависимости от значения ячейки.
Рендереры можно определить следующими способами:
-
Декларативно в XML
Существует несколько встроенных рендереров, которые можно назначить столбцу в XML:
-
numberRenderer
-
localDateRenderer
-
localDateTimeRenderer
Они принимают строку
format
. Например:<column property="joiningDate"> <localDateRenderer format="MMM dd, yyyy"/> </column>
Для добавления рендерера в Jmix Studio выберите элемент
column
XML-дескрипторе экрана или в панели структуры Jmix UI, затем нажмите кнопку Add→<Some>Renderer в панели инспектора Jmix UI.
-
-
Используя аннотацию @Supply
Рендереры могут быть предоставлены в контроллере экрана с помощью аннотации
@Supply
. Методы, помеченные этой аннотацией, возвращают значение, которое передаётся в качестве входного параметра методу, указанному в свойствеsubject
.Пользовательский рендерер может быть назначен столбцу с помощью обработчика
renderer
, доступного на вкладке Handlers в инспекторе Jmix UI для любого элементаcolumn
.
-
Используя FragmentRenderer
Колонки можно отображать с помощью вложенного элемента
fragmentRenderer
. Подробнее смотрите в разделе Рендерер фрагментов. -
Используя addColumn() и addComponentColumn()
Методы
addColumn()
иaddComponentColumn()
позволяют добавлять столбцы в таблицу.Добавленным столбцам можно настроить использование рендерера для отображения данных.
В следующем примере мы добавим столбец, показывающий фотографию пользователя:
@ViewComponent private DataGrid<User> usersDtGr; @Autowired private FileStorage fileStorage; @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"); StreamResource streamResource = new StreamResource( fileRef.getFileName(), () -> fileStorage.openStream(fileRef)); image.setSrc(streamResource); (3) return image; (4) } else { return new Span(); } }) .setHeader("Picture") .setAutoWidth(true) .setFlexGrow(0); usersDtGr.setColumnPosition(pictureColumn,0); }
1 Добавляет новый столбец, в котором отображается компонент image
.2 Экземпляр компонента image
создаётся с помощью фабрикиUiComponents
.3 Изображение получает содержимое из переданного StreamResource
, ссылка на который хранится в атрибутеpicture
сущностиUser
.4 Метод addComponentColumn()
возвращает визуальный компонент, который будет отображаться в ячейках столбца.
Рендерер LocalDate
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");
}
Рендерер LocalDateTime
LocalDateTimeRenderer
отвечает за отображение дат в формате значений типа LocalDateTime
.
В элементе column
таблицы присутствует вложенный элемент localDateRenderer
, который содержит необязательный атрибут nullRepresentation
и обязательный атрибут format
, задающий строку формата.
<column property="passwordExpiration">
<localDateTimeRenderer format="dd/MM/YYYY HH:mm:ss"/>
</column>
Атрибут nullRepresentation
используется для задания текстового отображения значений null
.
NumberRenderer
NumberRenderer
позволяет отображать числа в заданном формате в ячейках таблицы. Он особенно полезен для отображения различных типов чисел, включая числа с плавающей запятой.
В элементе column
таблицы присутствует вложенный элемент numberRenderer
, который содержит необязательный атрибут nullRepresentation
и обязательный атрибут format
или numberFormat
.
<column property="factor">
<numberRenderer numberFormat="#,#00.0000"/>
</column>
Атрибут nullRepresentation
используется для задания текстового отображения значений null
.
Атрибут numberFormat
использует правила и синтаксис форматирования класса java.text.DecimalFormat
.
Для |
TextRenderer
TextRenderer
- это рендерер для отображения простых строковых значений в виде обычного текста.
В приведённом ниже примере в колонке отображается пользовательский текст:
<column key="status" header="Status"/>
@Supply(to = "userStepsDataGrid.status", subject = "renderer")
private Renderer<UserStep> userStepsDataGridStatusRenderer() {
return new TextRenderer<>(userStep ->
isOverdue(userStep) ? "Overdue!" : "");
}
ComponentRenderer
В примере ниже показано, как определить столбец с пользовательским рендерером, отображающим чекбокс:
<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, который определяет способ отображения детализированной информации.

Атрибут detailsVisibleOnClick позволяет управлять отображением дополнительных сведений при клике на строку. Если необходимо, чтобы детализация появлялась по другому событию (не по клику), установите значение этого атрибута в false
.
Сортировка
Любой столбец таблицы может использоваться для сортировки отображаемых данных. При нажатии на заголовок столбца в таблице активируется специальный индикатор, который показывает текущий столбец сортировки и направление сортировки (по возрастанию или убыванию).
Последующие нажатия на тот же заголовок будут переключать направление сортировки на противоположное.
Сортировка по нескольким столбцам
Данные можно сортировать одновременно по нескольким столбцам. В этом случае первый выбранный столбец определяет основной критерий сортировки, второй столбец задаёт дополнительный критерий, а последующие столбцы устанавливают второстепенные критерии сортировки.
Настройка осуществляется с помощью атрибутов multiSort, multiSortOnShiftClickOnly и multiSortPriority.
Пример:
<dataGrid width="100%"
dataContainer="usersDc"
multiSort="true"
multiSortOnShiftClickOnly="true"
multiSortPriority="APPEND">
Агрегация данных
Компонент поддерживает агрегацию значений в строках. При включении этой функции отображается дополнительная строка с агрегированными значениями.
Например:
<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-дескрипторе экрана.
-
Атрибуты
В Jmix существует множество общих атрибутов, которые выполняют одинаковые функции для всех компонентов. Ниже перечислены атрибуты, специфичные для dataGrid
:
Название |
Описание |
Значение по-умолчанию |
---|---|---|
Если значение равно Использование этой функции не рекомендуется при работе с большим количеством элементов, так как это может вызвать проблемы с производительностью. |
|
|
Если значение |
|
|
Определяет положение строки с агрегированными данными. Допустимые значения: |
|
|
Если значение |
|
|
Если значение |
|
|
Определяет, в каких строках возможно выполнение операции перетаскивания (drop). Допустимые значения: |
– |
|
При значении - пользователь должен подтверждать изменения нажатием кнопки подтверждения; - предусмотрена возможность отмены внесённых изменений. В небуферизированном режиме (unbuffered mode) изменения применяются сразу без необходимости подтверждения. |
|
|
Определяет текст, отображаемый когда таблица данных пуста. Используйте |
– |
|
При значении |
|
|
При значении |
|
|
Определяет, добавляется ли выбранный столбец в начало или конец списка сортировки. Допустимые значения: |
|
|
Определяет поведение при обработке вложенных свойств, которые могут содержать значения null в цепочке свойств. Допустимые значения: |
|
|
Определяет размер страницы (количество элементов, загружаемых из источника данных за один раз). |
|
|
Если значение |
|
|
Устанавливает режим выделения элементов. Допустимые значения: - - |
|
Обработчики
В Jmix существует множество общих обработчиков, которые настраиваются одинаково для всех компонентов. Ниже представлены обработчики, специфичные для dataGrid
:
Чтобы сгенерировать заглушку обработчика в Jmix Studio, используйте вкладку Handlers панели инспектора Jmix UI, или команду Generate Handler, доступную на верхней панели контроллера экрана и через меню Code → Generate (Alt+Insert / Cmd+N). |
Название |
Описание |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Добавляет генератор данных для таблицы. Если генератор уже был добавлен, действие не выполняется. Подробнее см. в интерфейсе |
|
Позволяет задавать, какие именно строки можно перетаскивать, вместо активации этой функции для всех строк через атрибут rowDraggable. |
|
Позволяет задавать, какие именно строки могут быть целями для операции перетаскивания (drop targets). |
|
Обрабатывает событие нажатия пользователем клавиши Enter. |
|
Функция создает всплывающие подсказки (tooltip) для ячеек столбца на основе заданных условий. Смотрите рабочий пример в живой демонстрации. |
Элементы
Элементы dataGrid
предоставляют широкий набор возможностей для управления внешним видом, поведением и функциональностью столбцов как в целом, так и по отдельности.
Чтобы добавить элемент в выбранный компонент, нажмите кнопку Add в панели инспектора Jmix UI. |
columns
Элемент columns
позволяет задать набор атрибутов для отображения и поведения для всех столбцов.
XML-элемент |
|
---|---|
Атрибуты |
exclude - includeAll - resizable - sortable |
Элементы |
Название |
Описание |
Значение по-умолчанию |
---|---|---|
Исключает отображение определённых атрибутов. Несколько атрибутов следует перечислять через запятую. Например: |
– |
|
Если значение равно |
– |
|
При значении |
|
|
Если значение равно |
|
column
Элемент column
определяет отдельный столбец. Атрибуты, заданные для отдельного столбца, переопределяют атрибуты, установленные для всех столбцов.
XML-элемент |
|
---|---|
Атрибуты |
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 |
Название |
Описание |
Значение по-умолчанию |
---|---|---|
Если значение равно |
|
|
Если значение равно |
|
|
Если значение равно |
|
|
Задаёт коэффициент расширения (flex grow) для данного столбца. При значении |
|
|
Задаёт текст в нижней части столбца (футере). Значением атрибута может быть либо сам текст, либо ключ из пакета сообщений. В случае использования ключа значение должно начинаться с префикса |
– |
|
Если значение равно |
|
|
Задаёт текст заголовка столбца. Значением атрибута может быть либо сам текст, либо ключ из пакета сообщений. В случае использования ключа значение должно начинаться с префикса |
– |
|
Задаёт пользовательский идентификатор для привязки к этому столбцу. Этот ключ можно использовать для последующего получения столбца с помощью метода Ключ должен быть уникальным в пределах |
– |
|
Указывает имя атрибута сущности, который будет отображаться в столбце. Это может быть атрибут корневой сущности, например, |
– |
|
Если значение равно |
|
|
Если значение равно |
|
|
Задает выравнивание текста с возможными значениями: |
|
|
Если значение |
|
|
Задает ширину столбца в виде CSS-строки. |
– |
Название |
Описание |
---|---|
Срабатывает при изменении видимости столбца через компонент gridColumnVisibility. |
|
Генерирует части CSS-классов для этого столбца на основе заданных условий. Это позволяет настраивать внешний вид ячеек в зависимости от отображаемых данных. Смотрите живую демонстрацию. |
|
Отображает содержимое столбца с использованием текста или компонентов. Смотрите TextRenderer и ComponentRenderer. |
|
Генерирует всплывающую подсказку для ячейки столбца на основе заданных условий. Смотрите живую демонстрацию. |
contextMenu
Элемент contextMenu
организует пункты контекстного меню (вызываемого правой кнопкой мыши) в порядке, отличном от стандартного. Смотрите пример.
XML-элемент |
|
---|---|
Атрибуты |
id - classNames - css - enabled - visible |
Обработчики |
AttachEvent - DetachEvent - GridContextMenuOpenedEvent - openedChangeEvent - dynamicContentHandler |
Элементы |
item - separator |
Название |
Описание |
---|---|
Срабатывает при изменении состояния открытия контекстного меню. Может возвращать целевой элемент или идентификатор целевого столбца, позволяя меню отображать пункты в зависимости от выбранного элемента. |
|
Срабатывает при изменении состояния открытия контекстного меню. |
|
Обрабатывает динамические обновления меню при его открытии, такие как добавление пунктов меню или их содержимого. Смотрите пример. |
emptyStateComponent
Элемент emptyStateComponent
определяет компонент для отображения при пустом состоянии таблицы. Используйте null
, чтобы удалить текущее содержимое. Смотрите раздел Отображение при отсутствии данных.
Смотрите также
Смотрите документацию Vaadin для получения дополнительной информации.