Аннотация @ViewComponent с параметром не работает для таблиц в tabSheet

И снова здравствуйте!
Версия 2.1.2. Столкнулся с необходимостью скрывать таблицу tab в элементе tabSheet в зависимости от условий (если конкретнее, от параметра, переданного в экран при открытии, но это не суть).

Инжектировал в экран следующий компонент:

    @ViewComponent("tabSheet1.tab3")
    private Tab tabSheet1Tab3;

Как можно догадаться, tabSheet имеет id=tabSheet1, а таблица под номером 3 имеет id=tab3 в xml-дескрипторе.

В методе прописал следующее:

@Subscribe
    public void onBeforeShow(final BeforeShowEvent event) {
        if (mode.equals("new")) {
            tabSheet1Tab3.setVisible(false);
        }
    }

там ещё много чего в методе, но это не нужно.

В итоге получаем:

NullPointerException: Cannot invoke "com.vaadin.flow.component.tabs.Tab.setVisible(boolean)" because "this.tabSheet1Tab3" is null

Удалось обойти эту ошибку и добиться желаемого, если добавить в контроллер:

    @ViewComponent
    private JmixTabSheet tabSheet1;

и в метод beforeShow:

Tab tab3 = tabSheet1.getTabAt(2);
            tab3.setVisible(false);

Я где-то видел что можно создавать какие-то “тикеты”, чтобы их поправили в последующих патчах, если эта тема подходит под это, скиньте гайд пожалуйста.
Ну или если я что-то не так понял, то поправьте))

Доюрый день!

Спасибо что сообщаете об ошибках фреймворка! Данную багу починили как раз в 2.1.2 версии, см. DataGrid columns and TabSheet tabs are not injected into controller · Issue #2508 · jmix-framework/jmix · GitHub

На тестовом проекте 2.1.2 версии Tab инжектируется без проблем. Попробуйте удалить папку build, обновить gradle зависимости. Если не поможет, приложите, пожалуйста, код XML и View контроллера.

Здравствуйте! Удалил все “оранжевые” папки из проекта: .gradle, .jmix, build, generated (путь frontend/), dev-bundle (путь src/main/). Дополнительно хлопнул папку .gradle в C:\Пользователи\{user} и переустановил nodejs.

Не помогло. Ошибка та же.

Попутно обнаружилось, что в nexus.jmix.io отсутствует npm-зависимость ace-builds$1.18.0, пришлось ставить её вручную, чтобы приложение запустилось вновь. Поиском в нексусе я нашёл только версию 1.19.0.

Ниже код дескриптора (не весь, только tabSheet) и часть кода контроллера.

xml-дескриптор
<tabSheet id="tabSheet1"
                      classNames="suggestion-create-read-view-tab-sheet"
                      width="55%"
                      themeNames="equal-width-tabs">
                <tab id="tab1" label="Авторы">
                    <vbox id="form2"
                          width="100%"
                          classNames="suggestion-create-read-view-form2">
                        <hbox id="buttonsAuthorsPanel"
                              classNames="buttons-authors-panel"
                              justifyContent="CENTER"
                              width="100%">
                            <button id="addAuthorButton"
                                    text="msg://addAuthorButton.text"
                                    themeNames="primary, success"
                                    icon="PLUS"
                                    classNames="suggestion-create-read-view-add-author-button"/>
                            <button id="editAuthorButton"
                                    text="msg://editAuthorButton.text"
                                    themeNames="primary"
                                    icon="PENCIL"/>
                            <button action="authorsDataGrid.remove"
                                    themeNames="primary"/>
                        </hbox>
                        <dataGrid id="authorsDataGrid"
                                  dataContainer="authorsDc"
                                  classNames="suggestion-create-read-view-authors-dc-on-suggestion"
                                  themeNames="wrap-cell-content, compact, column-borders"
                                  maxHeight="300px">
                            <columns sortable="false">
                                <column property="fullName"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="jobTitle"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="departmentNumber"
                                        textAlign="CENTER"
                                        flexGrow="3"/>
                                <column property="phoneNumber"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="email"
                                        textAlign="CENTER"
                                        flexGrow="7"/>
                                <column property="participationPercent"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                            </columns>
                            <actions>
                                <action id="remove" type="list_remove"/>
                            </actions>
                        </dataGrid>
                    </vbox>
                </tab>
                <tab id="tab2" label="Файлы">
                    <vbox id="filesBox"
                          width="100%">
                        <hbox id="fileButtonsPanel"
                              width="100%"
                              justifyContent="CENTER">
                            <button id="addFileButton"
                                    text="msg://authorSuggestionDetailView.addFileButton"
                                    themeNames="primary, success"
                                    icon="PLUS"
                                    classNames="author-suggestion-detail-view-add-file-button"/>
                            <button id="deleteFileButton"
                                    text="msg://authorSuggestionDetailView.deleteFileButton"
                                    themeNames="primary, error"
                                    icon="TRASH"
                                    classNames="author-suggestion-detail-view-delete-file-button"/>
                            <button id="downloadButton"
                                    text="msg://authorSuggestionDetailView.downloadFileButton"
                                    themeNames="primary"
                                    icon="DOWNLOAD_ALT"
                                    classNames="author-suggestion-detail-view-download-file-button"/>
                        </hbox>
                        <dataGrid width="100%"
                                  id="filesDataGrid"
                                  dataContainer="filesDc"
                                  themeNames="compact, wrap-cell-content, column-borders"
                                  classNames="author-suggestion-detail-view-files-dc">
                            <columns sortable="false">
                                <column property="fileName"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="description"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="adder"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="stage"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="date"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                            </columns>
                        </dataGrid>
                    </vbox>
                </tab>
                <tab id="tab3" label="История">
                    <vbox id="historyBox"
                          width="100%">
                        <dataGrid width="100%"
                                  id="historyDataGrid"
                                  dataContainer="historyDc"
                                  themeNames="compact, wrap-cell-content, column-borders"
                                  classNames="suggestion-create-read-view-history-dc">
                            <actions/>
                            <columns sortable="false">
                                <column property="date"
                                        textAlign="CENTER"/>
                                <column property="changerFullName"
                                        textAlign="CENTER"/>
                                <column property="changerJobTitle"
                                        textAlign="CENTER"/>
                                <column property="changerDepartmentNumber"
                                        textAlign="CENTER"
                                        flexGrow="8"/>
                                <column property="recommendation"
                                        textAlign="CENTER"
                                        flexGrow="6"/>
                                <column property="conclusion"
                                        textAlign="CENTER"/>
                                <column property="stage"
                                        textAlign="CENTER"/>
                            </columns>
                        </dataGrid>
                    </vbox>
                </tab>
            </tabSheet>
Спойлер
@Route(value = "author-suggestion/:id", layout = MainView.class)
@ViewController("AuthorSuggestion.detail")
@ViewDescriptor("author-suggestion-detail-view.xml")
@EditedEntityContainer("suggestionDc")
public class AuthorSuggestionDetailView extends StandardDetailView<Suggestion> {
    @ViewComponent
    private JmixTabSheet tabSheet1;
    @ViewComponent("tabSheet1.tab3")
    private Tab tabSheet1Tab3;

    @Subscribe
    public void onBeforeShow(final BeforeShowEvent event) {
        
        if (mode.equals("new")) {
            Tab tab3 = tabSheet1.getTabAt(2);
            tab3.setVisible(false);
            //tabSheet1Tab3.setVisible(false);
        }

    }

}

Соответственно работает как показано сейчас и не работает когда снимаю коммент с tabSheet1Tab3 и закоменчиваю две другие строки.

Пока не удаётся воспроизвести проблему. Ваша XML разметка тоже не даёт ошибок.

Ещё один вариант проверить что фикс присутствует в исходниках это проверить класс компонента io.jmix.flowui.component.tabsheet.JmixTabSheet. Он должен реализовать интерфейс HasSubPart.
Если фикс в исходниках присутствует, то попробуйте воспроизвести свой кейс на новосозданном проекте и приложить его сюда.

Насколько мне известно репозитрий https://nexus.jmix.io/repository/public не хранит в себе npm зависимости. И поиск в нём находит только webjars с версией 1.1.9.jmix.*. Не подскажите как осуществлялся поиск? может искали в другом репозитории?

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

xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      title="msg://tabsheetUserDetailView.title"
      focusComponent="form">
    <data>
        <instance id="userDc"
                  class="com.company.testtabsheet.entity.User">
            <fetchPlan extends="_base"/>
            <loader/>
        </instance>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <actions>
        <action id="saveAction" type="detail_saveClose"/>
        <action id="closeAction" type="detail_close"/>
    </actions>
    <layout>
        <formLayout id="form" dataContainer="userDc">
            <tabSheet id="tabSheet1">
                <tab id="tab1" label="tab1">
                    <vbox>
                        <textField id="textField1" label="odin"/>
                    </vbox>
                </tab>
                <tab id="tab2" label="tab2">
                    <vbox>
                        <textField id="textField2" label="dva"/>
                    </vbox>
                </tab>
            </tabSheet>
        </formLayout>
        <hbox id="detailActions">
            <button id="saveAndCloseBtn" action="saveAction"/>
            <button id="closeBtn" action="closeAction"/>
        </hbox>
    </layout>
</view>

Контроллер
package com.company.testtabsheet.view.user;

import com.company.testtabsheet.entity.User;

import com.company.testtabsheet.view.main.MainView;

import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.router.Route;
import io.jmix.flowui.view.*;

@Route(value = "tabsheet-users/:id", layout = MainView.class)
@ViewController("TabsheetUser.detail")
@ViewDescriptor("tabsheet-user-detail-view.xml")
@EditedEntityContainer("userDc")
public class TabsheetUserDetailView extends StandardDetailView<User> {
    @ViewComponent("tabSheet1.tab2")
    private Tab tabSheet1Tab2;

    @Subscribe
    public void onBeforeShow(final BeforeShowEvent event) {

        tabSheet1Tab2.setVisible(false);

    }

}
NullPointerException: Cannot invoke "com.vaadin.flow.component.tabs.Tab.setVisible(boolean)" because "this.tabSheet1Tab2" is null

В пакетах нашёл этот класс, интерфейс HasSubPart есть.

Судя по второму сообщению, если на нексусе нет npm-зависимостей, тогда я не знаю откуда их проект берет, потому-что везде в настройках я указал один репозиторий.
А раз он их где-то берёт, значит они где-то есть и они не удалились ни в одном из случаев в моём первом сообщении. Соответственно и ошибка не поправится конкретно в моём случае.

Как вариант конечно держать полный спектр зависимостей на Вашем нексусе, но если они все равно остались где-то в cache, то и это не поможет. Без интернета конечно пока не получается стабильно поддерживать проект и получать все обновления.

Дополню, на проекте, собранном с интернетом на другом ПК всё работает.

Добрый день!

Удалось воспроизвести ошибку с NPE, когда TabSheet находится в FormLayout-е.

А на этом прокете такая же вёртска у View?

npm-зависимости выкачиваются из репозитория по умолчанию настроенного в npm. Jmix никаких дополнительных настроек не делает. Узнать какой npm репозиторий используется можно командой:

npm config get registry

Если нет доступа к npm репозиторию то, нужно хранить зависимости у себя. В документации есть инструкция по поднятию своего нексуса и загрузки туда npm зависимостей:

Здравствуйте!

Наверное стоило скидывать сразу полный код xml, хотя сам tabSheet находится вне formLayout.

