Passage du paramètre JavaFX FXML du contrôleur A au contrôleur B et retour

je veux créer une interface graphique JavaFX basée sur les controllers et composée de plusieurs controllers.

la tâche que je ne peux pas accomplir est de passer les paramètres d'une scène à l'autre et vice versa.

Ou en d'autres termes: Le contrôleur principal charge le FXML de SubController, passe un objet à SubController, change la scène. Il ne peut y avoir deux fenêtres ouvertes. Une fois que le travail est terminé, le sous-Controller doit alors basculer de nouveau la scène vers le Controller principal et passer un objet en arrière. C'est là où j'échoue.

cette question est très similaire à celle-ci mais reste sans réponse. Passing Parameters JavaFX FXML Il a également été mentionné dans les commentaires:

" ce travail quand vous passez le paramètre du premier contrôleur au second mais comment passer le paramètre du second au premier contrôleur,je veux dire après le premier.fxml était chargé.

– Xlint XMS Sep 18 '17 at 23: 15"

j'ai utilisé la première approche dans la réponse supérieure de ce fil.

est-ce que quelqu'un a une idée de comment réaliser ceci sans libs externes?

2
demandé sur J.Ober 2018-01-09 20:07:22

3 réponses

Il y a de nombreuses façons de le faire.

Voici une solution, qui passe un consommateur à un autre contrôleur. L'autre contrôleur peut invoquer le consommateur à accepter le résultat une fois qu'il a terminé son travail. L'échantillon est basé sur le code d'exemple de réponse à la question que vous avez lié.

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()
    )
  );

  Consumer<CustomerInteractionResult> onComplete = result -> {
    // update main screen based upon result.
  };
  CustomerDialogController controller = 
    loader.<CustomerDialogController>getController();
  controller.initData(customer, onComplete);

  stage.show();

  return stage;
}

...

class CustomerDialogController() {
  @FXML private Label customerName;
  private Consumer<CustomerInteractionResult> onComplete
  void initialize() {}
  void initData(Customer customer, Consumer<CustomerInteractionResult> onComplete) {
    customerName.setText(customer.getName());
    this.onComplete = onComplete;
  }

  @FXML
  void onSomeInteractionLikeCloseDialog(ActionEvent event) {
    onComplete.accept(new CustomerInteractionResult(someDataGatheredByDialog));
  }
}

une Autre façon de le faire est d'ajouter un résultat bien au contrôleur de l'écran de dialogue et de les invokers intéressés pourraient écouter ou récupérer la propriété de résultat. Une propriété de résultat est la façon dont les dialogues JavaFX intégrés fonctionnent, donc vous imiteriez essentiellement une partie de cette fonctionnalité.

si vous avez beaucoup de ces choses qui passent de part et d'autre, un modèle d'injection de dépendance partagée basé sur quelque chose comme Gluon Ignite , pourrait vous aider.

1
répondu jewelsea 2018-01-11 23:31:16

j'ai utilisé AfterBurner.fx for dependency injection, qui est très lisse et puissante aussi longtemps que vous suivez les conventions. Ce n'est pas nécessairement un lib externe si vous copiez simplement les 3 classes dans votre structure. Bien que vous ayez besoin du bocal d'injection javax, donc je suppose que c'est une référence éternelle.

alternativement, si vous avez un "écran" central à partir duquel la plupart de vos branches d'application sur vous pourriez utiliser propriété liant probablement dans un schéma unique. Il y a quelques bons articles sur l'utilisation de singleton dans JavaFX, comme celui-ci . J'ai fait cela pour une petite application qui fonctionne vraiment bien, mais définir toutes ces fixations peut devenir incontrôlable s'il y a beaucoup de propriétés.

0
répondu RonSiven 2018-01-11 19:59:47

pour renvoyer les données, la meilleure approche est probablement de lancer des événements personnalisés, auxquels le contrôleur parent souscrit avec Node::addEventHandler. Voir Comment émettre et gérer des événements personnalisés? pour Contexte.

dans les cas complexes où les deux contrôleurs n'ont aucune référence l'un à l'autre, un Bus D'événements comme @jewelsea mentionné est l'option supérieure.

pour l'architecture globale, ce commentaire de Reddit fournit de bons détails: https://www.reddit.com/r/java/comments/7c4vhv/are_there_any_canonical_javafx_design_patterns/dpnsedh/

0
répondu kantianethics 2018-01-27 01:48:01