Композитный компонент не отражается на экране

Добрый день.
Сделал компонент по инструкции: Composite Components :: Jmix Documentation
При открытии экрана в меню после лэйбла с пользователем должен отразится новый компонент, но там ничего нет:

скрин_1

В чём может быть проблема?

Используемые файлы:
Component Layout Descriptor

<composite xmlns="http://jmix.io/schema/ui/composite">
    <vbox id="dtwidget_rootBox"
               width="100%" visible="true" enable="true" height="100%">
        <label id="dtwidget_dtLbl" visible="true"/>
        <label id="dtwidget_regionLbl" visible="true" />
    </vbox>
</composite>

Component Implementation Class

public class DateTimeWidget
@CompositeDescriptor("dtwidget.xml")
public class DateTimeWidget
        extends CompositeComponent<VBoxLayout>
        implements CompositeWithCaption,
        CompositeWithHtmlCaption,
        CompositeWithHtmlDescription,
        CompositeWithIcon,
        CompositeWithContextHelp {

    public static final String NAME = "dtwidget";
    private Label<String> dtLbl;
    private Label<String> regionLbl;

    public DateTimeWidget() {
        addCreateListener(this::onCreate);
    }

    public Label<String> getDtLbl() {
        return dtLbl;
    }

    public void setDtLbl(Label<String> dtLbl) {
        this.dtLbl = dtLbl;
    }

    public Label<String> getRegionLbl() {
        return regionLbl;
    }

    public void setRegionLbl(Label<String> regionLbl) {
        this.regionLbl = regionLbl;
    }

    private void onCreate(CreateEvent createEvent) {
        dtLbl = getInnerComponent("dtwidget_dtLbl");
        regionLbl = getInnerComponent("dtwidget_regionLbl");
        
        dtLbl.setValue("dtLbl");
        regionLbl.setValue("regionLbl");
    }
}

Component Loader

public class DateTimeWidgetLoader  extends AbstractComponentLoader<DateTimeWidget> {

    @Override
    public void createComponent() {
        resultComponent = factory.create(DateTimeWidget.NAME);
        loadId(resultComponent, element);
    }

    @Override
    public void loadComponent() {
        assignFrame(resultComponent);
        assignXmlDescriptor(resultComponent, element);

        loadData(resultComponent, element);

        loadVisible(resultComponent, element);
        loadEditable(resultComponent, element);
        loadEnable(resultComponent, element);

        loadStyleName(resultComponent, element);

        loadHtmlSanitizerEnabled(resultComponent, element);

        loadCaption(resultComponent, element);
        loadIcon(resultComponent, element);
        loadDescription(resultComponent, element);
        loadContextHelp(resultComponent, element);

        loadHeight(resultComponent, element);
        loadWidth(resultComponent, element);
        loadAlign(resultComponent, element);
        loadResponsive(resultComponent, element);
        loadCss(resultComponent, element);
    }
}

Component Registration
Добавил в общую для приложения конфигурацию (бин с методом dtwidget())

@SpringBootApplication
public class AtsPszApplication {

    @Autowired
    private Environment environment;

    public static void main(String[] args) {
        SpringApplication.run(AtsPszApplication.class, args);
    }

    @Bean
    @Primary
    @ConfigurationProperties("main.datasource")
    DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("main.datasource.hikari")
    DataSource dataSource(DataSourceProperties dataSourceProperties) {
        return dataSourceProperties.initializeDataSourceBuilder().build();
    }

    @EventListener
    public void printApplicationUrl(ApplicationStartedEvent event) {
        LoggerFactory.getLogger(AtsPszApplication.class).info("Application started at "
                + "http://localhost:"
                + environment.getProperty("local.server.port")
                + Strings.nullToEmpty(environment.getProperty("server.servlet.context-path")));
    }
    @Bean
    public ComponentRegistration dtwidget() {
        return ComponentRegistrationBuilder.create(DateTimeWidget.NAME)
                .withComponentClass(DateTimeWidget.class)
                .withComponentLoaderClass(DateTimeWidgetLoader.class)
                .build();
    }
}

Component XSD

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns="http://com/ats/psz/ui/components/dtwidget/app-ui-component.xsd"
           attributeFormDefault="unqualified"
           elementFormDefault="qualified"
           targetNamespace="http://com/ats/psz/ui/components/dtwidget/app-ui-component.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:layout="http://jmix.io/schema/ui/layout">
    <xs:element name="dtwidget">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="layout:baseFieldComponent">
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
</xs:schema>

Using Composite Component

<window xmlns="http://jmix.io/schema/ui/window"
        caption="msg://caption"
        xmlns:app="http://com/ats/psz/ui/components/dtwidget/app-ui-component.xsd">
    <layout expand="workArea">
        <hbox id="header"
              expand="mainMenu"
              margin="false;true;false;true"
              stylename="jmix-app-menubar"
              spacing="true"
              width="100%">
            <image id="logoImage"
                   align="MIDDLE_CENTER"
                   scaleMode="SCALE_DOWN"
                   stylename="app-icon">
                <resource>
                    <theme path="branding/app-icon-menu.svg"/>
                </resource>
            </image>
            <menu id="mainMenu"
                  align="MIDDLE_LEFT"/>
            <userIndicator id="userIndicator"
                           align="MIDDLE_LEFT"/>
            <app:dtwidget id="dtwidget" align="MIDDLE_LEFT"/>
            <hbox id="mainButtonsBox"
                  align="MIDDLE_LEFT"
                  stylename="jmix-main-buttons">
                <newWindowButton id="newWindowButton"
                                 icon="TH_LARGE"
                                 description="msg://newWindowBtnDescription"/>
                <logoutButton id="logoutButton"
                              description="msg://logoutBtnDescription"
                              icon="SIGN_OUT"/>
            </hbox>
        </hbox>
        <workArea id="workArea"
                  stylename="jmix-workarea"
                  width="100%">
            <initialLayout margin="true"
                           spacing="true">
            </initialLayout>
        </workArea>
    </layout>
</window>

Добрый день.

у вас внутренний dtwidget_rootBox имеет ширину 100% (т.е. относительную). Т.к. для <hbox id="header"/> задан атрибут expand="mainMenu", то Ваш компонент просто “сплющивает”. Уберите width и height у dtwidget_rootBox и компонент должен начать отображаться.

Глеб

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

<composite xmlns="http://jmix.io/schema/ui/composite">
    <vbox id="dtwidget_rootBox">
        <label id="dtwidget_dtLbl"/>
        <label id="dtwidget_regionLbl"/>
    </vbox>
</composite>

после этого компонент всё равно не отражается в меню. Но если положить компонент, в hbox

<hbox>
      <app:dtwidget id="dtwidget" align="MIDDLE_LEFT"/>
</hbox>

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

скрин_2

Получается нужно сделать ещё один кастомный стиль отдельно для композитного компонента?

Моя ошибка, я забыл, что vbox по умолчанию имеет width = 100%, соответственно, чтобы Ваш компонент отображался, нужно явно указать ширину AUTO

<composite xmlns="http://jmix.io/schema/ui/composite">
    <vbox id="dtwidget_rootBox" width="AUTO">
        <label id="dtwidget_dtLbl"/>
        <label id="dtwidget_regionLbl"/>
    </vbox>
</composite>

Вам нужно написать стили для вашего компонента.

1 симпатия