224 votes

Passage de paramètres JavaFX FXML

Comment puis-je passer des paramètres à une fenêtre secondaire dans javafx ? Existe-t-il un moyen de communiquer avec le contrôleur correspondant ?

Par exemple : L'utilisateur choisit un client dans un TableView et une nouvelle fenêtre s'ouvre, montrant les informations du client.

Stage newStage = new Stage();
try 
{
    AnchorPane page = (AnchorPane) FXMLLoader.load(HectorGestion.class.getResource(fxmlResource));
    Scene scene = new Scene(page);
    newStage.setScene(scene);
    newStage.setTitle(windowTitle);
    newStage.setResizable(isResizable);
    if(showRightAway) 
    {
        newStage.show();
    }
}

newStage serait la nouvelle fenêtre. Le problème est que je ne trouve pas le moyen d'indiquer au contrôleur où chercher les informations sur le client (en passant l'id comme paramètre).

Des idées ?

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

3voto

CTN Points 175

Vous devez créer une classe de contexte.

public class Context {
    private final static Context instance = new Context();
    public static Context getInstance() {
        return instance;
    }

    private Connection con;
    public void setConnection(Connection con)
    {
        this.con=con;
    }
    public Connection getConnection() {
        return con;
    }

    private TabRoughController tabRough;
    public void setTabRough(TabRoughController tabRough) {
        this.tabRough=tabRough;
    }

    public TabRoughController getTabRough() {
        return tabRough;
    }
}

Vous devez juste définir l'instance du contrôleur dans l'initialisation en utilisant

Context.getInstance().setTabRough(this);

et vous pouvez l'utiliser depuis toute votre application en utilisant simplement

TabRoughController cont=Context.getInstance().getTabRough();

Maintenant vous pouvez passer des paramètres à n'importe quel contrôleur de l'application entière.

0 votes

Nous utilisons cette approche et cela fonctionne très bien. J'aime avoir accès aux données dans le constructeur ou dans la méthode d'initialisation et je n'ai pas à définir les données dans le contrôleur après sa construction.

2voto

Oui, vous pouvez.
Vous devez ajouter le premier contrôleur :

YourController controller = loader.getController();     
controller.setclient(client);

Puis dans le second déclarer un client, puis en bas de votre contrôleur :

public void setclien(Client c) {
    this.client = c;
}

0voto

jenglert Points 100

Voici un exemple d'utilisation d'un contrôleur injecté par Guice.

/**
 * Loads a FXML file and injects its controller from the given Guice {@code Provider}
 */
public abstract class GuiceFxmlLoader {

   public GuiceFxmlLoader(Stage stage, Provider<?> provider) {
      mStage = Objects.requireNonNull(stage);
      mProvider = Objects.requireNonNull(provider);
   }

   /**
    * @return the FXML file name
    */
   public abstract String getFileName();

   /**
    * Load FXML, set its controller with given {@code Provider}, and add it to {@code Stage}.
    */
   public void loadView() {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource(getFileName()));
         loader.setControllerFactory(p -> mProvider.get());
         Node view = loader.load();
         setViewInStage(view);
      }
      catch (IOException ex) {
         LOGGER.error("Failed to load FXML: " + getFileName(), ex);
      }
   }

   private void setViewInStage(Node view) {
      BorderPane pane = (BorderPane)mStage.getScene().getRoot();
      pane.setCenter(view);
   }

   private static final Logger LOGGER = Logger.getLogger(GuiceFxmlLoader.class);

   private final Stage mStage;
   private final Provider<?> mProvider;
}

Voici une implémentation concrète du chargeur :

public class ConcreteViewLoader extends GuiceFxmlLoader {

   @Inject
   public ConcreteViewLoader(Stage stage, Provider<MyController> provider) {
      super(stage, provider);
   }

   @Override
   public String getFileName() {
      return "my_view.fxml";
   }
}

Notez que cet exemple charge la vue au centre d'un BoarderPane qui est la racine de la scène dans la scène. Cela n'a rien à voir avec l'exemple (détail d'implémentation de mon cas d'utilisation spécifique) mais j'ai décidé de le laisser dans l'exemple car certains peuvent le trouver utile.

0voto

Java Man Points 983

Cela fonctionne parfaitement pour moi si vous voulez charger un autre FXML à partir de la fenêtre actuelle

    @FXML
    private void handleButtonAction(ActionEvent event) throws IOException 
    {
        Node node = (Node) event.getSource();
        Stage stage = (Stage) node.getScene().getWindow();
        Scene scene = stage.getScene();

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("NEWFXML.fxml"));
        Parent root = (Parent) fxmlLoader.load();
        scene.setRoot(root);
     }

Vérifiez si vous le souhaitez !

Merci.

-2voto

Nospaniol Noah Points 5

Vous pouvez décider d'utiliser une liste d'observables publics pour stocker les données publiques, ou simplement créer une méthode setter publique pour stocker les données et les récupérer à partir du contrôleur correspondant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X