Создание GWT-компонента

Создание пользовательского набора виджетов

Фреймворк Jmix предоставляет готовый набор виджетов в артефакте jmix-ui-widgets-compiled.

Для создания пользовательского набора виджетов в проекте необходимо:

  1. Удалить зависимость implementation 'io.jmix.ui:jmix-ui-widgets-compiled'.

  2. Добавить зависимости к вашему build.gradle:

    implementation 'io.jmix.ui:jmix-ui-widgets' (1)
    widgets 'io.jmix.ui:jmix-ui-widgets'
    1 Требуется только для разработки пользовательских клиентских компонентов.
  3. Добавьте задачу compileWidgets (измените пути в соответствии с базовым пакетом вашего приложения):

    compileWidgets {
        generate "ui.ex1.widgets.CustomWidgetSet"
        includePaths('**/io/jmix/**/widget/**', '**/ui/ex1/widgets/**')
    }

    Параметры excludePaths и includePaths для задачи compileWidgets полезны, если вы не хотите компилировать набор виджетов в случае, например, изменения какого-либо экрана.

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

    compileWidgets {
        generate 'com.company.demo.widgets.CustomWidgetSet'
        excludePaths('**/com/company/demo/**')
    }

    Теперь изменения в пакете com.company.demo не вызывают компиляцию набора виджетов.

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

    См. пример:

    compileWidgets {
        generate 'com.company.demo.widgets.CustomWidgetSet'
        includePaths('**/io/jmix/**/widget/**', '**/com/company/demo/widgets/**')
    }

    Теперь изменения в пакете com.company.demo.widgets и в любом пакете widget (включая подпакеты) внутри пакета io.jmix вызывают компиляцию набора виджетов. Другие изменения, например, в контроллерах экрана или XML-дескрипторах, не вызывают компиляции. Если наблюдается неожиданная перекомпиляция, проверьте причину (выполните compileWidgets с параметром --info).

    Параметры excludePaths и includePaths принимают список шаблонов строк.

    Шаблоны могут включать:

    • * для соответствия любому количеству символов.

    • ? для соответствия любому одиночному символу.

    • ** для соответствия любому количеству каталогов или файлов.

    '/' или '\' могут использоваться для разделения каталогов в шаблоне.

    Например, includePaths('**/com/company/demo/widgets/**') включает все файлы в каталоге com/company/demo/widgets, включая подкаталоги.

    См. дополнительную информацию по адресу https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/util/PatternFilterable.html.

  4. Добавьте свойство jmix.ui.widget-set в ваш файл application.properties (настройте местоположение в соответствии с задачей compileWidgets выше):

    jmix.ui.widget-set=ui.ex1.widgets.CustomWidgetSet

Наборы виджетов компилируются задачей WidgetsCompile с названием compileWidgets. Она создается автоматически при использовании плагина Jmix.

Скомпилированный набор виджетов помещается в каталог build/widgets и будет включен в JAR/WAR артефакт проекта.

Создание компонента ColorButton GWT

В этом разделе мы создадим новый компонент ColorButton. Он наследуется напрямую от компонента JmixButton.

Кастомные компоненты UI, (то есть компоненты, унаследованные напрямую от компонентов Vaadin) должны быть размещены в подпакете widgets, например, com.company.sample.widgets. Клиентские компоненты (коннекторы и виджеты), а также классы, используемые для связи на и стороне сервера, и клиента, такие как RPC и State, должны быть помещены в подпакет widgets.client, например com.company.sample.widgets.client. Подробнее об интеграции client-server можно прочитать в документации Vaadin.

Создание класса состояния компонента

Создайте ColorButtonState.java в пакете widgets.client.

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

ColorButtonState.java
public class ColorButtonState extends JmixButtonState {

    public String color = "";
}

Создание класса компонента Vaadin

ColorButton является классом компонента Vaadin. Он определяет API для серверного кода, методы доступа, слушатели событий и подключение источников данных. Прикладные разработчики используют в своем коде методы этого класса.

Создайте ColorButton.java в пакете widgets:

ColorButton.java
public class ColorButton extends JmixButton {

    @Override
    protected ColorButtonState getState() {
        return (ColorButtonState) super.getState();
    }

    @Override
    protected ColorButtonState getState(boolean markAsDirty) {
        return (ColorButtonState) super.getState(markAsDirty);
    }

    public String getColor() {
        return getState(false).color;
    }

    public void setColor(String color) {
        if (!Objects.equals(getState(false).color, color)) {
            getState().color = color;
        }
    }
}

Создание коннектора

Создайте ColorButtonConnector.java в пакете widgets.client.

Коннектор ColorButtonConnector связывает клиентский код с серверной частью.

ColorButtonConnector.java
@Connect(ColorButton.class) (1)
public class ColorButtonConnector extends JmixButtonConnector {

    @Override
    public ColorButtonState getState() {
        return (ColorButtonState) super.getState(); (2)
    }

    @Override
    public void onStateChanged(StateChangeEvent event) { (3)
        super.onStateChanged(event);

        if (event.hasPropertyChanged("color")) { (4)
            Style style = getWidget().getElement().getStyle();
            style.setBackgroundColor(getState().color);
            style.setBackgroundImage("none");
        }
    }
}
1 С помощью этой аннотации коннектор ColorButtonConnector помечен как имеющий аналог на стороне сервера. Значение аннотации – ColorButton, класс серверной реализации.
2 Возвращает объект ColorButtonState для этого коннектора.
3 Реагирует на изменение состояния сервера.
4 Обновляет стиль виджета, если значение на сервере изменилось.

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

Для демонстрации работы компонента создадим новый экран color-button-screen.

Откройте контроллер экрана ColorButtonScreen.java и добавьте код размещения компонента на экране:

ColorButtonScreen.java
@UiController("sample_ColorButtonScreen")
@UiDescriptor("color-button-screen.xml")
public class ColorButtonScreen extends Screen {
    @Subscribe
    protected void onInit(InitEvent event) {
        ColorButton button = new ColorButton(); (1)
        button.setCaption("Button");
        button.setColor("#AFEEEE");
        getWindow().unwrap(Layout.class).addComponent(button); (2)
    }
}
1 Инициализирует экземпляр компонента ColorButton.
2 Получает ссылку на контейнер Vaadin с помощью метода unwrap() и добавляет в него новый компонент.

На рисунке ниже показана завершенная структура проекта:

project structure

Запустите приложение и посмотрите результат:

color button