IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

FXML - Récupérer le contrôleur d'un sous contrôleur


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Par défaut FXML - Récupérer le contrôleur d'un sous contrôleur
    Bonjour,

    Je travaille avec Java11 et JavaFX11 (avec IntelliJ version Octobre 2019).

    Je cherche à construire une IG respectant MVC. Pour cela, je construis une trame de la fenêtre principale, incluant des composants xml. Chacun de ces composants indépendant a un contrôleur, à qui j'aimerais pouvoir transmettre le modèle pour qu'il puisse travailler.

    Le code repris en bas de cette page, posté il y a 2 ans, fonctionne sans problème. Il montre comment imbriquer des composants et récupérer le contrôleur par injection. Je cherche à l'adapter pour pouvoir transmettre le modèle à tous les contrôleurs. J'ai donc adapté le main en écrivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            MonModele monModele = ...  ;
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("a.fxml"));
            AController ac = new AController(monModele);
            loader.setControllerFactory(instanciatedClass -> { return ac; });
            Parent root = loader.load();
    J'ai bien sûr changé le code de la classe AControlleur en conséquence, pour la doter d'un constructeur adéquat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    package test;
    import java.net.URL;
    import java.util.ResourceBundle;
     
    import modele.MonModele;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Node;
     
    public class AController implements Initializable {
     
        @FXML
        private Node b;
        @FXML
        private BController bController;
     
        public AController(MonModele m) {
            System.out.println("A création avec modèle.");
        }
     
        public AController() {
            System.out.println("A création.");
        }
     
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            assert (b != null);
            assert (bController != null);
            assert (bController.getSubController() != null);
        }
    }
    A l'exécution, la trace indique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A création avec modèle.
    A controller initialized.
    et l'exécution s'arrête avec violation de l'assertion assert (b != null);

    Quelque chose m'échappe sûrement, mais je ne trouve pas laquelle.
    Quelqu'un a une idée ?
    Merci

    Citation Envoyé par bouye Voir le message
    Comme prevu ca marche impec...


    a.fxml
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
     
    <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.AController">
            <fx:include fx:id="b" source="b.fxml"/>
    </AnchorPane>

    b.fxml
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
     
    <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.BController">
        <fx:include fx:id="c" source="c.fxml"/>
    </AnchorPane>

    c.fxml
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
     
    <AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.CController">
    </AnchorPane>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package test;
     
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Node;
     
    public class AController implements Initializable {
     
        @FXML    
        private Node b;
        @FXML    
        private BController bController;
     
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            System.out.println("A controller initialized.");
            assert (b != null);
            assert (bController != null);
            assert (bController.getSubController() != null);
        }        
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package test;
     
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Node;
     
    public class BController implements Initializable {
     
        @FXML    
        private Node c;
        @FXML    
        private CController cController;
     
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            System.out.println("B controller initialized.");
            assert (c != null);
            assert (cController != null);
        }
     
        public CController getSubController() {
            return cController;
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package test;
     
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.fxml.Initializable;
     
    public class CController implements Initializable {
     
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            System.out.println("C controller initialized.");
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package test;
     
    import java.io.IOException;
    import java.util.Optional;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
     
    public class Main extends Application {
     
        @Override
        public void start(Stage primaryStage) {
            Optional.ofNullable(getClass().getResource("a.fxml"))
                    .ifPresent(url -> {
                        try {
                            final Parent root = new FXMLLoader(url).load();
                            final Scene scene = new Scene(root);
                            primaryStage.setScene(scene);
                        } catch (IOException ex) {
                            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    });
            primaryStage.setTitle("Hello World!");
            primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    Code console : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    C controller initialized.
    B controller initialized.
    A controller initialized.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 899
    Billets dans le blog
    54
    Par défaut
    Est-ce qu'il est possible de voir la portion du FXML ou tu as déclaré l'inclusion du sous-FXML STP ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Par défaut
    Le voilà. C'est celui de ton exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.vues.AController">
     
                    <fx:include fx:id="b" source="b.fxml"/>
                    <fx:include fx:id="c" source="c.fxml"/>
     
    </AnchorPane>
    J'ai essayé sans définir le contrôleur dans le fichier XML, mais ça ne change rien au résultat.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 899
    Billets dans le blog
    54
    Par défaut
    Bon j'ai repris mon code de l'epoque a l'indique et je l'ai colle dans un projet JDK 13 + JavaFX 13 et... ca marche toujours sans soucis.

    Dans ton code FXML, b et c sont tous les 2 inclus dans a, tandis que dans le mien c est inclus dans b qui est contenu dans a. C'est pas tout a fait la même chose et suivant ce que tu as change (ou pas) dans le code évidement ça peut mettre le bazar.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 4
    Par défaut
    Ton code fonctionne parfaitement bien avec Java 11.

    Je cherche juste à le modifier pour gérer l'instanciation du contrôleur (pour lui passer le modèle en paramètre). Si je ne mets qu'un seul include dans mon fichier a.xml, l'erreur est exactement la même. Ce n'est pas la double inclusion qui pose problème apparemment, mais le fait que je gère l'instanciation du contrôleur dans le Main.

    C'est l'utilisation de Java13 qui m'a permis de comprendre ce qui se passe. Avec Java11, il n'y a aucun message d'erreur mais l'injection des sous-composants inclus et de leurs contrôleurs ne se fait pas, sans qu'aucune exception ne se produise.

    Avec Java13, il se produit une exception qui permet de comprendre que dès qu'on utilise une fabrique de contrôleurs, cette fabrique est utilisée pour instancier tous les contrôleurs. Il faut donc qu'elle soit capable de distinguer les composants pour lesquels elle est utilisée, et instancier le bon contrôleur.
    C'est un peu bizarre que l'on puisse inclure des sous-composants n'importe où, alors que l'instanciation des contrôleurs doit se faire dans le main. Cela ne va pas favoriser l'évolutivité de l'application.

    A moins que je n'ai zappé quelque chose .....

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/10/2017, 22h45
  2. Récupérer la date du jour sous forme d'int...
    Par Empty_body dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 28/03/2007, 10h38
  3. Récupérer une valeur d'un sous formulaire
    Par Mariboo dans le forum Access
    Réponses: 7
    Dernier message: 23/05/2006, 11h13
  4. [CR]Récupérer un résumé d'un sous état dans l'état principal
    Par sylviefrfr dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 28/03/2006, 11h58
  5. récupérer dans 1 menu le sous menu séléctionner
    Par vincedjs dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 02/03/2006, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo