Approche recommandée
Cette réponse énumère différents mécanismes pour transmettre des paramètres aux contrôleurs FXML.
Pour les petites applications, je recommande fortement de passer des paramètres directement de l'appelant au contrôleur - c'est simple, direct et ne nécessite aucun cadre supplémentaire.
Pour les applications plus grandes et plus complexes, il serait utile de rechercher si vous souhaitez utiliser les mécanismes d' injection de dépendance ou de bus d'événements dans votre application.
Passage direct des paramètres de l'appelant au contrôleur
Passez des données personnalisées à un contrôleur FXML en récupérant le contrôleur à partir de l'instance de 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(
(Pane) loader.load()
)
);
CustomerDialogController controller =
loader.<CustomerDialogController>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 ie 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"));
Faites attention de NE PAS utiliser de fonction de chargement statique sur le FXMLLoader, sinon vous ne pourrez pas obtenir votre contrôleur à partir de votre instance de chargeur.
Les instances FXMLLoader elles-mêmes ne savent jamais rien des objets de domaine. Vous ne passez pas directement des objets de domaine spécifiques à l'application dans le constructeur FXMLLoader, mais vous:
- Construire un FXMLLoader basé sur le balisage fxml à un emplacement spécifié
- Obtenez un contrôleur à partir de l'instance FXMLLoader.
- Appelez des méthodes sur le contrôleur récupéré pour fournir au contrôleur des références aux objets de domaine.
Ce blog (par un autre auteur) fournit un autre, mais similaire, par exemple .
Configuration d'un contrôleur sur FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
Vous pouvez construire un nouveau contrôleur dans le code, en transmettant tous les paramètres de votre appelant au constructeur du contrôleur. Une fois que vous avez construit un contrôleur, vous pouvez le définir sur une instance FXMLLoader avant d'appeler la méthode d' load()
instance .
Pour définir un contrôleur sur un chargeur (dans JavaFX 2.x), vous NE POUVEZ PAS également définir un fx:controller
attribut 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 du FXMLLoader plutôt que de le configurer dans le FXMLLoader.
Demander au contrôleur d'extraire les paramètres d'une méthode statique externe
Cette méthode est illustrée par la réponse de Sergey à Javafx 2.0 How-to Application.getParameters () dans un fichier Controller.java .
Utiliser l'injection de dépendance
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ée sur FXMLLoader. Cela fournit un rappel que vous pouvez utiliser pour créer l'instance de contrôleur avec des valeurs dépendantes injectées par le système d'injection de dépendance respectif.
Un exemple d'injection JavaFX d'application et de dépendance de contrôleur avec Spring est fourni dans la réponse à:
Une approche d'injection de dépendances vraiment agréable et propre est illustrée par le framework afterburner.fx avec un exemple d'application air-hacks qui l'utilise. afterburner.fx s'appuie sur JEE6 javax.inject pour effectuer l'injection de dépendance.
Utiliser un bus d'événements
Greg Brown, le créateur et implémenteur d'origine de la spécification FXML, suggère souvent d'envisager l'utilisation d'un bus d'événements, tel que le Guava EventBus , pour la communication entre les contrôleurs instanciés FXML et d'autres logiques d'application.
L'EventBus est une API de publication / abonnement simple mais puissante avec des annotations qui permet aux POJO de communiquer entre eux n'importe où dans une machine virtuelle Java sans avoir à se référer les uns aux autres.
Questions et réponses sur le suivi
sur la première méthode, pourquoi renvoyez-vous Stage? La méthode peut également être annulée car vous donnez déjà la commande show (); juste avant l'étape de retour;. Comment planifiez-vous l'utilisation en renvoyant la scène
Il s'agit d'une solution fonctionnelle à un problème. Une étape est renvoyée par la showCustomerDialog
fonction afin qu'une référence à celle-ci puisse être stockée par une classe externe qui souhaitera peut-être faire quelque chose, comme masquer l'étape en fonction d'un clic sur le bouton dans la fenêtre principale, ultérieurement. Une autre solution orientée objet pourrait encapsuler la fonctionnalité et la référence d'étape à l'intérieur d'un objet CustomerDialog ou avoir une étape d'extension CustomerDialog. Un exemple complet d'interface orientée objet vers 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 peut constituer un article de blog intéressant pour quiconque est enclin à en créer un.
Informations supplémentaires fournies par l'utilisateur StackOverflow nommé @dzim
Exemple pour l'injection de dépendance de démarrage de Spring
La question de savoir comment le faire "The Spring Boot Way", il y avait une discussion sur JavaFX 2, que j'ai répondu dans le permalien ci-joint. L'approche est toujours valide et testée en mars 2016, sur Spring Boot v1.3.3.RELEASE:
https://stackoverflow.com/a/36310391/1281217
Parfois, vous souhaiterez peut-être transmettre les résultats à l'appelant, auquel cas vous pouvez consulter la réponse à la question connexe: