3.5.17.3.1. Подключение аддона Vaadin

Рассмотрим пример использования компонента Stepper, доступного по адресу http://vaadin.com/addon/stepper. Данный компонент позволяет пошагово изменять значение текстового поля с помощью клавиатуры, колесика мыши и встроенных кнопок вверх/вниз.

Создайте новый проект в CUBA Studio и назовите его addon-demo.

Для подключения аддона Vaadin проект должен иметь модуль web-toolkit. Его удобно создать с помощью CUBA Studio: В главном меню нажмите CUBA > Advanced > Manage modules > Create 'web-toolkit' Module.

Затем, добавьте зависимости аддона:

  1. В build.gradle, для модуля web, добавьте зависимость от аддона, который содержит компонент:

    configure(webModule) {
        ...
        dependencies {
            ...
            compile("org.vaadin.addons:stepper:2.4.0")
        }
  2. В файле AppWidgetSet.gwt.xml модуля web-toolkit укажите, что виджетсет проекта наследуется от виджетсета аддона:

    <module>
        <inherits name="com.haulmont.cuba.web.widgets.WidgetSet" />
    
        <inherits name="org.vaadin.risto.stepper.StepperWidgetset" />
    
        <set-property name="user.agent" value="safari" />
    </module>

    Для более быстрой сборки виджетов на время разработки вы можете установить свойство user.agent. В данном примере набор виджетов будет собираться только для браузеров, основанных на WebKit: Chrome, Safari, и т.д.

Компонент из аддона Vaadin подключен. Далее мы покажем как использовать его в экранах проекта.

  • Создаем новую сущность Customer с двумя полями:

    • name типа String

    • score типа Integer

  • Сгенерируем для новой сущности стандартные экраны. В диалоге генерации стандартных экранов убедитесь что значение поля Module - Module: 'app-web_main' (это поле отображается только, если к проекту подключен модуль gui). Экраны, использующие компоненты Vaadin напрямую, должны располагаться в модуле web.

    На самом деле экран может располагаться и в модуле gui, но тогда код, работающий с Vaadin компонентом, должен быть вынесен в отдельный компаньон.

  • Далее добавим компонент stepper на экран.

    В XML-дескрипторе экрана редактирования customer-edit.xml заменим поле score компонентом hBox, который будет использоваться в качестве контейнера для Vaadin компонента.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd"
            caption="msg://editorCaption"
            focusComponent="form"
            messagesPack="com.company.demo.web.customer">
        <data>
            <instance id="customerDc"
                      class="com.company.demo.entity.Customer"
                      view="_local">
                <loader/>
            </instance>
        </data>
        <dialogMode height="600"
                    width="800"/>
        <layout expand="editActions" spacing="true">
            <form id="form" dataContainer="customerDc">
                <column width="250px">
                    <textField id="nameField" property="name"/>
                    <!-- A box that will be used as a container for a Vaadin component -->
                    <hbox id="scoreBox"
                          caption="msg://com.company.demo.entity/Customer.score"
                          height="100%"
                          width="100%"/>
                </column>
            </form>
            <hbox id="editActions" spacing="true">
                <button action="windowCommitAndClose"/>
                <button action="windowClose"/>
            </hbox>
        </layout>
    </window>

    В контроллер экрана редактирования CustomerEdit.java добавим следующий код:

    package com.company.demo.web.customer;
    
    import com.company.demo.entity.Customer;
    import com.haulmont.cuba.gui.components.HBoxLayout;
    import com.haulmont.cuba.gui.screen.*;
    import com.vaadin.ui.Layout;
    import org.vaadin.risto.stepper.IntStepper;
    
    import javax.inject.Inject;
    
    @UiController("demo_Customer.edit")
    @UiDescriptor("customer-edit.xml")
    @EditedEntityContainer("customerDc")
    @LoadDataBeforeShow
    public class CustomerEdit extends StandardEditor<Customer> {
        @Inject
        private HBoxLayout scoreBox;
    
        private IntStepper stepper = new IntStepper();
    
        @Subscribe
        protected void onInit(InitEvent event) {
            scoreBox.unwrap(Layout.class)
                    .addComponent(stepper);
    
            stepper.setSizeFull();
            stepper.addValueChangeListener(valueChangeEvent ->
                    getEditedEntity().setScore(valueChangeEvent.getValue()));
        }
    
        @Subscribe
        protected void onInitEntity(InitEntityEvent<Customer> event) {
            event.getEntity().setScore(0);
        }
    
        @Subscribe
        protected void onBeforeShow(BeforeShowEvent event) {
            stepper.setValue(getEditedEntity().getScore());
        }
    }

    Здесь в методе onInit() производится инициализация компонента, подключенного из аддона, затем, с помощью метода unwrap, извлекается ссылка на Vaadin-контейнер, и в этот контейнер добавляется наш новый компонент.

    Для связи компонента с данными, во-первых, в методе onBeforeShow() ему устанавливается текущее значение из редактируемого Customer, а во-вторых, добавляется слушатель на изменение значения, который обновляет соответствующий атрибут сущности при изменении значения пользователем.

  • Для адаптации внешнего вида компонента создадим в проекте расширение темы. Это удобно сделать с помощью CUBA Studio: В главном меню нажмите CUBA > Advanced > Manage themes > Create theme extension. Другой способ - использовать команду extend-theme в CUBA CLI. В списке тем для расширения выберем hover и нажмем кнопку Create. Затем откроем файл themes/hover/com.company.demo/hover-ext.scss модуля web, и добавим в него следующий код:

    /* Define your theme modifications inside next mixin */
    @mixin com_company_demo-hover-ext {
      /* Basic styles for stepper inner text box */
      .stepper input[type="text"] {
        @include box-defaults;
        @include valo-textfield-style;
    
        &:focus {
          @include valo-textfield-focus-style;
        }
      }
    }
  • Запускаем сервер приложения. Экран редактирования должен выглядеть следующим образом:

customer edit result