Подтвердить что ты не робот

JavaPX TabPane - один контроллер для каждой вкладки

Я новичок в Fx. У меня есть TabPanel с 10 вкладками. Каждая вкладка имеет множество элементов управления (диаграммы, кнопки и т.д.), И я хочу назначить контроллер для каждой вкладки. SceneBuilder позволяет мне назначать контроллер для всего представления, я имею в виду, что только верхняя панель (корневая) имеет параметр "Контроллер-класс", поэтому мне нужно написать код для всех вкладок в одном классе, и это, как влекут за собой очень большой класс, который трудно понять и сохранить. Возможно, решение очень простое, но, как я уже сказал, у меня очень мало опыта работы с FX, и я не смог найти что-то подобное в Интернете.

Любая идея? Спасибо.

4b9b3361

Ответ 1

Один из подходов состоит в том, чтобы инкапсулировать каждую вашу вкладку в отдельный файл FXML с собственным классом контроллера.

Затем в вашем файле FXML для основного элемента управления вкладкой вы можете сделать что-то вроде этого:

<TabPane >
    <tabs>
        <Tab text="Untitled Tab 1">
            <content>
                <fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/>
            </content>
        </Tab>
        <Tab text="Untitled Tab 2">
            <content>
                <fx:include fx:id="barTabPage" source="barTabPage.fxml"/>
            </content>
        </Tab>
    </tabs>
</TabPane>

Обратите внимание, что вместо непосредственного встраивания содержимого я использую директиву fx:include, которая сообщает FXMLLoader загрузить файл FXML, на который ссылаются. Отдельные файлы FXML, используемые для содержимого страницы, будут иметь свой собственный контроллер, чтобы логика была прекрасно разделена.

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

public class MainController {
    // Inject tab content.
    @FXML private FooTabPage fooTabPage;
    // Inject controller
    @FXML private FooTabController fooTabPageController;

    // Inject tab content.
    @FXML private BarTabPage barTabPage;
    // Inject controller
    @FXML private BarTabController barTabPageController;
}

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

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

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