Table
Компонент Table
позволяет выводить информацию в табличном виде, сортировать данные, управлять колонками и заголовками таблицы, вызывать действия для выбранных строк.
XML-имя компонента: table
.
Основы
Ниже представлена типичная таблица:
-
Строка заголовка
-
Строки
-
Кнопка управления колонкой
-
Разбивка на страницы
-
Кнопка сортировки
-
Панель кнопок
Ниже представлен пример объявления таблицы в 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>
<table id="customersTable"
width="100%"
dataContainer="customersDc">
<actions>
<action id="create" type="create"/>
<action id="edit" type="edit"/>
<action id="remove" type="remove"/>
<action id="sendByEmail" type="sendByEmail">
<properties>
<property name="recipientAddress" value="peter@example.com"/>
</properties>
</action>
</actions>
<columns>
<column id="level"/>
<column id="age"/>
<column id="hobby"/>
<column id="firstName"/>
<column id="lastName"/>
<column id="rewardPoints"/>
</columns>
<simplePagination/>
<buttonsPanel id="buttonsPanel" alwaysVisible="true">
<button id="createBtn" action="customersTable.create"/>
<button id="editBtn" action="customersTable.edit"/>
<button id="removeBtn" action="customersTable.remove"/>
<button id="sendBtn" action="customersTable.sendByEmail"/>
</buttonsPanel>
</table>
</layout>
В приведенном примере есть контейнер коллекции для сущности Customer
. Таблица привязана к контейнеру с помощью атрибута dataContainer
, в то время как его элемент columns
определяет, какие атрибуты сущности отображаются в колонках таблицы.
Привязка к данным
Декларативная привязка
Обычно компонент table
привязывается к данным декларативно в 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>
<table id="keyValueTable" width="100%" dataContainer="salesDc">
<columns>
<column id="customerName" caption="Customer"/>
<column id="sum" caption="Summary amount" align="RIGHT"/>
</columns>
</table>
</layout>
Программная привязка
Если необходимо определить контейнер данных программно в контроллере экрана, установите атрибут metaClass вместо dataContainer в XML-дескрипторе:
<table id="customersTable1" width="100%" metaClass="uiex1_Customer">
<columns>
<column id="firstName"/>
<column id="lastName"/>
</columns>
</table>
В контроллере экрана используйте класс ContainerDataGridItems
для привязки таблицы к контейнеру данных:
customersTable1.setItems(new ContainerTableItems<>(customersDc));
Columns
Набор колонок таблицы определяется элементом columns
. Если он не задан, то колонки таблицы будут автоматически взяты из фетч-плана, определенного в dataContainer
.
Элемент columns
имеет следующие атрибуты:
-
includeAll
включает все атрибуты изfetchPlan
, определенного вdataContainer
.В приведенном ниже примере мы покажем все атрибуты из фетч-плана, используемого в
customersDc
:<table id="customersTableIncludeAll" width="100%" dataContainer="customersDc"> <columns includeAll="true"/> </table>
Если фетч-план сущности содержит ссылочный атрибут, этот атрибут выводится в соответствии с его именем экземпляра. Если нужно показать конкретный вложенный атрибут, он должен быть определен в фетч-плане, а также в элементе
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> <table id="tableIncludeAllReference" width="100%" dataContainer="customersDc1"> <columns includeAll="true"> <column id="city.country.name"/> </columns> </table> </layout>
-
exclude
содержит разделенный запятыми список атрибутов, которые не должны быть показаны вDataGrid
.В приведенном ниже примере мы покажем все атрибуты за исключением
id
,maritalStatus
, иemail
:<table id="tableExclude" width="100%" dataContainer="customersDc1"> <columns includeAll="true" exclude="id,maritalStatus,email"/> </table>
Column
Каждая колонка описывается во вложенном элементе column
.
id
– обязательный атрибут, содержит название атрибута сущности, выводимого в колонке. Может быть как непосредственным атрибутом сущности, находящейся в контейнере, так и атрибутом связанной сущности – переход по графу объектов обозначается точкой. Например:
<columns>
<column id="firstName"/>
<column id="lastName"/>
<column id="city.name"/>
<column id="city.country.name"/>
</columns>
Выравнивание колонок
Поддерживаются три различных выравнивания колонок: LEFT
(по умолчанию), CENTER
, and RIGHT
.
Как правило, имеет смысл выровнять числа по правому краю и выровнять по левому краю все остальное содержимое. Например:
<table id="keyValueTable" width="100%" dataContainer="salesDc">
<columns>
<column id="customerName" caption="Customer"/>
<column id="sum" caption="Summary amount" align="RIGHT"/>
</columns>
</table>
Заголовок колонки
<column id="firstName"
captionAsHtml="true"
caption="msg://firstName"/> (1)
<column id="lastName"/> (2)
1 | Заголовок колонки с HTML-тегами:
|
2 | Колонка с заголовком по умолчанию |
Видимость колонок
collapsed
- необязательный атрибут, при указании true
колонка будет изначально скрыта. Пользователи могут управлять видимостью колонки с помощью меню, доступного по нажатию кнопки в правом верхнем углу таблицы, если атрибут columnsCollapsingAllowed имеет значение true
. По умолчанию имеет значение false
.
Атрибут visible
устанавливает видимость колонки. Возможные значения – true
, false
. По умолчанию все колонки видимы.
Рассмотрим разницу между атрибутами collapsed
и visible
в следующем примере.
<columns>
<column id="firstName"
collapsed="true"/>
<column id="lastName"
visible="false"/>
<column id="city"/>
</columns>
Как можно видеть, колонка firstName
по умолчанию свернута, но пользователи могут развернуть ее из выпадающего меню кнопки .
В то же время колонка lastName
не может быть свернута пользователем.
Ширина колонки
width
- необязательный атрибут, отвечает за изначальную ширину колонки. Может принимать только числовые значения в пикселах.
<columns>
<column id="firstName" width="100"/>
<column id="lastName" width="150"/>
<column id="city" width="100"/>
</columns>
expandRatio
- необязательный атрибут, устанавливает соотношение, с которым колонка расширяется. Если хотя бы одной колонке установлено иное значение, все неявные значения игнорируются и учитываются только явно присвоенные. Если одновременно установить атрибуты width
и expandRatio
, это вызовет ошибку в приложении.
<columns>
<column id="firstName" expandRatio="1"/>
<column id="lastName" expandRatio="1.5"/>
<column id="city" expandRatio="1"/>
</columns>
Пользователи могут изменять размеры колонок:
Ширина колонки остается фиксированной только если атрибут enable
установлен в false
для всей таблицы.
Изменение порядка колонок
Table
позволяет пользователям менять порядок колонок с помощью перетаскивания.
Возможность менять порядок колонок включена по умолчанию. Чтобы отключить ее, задайте для атрибута reorderingAllowed
значение false
.
Ссылка на экран редактора
Если установить атрибут link
в true
, содержание колонки будет отображено в виде ссылки на экран редактора сущности. Такой подход может применяться для упрощения навигации – пользователи смогут открывать редактор одним кликом по некоторому ключевому атрибуту, например, по имени клиента.
Атрибут linkScreenId
содержит идентификатор экрана, который будет открыт при нажатии на ссылку. Если он не задан, фреймворк откроет экран с идентификатором {entity_name}.edit
.
Атрибут linkScreenOpenMode
задает режим открытия экрана (THIS_TAB
, NEW_TAB
, NEW_WINDOW
, или DIALOG
).
<column id="firstName"
link="true"
linkScreenOpenMode="DIALOG"/>
<column id="lastName"/>
<column id="city"/>
Максимальная длина текста
maxTextLength
– необязательный атрибут, позволяет ограничивать количество символов в ячейке. Лишние символы заменяются многоточием. Для просмотра полной записи пользователю надо кликнуть на ее видимую часть.
Если разница между фактическим и допустимым количеством символов не превышает порог в 10 символов, "лишние" символы не скрываются.
В приведенном ниже примере некоторые ячейки содержат значения длиннее чем maxTextLength+10
и обрезаются:
<columns>
<column id="firstName"/>
<column id="lastName"/>
<column id="email" maxTextLength="15"/>
<column id="city"/>
</columns>
Форматирование текста
Элемент column
может содержать вложенный элемент formatter для представления значения атрибута в виде, отличном от стандартного для данного Datatype
:
<table id="tableColumnFormatter"
width="100%"
dataContainer="ordersDc">
<columns>
<column id="customer"/>
<column id="amount"/>
<column id="deliveryTime">
<formatter>
<date format="h:mm a"/>
</formatter>
</column>
</columns>
</table>
captionProperty
Атрибут captionProperty
указывает имя атрибута сущности, который должен быть отображен в колонке вместо указанного в id
. Например, если имеется связанная сущность City
с атрибутами name
и id
, можно определить следующую колонку:
<column id="city"
caption="City ID"
captionProperty="id"/>
В этом случае в колонке будет отображаться id
, а сортировка колонки будет осуществляться по атрибуту name
.
Перенос строк в ячейке
Если атрибуту multiLineCells
таблицы присвоить значение true
, то ячейки, содержащие текст с переносами строк, будут отображать его в несколько строк. В таком режиме в веб-клиенте для правильной работы полосы прокрутки все строки текущей страницы таблицы будут загружены веб-браузером сразу, без ленивой загрузки видимой части таблицы. Это необходимо для правильной прокрутки и может повлиять на производительность. По умолчанию атрибут имеет значение false
.
Выделение
Компонент Table
позволяет пользователям выделять одну или несколько строк.
Единичный выбор строки
В режиме единичного выбора строки пользователи смогут выделять одну строку за раз. Единичный выбор строки установлен по умолчанию.
Множественный выбор
Атрибут multiselect
включает множественный выбор строк таблицы. Если ему задано значение true
, то пользователи смогут выделять несколько строк за раз, используя клавиатуру или мышь и зажимая клавиши Ctrl или Shift. По умолчанию множественный выбор отключен.
Заполнитель
Table
позволяет задать позволяет настроить заполнитель в виде сообщения и/или ссылки, отображаемый в случае, если контейнер данных пуст или не задан.
Заполнитель-сообщение определяется атрибутом emptyStateMessage
. Он должен содержать информацию о том, почему таблица пуста.
Заполнитель-ссылка определяется атрибутом emptyStateLinkMessage
. В нем должно быть описано действие, которое необходимо выполнить для заполнения таблицы.
Например:
<table id="tablePlaceholder"
width="100%"
height="200"
metaClass="uiex1_Customer"
emptyStateMessage="No customers added."
emptyStateLinkMessage="Add customer">
<columns>
<column id="firstName"/>
<column id="lastName"/>
</columns>
</table>
Сгенерируйте emptyStateLinkClickHandler
для обработки нажатий по ссылке:
@Install(to = "tablePlaceholder", subject = "emptyStateLinkClickHandler")
private void tablePlaceholderEmptyStateLinkClickHandler(
Table.EmptyStateClickEvent<Customer> emptyStateClickEvent) {
screenBuilders.editor(emptyStateClickEvent.getSource())
.newEntity()
.show();
}
Чтобы создать слушателя нажатий программно, используйте метод компонента setEmptyStateLinkClickHandler()
.
И emptyStateMessage
, и emptyStateLinkMessage
могут загружать сообщения из пакета сообщений.
Видимость заголовка
Атрибут columnHeaderVisible
устанавливает видимость заголовка таблицы. По умолчанию имеет значение true
.
Управление видимостью колонок
Пользователи могут выбрать, какие колонки будут видимы, используя кнопку управления колонками в правой части заголовка таблицы.
Отображаемые в данный момент колонки отмечены в выпадающем меню. В нем есть дополнительные пункты:
-
Select all
- показать все колонки; -
Deselect all
- спрятать все возможные колонки, кроме первой. Первая колонка остается видимой всегда для правильного отображения таблицы.
Если columnControlVisible
имеет значение false
, пользователи не смогут скрывать колонки.
Агрегация
Table
поддерживает агрегацию значений в строки.
Поддерживаются следующие операции:
-
SUM
- вычисление суммы; -
AVG
- вычисление среднего значения; -
COUNT
- вычисление общего количества; -
MIN
- вывод минимального значения; -
MAX
- вывод максимального значения.
Чтобы включить агрегацию для таблицы, необходимо:
-
Установить для атрибута
aggregatable
значениеtrue
. -
Указать элемент
aggregation
для агрегируемых колонок. -
Указать для элемента
aggregation
атрибутtype
, задающий функцию агрегации.
Агрегированные значения выводятся в дополнительной строке.
Атрибут aggregationStyle
позволяет задать расположение строки агрегации: TOP
или BOTTOM
. TOP
используется по умолчанию.
По умолчанию в агрегируемых колонках поддерживаются только числовые типы данных, такие как |
Пример описания таблицы с агрегацией:
<table id="tableAggregation"
width="100%"
aggregatable="true"
dataContainer="customersDc1">
<columns>
<column id="firstName"/>
<column id="lastName"/>
<column id="rewardPoints"/>
<column id="age">
<aggregation type="AVG"/>
</column>
</columns>
</table>
Атрибут valueDescription
задает текст всплывающей подсказки, отображаемой при наведении курсора мыши по агрегированному значению. Для операций, перечисленных выше (SUM
, AVG
, COUNT
, MIN
, MAX
), всплывающие подсказки уже есть по умолчанию.
Элемент aggregation
может содержать атрибут editable
. Установка атрибута в значение true
совместно с использованием AggregationDistributionProvider позволяет реализовать функциональность распределения значения агрегируемой ячейки между строками таблицы.
Для отображения агрегированного значения в виде, отличном от стандартного для данного Datatype
, для него можно указать Formatter:
<column id="amount">
<aggregation type="SUM">
<formatter>
<number format="#,##0.00"/>
</formatter>
</aggregation>
</column>
Элемент aggregation
может также содержать атрибут strategyClass
, указывающий класс, реализующий интерфейс AggregationStrategy
.
public class TableCustomerHobbyAggregation 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;
}
}
<table id="tableAggregationStrategy"
width="100%"
aggregatable="true"
dataContainer="customersDc">
<columns>
<column id="firstName"/>
<column id="lastName"/>
<column id="hobby">
<aggregation
strategyClass="ui.ex1.screen.component.table.TableCustomerHobbyAggregation"/>
</column>
</columns>
</table>
Сортировка
Table
позволяет пользователям сортировать данные колонки. Функция сортировки включена по умолчанию.
Атрибут sortable
позволяет сортировать данные в таблице. По умолчанию имеет значение true
. Если сортировка разрешена, при щелчке по заголовку колонки появится / значок справа от названия колонки.
Можно отключить сортировку для конкретной колонки, используя ее атрибут sortable
.
В примере ниже отключим сортировку по колонке lastName
:
<columns>
<column id="firstName"/>
<column id="lastName" sortable="false"/>
<column id="city"/>
</columns>
Атрибут sort
элемента column
позволяющий задать начальную сортировку таблицы по указанной колонке в соответствии с направлением сортировки. Возможные значения:
-
ASCENDING
- сортировка по возрастанию (0 → 9 → A → Z). -
DESCENDING
- сортировка по убыванию (Z → A → 9 → 0).
Например:
<columns>
<column id="firstName" sort="DESCENDING"/>
<column id="lastName"/>
<column id="city"/>
</columns>
В одно и то же время таблица может быть сортирована только по одной колонке. Если установить атрибут |
Разбивка на страницы
Компонент SimplePagination может быть использован внутри table
для обеспечения разбивки на страницы:
<table id="tablePaging"
width="100%"
dataContainer="customersDc">
<columns>
<column id="firstName"/>
<column id="lastName"/>
<column id="hobby"/>
<column id="age"/>
</columns>
<simplePagination
itemsPerPageVisible="true"
itemsPerPageOptions="2, 4, 6"/>
</table>
В качестве альтернативы можно использовать отдельный компонент Pagination.
Действия Table
Компонент Table
реализует интерфейс ActionsHolder
и может содержать настраиваемые действия и стандартные действия со списками.
Действия таблицы определяются во вложенном элементе actions
.
Если действие имеет название, оно отображается как элемент контекстного меню таблицы. Кроме того, действие таблицы может быть назначено кнопке, расположенной в любом месте экрана.
<table id="tableWithActions"
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"/>
<column id="firstName"/>
<column id="lastName"/>
</columns>
<buttonsPanel id="buttonsActionsPanel" alwaysVisible="true"> (3)
<button id="create" action="tableWithActions.create"/>
<button id="edit" action="tableWithActions.edit"/>
<button id="remove" action="tableWithActions.remove"/>
<button id="about" action="tableWithActions.about"/>
</buttonsPanel>
</table>
1 | Определение стандартного действия create . |
2 | Определение настраиваемого действия about . |
3 | Определение контейнера ButtonsPanel в таблице. |
Генерация колонок
Обработчик columnGenerator
позволяет задавать собственное отображение данных в колонке.
Этот обработчик вызывается фреймворком для каждой ячейки при рендеринге таблицы. Он получает экземпляр сущности, соответствующий отображаемой строке, и должен вернуть визуальный компонент, который будет отображаться в ячейке.
Обработчик columnGenerator
для таблицы можно создать с помощью Studio (см. ниже) и реализовать его следующим образом:
@Install(to = "tableGeneratedColumn.hasEmail", subject = "columnGenerator")
private Component tableGeneratedColumnIsEmailColumnGenerator(Customer customer) {
CheckBox hasEmail = uiComponents.create(CheckBox.class);
hasEmail.setValue(customer.getEmail() != null);
return hasEmail;
}
Если в ячейке необходимо отобразить просто динамически сформированный текст, вместо компонента Label используйте класс Table.PlainTextCell
. Это упростит рендеринг и сделает таблицу быстрее:
@Install(to = "tableGeneratedColumn.fullName", subject = "columnGenerator")
private Component tableGeneratedColumnFullNameColumnGenerator(Customer customer) {
return new Table.PlainTextCell(customer.getFirstName() + " " + customer.getLastName());
}
<table id="tableGeneratedColumn"
width="100%"
dataContainer="customersDc">
<columns>
<column id="age"/>
<column id="firstName"/>
<column id="lastName"/>
<column id="fullName" caption="Full name"/>
<column id="email"/>
<column id="hasEmail" caption="Has email"/>
</columns>
</table>
fullName
и isEmail
являются генерированными колонками.
Если идентификатор колонки указывает на атрибут связанной сущности (то есть содержит точки), то обработчик columnGenerator
должен быть объявлен как на примере ниже.
-
Колонка, ассоциированная с атрибутом связанной сущности:
<column id="city.country.name"/>
-
Соответствующий обработчик
columnGenerator
:@Install(to = "countryTable.[city.country.name]", subject = "columnGenerator") private Component countryTableCityCountryNameColumnGenerator(Customer customer) { return new Table.PlainTextCell(customer.getCity().getCountry().getName()); }
Чтобы создать генератора колонок программно, используйте метод addGeneratedColumn()
компонента Table
. Он принимает два параметра: идентификатор колонки и реализацию интерфейса Table.ColumnGenerator
. Идентификатор может совпадать с одним из идентификаторов, указанных для колонок таблицы в XML-дескрипторе – в этом случае новая колонка вставляется вместо заданной в XML. Если идентификатор не совпадает ни с одной колонкой, создается новая справа.
Метод generateCell()
интерфейса Table. ColumnGenerator
является аналогом описанного выше обработчика columnGenerator
: он принимает экземпляр сущности, отображаемой в данной строке, и должен вернуть визуальный компонент, который будет отображаться в ячейке.
Экспорт значений колонок
Чтобы экспортировать содержимое компонента Table
в виде файла в одном из поддерживаемых форматов, используйте дополнение Grid Export Actions.
После установки дополнения вы можете определить для таблицы действие excelExport или jsonExport или использовать TableExporter.
Если вы используете собственные генерируемые колонки, их содержимое по умолчанию не экспортируется. См. пример в разделе Экспорт таблиц со сгенерированными колонками.
Ниже приведен пример настройки пользовательского представления данных в колонке при экспорте в файл XLS с помощью действия excelExport
.
Дескриптор экрана:
<table id="printableTable"
width="100%"
dataContainer="customersDc1">
<actions>
<action id="excelExport" type="excelExport"/>
</actions>
</table>
Контроллер экрана:
@Named("printableTable.excelExport")
protected ExcelExportAction printableTableExcelExport;
@Subscribe
public void onInit(InitEvent event) {
printableTableExcelExport.addColumnValueProvider("firstName", context -> { (1)
Customer customer = context.getEntity();
return "Name: " + customer.getFirstName();
});
}
1 | Метод принимает идентификатор колонки и функцию для получения значения из колонки. |
Редактирование значений
Таблица может быть настроена таким образом, чтобы разрешить внутристрочное редактирование.
Используйте атрибут editable
для переключения таблицы в режим редактирования.
В этом режиме в колонках, имеющих атрибут editable = true
, отображаются компоненты для редактирования значений атрибутов соответствующей сущности. Изменение этого атрибута во время выполнения не поддерживается.
Тип компонента для каждой редактируемой колонки выбирается автоматически на основе типа соответствующего атрибута сущности. Например, для строковых и числовых атрибутов приложение будет использовать TextField, для Date
– DateField, для перечислений – ComboBox, для ссылок на другие сущности – EntityPicker.
Для редактируемой колонки типа Date
можно дополнительно указать атрибуты dateFormat или resolution аналогично описанным для DateField
.
Для редактируемой колонки, отображающей связанную сущность, можно дополнительно указать атрибуты optionsContainer и captionProperty. При указании optionsContainer
приложение будет использовать ComboBox
вместо EntityPicker
.
Контекстное меню
Контекстное меню активируется щелчком правой кнопки мыши в таблице данных.
Атрибут contextMenuEnabled
включает или выключает контекстное меню. По умолчанию имеет значение true
. В контекстном меню отображаются действия таблицы (если таковые имеются).
Стили
Компоненту Table
можно задать предопределенные стили с помощью атрибута stylename
в XML-дескрипторе или в контроллере экрана:
<table id="tableBorderless"
caption="Table with borderless style"
width="100%"
stylename="borderless"
dataContainer="customersDc1">
tableBorderless.setStyleName(ThemeClassNames.TABLE_BORDERLESS);
Предопределенные стили:
-
borderless
- удаляет внешнюю рамку; -
no-header
- скрывает заголовки колонок; -
no-horizontal-lines
- удаляет горизонтальные строковые разделители; -
no-vertical-lines
- удаляет вертикальные разделители колонок. -
no-stripes
- отключает чередование цветов строк таблицы.
Внешний вид компонента Table
можно настроить с помощью переменных SCSS с префиксом $jmix-table-*
. Эти переменные можно изменить в визуальном редакторе после создания новой темы.
Методы интерфейса Table
-
getSelected()
,getSingleSelected()
возвращают экземпляры сущностей, соответствующие выделенным в таблице строкам. Коллекцию можно получить вызовом методаgetSelected()
. Если ничего не выбрано, возвращается пустой набор. Еслиmultiselect
отключен, удобно пользоваться методомgetSingleSelected()
, возвращающим одну выбранную сущность илиnull
, если ничего не выбрано.
-
Метод
requestFocus()
позволяет установить фокус на определенное поле конкретной записи. Принимает два параметра: экземпляр сущности, определяющий строку и идентификатор колонки. Пример программной установки фокуса::table.requestFocus(item, "count");
-
Метод
scrollTo()
позволяет программно прокрутить таблицу до нужной записи. Метод принимает экземпляр сущности, определяющий нужную строку в таблице.Пример использования метода:
table.scrollTo(item);
-
Метод
setItemClickAction()
позволяет задать действие, выполняемое при двойном клике на строке таблицы. Если такое действие не задано, при двойном клике таблица пытается найти среди своих действий подходящее в следующем порядке:-
Действие, назначенное на клавишу Enter посредством свойства
shortcut
; -
Действие с именем edit;
-
Действие с именем view.
Если такое действие найдено и имеет свойство
enabled = true
, оно выполняется.Пример задания
ItemClickAction
для компонентаTable
, определенного в XML-файле экрана с идентификаторомtableClick
:@Autowired private Table<Customer> tableClick; @Subscribe public void onInit(InitEvent event) { tableClick.setItemClickAction(new BaseAction("itemClickAction") .withHandler(actionPerformedEvent -> { Customer customer = tableClick.getSingleSelected(); if (customer != null) { notifications.create() .withCaption("Item clicked for: " + customer.getFirstName()+ "" + customer.getLastName()) .show(); } })); }
-
-
Метод
setEnterPressAction()
позволяет задать действие, выполняемое при нажатии клавиши Enter. Если такое действие не задано, таблица пытается найти среди своих действий подходящее в следующем порядке:-
Действие, назначенное методом
setItemClickAction()
; -
Действие, назначенное на клавишу Enter посредством свойства
shortcut
; -
Действие с именем edit;
-
Действие с именем view.
Если такое действие найдено и имеет свойство
enabled = true
, оно выполняется.Пример задания
ItemClickAction
для компонентаTable
, определенного в XML-файле экрана с идентификаторомtableClick
:@Autowired private Table<Customer> tableClick; @Subscribe public void onInit(InitEvent event) { tableClick.setEnterPressAction(new BaseAction("enterPressAction") .withHandler(actionPerformedEvent -> { Customer customer = tableClick.getSingleSelected(); if (customer != null) { notifications.create() .withCaption("Enter pressed for: " + customer.getFirstName()+ "" + customer.getLastName()) .show(); } })); }
-
-
Метод
getAggregationResults()
возвращает мэп с результатами агрегации, где ключи в мэп – идентификаторы колонок таблицы, а значения – значения агрегации.
Слушатели и события
Чтобы сгенерировать заглушку слушателя в Jmix Studio, выберите компонент в XML-дескрипторе экрана или на панели иерархии Jmix UI и используйте вкладку Handlers на панели инспектора Jmix UI. В качестве альтернативы вы можете воспользоваться кнопкой Generate Handler на верхней панели контроллера экрана. |
AggregationDistributionProvider
Определяет правила распределения агрегированного значения между ячейками таблицы в соответствии с кастомным алгоритмом. Если пользователь вводит значение в агрегированную ячейку, оно распределяется по составляющим ячейкам. Поддерживается только для стиля агрегации TOP
. Для того чтобы сделать агрегированные ячейки редактируемыми, используйте атрибут editable элемента aggregation
.
При создании провайдера используется объект AggregationDistributionContext<E>
, который содержит данные, необходимые для распределения агрегируемого значения:
-
Column column
− колонка, в которой произошло изменение значения в общей или групповой агрегации; -
Object value
− новое значение агрегации; -
Collection<E> scope
− коллекция сущностей, на которые повлияет изменение значения агрегации; -
boolean isTotalAggregation
- указывает, в какой агрегации произошли изменения: в общей или групповой.
В качестве примера рассмотрим таблицу, представляющую бюджет. Пользователь создает категории бюджета и задает для каждой из них проценты, в соответствии с которыми должна распределяться сумма дохода. Далее в агрегируемой ячейке указывается общая сумма дохода, после чего происходит распределение по категориям.
Пример настройки таблицы в XML-дескрипторе экрана:
<table id="budgetTable"
width="100%"
aggregatable="true"
dataContainer="budgetItemsDc">
<columns>
<column id="category"/>
<column id="percent"/>
<column id="amount">
<aggregation type="SUM"
editable="true"/>
</column>
</columns>
</table>
Пример в контроллере экрана:
@Install(to = "budgetTable", subject = "aggregationDistributionProvider")
private void budgetTableAggregationDistributionProvider(
Table.AggregationDistributionContext<BudgetItem> context) {
Collection<BudgetItem> scope = context.getScope();
if (scope.isEmpty()) {
return;
}
double value = context.getValue() != null ?
((double) context.getValue()) : 0;
for (BudgetItem budgetItem : scope) {
budgetItem.setAmount(value / 100 * budgetItem.getPercent());
}
}
Чтобы создать провайдера программно, используйте метод компонента setAggregationDistributionProvider()
.
ColumnCollapseEvent
ColumnCollapseEvent
отправляется при изменении видимости колонки.
Пример подписки на событие таблицы, объявленного в XML с идентификатором tableCollapsed
:
@Subscribe("tableCollapsed")
public void onTableCollapsedColumnCollapse(Table.ColumnCollapseEvent<Customer> event) {
notifications.create()
.withCaption((event.isCollapsed() ? "Collapsed: " : "Expanded: ") +
event.getColumn().getCaption())
.show();
}
Чтобы создать слушателя события программно, используйте метод компонента addColumnCollapseListener()
.
ColumnReorderEvent
ColumnReorderEvent
отправляется при изменении пользователем порядка колонок.
Пример подписки на событие таблицы, объявленного в XML с идентификатором tableReorder
:
@Subscribe("tableReorder")
public void onTableReorderColumnReorder(Table.ColumnReorderEvent<Customer> event) {
notifications.create()
.withCaption("Columns were reordered!")
.show();
}
Чтобы создать слушателя события программно, используйте метод компонента addColumnReorderListener()
.
EmptyStateLinkClickHandler
См. EmptyStateClickEvent.
IconProvider
Данный провайдер позволяет добавлять значок в начало каждой строки таблицы:
@Install(to = "tableWithIcons", subject = "iconProvider")
private String tableWithIconsIconProvider(Customer customer) {
return customer.getEmail() != null ?
JmixIcon.MAIL_FORWARD.source() : JmixIcon.CANCEL.source();
}
Чтобы создать провайдер программно, используйте метод компонента setIconProvider()
.
ItemDescriptionProvider
Данный провайдер служит для генерации всплывающих подсказок для ячеек таблицы.
В приведенном ниже примере покажем использование ItemDescriptionProvider
для tableWithDescription
:
@Install(to = "tableWithDescription", subject = "itemDescriptionProvider")
private String tableWithDescriptionItemDescriptionProvider(
Customer customer, String property) {
if (property == null)
return null;
else if (property.equals("rewardPoints")) {
return "Reward points are a part of the loyalty program affecting the rating of the " +
customer.getFirstName() + " " + customer.getLastName();
} else if (property.equals("level")) {
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;
}
LookupSelectHandler
LookupSelectHandler
– это обработчик, вызываемый, когда пользователь нажимает Enter или дважды щелкает по строке таблицы на экране выбора. Он принимает коллекцию выделенных сущностей. Можно определить данный обработчик следующим образом:
@Install(to = "tableLookupSelect", subject = "lookupSelectHandler")
private void tableLookupSelectLookupSelectHandler(Collection<Customer> collection) {
checkCustomers(collection);
}
Чтобы создать обработчик программно, используйте метод компонента setLookupSelectHandler()
.
SelectionEvent
SelectionEvent
отправляется при изменении выделения.
Пример подписки на событие таблицы, объявленного в XML с идентификатором tableSelectEvent
:
@Autowired
private Table<Customer> tableSelectEvent;
@Subscribe("tableSelectEvent")
public void onTableSelectEventSelection(Table.SelectionEvent<Customer> event) {
Customer customer = tableSelectEvent.getSingleSelected();
notifications.create()
.withCaption("You selected " + customer.getFirstName() +
" " + customer.getLastName() + " customer")
.show();
}
Чтобы создать слушателя события программно, используйте метод компонента addSelectionListener()
.
StyleProvider
StyleProvider
позволяет задать стиль отображения ячеек таблицы. Провайдер вызывается таблицей отдельно для каждой строки и для каждой ячейки. Если метод вызван для строки, то первый параметр содержит экземпляр сущности, отображаемый этой строкой, а второй параметр null
. Если же метод вызван для ячейки, то второй параметр содержит имя атрибута, отображаемого этой ячейкой.
Пример задания стилей:
@Install(to = "styledTable", subject = "styleProvider")
private String styledTableStyleProvider(Customer entity, String property) {
if (property == null) {
if (Boolean.TRUE.equals(entity.getEmail() != null)) {
return "customer-has-email";
}
} else if (property.equals("level")) {
switch (entity.getLevel()) {
case SILVER:
return "level-silver";
case GOLD:
return "level-gold";
case PLATINUM:
return "level-platinum";
case DIAMOND:
return "level-diamond";
}
}
return null;
}
Далее нужно определить заданные для строк и ячеек стили в теме приложения. Подробная информация о создании темы находится в разделе Темы. Имена стилей, возвращаемые провайдером в контроллере должны использоваться как CSS-селекторы. Например:
.customer-has-email {
font-weight: bold;
}
.level-silver {
background-color: #f2f2f2;
color: black;
}
.level-gold {
background-color: #ffda79;
color: black;
}
.level-platinum {
background-color: #637497;
color: white;
}
.level-diamond {
background-color: #8befff;
color: black;
}
Чтобы создать провайдер программно, используйте метод компонента setStyleProvider()
.
Все XML-атрибуты
Просматривать и редактировать атрибуты, применимые к компоненту, можно с помощью панели инспектора Jmix UI в конструкторе экранов Studio. |
XML-атрибуты Table
aggregatable - aggregationStyle - align - caption - captionAsHtml - columnControlVisible - columnHeaderVisible - colspan - contextHelpText - contextHelpTextHtmlEnabled - contextMenuEnabled - css - dataContainer - description - descriptionAsHtml - editable - emptyStateLinkMessage - emptyStateMessage - enable - box.expandRatio - height - htmlSanitizerEnabled - icon - id - metaClass - multiLineCells - multiselect - reorderingAllowed - responsive - rowspan - showSelection - sortable - stylename - tabIndex - textSelectionEnabled - visible - width
XML-атрибуты Column
align - caption - captionAsHtml - captionProperty - collapsed - dateFormat - description - editable - expandRatio - id - link - linkScreenId - linkScreenOpenMode - maxTextLength - optionsContainer - resolution - required - requiredMessage - sort - sortable - visible - width