JavaFX TabPane - un contrôleur pour chaque onglet

Je suis nouveau sur Fx. J'ai un TabPanel avec 10 onglets. Chaque Onglet a de nombreux contrôles (graphiques, boutons, etc.), et ce que je veux est d'attribuer un contrôleur pour chaque onglet. Le SceneBuilder me permet seulement d'assigner un contrôleur pour l'ensemble de la vue, je veux dire, seul le panneau supérieur (la racine) a l'option "Controller class", donc je dois écrire le code pour tous les onglets dans une classe et cela entraîne une très grande classe et difficile à comprendre et à maintenir. Peut être que la solution est très simple, mais comme je le dis, j'ai très peu d'expérience avec FX et je n'ai pas été en mesure de trouver quelque chose de similaire sur le web.

Une idée? Merci.

26
demandé sur roneypc 2013-11-10 16:49:07

1 réponses

Une approche consiste à encapsuler chacune de vos pages d'onglets dans un fichier FXML séparé avec sa propre classe de contrôleur associée.

Ensuite, dans votre fichier FXML pour le contrôle de l'onglet principal, vous pouvez faire quelque chose comme ceci:

<TabPane fx:controller="com.foo.MainController">
    <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>

Notez qu'au lieu d'intégrer directement le contenu, j'utilise la directive fx:include qui indique au FXMLLoader de charger le fichier FXML référencé. Les fichiers FXML individuels utilisés pour le contenu de la page auront tous leur propre contrôleur de sorte que le la logique est bien séparée.

Si vous avez besoin d'interagir avec les sous-pages ou les sous-contrôleurs du contrôleur principal, vous pouvez les référencer comme vous le faites avec n'importe quel autre contrôle FXML pour les injecter.

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;
}

Si vous avez un grand nombre de pages (chacune avec un grand nombre de ses propres contrôles), une autre approche consiste à laisser chaque onglet vide, et une fois la vue principale chargée, chargez la page correspondante dans votre contrôle.

Vous devez écouter les changements d'onglet pour changez le contenu et ajoutez le code approprié pour charger / décharger les vues qui sont utilisées pour le contenu des pages d'onglet.

Je recommande de commencer par la première approche et le refactoring pour utiliser la deuxième approche si vous découvrez des problèmes de performance.

68
répondu Benjamin Gale 2018-05-08 12:27:30