DataGrid

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

В дополнение к этому, DataGrid обладает следующими функциями:

Однако у DataGrid нет соответствующей реализации с возможностями группировки (у Table есть).

XML-имя компонента: dataGrid.

Основы

Ниже представлен типичный dataGrid:

data grid anatomy
  1. Панель кнопок

  2. Кнопка сортировки

  3. Разбивка на страницы

  4. Кнопка управления колонкой

  5. Строки

  6. Строка заголовка

Ниже представлен пример объявления dataGrid в XML-дескрипторе экрана:

<data>
    <collection id="customersDc" class="ui.ex1.entity.Customer">
        <fetchPlan extends="_base"/>
        <loader id="customersDl">
            <query>
                <![CDATA[select e from uiex1_Customer e]]>
            </query>
        </loader>
    </collection>
</data>
<layout>
    <dataGrid id="customersGrid" width="100%" dataContainer="customersDc">
        <actions>
            <action id="create" type="create"/>
            <action id="edit" type="edit"/>
            <action id="remove" type="remove"/>
        </actions>
        <buttonsPanel alwaysVisible="true">
            <button id="customersGridCreateBtn" action="customersGrid.create"/>
            <button id="customersGridEditBtn" action="customersGrid.edit"/>
            <button id="customersGridRemoveBtn" action="customersGrid.remove"/>
        </buttonsPanel>
        <simplePagination/>
        <columns>
            <column id="hobby" property="hobby"/>
            <column id="firstName" property="firstName"/>
            <column id="lastName" property="lastName"/>
            <column id="age" property="age"/>
            <column id="email" property="email"/>
            <column id="level" property="level"/>
            <column id="rewardPoints" property="rewardPoints"/>
        </columns>
    </dataGrid>
</layout>

В приведенном примере есть контейнер коллекции для сущности Customer. Компонент DataGrid привязан к контейнеру с помощью атрибута dataContainer, в то время как его элемент columns определяет, какие атрибуты сущности отображаются в колонках таблицы.

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

Декларативная привязка

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

Использование контейнеров Key-Value

Таблицу можно привязать к контейнеру key-value для отображения результатов запроса, который возвращает скалярные значения и/или агрегаты. Например:

<data>
    <keyValueCollection id="salesDc">
        <loader id="salesLoader">
            <query>
                <![CDATA[select o.customer, o.customer.firstName,
                sum(o.amount) from uiex1_Order o group by o.customer]]>
            </query>
        </loader>
        <properties>
            <property class="ui.ex1.entity.Customer" name="customerEntity"/>
            <property datatype="string" name="customerName"/>
            <property datatype="decimal" name="sum"/>
        </properties>
    </keyValueCollection>
</data>
<layout>
    <dataGrid id="keyValueGrid" width="100%" dataContainer="salesDc">
        <columns>
            <column id="customerName" caption="Customer"/>
            <column id="sum" caption="Summary amount"/>
        </columns>
    </dataGrid>
</layout>

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

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

<dataGrid id="customersDataGrid"
          width="100%"
          metaClass="uiex1_Customer">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
    </columns>
</dataGrid>

В контроллере экрана используйте класс ContainerDataGridItems для привязки таблицы к контейнеру данных:

@Autowired
private DataGrid<Customer> customersDataGrid;

@Autowired
private CollectionContainer<Customer> customersDc;


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

Columns

Набор колонок DataGrid определяется элементом columns. Если он не задан, то колонки таблицы будут автоматически взяты из фетч-плана, определенного в dataContainer.

Элемент columns имеет следующие атрибуты:

  • includeAll включает все атрибуты из fetchPlan, определенного в dataContainer.

    В приведенном ниже примере мы покажем все атрибуты из фетч-плана, используемого в customersDc:

    <dataGrid id="gridIncludeAll"
              width="100%"
              dataContainer="customersDc">
        <columns includeAll="true"/>
    </dataGrid>

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

    <data>
        <collection id="customersDc1" class="ui.ex1.entity.Customer">
            <fetchPlan extends="_base">
                <property name="city" fetchPlan="_base">
                    <property name="country" fetchPlan="_base"/>
                </property>
            </fetchPlan>
            <loader id="customersDl1">
                <query>
                    <![CDATA[select e from uiex1_Customer e]]>
                </query>
            </loader>
        </collection>
    </data>
    <layout>
        <dataGrid id="gridIncludeAllReference"
                  width="100%"
                  dataContainer="customersDc1">
            <columns includeAll="true">
                <column id="city.country.name"/>
            </columns>
        </dataGrid>
    </layout>
  • exclude содержит разделенный запятыми список атрибутов, которые не должны быть показаны в DataGrid.

    В приведенном ниже примере мы покажем все атрибуты за исключением id, maritalStatus, и email:

    <dataGrid id="gridExclude"
              width="100%"
              dataContainer="customersDc">
        <columns includeAll="true"
                 exclude="id,maritalStatus,email"/>
    </dataGrid>

Column

Каждая колонка описывается во вложенном элементе column.

id - необязательный атрибут, содержит строковый идентификатор колонки. Если не задан, в качестве идентификатора колонки будет использоваться строковое значение атрибута property. Если не указан ни атрибут id, ни атрибут property, во время выполнения будет брошено исключение GuiDevelopmentException. Атрибут id является обязательным для генерируемых колонок.

property содержит название атрибута сущности, выводимого в колонке. Может быть как непосредственным атрибутом сущности, находящейся в контейнере данных, так и атрибутом связанной сущности; переход по графу объектов обозначается точкой. Например:

<columns>
    <column property="firstName"/>
    <column property="lastName"/>
    <column property="city.name"/>
    <column property="city.country.name"/>
</columns>

Заголовок колонки

caption - необязательный атрибут, содержит заголовок колонки. Если не задан, будет отображено локализованное название атрибута сущности.

Этот заголовок также используется для названия колонки в выпадающем меню управления колонками, если оно не определено в атрибуте collapsingToggleCaption.

Сворачивание колонок

collapsed - необязательный атрибут, при указании true колонка будет изначально скрыта. Пользователи могут управлять видимостью колонки с помощью меню, доступного по нажатию кнопки table column control button в правом верхнем углу таблицы, если атрибут columnsCollapsingAllowed имеет значение true. По умолчанию имеет значение false.

Атрибут collapsible определяет, может ли пользователь управлять отображением колонок с помощью кнопки управления колонкой. По умолчанию имеет значение true.

Атрибут collapsingToggleCaption задает имя колонки в меню управления колонкой. По умолчанию имеет значение null, и в этом случае берется значение заголовка колонки, доступного из свойства caption.

<dataGrid id="collapsedGrid"
          width="100%"
          dataContainer="customersDc">
    <columns>
        <column property="firstName"
                collapsible="false"/>
        <column property="lastName"
                collapsible="false"/>
        <column property="age"
                collapsed="true"/>
        <column property="hobby"
                collapsingToggleCaption="The favourite customer's hobby"/>
        <column property="level"/>
        <column property="city"/>
    </columns>
</dataGrid>
data grid collapse

Как можно видеть, колонка age по умолчанию свернута, но пользователи могут развернуть ее из выпадающего меню кнопки table column control button.

В то же время колонки firstName и lastName не могут быть свернуты пользователем.

Настраиваемый заголовок для колонки hobby отображается в выпадающем меню кнопки управления колонкой.

Сворачивание колонки можно отследить с помощью ColumnCollapsingChangeEvent.

Ширина колонки

width - необязательный атрибут, отвечает за изначальную ширину колонки. Может принимать только числовые значения в пикселах.

<columns>
    <column property="firstName" width="120"/>
    <column property="lastName" width="150"/>
    <column property="city" width="100"/>
</columns>
data grid column width

expandRatio - необязательный атрибут, устанавливает соотношение, с которым колонка расширяется. Если хотя бы одной колонке установлено иное значение, все неявные значения игнорируются и учитываются только явно присвоенные.

По умолчанию все колонки расширяются равномерно (словно все колонки имеют expandRatio = 1).

Если одновременно задать атрибуты width и expandRatio, атрибут expandRatio будет проигнорирован.

<columns>
    <column property="firstName" expandRatio="0"/>
    <column property="lastName" expandRatio="1"/>
    <column property="city" expandRatio="2"/>
</columns>
data grid ratio

В приведенном выше примере компонент DataGrid имеет три колонки с соотношениями расширения (expand ratio) 0, 1, и 2 соответственно. Колонка с соотношением 0 будет иметь ровно такую ширину, какая требуется для ее содержимого. Колонка с соотношением 1 будет широкой настолько, насколько требуется, плюс треть любого лишнего места, потому что всего есть три части, и эта колонка занимает одну из них. Колонка с соотношением 2 будет широкой настолько, насколько требуется, плюс две трети лишнего места.

Чтобы очистить значение расширения, задайте отрицательное число для атрибута expandRatio.

Атрибут minimumWidth отвечает за минимальную ширину колонки в пикселях при расширении.

Атрибут maximumWidth отвечает за максимальную ширину колонки в пикселях при расширении.

Изменение размера колонок

Пользователи могут изменять размер колонок DataGrid:

data grid resize

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

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

  • В режиме ANIMATED размер колонки меняется сразу вслед за курсором.

  • В режиме SIMPLE размер колонки меняется только после того, как курсор будет отпущен.

Изменение размера колонок можно отслеживать с помощью ColumnResizeEvent.

Изменение порядка колонок

DataGrid позволяет пользователям менять порядок колонок с помощью перетаскивания.

table columns reordering

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

Изменение расположения колонок можно отслеживать с помощью ColumnReorderEvent.

Фиксация колонок

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

Атрибут frozenColumnCount устанавливает количество фиксированных колонок. Значение 0 означает, что фиксированных колонок не будет, кроме встроенной колонки с чекбоксами для множественного выбора, если она используется. Значение -1 означает, что фиксированных колонок не будет вообще. По умолчанию имеет значение 0.

Рассмотрим пример DataGrid, в котором первые две колонки зафиксированы.

<dataGrid id="frozenGrid"
          width="100%" footerVisible="false"
          dataContainer="customersDc"
          frozenColumnCount="2">
    <columns>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="age"/>
        <column property="email"/>
        <column property="level"/>
        <column property="rewardPoints"/>
        <column property="hobby"/>
        <column property="city"/>
    </columns>
</dataGrid>
data grid frozen

Размеры

Размеры таблицы

В дополнение к атрибутам height и width, DataGrid имеет необязательные атрибуты minHeight и minWidth:

  • minHeight определяет минимальную высоту компонента DataGrid.

  • minWidth определяет минимальную ширину компонента DataGrid.

Размеры колонок

См. атрибуты width, expandRatio, minimumWidth и maximumWidth в разделе Ширина колонки.

Размеры строк

Чтобы задать высоту строки заголовка, используйте атрибут headerRowHeight.

Используйте атрибут bodyRowHeight, чтобы задать высоту строки тела таблицы в пикселях. Значение -1 означает, что высота строки рассчитывается на основе темы для пустой строки перед отображением DataGrid.

Чтобы задать высоту строки итогов, используйте атрибут footerRowHeight.

В приведенном ниже примере показан компонент DataGrid с настроенной высотой строк заголовка и основных строк:

<dataGrid id="sizedGrid"
          width="100%"
          dataContainer="customersDc"
          headerRowHeight="36"
          bodyRowHeight="28">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
        <column id="level" property="level"/>
        <column id="age" property="age"/>
        <column id="rewardPoints" property="rewardPoints"/>
    </columns>
</dataGrid>
data grid custom row height

Выделение

Компонент DataGrid позволяет пользователям выделять одну или несколько строк.

Атрибут selectionMode определяет режим выделения строк. Существует 4 предопределенных режима:

  • SINGLE;

  • MULTI;

  • MULTI_CHECK;

  • NONE.

Выделение строк можно отслеживать с помощью SelectionEvent.

Единичный выбор строки

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

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

Если у атрибута selectionMode задано значение MULTI, то пользователи смогут выделять несколько строк за раз, используя клавиатуру или мышь и зажимая клавиши Ctrl или Shift.

Множественный выбор с чекбоксами

Если у атрибута selectionMode задано значение MULTI_CHECK, то пользователи смогут выделять несколько строк, используя колонку чекбоксов слева.

data grid checkbox select

Отключение выделения

Если атрибут selectionMode имеет значение NONE, выделение строк отключено.

Выделение текста

Атрибут textSelectionEnabled разрешает или запрещает выделение текста в ячейках DataGrid. По умолчанию имеет значение false.

Заполнитель

DataGrid позволяет задать позволяет настроить заполнитель в виде сообщения и/или ссылки, отображаемый в случае, если контейнер данных пуст или не задан.

Заполнитель-сообщение определяется атрибутом emptyStateMessage. Он должен содержать информацию о том, почему таблица пуста.

Например:

