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 :

stage.setOnCloseRequest dans un controller FXML


Sujet :

JavaFX

Vue hybride

encoreUnDebutant stage.setOnCloseRequest dans... 01/10/2020, 19h06
encoreUnDebutant c'est un peu idiot car je me... 01/10/2020, 19h41
bouye Bindings.<Window>select(monCon... 02/10/2020, 00h19
encoreUnDebutant Merci Bouye ! bon j'ai... 02/10/2020, 15h11
bouye Il est pas du tout normal que... 03/10/2020, 10h07
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    styliste
    Inscrit en
    Juillet 2020
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : styliste
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2020
    Messages : 27
    Par défaut stage.setOnCloseRequest dans un controller FXML
    Hello bonjour à tous,
    et un bonjour particulier à Bouye toujours là pour nous aider avec nos soucis de grands débutant !!

    bon j'ai plutot pas mal avancé sur mon nouveau projet. en gros c'est un gestionnaire de base de donnée SQLite avec une interface FXML.

    j'ai une base de donnée super simple avec des artistes avec lesquels je travaille dans la vraie vie, et dans cette base de donnée les champs renseignés sont le NOM, l'adresse du SITE INTERNET, le EMAIL, et les SAISONS sur lesquels nous avons travaillés avec eux ( hiver 2019, été 2018, etc....)

    le but de ce petit desktop programme, c'est de gérer ma base d'artiste, de les ajouter ou de les supprimer des saisons, puis in fine a la fin d'exporter ces infos par mail ou pdf à des fins de communication dans mon entreprise !!

    a ma grande surprise, j'ai quasimment réussi à remplir toute ces fonctionnalitées ! bon mon interface est très moche mais ca je vais le traiter après quand tout fonctionnera.

    et aujourd'hui, j'en suis au stade du DEBUG, je régle toutes les petites anomalies de fonctionnement.

    PAr exemple, j'aimerais déclencher une action à la fermeture d'un stage associée à un FXML controller. tout simplement, je souhaiterais que lorsque je clique la petite croix de mon interface window, la petite croix rouge, et bien j'aimerais déclencher une action.

    le problème, c'est que je ne parviens pas à mettre la main sur le STage, car il a été crée à partir du Main de mon application principale.

    mais un code vaut mieux que de longs discours, ok, voici donc mon main :

    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
    package com.politi.bibliotheque.bibli;
     
    import java.io.IOException;
    import java.sql.SQLException;
     
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
     
    /**
     * JavaFX App
     */
    public class App extends Application {
     
     
     
        @Override
        public void start(Stage stage) throws IOException, SQLException {
        	setRoot("primary",800,500);
        }
     
        static void setRoot(String fxml, int x, int y) throws IOException {
     
        	Scene scene2 = new Scene(loadFXML(fxml),x,y);
        	Stage stage2 = new Stage();
        	stage2.setScene(scene2);
            stage2.setResizable(false);
            stage2.show();
     
        }
     
     
        private static Parent loadFXML(String fxml) throws IOException {
            FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
            return fxmlLoader.load();
        }
     
        public static void main(String[] args) {
            launch();
        }
     
    }
    dans ce main qui se nomme App.java, on voit bien qu'il existe une méthode qui se nomme setRoot, et dont je me sers pour apeller par exemple le fichier "primary.fxml" qui a pour controlleur le fichier "PrimaryController.java"

    pour ne pas surcharger ma question , disons que à partir de "PrimaryController.java", je vais à nouveau invoquer la méthode App.SetRoot pour charger un fichier "addArtist.fxml" qui a pour controlleur le fichier "SecondaryController.java"

    voici le code du controlleur ""SecondaryController.java" :

    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
     
    package com.politi.bibliotheque.bibli;
     
    import java.io.IOException;
    import java.net.URL;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.ResourceBundle;
     
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextField;
    import javafx.stage.Stage;
     
    public class SecondaryController implements Initializable {
     
     
    	@FXML
    	private TextField textFieldAddName;
     
    	@FXML
    	private TextField textFieldAddUrl;
     
    	@FXML
    	private TextField textFieldAddEmail;
     
    	@FXML
    	private Button btnAddArtist;
     
    	private DbConnection dc;
     
    	@FXML
    	public void insertArtistToDatabase(ActionEvent e) {
     
    		//récupération des infos dans les champs de saisie de texte
    		String NameArtist = textFieldAddName.getText();
    		String UrlArtist = textFieldAddUrl.getText();
    		String EmailArtist = textFieldAddEmail.getText();
     
    		//ouverture de la conection avec la base de donnée
    		dc = new DbConnection();
    		Connection connAddArtist = dc.connect();
     
    		// insertion nouvel artiste
    		try {
    			System.out.println(NameArtist);
    			int rv = connAddArtist.createStatement()
    					.executeUpdate("INSERT INTO artistes ( artistName, artistUrl, artistEmail ) VALUES ( '" + NameArtist + "','"
    							+ UrlArtist + "','"+EmailArtist+"' )");
    		} catch (SQLException e2) {
    				e2.printStackTrace();
    			}
     
    		try {
    			App.setRoot("primary",800,500);
    		} catch (IOException e1) {
    			e1.printStackTrace();
    		}
     
    		//fermeture de la secondary window = fenetre actuelle
    		Stage stage = (Stage) btnAddArtist.getScene().getWindow();
    	    stage.close();
     
    	}
     
    	@Override
    	public void initialize(URL location, ResourceBundle resources) {
     
    	}
     
    }
    ici , on voit bien que lorsque je valide l'ajout d'un nouvel artiste dans ma base de donnée en cliquant sur un bouton qui va apeller la méthode insertArtistToDatabase, et bien on voit qu'après avoir inscrit cette artiste dans ma BD, je repasse sur ma main window en chargeant a nouveau mon"primary.fxml", et j'en profite pour fermer ma fenetre courante en me servant de Stage stage = (Stage) btnAddArtist.getScene().getWindow(); pour choper mon stage

    ca, ca marche bien....c'est peut être bizzarre, c'est sans doute pas très élégant comme code mais je suis débutant

    par contre, il m'est impossible dans ce Secondarycontroller de choper mon stage au niveau de Initialize , en profitant d'un node comme j'ai pu le faire avec : Stage stage = (Stage) btnAddArtist.getScene().getWindow();
    car au moment de initialize, les nodes ne sont pas encore crées, les boutons n'existent pas par exemple, et donc je ne peux pas remonter jusqu'au stage principal...

    mince...

  2. #2
    Membre averti
    Homme Profil pro
    styliste
    Inscrit en
    Juillet 2020
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : styliste
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2020
    Messages : 27
    Par défaut
    c'est un peu idiot car je me rends compte que j'avais posé la meme question ici meme, juste deux messages plus bas !

    à l'époque j'avais esquivé le probleme en me débarassant du bouton de fermeture de la fenetre

    et Bouye avait eu la gentilless de de me donner des pistes, je vais tout de suite m'y plonger !

    Ton contrôleur aurait pu tenter de retrouver la fenêtre dans laquelle ses contrôles sont affichés en faisant monControle.getScene().getWindow() sur n'importe lequel des contrôles qu'il référence. Seul hic : la valeur de retournée par getScene() est null tant que les contrôles ne sont pas attachés à la scène et la getWindow() est null tant que cette scène n'est pas insérée dans une fenêtre. Mais bon rien de bien critique puisqu'on est en JavaFX et que tout est observable.
    Ton contrôleur aurait pu fournir un callback que la partie principale de l'application aurait pu invoquer lors de la fermeture de la fenêtre. Là c'est juste écrire un getter ou une propriété dans le contrôleur à destination de la partie principale de l'application.
    Inversement la partie principale de l'application aurait pu fournir dans ton ton contrôleur un callback invoqué lors de la fermeture de la fenêtre. Là il faut juste écrire un setter ou une propriété dans le contrôleur qui sera accédée par la partie principale de l'application.

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 904
    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 904
    Billets dans le blog
    54
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Bindings.<Window>select(monControl.getScene(), "window")
            .addListener((obs, oldV, newV) -> Optional.ofNullable(newV)
                                                      .ifPresent(window -> window.setOnCloseRequest(...)));
    ou un truc du genre devrait être une première approche suffisamment simple a défaut d’être optimisée.
    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

  4. #4
    Membre averti
    Homme Profil pro
    styliste
    Inscrit en
    Juillet 2020
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : styliste
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2020
    Messages : 27
    Par défaut
    Merci Bouye !

    bon j'ai essayé une heure (plutôt deux ) mais sans succès, je m'y prends mal c'est sur.

    j'imagine que l'idée de fond est de parvenir à lier un listener à mon stage, mais mon problème reste le même qu'avant c'est à dire quelque soit le 'MonControl' que je choisis ( un bouton par exemple), je ne peux le faire dans le Initialize car aucun contrôle n'est crée à ce stade. ca ne semble fonctionner qu'à à l'intérieur dune méthode.

    d'ailleurs il me vient une idée, peut être pourrais-invoquer une méthode de manière automatique indépendamment de toute action, qui démarrerait toute seul juste après la création de l'ensemble de mon stage ? c'est une solution non ? Comme une sorte de second Intiialize mais qui aurait lieu à la suite ed la création de tout les controls, boutons , etc ...,?


    j'ai encore tellement à apprendre, c'est pas encore de mon niveau tout ca je pense...

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 904
    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 904
    Billets dans le blog
    54
    Par défaut
    Il est pas du tout normal que tes contrôles marqués par @FXML ne soient pas déjà injectés dans ton contrôleur lorsque initialize() est invoqué. T'est-il possible de produire un exemple simple (2-4 classes) démontrant comment tu crées ton UI ?
    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

  6. #6
    Membre averti
    Homme Profil pro
    styliste
    Inscrit en
    Juillet 2020
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : styliste
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2020
    Messages : 27
    Par défaut
    oui je pourrait faire ca, produire quelques classe pour voir si je crée correctement mon UI...

    Mais en attendant, je pense surtout avoir été un peu imprécis/inexact en affirmant que mes contrôles marqués @FXML n'étaient pas crées au moment ou initialize() est invoqué, c'est faux, pour être très clair j'ai dis une connerie...

    j'ai refait le test, et effectivement, en mettant le code ci dessous dans initialize(), le texte de mon bouton change, ce qui prouve qu'il existe si je peux le modifier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    btnAddArtist.setText("nouveau nom");
    par contre, si je mets ce code dans le initialize() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println(" scene =  : " + btnAddArtist.getScene());
    et bien avec ca j'obtiens dans ma console:
    scene = : null


    par contre , si je met le code ci dessous dans ma méthode d'enregistrement d'un nouvel objet ArtistDetail dans ma Bd SQlite, méthode qui se nomme 'insertArtistToDatabase', j'obtiens un résultat cohérent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println("largeur de la scene =  : " + btnAddArtist.getScene().getWidth());
    et avec ca j'obtiens bien la bonne valeur qui est :
    largeur de la scene = : 300.0

    ce qui veut dire que dans ma méthode le Stage peut etre atteint, ce qui n'est pas le cas au moment de initiliaze.
    j'en conclus que au moment de initiliaze() les control marqués @FXML sont bien crées, mais pas encore attaché au Stage principal.

    voici le code de mon fichier 'secondaryController.java' :

    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
    79
    80
    81
    82
    83
    84
    package com.politi.bibliotheque.bibli;
     
    import java.io.IOException;
    import java.net.URL;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.ResourceBundle;
     
    import javafx.beans.binding.Bindings;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextField;
    import javafx.stage.Stage;
    import javafx.stage.Window;
     
    public class SecondaryController implements Initializable {
     
    	@FXML
    	private Stage stage;
     
     
     
    	@FXML
    	private TextField textFieldAddName;
     
    	@FXML
    	private TextField textFieldAddUrl;
     
    	@FXML
    	private TextField textFieldAddEmail;
     
    	@FXML
    	private Button btnAddArtist;
     
     
    	private DbConnection dc;
     
    	@FXML
    	public void insertArtistToDatabase(ActionEvent e) {
     
    		System.out.println("largeur de la scene =  : " + btnAddArtist.getScene().getWidth());
     
    		//récupération des infos dans les champs de saisie de texte
    		String NameArtist = textFieldAddName.getText();
    		String UrlArtist = textFieldAddUrl.getText();
    		String EmailArtist = textFieldAddEmail.getText();
     
    		//ouverture de la conection avec la base de donnée
    		dc = new DbConnection();
    		Connection connAddArtist = dc.connect();
     
    		// insertion nouvel artiste
    		try {
    			System.out.println(NameArtist);
    			int rv = connAddArtist.createStatement()
    					.executeUpdate("INSERT INTO artistes ( artistName, artistUrl, artistEmail ) VALUES ( '" + NameArtist + "','"
    							+ UrlArtist + "','"+EmailArtist+"' )");
    		} catch (SQLException e2) {
    				e2.printStackTrace();
    			}
     
    		// ouverture de la fenetre princpale
    		try {
    			App.setRoot("primary",800,500);
    		} catch (IOException e1) {
    			e1.printStackTrace();
    		}
     
    		//fermeture de la fenetre actuelle
    		Stage stage = (Stage) btnAddArtist.getScene().getWindow();
    	    stage.close();
    	}
     
    	@Override
    	public void initialize(URL location, ResourceBundle resources) {
    		btnAddArtist.setText("nouveau nom"); //test pour voir si mon bouton existe 
    		System.out.println(" scene =  : " + btnAddArtist.getScene()); // test qui retourne Null
     
    	}
     
    }

    je tourne un peu en rond avec cette histoire, mais au moins ca me permet de comprendre comment ca fonctionne

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/10/2020, 23h54
  2. [C#] Copie d'un texte selectionner dans un control
    Par Khrysby dans le forum Windows Forms
    Réponses: 4
    Dernier message: 24/12/2005, 09h55
  3. [HTML][Opera] texte dans les controles input type="subm
    Par frochard dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 29/11/2005, 14h29
  4. Ouvrir un Formulaire dans un control sous-Formulaire
    Par Berny03 dans le forum Access
    Réponses: 2
    Dernier message: 27/09/2005, 12h22
  5. Afficher un jpeg 2000 dans un controle
    Par barthelv dans le forum MFC
    Réponses: 1
    Dernier message: 17/05/2005, 09h57

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