Scénario
Je crée une interface utilisateur graphique où plusieurs vues font référence au même objet de modèle.
A quoi je suis habitué
Dans Swing, si je veux que toutes les vues fassent référence au même modèle, je passe le modèle au constructeur.
Ce que je fais actuellement
En JavaFX, je passe du modèle à une méthode de définition dans les vues/contrôleurs (barres de menu, volets divisés, onglets, ...), après le chargement de chaque vue/contrôleur. Je trouve cela très collant et encombrant. De plus, je constate que cela ne fonctionnera pas car, dans certaines situations, le modèle doit déjà exister dans un contrôleur avant que certains des widgets de contrôleur ne soient initialisés.
Alternatives peu recommandables
(Remarque: je fais référence à ces questions de stackoverflow:
Passer des paramètres à un contrôleur lors du chargement d'un FXML )
Injection de dépendance
Enregistrement de l'objet de modèle en tant que variable statique publique
Passage des paramètres de l'appelant au contrôleur
Je veux que chaque contrôleur se charge dans son constructeur et que chaque contrôleur personnalisé soit automatiquement injecté dans son contrôleur parent. Par exemple, l'onglet de vue d'ensemble de la carte se charge comme suit:
public CardOverviewTab() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("card_overview_tab.fxml"));
fxmlLoader.setRoot(content);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (Exception e) {
e.printStackTrace();
}
}
Et le contrôleur SingleGameSetup a l'onglet de vue d'ensemble de la carte automatiquement injecté dans une variable:
public class SingleGameSetupController extends AnchorPane {
@FXML private CardOverviewTab cardOverviewTab;
// Rest of the class
}
Et la partie du fxml contenant l'onglet Vue d'ensemble de la carte se présente comme suit:
<CardOverviewTab fx:id="cardOverviewTab" />
De cette façon, je n'ai pas à m'inquiéter du chargement manuel d'un contrôleur, mais j'ai toujours le problème de la configuration du modèle.
Définir un contrôleur sur le FXMLLoader
Bus d'événement
Singleton
Ce que je cherche
Existe-t-il un moyen de faire passer l'objet de modèle de manière moins encombrante? Je cherche un moyen aussi simple que de transmettre le modèle à un constructeur, mais je ne souhaite pas traiter le chargement manuel des contrôleurs via FXMLLoader, ni configurer le modèle après le chargement des contrôleurs. Avoir un cours pour récupérer le modèle est peut-être la meilleure option, mais je demande juste au cas où il y aurait un meilleur moyen.
J'ai étudié ce problème et j'ai constaté que l'injection de dépendance avec un singleton (pour le modèle) est ma conception optimale. J'ai appris qu'avoir une méthode de définition du modèle dans chacun de mes contrôleurs est une forme d'injection de dépendance, tout comme le fait de faire passer le modèle par le constructeur. Spring et Guice sont des cadres pour aider cela.
J'ai essayé d'utiliser Spring comme indiqué ci-dessous: http://www.zenjava.com/2011/10/23/better-controller-injection/ mais j'ai rencontré le problème lorsque la classe de configuration a essayé de charger un contrôleur, il n'a pas été possible de charger les contrôleurs membres. Ce n’était peut-être pas un numéro du printemps, mais j’ai pensé que je ne me souciais pas assez de passer le temps de le faire fonctionner. De plus, il aurait fallu que je consulte tous mes fichiers de contrôleur et modifie la manière dont ils ont été créés.
Après avoir fait des recherches et lu beaucoup, j'ai trouvé que cet article exprime le mieux ce que j'aimerais pouvoir faire: https://forums.Oracle.com/thread/2301217?tstart=0 . Étant donné que l'article fait référence aux améliorations suggérées, ces améliorations n'existent pas encore dans JavaFX. Mais quand ils le feront, je les appliquerai. Juste à titre d'exemple, être capable d'injecter un modèle via le fxml:
<usevar name="model" type="com.mycom.myapp.ModelObject"/>
DataFX Framework dispose d'une nouvelle API appelée DataFX-Flow. Avec cette API, vous pouvez simplement injecter des objets dans un contrôleur de vue. Les autres étendues Afterburner.fx sont prises en charge ici. Vous pouvez trouver un exemple ici: http://www.guigarage.com/2013/12/datafx-controller-framework-preview/