<dataGrid id="placeholderGrid"
          width="100%"
          height="200"
          metaClass="uiex1_Customer"
          emptyStateMessage="No customers added."
          emptyStateLinkMessage="Add customer">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
        <column id="level" property="level"/>
        <column id="age" property="age"/>
        <column id="rewardPoints" property="rewardPoints"/>
    </columns>
</dataGrid>
data grid placeholder

И emptyStateMessage, и emptyStateLinkMessage могут загружать сообщения из пакета сообщений.

Нажатия по ссылке можно отслеживать с помощью EmptyStateLinkClickHandler.

Управление видимостью колонок

Пользователи могут выбрать, какие колонки будут свернуты, используя кнопку управления колонками table column control button в правой части заголовка таблицы.

Отображаемые в данный момент колонки отмечены в выпадающем меню. В нем есть дополнительные пункты:

  • Select all - показать все колонки;

  • Deselect all - спрятать все возможные колонки.

data grid column collapsing allowed

Если columnsCollapsingAllowed имеет значение false, пользователи не смогут сворачивать колонки. Значение по умолчанию – true.

Заголовки и строки итогов

Атрибут headerVisible определяет видимость заголовка DataGrid. По умолчанию имеет значение true.

Используйте атрибут headerRowHeight, чтобы задать высоту строки заголовка в пикселях. Значение -1 означает, что высота строки рассчитывается на основе темы для пустой строки перед отображением DataGrid. Значение по умолчанию – -1.

Интерфейсы HeaderRow и FooterRow используются для отображения ячеек заголовка и итогов соответственно. Эти ячейки могут быть объединены для нескольких колонок.

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

  • appendHeaderRow(), appendFooterRow() - добавляет новую строку внизу секции заголовков/итогов.

  • prependHeaderRow(), prependFooterRow() - добавляет новую строку наверху секции заголовков/итогов.

  • addHeaderRowAt(), addFooterRowAt() - вставляет новую строку на заданную позицию в секции. Текущая строка на этой позиции, а также все следующие ниже, сдвигаются вниз с увеличением их индекса на 1.

  • removeHeaderRow(), removeFooterRow() - удаляет указанную строку в секции.

  • getHeaderRowCount(), getFooterRowCount() - возвращает количество строк в секции.

  • setDefaultHeaderRow() - устанавливает заголовок таблицы по умолчанию. Интерфейс стандартного заголовка по умолчанию включает в себя элементы для сортировки колонок таблицы.

Интерфейсы HeaderCell и FooterCell позволяют управлять статическими ячейками:

  • setStyleName() - устанавливает пользовательский стиль для данной ячейки.

  • getCellType() - возвращает тип содержимого данной ячейки. Перечисление DataGridStaticCellType содержит 3 стандартных типа статических ячеек:

    • TEXT

    • HTML

    • COMPONENT

  • getComponent(), getHtml(), getText() - возвращает содержимое данной ячейки в зависимости от ее типа.

Ниже приведен пример таблицы DataGrid с заголовком, содержащим объединtнные ячейки, и строкой итогов, в которой отображаются вычисляемые значения:

<dataGrid id="dataGrid"
          width="100%"
          footerRowHeight="140"
          headerRowHeight="40"
          dataContainer="customersDc">
    <columns>
        <column property="firstName"/>
        <column property="lastName"/>
        <column property="age"/>
        <column property="level"/>
        <column property="rewardPoints"/>
    </columns>
</dataGrid>
@Autowired
private DataGrid<Customer> dataGrid;
@Autowired
private CollectionLoader<Customer> customersDl;

private int silverCount = 0;
private int goldCount = 0;
private int platinumCount = 0;
private int diamondCount = 0;


@Subscribe
public void onInit(InitEvent event) {
    customersDl.load();
    initFooter();
    initHeader();
}

private void initFooter() {
    DataGrid.FooterRow footerRow = dataGrid.prependFooterRow();
    DataGrid.FooterCell footerCell = footerRow.join("firstName","lastName");
    footerCell.setHtml("<strong>Total customers count: " +
            customersDc.getItems().size() + "</strong>");
    calculateMemberCount();
    footerRow.getCell("age").setHtml("<strong>Average age: " + getAverage("age") +
            "</strong>");
    footerRow.getCell("level").setHtml("<strong>Silver Members: " + silverCount +
            "<br>" + "Gold Members: " + goldCount + "<br>" +
            "Platinum Members: " + platinumCount + "<br>" +
            "Diamond Members: " + diamondCount + "<br>" +
            "</strong>");
    footerRow.getCell("rewardPoints").setHtml("<strong>Average reward points: " +
            getAverage("rewardPoints") + "</strong>");
}

private void initHeader() {
    DataGrid.HeaderRow headerRow = dataGrid.prependHeaderRow();
    DataGrid.HeaderCell headerCell = headerRow.join("firstName", "lastName");
    headerCell.setText("Full name");
    headerCell.setStyleName("center-bold");
    headerCell = headerRow.join("level", "rewardPoints");
    headerCell.setText("Account information");
    headerCell.setStyleName("center-bold");
}

private int getAverage(String propertyId) {
    double average = 0.0;
    Collection<Customer> items = customersDc.getItems();
    for (Customer customer : items) {
        Double value = propertyId.equals("rewardPoints") ?
                customer.getRewardPoints().doubleValue() :
                customer.getAge().doubleValue();
        average += value != null ? value : 0.0;
    }
    return (int) (average / items.size());
}

private void calculateMemberCount() {
    Collection<Customer> items = customersDc.getItems();
    for (Customer customer : items) {
        switch (customer.getLevel()) {
            case SILVER:
                silverCount++;
                break;
            case GOLD:
                goldCount++;
                break;
            case PLATINUM:
                platinumCount++;
                break;
            case DIAMOND:
                diamondCount++;
                break;
        }
    }
}
data grid header footer

Агрегация

DataGrid поддерживает агрегацию значений в строки.

Поддерживаются следующие операции:

  • SUM - вычисление суммы;

  • AVG - вычисление среднего значения;

  • COUNT - вычисление общего количества;

  • MIN - вывод минимального значения;

  • MAX - вывод максимального значения.

Чтобы включить агрегацию для таблицы данных, необходимо:

  1. Установить для атрибута aggregatable значение true.

  2. Указать элемент aggregation для агрегируемых колонок.

  3. Указать для элемента aggregation атрибут type, задающий функцию агрегации.

Агрегированные значения выводятся в дополнительной строке.

Атрибут aggregationPosition позволяет задать расположение строки агрегации: TOP или BOTTOM. TOP используется по умолчанию.

По умолчанию в агрегируемых колонках поддерживаются только числовые типы данных, такие как Integer, Double, Long, и BigDecimal.

Пример описания DataGrid с агрегацией:

<dataGrid id="aggregationGrid"
          width="100%"
          dataContainer="customersDc1"
          aggregatable="true">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
        <column id="level" property="level"/>
        <column id="age" property="age">
            <aggregation type="AVG"/>
        </column>
        <column id="rewardPoints" property="rewardPoints"/>
    </columns>
</dataGrid>
data grid aggregation

Атрибут valueDescription задает текст всплывающей подсказки, отображаемой при наведении курсора мыши по агрегированному значению. Для операций, перечисленных выше (SUM, AVG, COUNT, MIN, MAX), всплывающие подсказки уже есть по умолчанию.

Для отображения агрегированного значения в виде, отличном от стандартного для данного Datatype, для него можно указать Formatter:

<column id="amount" property="amount">
    <aggregation type="SUM">
        <formatter>
            <number format="#,##0.00"/>
        </formatter>
    </aggregation>
</column>

Элемент aggregation может также содержать атрибут strategyClass, указывающий класс, реализующий интерфейс AggregationStrategy.

public class CustomerHobbyAggregation implements AggregationStrategy<Hobby, String> {
    @Override
    public String aggregate(Collection<Hobby> propertyValues) {
        Hobby mostFrequent = null;
        long max = 0;
        if (CollectionUtils.isNotEmpty(propertyValues)) {
            for (Hobby hobby : Hobby.values()) {
                long current = propertyValues.stream()
                        .filter(customerHobby -> customerHobby.equals(hobby))
                        .count();

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

        if (mostFrequent != null) {
            return String.format("%s: %d/%d",
                    mostFrequent.name(), max, propertyValues.size());
        }

        return null;
    }

    @Override
    public Class<String> getResultClass() {
        return String.class;
    }
}
<dataGrid id="gridAggregationStrategy"
          width="100%"
          aggregatable="true"
          dataContainer="customersDc">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
        <column id="hobby" property="hobby">
            <aggregation
                strategyClass="ui.ex1.screen.component.datagrid.CustomerHobbyAggregation"/>
        </column>
    </columns>
</dataGrid>

Сортировка

DataGrid позволяет пользователям сортировать данные колонки. Функция сортировки включена по умолчанию.

Атрибут sortable позволяет сортировать данные в таблице. По умолчанию имеет значение true. Если сортировка разрешена, при щелчке по заголовку колонки появится table sortable down/table sortable upзначок справа от названия колонки.

Можно отключить сортировку для конкретной колонки, используя ее атрибут sortable.

В примере ниже отключим сортировку по колонке lastName:

<columns>
    <column id="firstName" property="firstName"/>
    <column id="lastName" property="lastName" sortable="false"/>
    <column id="city" property="city"/>
    <column id="hobby" property="hobby"/>
</columns>

Атрибут sort элемента column позволяющий задать начальную сортировку таблицы по указанной колонке в соответствии с направлением сортировки. Возможные значения:

  • ASCENDING - сортировка по возрастанию (0 → 9 → A → Z).

  • DESCENDING - сортировка по убыванию (Z → A → 9 → 0).

Например:

<columns>
    <column id="firstName" property="firstName" sort="DESCENDING"/>
    <column id="lastName" property="lastName"/>
    <column id="city" property="city"/>
    <column id="hobby" property="hobby"/>
</columns>

В одно и то же время таблица DataGrid может быть сортирована только по одной колонке. Если установить атрибут sort для нескольких колонок или установить для колонки атрибуты sort и sortable="false" одновременно, это вызовет исключение.

События сортировки DataGrid можно отслеживать с помощью SortEvent.

Разбивка на страницы

Компонент SimplePagination может быть использован внутри dataGrid для обеспечения разбивки на страницы:

<dataGrid id="gridPagination"
          width="100%"
          dataContainer="customersDc">
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
        <column id="hobby" property="hobby"/>
        <column id="age" property="age"/>
    </columns>
    <simplePagination
            itemsPerPageVisible="true"
            itemsPerPageOptions="2, 4, 6"/>
</dataGrid>
data grid pagination

В качестве альтернативы можно использовать отдельный компонент Pagination.

Действия DataGrid

Компонент DataGrid реализует интерфейс ActionsHolder и может содержать настраиваемые действия и стандартные действия с коллекцией.

Действия таблицы данных определяются во вложенном элементе actions.

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

Для отображения кнопок действий над таблицей данных можно использовать контейнер ButtonsPanel.

<dataGrid id="gridWithActions"
       width="100%"
       dataContainer="customersDc">
    <actions>
        <action id="create" type="create"/> (1)
        <action id="edit" type="edit"/>
        <action id="remove" type="remove"/>
        <action id="about" caption="Get info"/> (2)
    </actions>
    <columns>
        <column id="age" property="age"/>
        <column id="firstName" property="firstName"/>
        <column id="lastName" property="lastName"/>
    </columns>
    <buttonsPanel id="buttonsActionsPanel" alwaysVisible="true"> (3)
        <button id="create" action="gridWithActions.create"/>
        <button id="edit" action="gridWithActions.edit"/>
        <button id="remove" action="gridWithActions.remove"/>
        <button id="about" action="gridWithActions.about"/>
    </buttonsPanel>
</dataGrid>
1 Определение стандартного действия create.
2 Определение настраиваемого действия about.
3 Определение контейнера ButtonsPanel в таблице данных.
data grid actions

Генерация колонок

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

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

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

В качестве примера создадим генерированную колонку, содержащую полное имя клиента.

Сначала создайте колонку с id fullName:

<column id="fullName" caption="Full name">
    <textRenderer nullRepresentation="null"/>
</column>

Затем создайте слушателя ColumnGeneratorEvent для колонки fullName с помощью Studio и реализуйте его следующим образом:

@Install(to = "grid.fullName", subject = "columnGenerator")
private String gridFullNameColumnGenerator(DataGrid.ColumnGeneratorEvent<Customer> columnGeneratorEvent) {
    return columnGeneratorEvent.getItem().getFirstName() + " " + columnGeneratorEvent.getItem().getLastName();
}

Результат:

data grid generated column

Колонка fullName является генерированной колонкой с TextRenderer.

Чтобы создать слушателя генератора колонок программно, используйте метод addGeneratedColumn() вместо компонента DataGrid.

Экспорт значений колонок

Чтобы экспортировать содержимое компонента DataGrid в виде файла в одном из поддерживаемых форматов, используйте дополнение Grid Export Actions.

После установки дополнения вы можете определить для таблицы действие excelExport или jsonExport или использовать TableExporter.

Ниже приведен пример настройки пользовательского представления данных в колонке при экспорте в файл XLSX с помощью действия excelExport.

Дескриптор экрана:

<dataGrid id="gridExport"
          width="100%"
          dataContainer="customersDc">
    <actions>
        <action id="excelExport" type="excelExport"/>
    </actions>
    <columns>
        <column id="firstName" property="firstName"/>
        <column id="hobby" property="hobby"/>
        <column id="age" property="age"/>
    </columns>
</dataGrid>

Контроллер экрана:

@Named("gridExport.excelExport")
protected ExcelExportAction gridExcelExport;

@Subscribe
public void onInit(InitEvent event) {
    gridExcelExport.addColumnValueProvider("firstName", context -> { (1)
        Customer customer = context.getEntity();
        return "Name: " + customer.getFirstName();
    });
}
1 Метод принимает идентификатор колонки и функцию для получения значения из колонки.

Рендереры

Отображение данных в колонках может быть изменено с помощью параметризованных декларативных рендереров. Некоторые рендереры DataGrid задаются специальными XML-элементами с параметрами, определенными в соответствующих атрибутах. Рендереры могут быть объявлены также и для не генерируемых колонок.

Список рендереров, поддерживаемых фреймворком:

ButtonRenderer

ButtonRenderer – рендерер для отображения строкового значения в качестве заголовка кнопки.

ButtonRenderer не может быть объявлен в XML-дескрипторе, так как в нем невозможно определить слушатель отслеживания кликов по кнопке. Studio сгенерирует код объявления ButtonRenderer в методе onInit() контроллера экрана, например:

@Autowired
private Notifications notifications;

@Autowired
private DataGrid<Customer> gridButtonRenderer;


@Subscribe
public void onInit(InitEvent event) {
    DataGrid.ButtonRenderer<Customer> gridButtonRendererFirstNameRenderer =
            getApplicationContext().getBean(DataGrid.ButtonRenderer.class);
    gridButtonRendererFirstNameRenderer.setRendererClickListener(
            clickableRendererClickEvent ->
            notifications.create()
                    .withCaption("ButtonRenderer")
                    .withDescription("Column id: " +
                            clickableRendererClickEvent.getColumnId())
                    .show());
    gridButtonRenderer.getColumn("firstName")
            .setRenderer(gridButtonRendererFirstNameRenderer);
}
data grid button renderer

ImageRenderer

ImageRenderer – рендерер для отображения изображений. Значение соответствующего свойства используется в качестве местоположения изображения. Местоположение может быть ресурсом темы или URL-адресом.

ImageRenderer не может быть объявлен в XML-дескрипторе, так как в нем невозможно определить слушатель отслеживания кликов по кнопке. Studio сгенерирует код объявления ImageRenderer в методе onInit() контроллера экрана, например:

@Autowired
private Notifications notifications;

@Autowired
private DataGrid<Country> imageGrid;


@Subscribe
public void onInit(InitEvent event) {
    DataGrid.ImageRenderer<Country> imageGridFlagRenderer =
            getApplicationContext().getBean(DataGrid.ImageRenderer.class);
    imageGridFlagRenderer.setRendererClickListener(clickableTextRendererClickEvent -> {
    });
    imageGrid.getColumn("flag").setRenderer(imageGridFlagRenderer);
}

Результат:

data grid image renderer

CheckBoxRenderer

CheckBoxRenderer отображает булево значение в виде значков чек-бокса.

Элемент column компонента DataGrid имеет вложенный элемент checkBoxRenderer:

<column id="isEmail" caption="Is email">
    <checkBoxRenderer/>
</column>

NumberRenderer

NumberRenderer отображает числа в заданном формате.

Элемент column компонента DataGrid имеет вложенный элемент numberRenderer с необязательным атрибутом nullRepresentation и обязательным строковым атрибутом format:

<column id="percent" property="percent">
    <numberRenderer nullRepresentation="null" format="%d%%"/>
</column>

formatString – это строка формата, описывающая формат чисел, который будет использоваться для создания экземпляра NumberFormat.

LocalDateTimeRenderer

LocalDateTimeRenderer отображает даты как значения LocalDateTime.

Элемент column компонента DataGrid имеет вложенный элемент localDateTimeRenderer с необязательным атрибутом nullRepresentation и обязательным строковым атрибутом format:

<column id="dateTime" property="dateTime">
    <localDateTimeRenderer nullRepresentation="null"
                           format="dd/MM/YYYY HH:mm:ss"/>
</column>

LocalDateRenderer

LocalDateRenderer отображает даты как значения LocalDate values.

Элемент column компонента DataGrid имеет вложенный элемент localDateRenderer с необязательным атрибутом nullRepresentation и обязательным строковым атрибутом format:

<column id="date" property="date">
    <localDateRenderer nullRepresentation="null" format="dd/MM/YYYY"/>
</column>

Результат:

data grid local date renderer

DateRenderer

DateRenderer отображает даты в заданном формате.

Элемент column компонента DataGrid имеет вложенный элемент dateRenderer с необязательным атрибутом nullRepresentation и обязательным строковым атрибутом format:

<dataGrid id="eventGrid"
          width="100%"
          dataContainer="eventsDc">
    <columns>
        <column id="name" property="name"/>
        <column id="startDate" property="startDate">
            <dateRenderer nullRepresentation="null"
                          format="yyyy-MM-dd HH:mm:ss"/>
        </column>
        <column id="endDate" property="endDate"/>
    </columns>
</dataGrid>

formatString – это строка формата, описывающая формат чисел, который будет использоваться для создания экземпляра DateFormat.

data grid date renderer

Обратите внимание, что поле startDate имеет DateRenderer, а поле endDate – нет.

ProgressBarRenderer

ProgressBarRenderer отображает double-значения от 0 до 1 в виде компонента ProgressBar.

Элемент column компонента DataGrid имеет вложенный элемент progressBarRenderer:

<column id="percent" property="percent">
    <progressBarRenderer/>
</column>

Результат:

data grid progress bar renderer

HtmlRenderer

HtmlRenderer отображает HTML-разметку.

Элемент column компонента DataGrid имеет вложенный элемент htmlRenderer с необязательным атрибутом nullRepresentation.

Ниже приведен пример рендеринга атрибута endDate:

<column id="endDate" property="endDate">
    <htmlRenderer nullRepresentation="null"/>
</column>
@Install(to = "htmlGrid.endDate", subject = "columnGenerator")
private String htmlGridEndDateColumnGenerator(DataGrid.ColumnGeneratorEvent<Event> columnGeneratorEvent) {
    return columnGeneratorEvent.getItem().getEndDate().before(new Date())
            ? "<font color='red'>" +
            columnGeneratorEvent.getItem().getEndDate() + "</font>"
            : "<font color='green'>" +
            columnGeneratorEvent.getItem().getEndDate() + "</font>";
}

Результат:

data grid html renderer

ClickableTextRenderer

ClickableTextRenderer отображает простой текст в виде ссылки со слушателем кликов.

ClickableTextRenderer не может быть объявлен в XML-дескрипторе, так как в нем невозможно определить слушатель отслеживания кликов по кнопке. Studio сгенерирует код объявления ClickableTextRenderer в методе onInit() контроллера экрана, например:

@Autowired
private Notifications notifications;

@Autowired
private DataGrid<Customer> gridClick;


@Subscribe
public void onInit(InitEvent event) {
    DataGrid.ClickableTextRenderer<Customer> gridClickFirstNameRenderer =
            getApplicationContext().getBean(DataGrid.ClickableTextRenderer.class);
    gridClickFirstNameRenderer.setRendererClickListener(clickEvent ->
            notifications.create()
                    .withDescription("The full name: " +
                            clickEvent.getItem().getFirstName() +
                            " " + clickEvent.getItem().getLastName())
                    .show());
    gridClick.getColumn("firstName").setRenderer(gridClickFirstNameRenderer);
}

Результат:

data grid click text renderer

TextRenderer

TextRenderer отображает простой текст.

Элемент column компонента DataGrid имеет вложенный элемент textRenderer с необязательным атрибутом nullRepresentation:

<column id="fullName" caption="Full name">
    <textRenderer nullRepresentation="null"/>
</column>

ComponentRenderer

ComponentRenderer – рендерер для компонентов UI.

Элемент column компонента DataGrid имеет вложенный элемент componentRenderer:

<column id="age" property="age">
    <componentRenderer/>
</column>

В приведенном ниже примере отобразим значение age в компоненте Slider.

@Install(to = "gridComponent.age", subject = "columnGenerator")
private Component gridComponentAgeColumnGenerator(DataGrid.ColumnGeneratorEvent<Customer> columnGeneratorEvent) {
    Slider<Integer> slider = uiComponents.create(Slider.NAME);
    slider.setValue(columnGeneratorEvent.getItem().getAge());
    slider.setEditable(false);
    slider.setWidth("150px");
    return slider;
}

Результат:

data grid component renderer

IconRenderer

IconRenderer – рендерер, который представляет JmixIcon.

Элемент column компонента DataGrid имеет вложенный элемент iconRenderer.

Ниже приведен пример рендеринга сгенерированного атрибута hasEmail:

<column id="hasEmail" caption="Has id">
    <iconRenderer/>
</column>
@Install(to = "iconGrid.hasEmail", subject = "columnGenerator")
private Icons.Icon iconGridHasEmailColumnGenerator(DataGrid.ColumnGeneratorEvent<Customer> columnGeneratorEvent) {
    return columnGeneratorEvent.getItem().getEmail() != null ?
            JmixIcon.OK : JmixIcon.EXCLAMATION_TRIANGLE;
}

Результат:

data grid icon renderer

Генератор Item Details

Item details (подробности) – это раскрываемые области содержимого, используемые для отображения дополнительной информации для определенной строки.

Интерфейс DetailsGenerator позволяет создать настраиваемый компонент для отображения подробностей.

Можно создать слушателя DetailsGenerator для DataGrid с помощью Studio (см. ниже) и реализовать его следующим образом:

@Autowired
private DataGrid<Customer> detailsGrid;

@Install(to = "detailsGrid", subject = "detailsGenerator")
private Component detailsGridDetailsGenerator(Customer customer) {
    VBoxLayout mainLayout = uiComponents.create(VBoxLayout.class);
    mainLayout.setWidth("100%");
    mainLayout.setMargin(true);

    HBoxLayout headerBox = uiComponents.create(HBoxLayout.class);
    headerBox.setWidth("100%");

    Label<String> infoLabel = uiComponents.create(Label.TYPE_STRING);
    infoLabel.setHtmlEnabled(true);
    infoLabel.setStyleName("h1");
    infoLabel.setValue("Customer info:");

    Component closeButton = createCloseButton(customer);
    headerBox.add(infoLabel);
    headerBox.add(closeButton);
    headerBox.expand(infoLabel);

    Component content = getContent(customer);

    mainLayout.add(headerBox);
    mainLayout.add(content);
    mainLayout.expand(content);

    return mainLayout;
}

protected Component createCloseButton(Customer entity) {
    Button closeButton = uiComponents.create(Button.class);
    closeButton.setIcon("font-icon:TIMES");
    BaseAction closeAction = new BaseAction("closeAction")
            .withHandler(actionPerformedEvent ->
                    detailsGrid.setDetailsVisible(entity, false))
            .withCaption("");
    closeButton.setAction(closeAction);
    return closeButton;
}

protected Component getContent(Customer entity) {
    Label<String> content = uiComponents.create(Label.TYPE_STRING);
    content.setHtmlEnabled(true);
    content.setId("contentLabel");

    StringBuilder sb = new StringBuilder();
    sb.append("<b>Full name</b><br>")
            .append(entity.getFirstName() + " " + entity.getLastName() + "<br><br>")
            .append("<b>Country</b><br>")
            .append(entity.getCity().getCountry().getName()+ "<br><br>")
            .append("<b>City</b><br>")
            .append(entity.getCity().getName());

    content.setValue(sb.toString());

    return content;
}

Для отслеживания отображения и скрытия подробностей нужно реализовать свой собственный слушатель. Например, в данном примере отслеживается отображение подробностей в ItemClickAction компонента DataGrid:

@Subscribe("detailsGrid")
public void onDetailsGridItemClick(DataGrid.ItemClickEvent<Customer> event) {
    detailsGrid.setItemClickAction(new BaseAction("itemClickAction")
            .withHandler(actionPerformedEvent ->
                    detailsGrid.setDetailsVisible(detailsGrid.getSingleSelected(), true)));
}

Результат:

data grid detail generator

Редактирование значений

DataGrid обеспечивает внутристрочное редактирование, которое позволяет пользователям манипулировать данными таблицы. Чтобы включить внутристрочное редактирование, установите для атрибута editorEnabled значение true.

Использование

  • Внутристрочное редактирование активируется при двойном щелчке по редактируемому полю или нажатии Enter, когда редактируемая ячейка находится в фокусе.

  • Колонки с атрибутом editable = true показывают компоненты для редактирования атрибутов соответствующей сущности. Не редактируемые поля будут отключены.

  • Тип компонента для каждой редактируемой колонки выбирается автоматически на основе типа соответствующего атрибута сущности. Например, для строковых и числовых атрибутов приложение будет использовать TextField, для DateDateField, для перечислений – ComboBox, для ссылок на другие сущности – EntityPicker.

  • Как только строка станет доступной для редактирования, рядом со строкой появятся кнопки по умолчанию OK и Cancel, позволяющие пользователям завершить или отменить редактирование.

  • Чтобы сохранить изменения и выйти из режима редактирования, нажмите OK или клавишу Enter.

  • Чтобы отменить изменения и выйти из режима редактирования, нажмите кнопку Cancel или клавишу Esc.

data grid editing

Режимы

Редактирование может быть как буферизованным, так и небуферизованным.

  • В буферизованном режиме изменения должны быть явно зафиксированы.

  • Редактирование без буферизации автоматически фиксирует изменения, когда поле теряет фокус.

Атрибут editorBuffered задает режим буферизованного редактирования. Значение по умолчанию – true.

Изменения сохраняются только в контейнере данных. Сохранение изменений в базе данных обычно выполняется с помощью DataContext на экране коммита.

Настройка внутристрочного редактора

Атрибут editorCancelCaption устанавливает заголовок кнопки отмены в режиме редактирования DataGrid.

The editorSaveCaption устанавливает заголовок кнопки сохранения изменений в режиме редактирования DataGrid.

Само поле редактирования может быть изменено с помощью класса EditorFieldGenerationContext.

Создайте генератор полей редактирования, который генерирует компонент для этой колонки в редакторе DataGrid, например:

@Autowired
private CollectionContainer<City> citiesDc;

@Install(to = "editingGrid.city", subject = "editFieldGenerator")
private Field<City> editingGridCityEditFieldGenerator(
        DataGrid.EditorFieldGenerationContext<Customer> editorFieldGenerationContext) {
    ComboBox<City> comboBox = uiComponents.create(ComboBox.NAME);
    comboBox.setValueSource((ValueSource<City>) editorFieldGenerationContext
            .getValueSourceProvider().getValueSource("city"));
    comboBox.setOptionsList(citiesDc.getItems());
    return comboBox;
}

Результат:

data grid edit field generator

Существует также декларативный способ определения того, какой компонент использовать для выбора сущности в системных механизмах. Он основан на свойствах jmix.ui.component.entity-field-type и jmix.ui.component.entity-field-actions.

Например, если добавить следующие строки в файл application.properties:

jmix.ui.component.entity-field-type.uiex1_City = entityComboBox
jmix.ui.component.entity-field-actions.uiex1_City = entity_lookup, entity_open, entity_clear

Тогда компонент EntityComboBox будет сгенерирован для сущности City:

data grid editable custom field

Перекрестная проверка полей

Внутристрочный редактор DataGrid может учитывать ограничения сущностей (перекрестная проверка полей). Если есть ошибки валидации, DataGrid покажет сообщение об ошибке. Чтобы включить или отключить проверку, используйте атрибут editorCrossFieldValidate. Значение по умолчанию – true

События редактора

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

  • EditorOpenEvent посылается перед открытием редактора DataGrid.

    Например:

    @Subscribe("editEventsGrid")
    public void onEditEventsGridEditorOpen(DataGrid.EditorOpenEvent<Event> event) {
        Map<String, Field> fields = event.getFields();
        Field field1 = fields.get("startDate");
        Field field2 = fields.get("endDate");
        field1.addValueChangeListener(valueChangeEvent ->
                field2.setValue(DateUtils.addDays((Date) field1.getValue(), 1)));
        field2.addValueChangeListener(valueChangeEvent ->
                field1.setValue(DateUtils.addDays((Date) field2.getValue(), -1)));
    }
  • EditorCloseEvent посылается при закрытии редактора DataGrid.

  • EditorPreCommitEvent посылается перед сохранением записи.

  • EditorPostCommitEvent посылается после сохранения записи.

Методы редактора

  • getEditedItem() возвращает редактируемую запись или null, если в данный момент ни одна запись не редактируется.

  • isEditorActive() возвращает true, если в момент вызова редактируется какая-либо запись.

  • Метод edit() открывает интерфейс внутристрочного редактора для предоставленной сущности. Пролистывает таблицу до нужной записи, если в момент вызова она не была видна на экране.

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

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

Атрибут contextMenuEnabled включает или выключает контекстное меню. По умолчанию имеет значение true. В контекстном меню отображаются действия DataGrid (если таковые имеются).

Щелчки правой кнопкой мыши по области компонента DataGrid можно отслеживать с помощью слушателя ContextClickEvent.

Стили

Компоненту DataGrid можно задать предопределенные стили с помощью атрибута stylename в XML-дескрипторе или в контроллере экрана.

<dataGrid id="progressGrid"
          width="100%"
          stylename="no-stripes"
          dataContainer="budgetItemsDc">
progressGrid.setStyleName(ThemeClassNames.DATAGRID_NO_STRIPES);

Предопределенные стили:

  • borderless - удаляет внешнюю рамку;

  • no-horizontal-lines - удаляет горизонтальные строковые разделители;

  • no-vertical-lines - удаляет вертикальные разделители колонок;

  • no-stripes - отключает чередование цветов строк таблицы.

Внешний вид компонента DataGrid можно настроить с помощью переменных SCSS с префиксом $jmix-datagrid-*. Эти переменные можно изменить в визуальном редакторе после создания новой темы.

См. также RowStyleProvider.

Методы интерфейса DataGrid

  • getColumns() возвращает копию текущего набора колонок DataGrid в порядке их текущего отображения.

  • getVisibleColumns() возвращет копию набора колонок DataGrid, не скрытых разрешениями безопасности.

  • Метод sort() сортирует данные в переданной колонке в заданном направлении.

  • scrollTo() позволяет прокрутить DataGrid до указанной строки. Метод принимает экземпляр сущности, определяющий нужную строку. Перегруженный метод, помимо сущности, принимает ScrollDestination, имеющий следующие возможные значения:

    • ANY - прокрутить как можно меньше, чтобы показать нужную запись. Если запись помещается в видимую область, работает как START и END, в зависимости от текущего положения прокрутки. Если запись не помещается в видимую область, работает как START`.

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

    • MIDDLE - прокрутить так, чтобы нужная запись оказалась в центре видимой области. Однако область просмотра не будет прокручиваться за пределы своего содержимого, учитывая большее количество записей, чем то, что область просмотра может отображать одновременно. Ни при каких обстоятельствах область просмотра не будет прокручиваться выше своей первой записи.

    • END - прокрутить так, чтобы нужная запись оказалась в конце видимой области. Однако область просмотра не будет прокручиваться выше своей первой записи.

  • scrollToStart() и scrollToEnd() позволяют прокрутить DataGrid до первой и последней записи соответственно.

  • Метод getAggregationResults() возвращает мэп с результатами агрегации, где ключи в мэп – идентификаторы колонок DataGrid, а значения – значения агрегации.

События и слушатели

Чтобы сгенерировать заглушку слушателя в Jmix Studio, выберите компонент в XML-дескрипторе экрана или на панели иерархии Jmix UI и используйте вкладку Handlers на панели инспектора Jmix UI.

В качестве альтернативы вы можете воспользоваться кнопкой Generate Handler на верхней панели контроллера экрана.

ColumnCollapsingChangeEvent

ColumnCollapsingChangeEvent отправляется при изменении сворачивания колонки.

Пример подписки на событие таблицы, объявленного в XML с идентификатором collapseGrid:

@Subscribe("collapseGrid")
public void onCollapseGridColumnCollapsingChange(DataGrid.ColumnCollapsingChangeEvent event) {
    notifications.create()
            .withCaption((event.isCollapsed() ? "Collapsed: " : "Expanded: ") +
                    event.getColumn().getCaption())
            .show();
}

Чтобы создать слушателя события программно, используйте метод компонента addColumnCollapsingChangeListener().

ColumnReorderEvent

ColumnResizeEvent

ColumnResizeEvent отправляется при изменении размера колонки.

Пример подписки на событие таблицы, объявленного в XML с идентификатором resizedEventGrid:

@Subscribe("resizedEventGrid")
public void onResizedEventGridColumnResize(DataGrid.ColumnResizeEvent event) {
    notifications.create()
            .withCaption("The " + event.getColumn().getCaption() + " column was resized")
            .show();
}

Чтобы создать слушателя события программно, используйте метод компонента addColumnResizeListener().

ContextClickEvent

ContextClickEvent отправляется при щелчке правой кнопкой мыши в DataGrid.

ContextClickEvent содержит информацию о событии мыши.

Пример подписки на событие таблицы, объявленного в XML с идентификатором contextGrid:

@Subscribe("contextGrid")
public void onContextGridContextClick(DataGrid.ContextClickEvent event) {
    notifications.create()
            .withCaption("Clicked " + event.getButton().name())
            .show();
}

Чтобы создать слушателя события программно, используйте метод компонента addContextClickListener().

EditorCloseEvent

EditorOpenEvent

EditorPostCommitEvent

EditorPreCommitEvent

ItemClickEvent

ItemClickEvent отправляется при клике пользователем по таблице данных. ItemClickEvent содержит информацию о:

  • Подробностях события мыши;

  • Экземпляр сущности, представленный кликнутой строкой;

  • id записи;

  • id кликнутой колонки DataGrid.

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

@Subscribe("clickGrid")
public void onClickGridItemClick(DataGrid.ItemClickEvent<Event> event) {
    clickGrid.edit(event.getItem());
}

Чтобы создать слушателя события программно, используйте метод компонента addItemClickListener().

SelectionEvent

SortEvent

SortEvent отправляется при изменении сортировки.

Пример подписки на событие таблицы, объявленного в XML с идентификатором sortGrid id:

@Subscribe("sortGrid")
public void onSortGridSort(DataGrid.SortEvent event) {
    notifications.create()
            .withCaption("The sort order was changed")
            .show();
}

Чтобы создать слушателя события программно, используйте метод компонента addSortListener().

ContextHelpIconClickHandler

DetailsGenerator

LookupSelectHandler

RowDescriptionProvider

RowDescriptionProvider генерирует всплывающие подсказки, когда пользователь наводит курсор на строку DataGrid. Если для колонки также задан DescriptionProvider, то описание строки, сгенерированное RowDescriptionProvider, используется для ячеек, для которых DescriptionProvider возвращает null.

В приведенном ниже примере показано использование RowDescriptionProvider для rowDescGrid:

@Install(to = "rowDescGrid", subject = "rowDescriptionProvider")
private String rowDescGridRowDescriptionProvider(Customer customer) {
    switch (customer.getLevel()) {
        case SILVER:
            return "The customer gets special offers from sellers and birthday congratulations";
        case GOLD:
            return "The customer gets 2 coupons with a rating of $ 1";
        case PLATINUM:
            return "The customer gets a coupons with a par value of $ 3";
        case DIAMOND:
            return "The customer gets a coupon with a par value of $ 5";
    }
    return null;
}

Результат:

data grid row description

Чтобы создать слушателя события программно, используйте метод компонента setRowDescriptionProvider().

RowStyleProvider

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

Пример установки стиля:

@Install(to = "styledGrid", subject = "rowStyleProvider")
private String styledGridRowStyleProvider(Customer customer) {
    switch (customer.getLevel()) {
        case SILVER:
            return "level-silver";
        case GOLD:
            return "level-gold";
        case PLATINUM:
            return "level-platinum";
        case DIAMOND:
            return "level-diamond";
    }
    return null;
}

После этого следует определить стили строк в теме приложения. Подробная информация о создании темы доступна в разделе Темы. Имена стилей, возвращаемые провайдером в контроллере экрана, должны использоваться в качестве селекторов CSS. Например:

.v-grid-row.level-silver > td {
  background-color: #f2f2f2;
  color: black;
}

.v-grid-row.level-gold > td {
    background-color: #ffda79;
    color: black;
}

.v-grid-row.level-platinum > td {
      background-color: #637497;
      color: black;
}

.v-grid-row.level-diamond > td {
        background-color: #8befff;
        color: black;
}

Результат:

data grid row style

Все XML-атрибуты

Просматривать и редактировать атрибуты, применимые к компоненту, можно с помощью панели инспектора Jmix UI в конструкторе экранов Studio.

XML-элементы DataGrid

XML-атрибуты Columns

XML-атрибуты Aggregation

XML-элемент Aggregation