Approche recommandée
Cette réponse énumère les différents mécanismes permettant de passer des paramètres aux contrôleurs FXML.
Pour les petites applications, je recommande vivement de passer les paramètres directement de l'appelant au contrôleur - c'est simple, direct et ne nécessite pas de frameworks supplémentaires.
Pour les applications plus importantes et plus compliquées, il serait utile d'étudier la possibilité d'utiliser les services suivants Injection de dépendances o Bus événementiel dans votre application.
Passage des paramètres directement de l'appelant au contrôleur
Transmettez des données personnalisées à un contrôleur FXML en récupérant le contrôleur dans l'instance du chargeur FXML et en appelant une méthode sur le contrôleur pour l'initialiser avec les valeurs de données requises.
Quelque chose comme le code suivant :
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(loader.load())
);
CustomerDialogController controller = loader.getController();
controller.initData(customer);
stage.show();
return stage;
}
...
class CustomerDialogController {
@FXML private Label customerName;
void initialize() {}
void initData(Customer customer) {
customerName.setText(customer.getName());
}
}
Un nouveau FXMLLoader est construit comme indiqué dans l'exemple de code, à savoir new FXMLLoader(location)
. L'emplacement est une URL et vous pouvez générer une telle URL à partir d'une ressource FXML en :
new FXMLLoader(getClass().getResource("sample.fxml"));
Veillez à NE PAS utiliser une fonction de chargement statique sur le FXMLLoader, ou vous ne serez pas en mesure d'obtenir votre contrôleur à partir de votre instance de chargeur.
Les instances de FXMLLoader elles-mêmes ne savent jamais rien des objets du domaine. Vous ne passez pas directement les objets de domaine spécifiques à l'application dans le constructeur de FXMLLoader, mais vous le faites :
- Construit un FXMLLoader basé sur le balisage fxml à un emplacement spécifié.
- Obtenir un contrôleur à partir de l'instance FXMLLoader.
- Invoquez des méthodes sur le contrôleur récupéré pour lui fournir des références aux objets du domaine.
Ce blog (d'un autre auteur) propose une approche différente, mais similaire, exemple .
Configuration d'un contrôleur sur le FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = loader.load();
Vous pouvez construire un nouveau contrôleur dans le code, en passant tous les paramètres que vous voulez de votre appelant dans le constructeur du contrôleur. Une fois que vous avez construit un contrôleur, vous pouvez le définir sur une instance de FXMLLoader. antes de vous invoquez le load()
instance méthode.
Pour définir un contrôleur sur un chargeur (dans JavaFX 2.x), vous NE POUVEZ PAS définir également un contrôleur de type fx:controller
dans votre fichier fxml.
En raison de la limitation de la fx:controller
définition dans FXML, je préfère personnellement obtenir le contrôleur à partir du FXMLLoader plutôt que de définir le contrôleur dans le FXMLLoader.
Faire en sorte que le contrôleur récupère les paramètres d'une méthode statique externe
Cette méthode est illustrée par la réponse de Sergey à la question suivante Javafx 2.0 How-to Application.getParameters() dans un fichier Controller.java .
Utiliser l'injection de dépendances
FXMLLoader prend en charge les systèmes d'injection de dépendances comme Guice, Spring ou Java EE CDI en vous permettant de définir une fabrique de contrôleurs personnalisés sur FXMLLoader. Cela fournit un callback que vous pouvez utiliser pour créer l'instance du contrôleur avec les valeurs dépendantes injectées par le système d'injection de dépendances respectif.
Un exemple d'injection de dépendance d'une application JavaFX et d'un contrôleur avec Spring est fourni dans la réponse à la question :
Une approche d'injection de dépendances vraiment agréable et propre est illustrée par la fonction cadre afterburner.fx avec un échantillon application air-hacks qui l'utilise. afterburner.fx s'appuie sur JEE6 javax.inject pour effectuer l'injection de dépendances.
Utiliser un bus d'événements
Greg Brown, créateur et implémenteur de la spécification FXML originale, suggère souvent d'envisager l'utilisation d'un bus d'événements, tel que le bus Guava EventBus pour la communication entre les contrôleurs instanciés FXML et les autres logiques d'application.
L'EventBus est une API simple mais puissante de publication/abonnement avec annotations qui permet aux POJO de communiquer entre eux partout dans une JVM sans avoir à se référer les uns aux autres.
Questions et réponses sur le suivi
Dans la première méthode, pourquoi renvoyer Stage ? La méthode peut aussi être nulle car vous avez déjà donné la commande show() ; juste avant return stage ;. Comment prévoyez-vous l'utilisation en retournant la scène
Il s'agit d'une solution fonctionnelle à un problème. Une étape est renvoyée de la showCustomerDialog
de façon à ce qu'une référence à celle-ci puisse être stockée par une classe externe qui pourrait souhaiter faire quelque chose, comme masquer la scène en fonction d'un clic sur un bouton dans la fenêtre principale, à un moment ultérieur. Une autre solution, orientée objet, pourrait encapsuler la fonctionnalité et la référence à la scène dans un objet CustomerDialog ou faire en sorte qu'un CustomerDialog étende Stage. Un exemple complet d'interface orientée objet pour une boîte de dialogue personnalisée encapsulant des données FXML, de contrôleur et de modèle dépasse le cadre de cette réponse, mais pourrait faire l'objet d'un article de blog intéressant pour toute personne désireuse d'en créer une.
Informations supplémentaires fournies par l'utilisateur de StackOverflow nommé @dzim
Exemple d'injection de dépendances pour Spring Boot
La question de savoir comment faire "The Spring Boot Way", il y avait une discussion sur JavaFX 2, à laquelle j'ai répondu dans le permalien ci-joint. L'approche est toujours valable et testée en mars 2016, sur Spring Boot v1.3.3.RELEASE : https://stackoverflow.com/a/36310391/1281217
Parfois, vous voudrez peut-être renvoyer les résultats à l'appelant, auquel cas vous pourrez consulter la réponse à la question connexe :
0 votes
Vérifiez si cela fonctionne aussi : stackoverflow.com/questions/14370183/
0 votes
@Alvaro : avez-vous obtenu votre solution ? pouvez-vous passer des paramètres ? d'un contrôleur à un autre fichier contrôleur ?
3 votes
Oui. jewelsea a donné une explication au niveau du livre. C'est pourquoi j'ai accepté sa réponse