Создание GWT-компонента
Создание пользовательского набора виджетов
Фреймворк Jmix предоставляет готовый набор виджетов в артефакте jmix-ui-widgets-compiled
.
Для создания пользовательского набора виджетов в проекте необходимо:
-
Удалить зависимость
implementation 'io.jmix.ui:jmix-ui-widgets-compiled'
. -
Добавить зависимости к вашему
build.gradle
:implementation 'io.jmix.ui:jmix-ui-widgets' (1) widgets 'io.jmix.ui:jmix-ui-widgets'
1 Требуется только для разработки пользовательских клиентских компонентов. -
Добавьте задачу
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.
-
-
Добавьте свойство
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
отвечает за то, какие данные будут пересылаться между клиентом и сервером. В нем определяются публичные поля, которые будут автоматически сериализованы на сервере и десериализованы на клиенте.
public class ColorButtonState extends JmixButtonState {
public String color = "";
}
Создание класса компонента Vaadin
ColorButton
является классом компонента Vaadin. Он определяет API для серверного кода, методы доступа, слушатели событий и подключение источников данных. Прикладные разработчики используют в своем коде методы этого класса.
Создайте ColorButton.java
в пакете widgets
:
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
связывает клиентский код с серверной частью.
@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
и добавьте код размещения компонента на экране:
@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() и добавляет в него новый компонент. |
На рисунке ниже показана завершенная структура проекта:
Запустите приложение и посмотрите результат: