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 :

recuperer valeur TextField dans 1 fenetre deja existante: pble de loader.load()


Sujet :

JavaFX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    conducteur autocar
    Inscrit en
    Janvier 2020
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : conducteur autocar
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2020
    Messages : 67
    Par défaut recuperer valeur TextField dans 1 fenetre deja existante: pble de loader.load()
    re,

    apres 4j, me revoici

    je cree 1 stage
    fichier Main.java
    fichier FXML_Main.fxml
    fichier CONTROLLER_Main.java

    ma Stage s'affiche:
    dedans 1 TextField
    j'entre 1 valeur

    j'affiche cette valeur ds une nvelle stage
    fichier FXML_F02.fxml
    fichier CONTROLLER_F02.java

    ma stage s'affiche
    dedans 1 TextField
    j'entre 1 valeur
    QUE JE SOUHAITE AFFICHER DS MA PRECEDENTE STAGE

    et là... pfff cata:
    Je comprends pas le coup du loader et des instances du controller

    Un peu de code a propos du CONTROLLER de la stage F02, là ou je peche (profond, tres profond).
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    // ajouté pr permettre d'envoyer la valeur
    	// de F02 vers la fenetre Main
    	public void action_bis() throws IOException {
     
    		System.out.println("action");
     
    		String p_data = getF02_txtF();
    		System.out.print(p_data);
     
    		CONTROLLER_Main ctrl_Main = new CONTROLLER_Main();
     
    		// ???
    		// Parent root = FXMLLoader.load(getClass().getResource("FXML_Main.fxml"));
     
    		// SOIT 
     
    		// ce bloc ensemble
    		FXMLLoader loader_Main = new FXMLLoader();
    		// tu précises le fichier à charger
    		loader_Main.setLocation(Main.class.getResource("FXML_Main.fxml"));
    		// OU
    		// loader_Main.setController(this);
    		// loader_Main.getController();
    		// loader_Main.load();
     
     
    		// SOIT
     
    		// ce bloc
    		// FXMLLoader loader_Main = new FXMLLoader(getClass().getResource("FXML_Main.fxml"));
    		loader_Main.getController();
    		loader_Main.load();
     
     
    		// on a 1 scene
    		System.out.println(F02_lbl02.getScene());
    		// on a 1 stage
    		System.out.println(F02_lbl02.getScene().getWindow());
     
    		// ne peut pas etre resolu
    		// System.out.println(Main_AC.getScene());
     
    		// loader_Main.getController();
     
    		// les 2 fonctionnent qd il n'y a rien en dessous
     
    		// ctrl_Main = loader_Main.load();
    		// ctrl_Main = loader_Main.getController();
     
     
    		// ajout 01
    		// try {
     
    			// tu précises le fichier à charger
    			// loader_Main.setLocation(Main.class.getResource("FXML_Main.fxml"));
     
     
    			// ctrl_Main = loader_Main.load();
    			// ctrl_Main = loader_Main.getController();
     
    		// } catch (IOException except) {
    			// except.printStackTrace();
    		// }
     
    		// ctrl_Main is null
    		ctrl_Main.setLblFromController2(F02_txtF.getText());
     
    		// ctrl_Main is null
    		// ctrl_Main.setLblFromController2(p_data);
     
    		// fonctionne sans les ajouts 01
    		System.out.println(ctrl_Main.test);
     
    		// because the return value of
    		// "application.CONTROLLER_Main.getMain_P()" is null
    		// System.out.println(ctrl_Main.getMain_P().getHeight());
    	}
    DE ce que je comprends
    L11; je cree 1 instance de mon CONTROLLER_Main
    L19: je cree 1 instance de FXMLLoader
    L21: je charge le fichier FXML_Main.fxml ds mon instance de FXMLLoader
    L32 + L33: je peche ms sans appât
    L37 et L39: j'ai 2 "adresses memoire", dc j'ai bien ma scene et ma stage (lesquelles? celles du Main ou celles de F02?)
    L67: j'ai 1 retour console
    java.lang.NullPointerException: Cannot invoke "javafx.scene.control.Label.setText(String)" because "this.lblFromController2" is null

    Voilà,
    j'arrive pas a comprendre l'histoire du loader qui load().
    J'ai essayé plein de trucs au pifometre ms non, je ne comprends pas ce que je dois faire
    re creer stage et scene?
    utiliser le loader.load() correctement? (ms ça je ne sais pas faire).

    Bon, voilà
    si vs pviez me montrer et m'expliquer SVP parce que ce we j'ai bronze grace a mon ecran, pas le soleil...

    En vs remerciant
    grub

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    En général il y a pas vraiment d'intérêt à instancier un contrôleur à mano sauf si c'est pour l'injecter dans un loader derrière.

    Donc oui tu as bien 2 instances du contrôleur, la 1ere servant sans doute a rien et avec tous ses champs @FXML toujours à null/
    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
    Membre confirmé
    Homme Profil pro
    conducteur autocar
    Inscrit en
    Janvier 2020
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : conducteur autocar
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2020
    Messages : 67
    Par défaut
    Bon déjà,
    merci de tes réponses, on voit bien que t'es hyperactif pr aider les noobs et ca fait plaisir.
    Encore Merci,
    Malheureusement, je ne comprends pas du tt ce que tu vx dire

    En général il y a pas vraiment d'intérêt à instancier un contrôleur à mano
    ou est ce que j'instancie 1 controleur a la mano?
    soit la L11
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONTROLLER_Main ctrl_Main = new CONTROLLER_Main();
    soit les L19 et 21
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FXMLLoader loader_Main = new FXMLLoader();
    loader_Main.setLocation(Main.class.getResource("FXML_Main.fxml"));
    En ce qui me concerne
    L11 instancie 1 controleur
    L 19, 21 instancient 1 objet FXMLLoader (qui va charger 1 .fxml, qui va charger 1 Controleur)

    dc que j'instancie a la mano ou pas, je comprends que c'est soit l'1, soit l'autre?

    Ensuite, je vx afficher la valeur d'1 TextField (n'importe quelle valeur en fait, ça ns est égal),
    il faut bien que j'accede a la methode setText de l'objet (widget) qui va afficher cette valeur (setText pr 1 Label ou TextField).
    Et pr ça je dois bien injecter mon controleur ds 1 loader?
    c'est grace au loader que je vais acceder aux proprietes de mes widgets?
    Dc, comment je crée ce fameux loader?

    Désolé d'être lourdaud ms j'ai qd besoin de savoir ce que je fais.

    Merci a toi
    grub

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par grub_fr Voir le message
    ou est ce que j'instancie 1 controleur a la mano?
    soit la L11
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONTROLLER_Main ctrl_Main = new CONTROLLER_Main();
    Ici, puisque tu fais new CONTROLLER_Main().

    Reprenons, généralement pour obtenir une instance d'un controleur, on fera :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    final var loader = new FXMLLoader(....
    final var monNoeud = loader.load();
    final var monController = loader.getControler();
    Bref, un nouveau controleur est instancié et injecté par le loader.


    Moins souvent on fera :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    final var loader = new FXMLLoader(....
    loader.setControler(unControllerQueJavaisDejaAvant);
    final var monNoeud = loader.load();
    Cela permet de réutiliser un contrôleur déjà existant pour peu qu'il soit compatible avec le FXML qu'on charge. Le loader va injecter et initialiser les variables.

    -> si les variables marquées @FXML sont null
    • soit le contrôleur a pas eut d'injection faite par le loader et donc est pas initialisé ;
    • soit le nom des variables correspond pas au valeurs fx:id dans le FXML.
    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
    Membre confirmé
    Homme Profil pro
    conducteur autocar
    Inscrit en
    Janvier 2020
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : conducteur autocar
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2020
    Messages : 67
    Par défaut
    ok,

    je comprends la logique.
    dc
    ds le controleur de ma derniere fenetre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // tu vas chercher le .fxml de la precedente fenetre
    FXMLLoader loader_Main = new FXMLLoader(getClass().getResource("FXML_Main.fxml"));
    // tu binds (ou tu appaires, parce que binder c'est peut etre autre chose)
    // ton loader (ici loader_Main) avec
    // 1 elt du .fxml de la precedente fenetre
    // CA, CA ME MANQUAIT
    AnchorPane main_AC = (AnchorPane) loader_Main.load();
    // tu crees l'instance du controleur de la precedente fenetre et tu l'"injectes" par le loader
    // cette phrase est encore floue pr moi, va falloir que je l'adapte a ma "logique"
    CONTROLLER_Main ctrl_Main = (CONTROLLER_Main) loader_Main.getController();
    Bref, pr le moment on est tt bon.
    Tu m'as déjà retiré une sacrée epine du pied.
    Un grd merci pour ça.

    Mais là on en revient a la 1° partie du titre de ce post
    recuperer la valeur d'1 TextField de la derniere fenetre pr l'afficher (mettre a jour) ds 1 label de la 1° fenetre

    dc
    1] Par souci de securite j'obtiens 1 instance
    de mon CONTROLLER_F02.java (derniere fenetre) que je mets ds la methode
    initialize() de mon CONTROLLER_Main.java (premiere fenetre)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    FXMLLoader loader_F02 = new FXMLLoader(getClass().getResource("FXML_F02.fxml"));
    //
    try {
    	AnchorPane F02_AC = (AnchorPane) loader_F02.load();
    } catch (IOException e) {
    	e.printStackTrace();
    }
    CONTROLLER_F02 ctrl_F02 = (CONTROLLER_F02) loader_F02.getController();
    ds le CONTROLLER_Main.java (1° fenetre)
    je mets aussi 1 setter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void setLblFromController2(String p_data) {
            lblFromController2.setText(p_data);
    }
    Le setter fonctionne, je l'ai testé

    et enfin, ds le CONTROLLER_F02.java
    je mets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void action_bis(ActionEvent event) throws IOException {
            System.out.println("action_bis");
            FXMLLoader loader_Main = new FXMLLoader(getClass().getResource("FXML_Main.fxml"));
    	AnchorPane main_AC = (AnchorPane) loader_Main.load();
    	CONTROLLER_Main ctrl_Main = (CONTROLLER_Main) loader_Main.getController();
            System.out.println("valeur tapée:");
    	System.out.println(F02_txtF.getText());
            ctrl_Main.setLblFromController2(F02_txtF.getText());
    }
    Mais le label de la 1° fenetre ne change pas, ne se met pas a jour
    pourquoi?

    Je continue a chercher de mon côté,
    peut etre que l'appairage devrait se faire ds la méthode initialize(), qque chose comme ça.

    En ts les k, merci pr ton aide.
    Apres ca, je posterai le code complet (en enlevant les T de commentaires), histoire d'etre actif moi aussi (au moins 1x)
    a+
    grub

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    Le truc c'est que j'imagine que tu es sensé avoir juste 1 fenêtre principale + son contrôleur. Or, dans le code du second controleur, tu en crées une nouvelle + son contrôleur a elle.

    Tout ce bloc-la

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     FXMLLoader loader_Main = new FXMLLoader(getClass().getResource("FXML_Main.fxml"));
    	AnchorPane main_AC = (AnchorPane) loader_Main.load();
    	CONTROLLER_Main ctrl_Main = (CONTROLLER_Main) loader_Main.getController();
    crée une toute nouvelle instance du contenu de la fenêtre et une toute nouvelle instance du contrôleur. Donc aucun lien avec la fenêtre initiale et le contrôleur initial.

    Plusieurs manières pour faire ce que tu veux :
    PS: je pars du principe que CONTROLLER_F02 est géré depuis CONTROLLER_Main.
    PS2: je tape de mémoire donc il y aura sans doute des erreurs dans le code.

    1. Dans CONTROLLER_F02 mettre une propriété text (nom choisi au pif).


      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      private final ReadOnlyStringProperty textProperty = new ReadOnlyStringWrapper(this, "text", null);
       
      public ReadOnlyStringProperty textProperty() {
          return textProperty.readOnlyProperty();
      }
       
      public String getText() {
          return textProperty.getValue();
      }
      et dans CONTROLLER_Main, on reagit quand la valeur du texte change :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      ctrl_F02.textProperty().addListener((observable, oldValue, newValue) -> {
          setLblFromController2(newValue);
      });
    2. Donner une référence a ctrl_Main dans ctrl_F02Dans CONTROLLER_Main :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ctrl_F02.setMainController(this);
      Dans CONTROLLER_F02 :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      private CONTROLLER_Main mainController;
       
      public void setMainController(CONTROLLER_Main value) {
          this.mainController = value; 
      }
       
      [...]
       
      Optional.ofNullable(mainController)
          .ifPresent(c -> c.setLblFromController2(F02_txtF.getText()));
      Cela permet d'invoquer la bonne méthode sur l'instance du contrôleur principal qui existe déjà, mais cela met un couplage fort entre CONTROLLER_F02 et CONTROLLER_Main.
    3. Il est possible de rendre la chose moins fortement couplée en utilisant des références de méthodes, par exemple:

      Dans CONTROLLER_Main :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ctrl_F02.setOnTextChange(this::setLblFromController2);
      Dans CONTROLLER_F02 :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      private Consumer<String> onTextChange;
       
      public void setOnTextChange(Consumer<String> value) {
          this.onTextChange= value; 
      }
       
      [...]
       
      Optional.ofNullable(onTextChange)
          .ifPresent(c -> c.apply(F02_txtF.getText()));
      Comme ça la boite de dialogue est beaucoup plus générique et on peut la réutiliser ailleurs
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. recuperer valeur formulaire dans VB
    Par PC81 dans le forum IHM
    Réponses: 2
    Dernier message: 13/05/2008, 11h04
  2. [VB.NET] Recuperation valeur selectionnee dans COMBOBOX
    Par stephane77fr dans le forum Windows Forms
    Réponses: 2
    Dernier message: 30/07/2007, 17h43
  3. [XSLT]Recuperer valeur concatenee dans une balise
    Par e_peigne dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 25/10/2006, 13h49
  4. [VB6 ArcView9] Recuperer valeur RMS dans une variable
    Par TiT0f dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 23/05/2006, 15h49
  5. recuperer valeur liste dans champs texte
    Par fredaphp dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 20/05/2006, 19h17

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