Спойлер
<layout>
    <vbox>
        <hbox>
            <formLayout id="suggestionFormLayout"
                        dataContainer="suggestionDc"
                        labelsPosition="ASIDE"
                        width="45%"
                        classNames="suggestion-detail-view-form-layout">
                <formItem id="formItemAuthorSolutionButtonPanel"
                          colspan="2">
                    <hbox id="authorSolutionButtonPanel"
                          justifyContent="END"
                          width="100%">
                        <button id="sendToApproveButton"
                                themeNames="primary, contrast, small"
                                icon="AIRPLANE"
                                text="msg://sendToApproveButton.text"/>
                        <button id="exportToWordButton"
                                themeNames="primary, small"
                                text="msg://exportToWordButton.text"
                                icon="DOWNLOAD_ALT"/>
                    </hbox>
                </formItem>
                <formItem id="formItemBossCommentField"
                          colspan="2">
                    <textArea id="bossCommentField"
                              property="bossComment"
                              readOnly="true"/>
                </formItem>
                <formItem id="formItemCuratorCommentField"
                          colspan="2">
                    <textArea id="curatorCommentField"
                              property="curatorComment"
                              readOnly="true"/>
                </formItem>
                <formItem id="formItemIsMySelfImplementation"
                          colspan="2">
                    <checkbox id="isMyselfImplementationField"
                              property="isMyselfImplementation"/>
                </formItem>
                <formItem id="formItemIsRequiresToChangeDocumentationField"
                          colspan="2">
                    <checkbox id="isRequiresToChangeDocumentationField"
                              property="isRequiresToChangeDocumentation"/>
                </formItem>
                <formItem id="formItemCuratorEmployeeComboBox"
                          colspan="2">
                    <entityComboBox id="curatorEmployeeField"
                                    property="curatorEmployee"
                                    dataContainer="suggestionDc"
                                    itemsContainer="curatorEmployeeDc">
                    </entityComboBox>
                </formItem>
                <formItem id="formItemNumberField"
                          colspan="2">
                    <textField id="numberField"
                               property="number"
                               maxWidth="200px"
                               readOnly="true"/>
                </formItem>
                <formItem id="formItemCuratorTextField"
                          colspan="2">
                    <textField id="curatorTextField"
                               property="curatorString"
                               readOnly="true"/>
                </formItem>
                <formItem id="formItemBossTextField"
                          colspan="2">
                    <textField id="bossTextField"
                               property="boss"
                               readOnly="true"/>
                </formItem>
                <formItem id="formItemProblemField"
                          colspan="2">
                    <textArea id="problemField"
                              property="problem"/>
                </formItem>
                <formItem id="formItemSolutionField"
                          colspan="2">
                    <textArea id="solutionField"
                              property="solution"/>
                </formItem>
                <formItem id="formItemEffectField"
                          colspan="2">
                    <entityComboBox id="effectField"
                                    property="effect"
                                    itemsContainer="effectsDc"
                                    required="true"
                                    requiredMessage="msg://effectField.requiredMessage"/>
                </formItem>
                <formItem id="formItemImprovementEffectField"
                          colspan="2">
                    <textArea id="improvementEffectField"
                              property="improvementEffect"/>
                </formItem>
                <formItem id="formItemKeywordsField"
                          colspan="2">
                    <textField id="keywordsField"
                               property="keywords"/>
                </formItem>
                <formItem id="formItemStatusField"
                          colspan="2">
                    <comboBox id="statusField"
                              property="status"
                              readOnly="true"/>
                </formItem>
                <formItem id="formItemCreationDateField"
                          colspan="2">
                    <datePicker id="creationDateField"
                                property="creationDate"
                                maxWidth="200px"
                                readOnly="true"/>
                </formItem>
            </formLayout>
            <tabSheet id="tabSheet1"
                      width="55%"
                      themeNames="equal-width-tabs">
                <tab id="authorsTab" label="2B>@K">
                    <vbox id="authorsTabVBox"
                          width="100%">
                        <hbox id="authorsButtonPanel"
                              justifyContent="CENTER"
                              width="100%">
                            <button id="addAuthorButton"
                                    text="msg://addAuthorButton.text"
                                    themeNames="primary, success, small"
                                    icon="PLUS"/>
                            <button id="editAuthorButton"
                                    text="msg://editAuthorButton.text"
                                    themeNames="primary, small"
                                    icon="PENCIL"/>
                            <button action="authorsDataGrid.remove"
                                    themeNames="primary, small"/>
                        </hbox>
                        <dataGrid id="authorsDataGrid"
                                  dataContainer="authorsDc"
                                  classNames="suggestion-detail-view-authors-data-grid"
                                  themeNames="wrap-cell-content, compact, column-borders"
                                  maxHeight="300px">
                            <columns sortable="false">
                                <column property="fullName"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="jobTitle"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="departmentNumber"
                                        textAlign="CENTER"
                                        flexGrow="3"/>
                                <column property="phoneNumber"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="email"
                                        textAlign="CENTER"
                                        flexGrow="7"/>
                                <column property="participationPercent"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                            </columns>
                            <actions>
                                <action id="remove" type="list_remove"/>
                            </actions>
                        </dataGrid>
                    </vbox>
                </tab>
                <tab id="filesTab" label="$09;K">
                    <vbox id="filesTabVBox"
                          width="100%">
                        <hbox id="filesButtonsPanel"
                              width="100%"
                              justifyContent="CENTER">
                            <button id="addFileButton"
                                    text="msg://authorSuggestionDetailView.addFileButton"
                                    themeNames="primary, success, small"
                                    icon="PLUS"/>
                            <button id="deleteFileButton"
                                    text="msg://authorSuggestionDetailView.deleteFileButton"
                                    themeNames="primary, error, small"
                                    icon="TRASH"/>
                            <button id="downloadButton"
                                    text="msg://authorSuggestionDetailView.downloadFileButton"
                                    themeNames="primary, small"
                                    icon="DOWNLOAD_ALT"/>
                        </hbox>
                        <dataGrid width="100%"
                                  id="filesDataGrid"
                                  dataContainer="filesDc"
                                  themeNames="compact, wrap-cell-content, column-borders"
                                  classNames="suggestion-detail-view-files-data-grid">
                            <columns sortable="false">
                                <column property="fileName"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="description"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="adder"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="stage"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                                <column property="date"
                                        textAlign="CENTER"
                                        flexGrow="1"/>
                            </columns>
                        </dataGrid>
                    </vbox>
                </tab>
                <tab id="historyTab" label="AB>@8O">
                    <vbox id="historyTabVBox"
                          width="100%">
                        <dataGrid width="100%"
                                  id="historyDataGrid"
                                  dataContainer="historyDc"
                                  themeNames="compact, wrap-cell-content, column-borders"
                                  classNames="suggestion-detail-view-history-data-grid">
                            <actions/>
                            <columns sortable="false">
                                <column property="date"
                                        textAlign="CENTER"/>
                                <column property="changerFullName"
                                        textAlign="CENTER"/>
                                <column property="changerJobTitle"
                                        textAlign="CENTER"/>
                                <column property="changerDepartmentNumber"
                                        textAlign="CENTER"
                                        flexGrow="8"/>
                                <column property="recommendation"
                                        textAlign="CENTER"
                                        flexGrow="6"/>
                                <column property="conclusion"
                                        textAlign="CENTER"/>
                                <column property="stage"
                                        textAlign="CENTER"/>
                            </columns>
                        </dataGrid>
                    </vbox>
                </tab>
            </tabSheet>
        </hbox>
        <tabSheet id="expertAndReviewTabSheet"
                  width="100%">
            <tab id="ExpertsTab" label="-:A?5@B870 A>25B0 M:A?5@B>2">
                <vbox id="expertsTabVBox"
                      width="100%">
                    <dataGrid width="100%"
                              id="suggestionExpertsDataGrid"
                              dataContainer="expertsDc"
                              themeNames="compact, wrap-cell-content, column-borders"
                              classNames="suggestion-detail-view-experts-data-grid"
                              allRowsVisible="true">
                        <actions/>
                        <columns sortable="false">
                            <column property="receivedDate"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="fullName"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="departmentNumber"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="jobTitle"
                                    textAlign="CENTER"
                                    flexGrow="2"/>
                            <column property="resolution"
                                    textAlign="CENTER"
                                    flexGrow="4"/>
                            <column property="comment"
                                    textAlign="CENTER"
                                    flexGrow="4"/>
                            <column property="resolutionDate"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                        </columns>
                    </dataGrid>
                </vbox>
            </tab>
            <tab id="reviewersTab"
                 label=" 0AA<>B@5=85 2 ?>4@0745;5=8OE">
                <vbox id="reviewersTabVBox"
                      width="100%">
                    <dataGrid width="100%"
                              id="reviewersDataGrid"
                              dataContainer="reviewersDc"
                              themeNames="compact, wrap-cell-content, column-borders"
                              classNames="suggestion-detail-view-reviewers-data-grid"
                              allRowsVisible="true">
                        <actions/>
                        <columns resizable="false">
                            <column property="sendDate"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="senderFullName"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="request"
                                    textAlign="CENTER"
                                    flexGrow="4"/>
                            <column property="recipientFullName"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="departmentNumber"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                            <column property="recipientJobTitle"
                                    textAlign="CENTER"
                                    flexGrow="2"/>
                            <column property="resolution"
                                    textAlign="CENTER"
                                    flexGrow="4"/>
                            <column property="comment"
                                    textAlign="CENTER"
                                    flexGrow="4"/>
                            <column property="resolutionDate"
                                    textAlign="CENTER"
                                    flexGrow="1"/>
                        </columns>
                    </dataGrid>
                </vbox>
            </tab>
        </tabSheet>
    </vbox>
    <hbox id="detailActions">
        <button id="saveAndCloseBtn" action="saveAction" themeNames="primary, success"/>
        <button id="closeBtn" action="closeAction" themeNames="primary, error"/>
        <button id="discardButton" action="discardAction" themeNames="primary"/>
    </hbox>
</layout>

При таком способе получится воспроизвести ошибку?

Нет, там просто в blank view в layout поместил tabSheet, без ничего.

В конечном итоге так и пришлось сделать, полностью собственный nexus. Но, как я понимаю, зависимости для обновлений будут выходить несколько позже, чем их официальный релиз.

Ошибка теперь воспроизводится во всех случаях. Похоже она возникает когда TabSheet помещается в любой контейнер компонентов.

Спасибо за помощь в установлении ошибки! Создал задачу: Tab injection does not work when TabSheet is placed in component container · Issue #2868 · jmix-framework/jmix · GitHub

Промежуток может занимать от половины дня до суток после релиза.

и Вам спасибо за помощь)

А, ну это совсем не проблема.