Интеграция в Jmix UI

После создания клиентской и серверной частей компонента его можно использовать в экранах путем создания экземпляра его Java-класса и добавления в родительский компонент.

Обычно содержимое экрана определяется в XML-дескрипторе. Этот раздел описывает, как предоставить возможность использовать новый компонент в XML и в визуальном дизайнере Studio так же, как стандартные компоненты Jmix UI.

Поддержка в XML-дескрипторах

Ниже приведен пример реализации поддержки XML для компонента Slider, созданного в разделе предыдущем.

  1. Создайте файл app-ui-components.xsd и определите XML-разметку для компонента:

    <xs:schema xmlns="http://company.com/schema/app-ui-components"
               elementFormDefault="qualified"
               targetNamespace="http://company.com/schema/app-ui-components"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:layout="http://jmix.io/schema/flowui/layout">
    
        <xs:element name="slider">
            <xs:complexType>
                <xs:complexContent>
                    <xs:extension base="layout:baseComponent">
                        <xs:attribute name="min" type="xs:integer"/>
                        <xs:attribute name="max" type="xs:integer"/>
    
                        <xs:attributeGroup ref="layout:hasSize"/>
                    </xs:extension>
                </xs:complexContent>
            </xs:complexType>
        </xs:element>
    
    </xs:schema>
  2. Создайте загрузчик компонента, который необходим для инициализации компонента при его использовании в XML-описателях экрана.

    import io.jmix.flowui.xml.layout.loader.AbstractComponentLoader;
    
    public class SliderLoader extends AbstractComponentLoader<Slider> {
    
        @Override
        protected Slider createComponent() {
            return factory.create(Slider.class);
        }
    
        @Override
        public void loadComponent() {
            loadInteger(element, "min", resultComponent::setMin); (1)
            loadInteger(element, "max", resultComponent::setMax);
    
            componentLoader().loadSizeAttributes(resultComponent, element); (2)
        }
    }
    1 Базовый класс предоставляет вспомогательные методы для загрузки значений атрибутов.
    2 Метод componentLoader() возвращает экземпляр бина ComponentLoaderSupport, который предоставляет методы для загрузки общих атрибутов.
  3. Чтобы зарегистрировать компонент и его загрузчик в фреймворке, необходимо создать класс конфигурации Spring используя аннотацию @Configuration:

    @Configuration
    public class ComponentRegistrationConfiguration {
    
        @Bean
        public ComponentRegistration slider() {
            return ComponentRegistrationBuilder.create(Slider.class)
                    .withComponentLoader("slider", SliderLoader.class)
                    .build();
        }
    
    }

После этого компонент Slider может быть определен в дескрипторе экрана:

<view xmlns="http://jmix.io/schema/flowui/view"
      xmlns:app="http://company.com/schema/app-ui-components"> (1)
    <layout>
        <app:slider id="slider"
                    width="20em"
                    min="10" max="100"/> (2)
    </layout>
</view>
1 Пространство имен задается с тем же значением, что и в атрибутах xmlns и targetNamespace XSD компонента.
2 Элемент slider добавляется с префиксом пространства имен.

Поддержка в Studio

Чтобы Studio поддерживала новый компонент, необходимо создать интерфейс, аннотированный @StudioUiKit, и метод, аннотированный @StudioComponent:

import io.jmix.flowui.kit.meta.StudioComponent;
import io.jmix.flowui.kit.meta.StudioProperty;
import io.jmix.flowui.kit.meta.StudioPropertyType;
import io.jmix.flowui.kit.meta.StudioUiKit;

@StudioUiKit
public interface StudioComponents {

    @StudioComponent(
            name = "Slider",
            classFqn = "com.company.onboarding.component.Slider",
            category = "Components",
            xmlElement = "slider",
            xmlns = "http://company.com/schema/app-ui-components",
            xmlnsAlias = "app",
            properties = {
                    /* Common attributes */
                    @StudioProperty(xmlAttribute = "id", type = StudioPropertyType.COMPONENT_ID),
                    @StudioProperty(xmlAttribute = "alignSelf", type = StudioPropertyType.ENUMERATION,
                            classFqn = "com.vaadin.flow.component.orderedlayout.FlexComponent$Alignment",
                            defaultValue = "AUTO",
                            options = {"START", "END", "CENTER", "STRETCH", "BASELINE", "AUTO"}),
                    @StudioProperty(xmlAttribute = "css", type = StudioPropertyType.STRING),
                    @StudioProperty(xmlAttribute = "colspan", type = StudioPropertyType.INTEGER),
                    @StudioProperty(xmlAttribute = "visible", type = StudioPropertyType.BOOLEAN,
                            defaultValue = "true"),

                    /* Size attributes */
                    @StudioProperty(xmlAttribute = "height", type = StudioPropertyType.SIZE),
                    @StudioProperty(xmlAttribute = "width", type = StudioPropertyType.SIZE),
                    @StudioProperty(xmlAttribute = "maxHeight", type = StudioPropertyType.SIZE),
                    @StudioProperty(xmlAttribute = "maxWidth", type = StudioPropertyType.SIZE),
                    @StudioProperty(xmlAttribute = "minHeight", type = StudioPropertyType.SIZE),
                    @StudioProperty(xmlAttribute = "minWidth", type = StudioPropertyType.SIZE),

                    /* Slider attributes */
                    @StudioProperty(xmlAttribute = "min", type = StudioPropertyType.INTEGER,
                            defaultValue = "0"),
                    @StudioProperty(xmlAttribute = "max", type = StudioPropertyType.INTEGER,
                            defaultValue = "100")
            }
    )
    void slider();
}

После этого Studio отобразит новый компонент в палитре Add Component:

add component menu

И покажет доступные свойства компонента в инспекторе:

studio support