Рендереры

В этом разделе описывается, как настроить отображение элементов UI, таких как comboBox, dataGrid, checkboxGroup, select и других, с помощью пользовательских рендереров в Jmix. Пользовательские рендереры позволяют разработчикам управлять визуальным представлением данных внутри этих компонентов, адаптируя интерфейс под специфические требования приложения. Это особенно полезно для:

  • Улучшенного визуального представления: Они позволяют включать визуальные элементы помимо простого текста, такие как иконки, изображения, индикаторы выполнения и другие, чтобы сделать данные более понятными и привлекательными. Это может улучшить общий пользовательский опыт и ясность интерфейса.

    radio button group renderer
  • Условное отображение: Рендереры могут реализовывать логику, изменяющую визуальное представление в зависимости от значения данных или другой контекстной информации. Например, рендерер может отображать зеленую галочку для успешных записей и красный крестик для неудачных.

    renderer 2
  • Сложные макеты: В случаях, требующих более сложных визуальных макетов, чем предлагает стандартное отображение, пользовательские рендереры обеспечивают гибкость в организации и отображении данных нестандартными способами. Это может включать в себя комбинирование нескольких элементов UI в одной ячейке компонента или создание полностью пользовательских макетов.

    renderer 3

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

Если вам нужно просто отформатировать данные (например, изменить способ отображения даты или числа), используйте форматтер.

Предопределенные XML-рендереры

Jmix предоставляет предопределённые XML-рендереры для колонок DataGrid и TreeDataGrid, упрощающие общее форматирование и отображение табличных данных:

Они принимают строку format. Например:

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

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

Компонентный рендерер

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

Компонентный рендерер принимает данные на вход и генерирует UI-компонент (например, checkBox или image) для представления этих данных. Затем этот сгенерированный компонент используется родительским компонентом UI (например, колонкой dataGrid) для отображения данных. Этот подход особенно полезен, когда необходимо визуально представить данные с помощью чего-то большего, чем простое форматирование текста.

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

Для создания рендерера используйте метод setRenderer() или аннотацию @Supply.

Для генерации метода-обработчика renderer в Jmix Studio, выберите компонент или колонку таблицы, перейдите на вкладку Handlers панели инспектора Jmix UI и дважды щелкните соответствующую строку. Также можно использовать действие Generate Handler, доступное на верхней панели класса экрана, и через меню Code → Generate (Alt+Insert / Cmd+N).

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

Выберите колонку active, переключитесь на вкладку Handlers в инспекторе Jmix UI и дважды щелкните по методу-обработчику renderer:

renderer 1

Реализуйте метод dataGridCheckboxActiveRenderer:

@Supply(to = "dataGridCheckbox.active", subject = "renderer")
private Renderer<User> dataGridCheckboxActiveRenderer() {
    return new ComponentRenderer<>(
            () -> {
                JmixCheckbox checkbox = uiComponents.create(JmixCheckbox.class); (1)
                checkbox.setReadOnly(true); (2)
                return checkbox; (3)
            },
            (checkbox, user) -> checkbox.setValue(user.getActive()) (4)
    );
}
1 Экземпляр компонента JmixCheckbox создается с помощью фабрики UiComponents.
2 Устанавливает checkbox в режим "только для чтения", предотвращая изменение его состояния пользователями напрямую.
3 Рендерер возвращает вновь созданный checkbox для отображения в ячейках колонки.
4 Лямбда-выражение, настраивающее значение checkbox. Это consumer, который принимает два параметра: компонент checkbox и экземпляр User. Он устанавливает значение флажка на основе атрибута active сущности User.
renderer 4

Примеры пользовательских рендереров для различных UI-компонентов приведены в соответствующих разделах документации Jmix:

LitRenderer

LitRenderer выполняет рендеринг контента с использованием HTML и синтаксиса привязки данных Lit; он более легковесный, чем компонентные рендереры.

LitRenderer позволяет определять HTML-шаблон и связывать свойства сущности с переменными шаблона.

@Supply(to = "dataGridLit.userInfo", subject = "renderer")
private Renderer<User> dataGridLitUserInfoRenderer() {
    return LitRenderer.<User>of("${item.firstName}<br>${item.lastName}<br>${item.email}")
            .withProperty("firstName", User::getFirstName)
            .withProperty("lastName", User::getLastName)
            .withProperty("email", User::getEmail);
}
renderer 5
LitRenderer выполняет рендеринг эффективно и идеально подходит для высокопроизводительных приложений, требующих частых обновлений. Его легковесность делает его подходящим для приложений со множеством компонентов или динамическим контентом.

LitRenderer можно использовать в следующих компонентах пользовательского интерфейса:

Рендерер фрагментов

Рендереры для virtualList, dataGrid и других компонентов могут быть определены с помощью фрагментов. Специальный XML-элемент fragmentRenderer используется для декларативного описания рендерера.

Как и обычные фрагменты, fragmentRenderer определяется с помощью дескриптора и контроллера Java.

  1. Создайте XML-дескриптор FragmentRenderer

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

    <fragment xmlns="http://jmix.io/schema/flowui/fragment">
        <data>
            <instance id="userDc" class="com.company.onboarding.entity.User">
                <loader id="userDl"/>
                <fetchPlan extends="_base"/>
            </instance>
        </data>
        <content>
            <hbox>
                <icon icon="ANGLE_DOUBLE_RIGHT"/>
                <formLayout id="form" dataContainer="userDc">
                    <textField property="username" readOnly="true"/>
                    <textField property="firstName" readOnly="true"/>
                    <textField property="lastName" readOnly="true"/>
                    <textField property="email" readOnly="true"/>
                </formLayout>
            </hbox>
        </content>
    </fragment>
    Если instanceContainer не определен, вы можете использовать метод FragmentRenderer.getItem() для обработки рендеринга.
  2. Создайте FragmentRenderer Java-контроллер

    Класс рендерера фрагмента должен расширять базовый класс FragmentRenderer с параметрами типа, указывающими корневой компонент и отображаемую сущность, например:

    @FragmentDescriptor("user-fragment.xml") (1)
    @RendererItemContainer("userDc") (2)
    public class UserFragment extends FragmentRenderer<HorizontalLayout, User> {
    }
    1 Аннотация @FragmentDescriptor задает строковое значение - путь к XML-файлу, используемому для инициализации фрагмента.
    2 Аннотация @RendererItemContainer используется для указания контейнера данных, принимающего отображаемую сущность.
  3. Используйте FragmentRenderer в экране

    Выберите компонент, в котором вы хотите отобразить элементы, и добавьте элемент fragmentRenderer. Этот элемент требует атрибут class, указывающий полное имя класса (FQN), расширяющего абстрактный класс io.jmix.flowui.fragmentrenderer.FragmentRenderer.

    <virtualList itemsContainer="usersDc">
        <fragmentRenderer
                class="com.company.onboarding.view.component.virtuallist.UserFragment"/>
    </virtualList>

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

    Элемент fragmentRenderer также поддерживает загрузку свойств, так же как и элемент fragment.

renderer 6

Вы можете использовать fragmentRenderer в следующих UI-компонентах: