Partage
  • Partager sur Facebook
  • Partager sur Twitter

Cours OpenClassrooms Java FX

Impossible de "compiler"

19 avril 2018 à 23:19:43

Bonsoir, 

j'ai suivi le cours sur Java FX pas à pas, mais j'ai une erreur sur une ligne.

dans PersonneMenuMapping : this.main.getStage().close(); (dommage qu'il y a pas le code source complet à la fin)

Voici tout le code ci-dessous.

PersonneMenuMapping

package fr.testfx.personnes.view;

import fr.testfx.personnes.MainClass;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;

public class PersonneMenuMapping {
    //Objet servant de référence à notre classe principale
    //afin de pouvoir récupérer le Stage principal.
	//et ainsi fermer l'application
    private MainClass main;
    
    //Méthode qui sera utilisée dans l'initialisation de l'IHM
    //dans notre classe principale
    public void setMainApp(MainClass mainApp) {
        this.main = mainApp;
    }
    
	//Fermer l'application
	@FXML
	public void fermer() {
		//On affiche un message car on est poli.
		Alert bye = new Alert(AlertType.INFORMATION);
		bye.setTitle("Au revoir !");
		bye.setHeaderText("See you soon...");
		bye.setContentText("Et merci d'avoir suivi ce cours");
		bye.showAndWait();
		
		//Et on clos le stage principal, donc l'application
		this.main.getStage().close();
		
		
	}
	
	@FXML
	public void nouveau() {
		
	}	
}

MainClass

package fr.testfx.personnes;

import java.io.IOException;
import java.time.LocalDate;

import fr.testfx.personnes.model.Personne;
import fr.testfx.personnes.model.Sexe;
import fr.testfx.personnes.view.PersonneMapping;
import fr.testfx.personnes.view.PersonneMenuMapping;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class MainClass extends Application {

	//Nous créons des variable de classes afin de pouvoir y accéder partout
	//Ceci afin de pouvoir y positionner les éléments que nous avons fait
	//Il y a un BorderPane car le conteneur principal de notre IHM
	//est un BorderPane, nous reparlerons de l'objet Stage
	private Stage stagePrincipal;
	private BorderPane conteneurPrincipal;
	
	private ObservableList<Personne> listDePersonne = FXCollections.observableArrayList();
	
	public MainClass() {
		listDePersonne.add(new Personne("Proviste", "Alain", LocalDate.of(1970, 1, 1), Sexe.MASCULIN));
		listDePersonne.add(new Personne("D'Arc", "Jeanne", LocalDate.of(1431, 5, 30), Sexe.FEMININ));
		listDePersonne.add(new Personne("Caisse", "Jean", LocalDate.of(1950, 3, 3), Sexe.MASCULIN));
	}
		
	public ObservableList<Personne> getListDePersonne(){return listDePersonne;}
	
	@Override
	public void start(Stage primaryStage) {
		stagePrincipal = primaryStage;
		//Ca ne vous rappelle pas une JFrame ?
		stagePrincipal.setTitle("Application de gestion de personnes");
		
		//Nous allons utiliser nos fichier FXML dans ces deux méthodes
		initialisationConteneurPrincipal();
		initialisationContenu();
	}

	private void initialisationConteneurPrincipal() {
		//On créé un chargeur de FXML
		FXMLLoader loader = new FXMLLoader();
		//On lui spécifie le chemin relatif à notre classe
		//du fichier FXML a charger : dans le sous-dossier view
		loader.setLocation(MainClass.class.getResource("view/ConteneurPrincipal.fxml"));
		//*
		try {
			//Le chargement nous donne notre conteneur
			conteneurPrincipal = (BorderPane) loader.load();
			System.out.println(conteneurPrincipal);
			//On définit une scène principale avec notre conteneur
			Scene scene = new Scene(conteneurPrincipal);
			//Que nous affectons à notre Stage
			stagePrincipal.setScene(scene);
			
			//Initialisation de notre contrôleur
			PersonneMenuMapping controleur = loader.getController();
			//On spécifie la classe principale afin de pour récupérer le Stage
			//Et ainsi fermer l'application
			controleur.setMainApp(this);
			
			stagePrincipal.show();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	
	private void initialisationContenu() {
		FXMLLoader loader = new FXMLLoader();
		loader.setLocation(MainClass.class.getResource("view/PersonView.fxml"));
		try {
			//Nous récupérons notre conteneur qui contiendra les données
			//Pour rappel, c'est un AnchorPane...
			AnchorPane conteneurPersonne = (AnchorPane) loader.load();
			//Qui nous ajoutons à notre conteneur principal
			//Au centre, puisque'il s'agit d'un BorderPane
			conteneurPrincipal.setCenter(conteneurPersonne);
			
			//Nous récupérons notre mappeur via l'objet FXMLLoader
			PersonneMapping controleur = loader.getController();
			//Nous lui passons notre instance de classe
			//pour qu'il puisse récupérer notre liste observable
			controleur.setMainApp(this);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	public static void main(String[] args) {
		launch(args);
	}

}

L'erreur : The method getStage() is undefined for the type MainClass (dans fermer de PersonneMenuMapping)

je peux mettre le code des autres classes ainsi que les fichiers FXML si nécessaire.

Merci d'avance.


  • Partager sur Facebook
  • Partager sur Twitter
20 avril 2018 à 7:01:01

Bonjour,

Normal, il n'y a pas de méthode getStage() définie dans la classe MainClass, seul l'attribut est stage défini.

Il faut définir des getter/setter pour chaque attribut à exposer en dehors de la classe. Pour le getter:

public Stage getStage() {
  return stagePrincipal;
}



  • Partager sur Facebook
  • Partager sur Twitter
20 avril 2018 à 13:33:42

Merci en effet avec le getter c'est résolu. 

-
Edité par TonyDeiure 21 avril 2018 à 21:50:03

  • Partager sur Facebook
  • Partager sur Twitter
21 avril 2018 à 21:50:11

Petit soucis maintenant avec la mise à jour des données. 

Quand je sauvegarde ou j'annule c'est l'application qui se ferme et non la fenêtre d'ajout/modification.

Code PersonneDialogueMapping

package fr.testfx.personnes.view;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import fr.testfx.personnes.MainClass;
import fr.testfx.personnes.model.Personne;
import fr.testfx.personnes.model.Sexe;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class PersonneDialogueMapping {

	private Stage stageDialogue;
	@FXML
	private TextField nomFormulaire;
	@FXML
	private TextField prenomFormulaire;
	@FXML
	private DatePicker dateFormulaire;
	@FXML
	private ComboBox<Sexe> sexeFormulaire;
	
	private MainClass main;	
	private Personne personne;
	
	public void setMainClass(MainClass m) {
		main = m;
		stageDialogue = main.getStage();
	}
	
	//On initialise ici les valeurs de la liste déroulante
	//avant de sélectionner la valeur de la personne
	public void initialize() {
		sexeFormulaire.getItems().setAll(Sexe.values());
	}
	
	//Afin de récupérer le stage de la popup
	//et pouvoir la clore
	public void setStage(Stage s) {stageDialogue = s;}
	
	public void setPersonne(Personne p) {
		personne = p;
		nomFormulaire.setText(personne.getNom().get());
		prenomFormulaire.setText(personne.getPrenom().get());
		dateFormulaire.setValue(personne.getDateDeNaissance().get());
		sexeFormulaire.getSelectionModel().select(personne.getSexe().get());
	}
	
	//Méthode de contrôle de la validité des données saisies
	private boolean controlerFormulaire() {
		boolean isOk = true;
		List<String> messageErreur = new ArrayList<>();
		if (nomFormulaire.getText() == null || nomFormulaire.getText().isEmpty()) {
			isOk = false;
			messageErreur.add("Le champ \"Nom\" est obligatoire");
		}
		if (prenomFormulaire.getText() == null || prenomFormulaire.getText().isEmpty()) {
			isOk = false;
			messageErreur.add("Le champ \"Prénom\" est obligatoire");
		}	
		if (dateFormulaire.getValue() == null || dateFormulaire.getValue().toString().isEmpty()) {
			isOk = false;
			messageErreur.add("Le champ \"Date\" est obligatoire");
		}
		
		if(!isOk) {
			Alert erreur = new Alert(AlertType.ERROR);
			erreur.setTitle("Erreur ! ");
			StringBuilder sb = new StringBuilder();
			messageErreur.stream().forEach((x) -> sb.append("\n" + x));
			erreur.setHeaderText(sb.toString());
			erreur.showAndWait();
		}		
		return isOk;
	}
	
	@FXML
	public void annuler() {
		//On ferme la boîte de dialogue
		stageDialogue.close();
	}
	
	//sauvegarde de la personne, que ce soit une édition ou une création
	public void sauvegarder() {
		if(controlerFormulaire()) {
			personne.setNom(new SimpleStringProperty(nomFormulaire.getText()));
			personne.setPrenom(new SimpleStringProperty(prenomFormulaire.getText()));
			
			//Afin de pouvoir gérer la modification de date à la souris
			//ou en modifiant le texte du composant directement
			//On récupère la date au format texte pour la réinjecter 
			//dans le composant
			dateFormulaire.setValue(
					dateFormulaire	.getConverter()
									.fromString(
											//Date du composant au format texte
											dateFormulaire.getEditor().getText()
									)
								);
			
			personne.setDateDeNaissance(new SimpleObjectProperty<LocalDate>(dateFormulaire.getValue()));
			personne.setSexe(new SimpleObjectProperty<Sexe>(sexeFormulaire.getValue()));

			//S'il s'agit d'une création, on ajoute la personne dans le tableau
			if(stageDialogue.getTitle().startsWith("Création")) {
				main.getListDePersonne().add(personne);
			}

			//On ferme la boîte de dialogue
			stageDialogue.close();
		}
	}
}


MainClass

package fr.testfx.personnes;

import java.io.IOException;
import java.time.LocalDate;

import fr.testfx.personnes.model.Personne;
import fr.testfx.personnes.model.Sexe;
import fr.testfx.personnes.view.PersonneDialogueMapping;
import fr.testfx.personnes.view.PersonneMapping;
import fr.testfx.personnes.view.PersonneMenuMapping;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class MainClass extends Application {

	//Nous créons des variable de classes afin de pouvoir y accéder partout
	//Ceci afin de pouvoir y positionner les éléments que nous avons fait
	//Il y a un BorderPane car le conteneur principal de notre IHM
	//est un BorderPane, nous reparlerons de l'objet Stage
	private Stage stagePrincipal;
	private BorderPane conteneurPrincipal;
	
	private ObservableList<Personne> listDePersonne = FXCollections.observableArrayList();
	
	public MainClass() {
		listDePersonne.add(new Personne("Proviste", "Alain", LocalDate.of(1970, 1, 1), Sexe.MASCULIN));
		listDePersonne.add(new Personne("D'Arc", "Jeanne", LocalDate.of(1431, 5, 30), Sexe.FEMININ));
		listDePersonne.add(new Personne("Caisse", "Jean", LocalDate.of(1950, 3, 3), Sexe.MASCULIN));
	}
		
	public ObservableList<Personne> getListDePersonne(){return listDePersonne;}
	
	@Override
	public void start(Stage primaryStage) {
		stagePrincipal = primaryStage;
		//Ca ne vous rappelle pas une JFrame ?
		stagePrincipal.setTitle("Application de gestion de personnes");
		
		//Nous allons utiliser nos fichier FXML dans ces deux méthodes
		initialisationConteneurPrincipal();
		initialisationContenu();
	}

	private void initialisationConteneurPrincipal() {
		//On créé un chargeur de FXML
		FXMLLoader loader = new FXMLLoader();
		//On lui spécifie le chemin relatif à notre classe
		//du fichier FXML a charger : dans le sous-dossier view
		loader.setLocation(MainClass.class.getResource("view/ConteneurPrincipal.fxml"));
		//*
		try {
			//Le chargement nous donne notre conteneur
			conteneurPrincipal = (BorderPane) loader.load();
			System.out.println(conteneurPrincipal);
			//On définit une scène principale avec notre conteneur
			Scene scene = new Scene(conteneurPrincipal);
			//Que nous affectons à notre Stage
			stagePrincipal.setScene(scene);
			
			//Initialisation de notre contrôleur
			PersonneMenuMapping controleur = loader.getController();
			//On spécifie la classe principale afin de pour récupérer le Stage
			//Et ainsi fermer l'application
			controleur.setMainApp(this);
			
			stagePrincipal.show();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	
	private void initialisationContenu() {
		FXMLLoader loader = new FXMLLoader();
		loader.setLocation(MainClass.class.getResource("view/PersonView.fxml"));
		try {
			//Nous récupérons notre conteneur qui contiendra les données
			//Pour rappel, c'est un AnchorPane...
			AnchorPane conteneurPersonne = (AnchorPane) loader.load();
			//Qui nous ajoutons à notre conteneur principal
			//Au centre, puisque'il s'agit d'un BorderPane
			conteneurPrincipal.setCenter(conteneurPersonne);
			
			//Nous récupérons notre mappeur via l'objet FXMLLoader
			PersonneMapping controleur = loader.getController();
			//Nous lui passons notre instance de classe
			//pour qu'il puisse récupérer notre liste observable
			controleur.setMainApp(this);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	public static void main(String[] args) {
		launch(args);
	}
	
	
	//Méthode qui va va afficher la popup d'édition
	//ou de création d'une personne et initialiser son contrôleur
	public void affichePersonneDialogue(Personne personne, String titre) {
	    try {
	        FXMLLoader loader = new FXMLLoader();
	        loader.setLocation(MainClass.class.getResource("view/PersonneDialogue.fxml"));
	        AnchorPane page = (AnchorPane) loader.load();
	        
	        // Création d'un nouveau Stage qui sera dépendant du Stage principal
	        Stage stageDialogue = new Stage();
	        stageDialogue.setTitle(titre);
	        stageDialogue.initModality(Modality.WINDOW_MODAL);
	        
	        //Avec cette instruction, notre fenêtre modifiée sera modale
	        //par rapport à notre stage principal
	        stageDialogue.initOwner(stagePrincipal);
	        Scene scene = new Scene(page);
	        stageDialogue.setScene(scene);
	        
	        // initialisation du contrôleur
	        PersonneDialogueMapping controller = loader.getController();
	        //On passe la personne avec laquelle nous souhaitons travailler
	        //une existante ou une nouvelle
	        controller.setPersonne(personne);
	        controller.setMainClass(this);
	        
	        // Show the dialog and wait until the user closes it
	        stageDialogue.showAndWait();
	        //return controller.isOkClicked();
	    } catch (IOException e) {
	    	e.printStackTrace();
	    }
	}
	
	public Stage getStage() {
		  return stagePrincipal;
		}

}

Je pense que le soucis vient du getter getStage() qui me retourne le stage principal et non courant? 

Avez-vous une solution? Merci d'avance

  • Partager sur Facebook
  • Partager sur Twitter
22 avril 2018 à 22:15:39

Sinon personne a le code complet du tuto de "Apprenez à programmer en Java - OpenClassrooms"  partie JavaFX

Merci d'avance.

  • Partager sur Facebook
  • Partager sur Twitter
12 mai 2018 à 0:15:03

Bonjour,

J'ai le même probleme: 

stageDialogue.close();


ferme le stage principal et pas le stage courant.

Pas de solutions ?

  • Partager sur Facebook
  • Partager sur Twitter
13 mai 2018 à 15:32:26

Bonjour,

pour faire fonctionner le code (du mois avec le menu nouveau), j'ai ajouté dans la class Mainclass>methode affichePersonneDialogue()

controller.setStage(stageDialogue);

ce qui donne

//code
controller.setMainClass(this); controller.setStage(stageDialogue); // Show the dialog and wait until the user closes it stageDialogue.showAndWait()
//code

... puis retirer (commenter) dans la class PersonneDialogueMapping, methode setMainClass()

//stageDialogue = main.getStage();

ce qui donne

public void setMainClass(MainClass mainApp) {
	this.main = mainApp;
	//stageDialogue = main.getStage();            
	}

De ce que j'ai compris, cette dernière ligne revient à dire "prends le 'Stage' de la class 'MainClass' (stagePrincipal) et met le dans 'stageDialogue'".

Donc lorsque l'on ferme stageDialogue, bah on ferme stagePrincipal et beh on ferme tout!






  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
6 juin 2018 à 22:45:31

@Gregmartial : Bien vu pour les modifs.

C'est dingue que l'appli finale soit buggée à ce point et que depuis 2015 le créateur ne soit jamais repassé dessus pour corriger les erreurs, sans même parler de toutes les fautes qui truffent l'ensemble.

Je rêve ou le traitement du bouton "Editer" n'est jamais réalisé ?

Ma solution :

rajouter la méthode modifierPersonne à la classe PersonneMapping, et "binder" le bouton Editer dessus

	@FXML
	public void modifierPersonne() {
		int index = personneTable.getSelectionModel().getSelectedIndex();
		//Si aucune ligne n'est sélectionnée, index vaudra -1
		if (index > -1) {
			this.main.affichePersonneDialogue(personneTable.getItems().get(index), "Modification d'une personne");
		} else {
			Alert probleme = new Alert(Alert.AlertType.ERROR);
			probleme.setTitle("Erreur");
			probleme.setHeaderText("Veuillez sélectionnez une ligne dans le tableau");
			probleme.showAndWait();
		}
	}

Par contre, cela ne rafraichit pas la partie Informations après la sauvegarde. Sans doute quelque chose à rajouter dans la partie concernée de la méthode sauvegarder de PersonneDialogueMapping :

			//S'il s'agit d'une création, on ajoute la personne dans le tableau
			if(stageDialogue.getTitle().startsWith("Création")) {
				main.getListDePersonne().add(personne);
			} else {
				// fonction à rajouter pour le rafraichissement Informations après Edition
			}

Mais je n'ai pas encore trouvé quoi...

EDIT :

Bon, j'ai essayé en y plaçant :

				// fonction à rajouter pour le rafraichissement Informations après Edition
				FXMLLoader loader = new FXMLLoader();
				loader.setLocation(MainClass.class.getResource("view/PersonView.fxml"));
				PersonneMapping controleur = loader.getController();
				controleur.initializeDescription( personne );

mais sans succès.

Ça me semblait plus propre de rafraichir à cet endroit, mais en rajoutant

			this.initializeDescription(personneTable.getItems().get(index));

dans la méthode modifierPersonne() (rajoutée plus haut) pour obtenir :

	@FXML
	public void modifierPersonne() {
		int index = personneTable.getSelectionModel().getSelectedIndex();
		//Si aucune ligne n'est sélectionnée, index vaudra -1
		if (index > -1) {
			this.main.affichePersonneDialogue(personneTable.getItems().get(index), "Modification d'une personne");
			this.initializeDescription(personneTable.getItems().get(index));
		} else {
			Alert probleme = new Alert(Alert.AlertType.ERROR);
			probleme.setTitle("Erreur");
			probleme.setHeaderText("Veuillez sélectionnez une ligne dans le tableau");
			probleme.showAndWait();
		}
	}

ça fonctionne correctement.
Si ça peut aider quelqu'un à y voir plus clair...

-
Edité par Anonyme 6 juin 2018 à 23:59:17

  • Partager sur Facebook
  • Partager sur Twitter
17 juin 2018 à 14:57:46

J'ai une solution toute facile et fonctionnelle :ange:

Dans votre classe MainClass, il faut:

  • Premièrement, ajouter une méthode getStage() comme ceci
    public Stage getStage() {
    	return this.stagePrincipal;
    }
  • Deuxièmement, ajouter deux lignes de code à votre méthode initialisationConteneurPrincipal() comme ceci
    private void initialisationConteneurPrincipal() {
    		
    	FXMLLoader loader = new FXMLLoader();
    	loader.setLocation(MainClass.class.getResource("view/ConteneurPrincipal.fxml"));
    		
    	try {
    		conteneurPrincipal = (BorderPane) loader.load();
    		Scene scene = new Scene(conteneurPrincipal);
    			
    		PersonneMenuMapping controller = loader.getController(); // ici
    		controller.setMainApp(this);  // et ici
    			
    		stagePrincipal.setScene(scene);
    		stagePrincipal.show();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    }



-
Edité par African_King 17 décembre 2018 à 17:59:44

  • Partager sur Facebook
  • Partager sur Twitter
Je suis ce que je veux être
19 juin 2018 à 17:48:47

Chris972 : j'ai essayé votre solution, mais j'ai toujours le bouton ''Valider'' qui ne fonctionne pas. Je voudrais savoir ce que vous avez mis comme méthode dans ''On Action" correspond à ce bouton.
S'il vous plait, je suis vraiment bloquée, si quelqu'un peut me dire ce je dois rajouter à mon code pour faire fonctionner le bouton ''Valider'' ?
Merci pour votre aide.

-
Edité par FatimaAaa1 19 juin 2018 à 19:53:37

  • Partager sur Facebook
  • Partager sur Twitter
Anonyme
21 juin 2018 à 3:16:39

FatimaAaa1 a écrit:

Chris972 : j'ai essayé votre solution, mais j'ai toujours le bouton ''Valider'' qui ne fonctionne pas. Je voudrais savoir ce que vous avez mis comme méthode dans ''On Action" correspond à ce bouton.

S'il vous plait, je suis vraiment bloquée, si quelqu'un peut me dire ce je dois rajouter à mon code pour faire fonctionner le bouton ''Valider'' ?
Merci pour votre aide.

-
Edité par FatimaAaa1 19 juin 2018 à 19:53:37

Je ne sais pas si ça répondra totalement à la question étant donné même seulement 10 jours après, il me semble que ça date d'un siècle (je suis passé au dev d'appli android depuis, et j'ai l'impression d'avoir tout oublié de de cours :( ), mais j'ai retrouvé mes sources et j'ai :

./view/PersonneDialogue.fxml:            <Button mnemonicParsing="false" onAction="#sauvegarder" text="Valider" GridPane.halignment="CENTER" GridPane.rowIndex="4" />

Bon courage.


  • Partager sur Facebook
  • Partager sur Twitter
21 juin 2018 à 11:38:20

Merci beaucoup Chris972.

Bon courage à vous aussi.

  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2018 à 15:43:40

J'ai trouvé ce tutoriel qui est très similaire à celui-ci : https://code.makery.ch/fr/library/javafx-tutorial/ et il n'y a pas de problème.
  • Partager sur Facebook
  • Partager sur Twitter
Quentin
10 mai 2019 à 19:28:53

Bonjour,

Au cas où ça peut aider, il manque quelques lignes dans le tutoriel pour pouvoir afficher les changements en cas d'édition d'une Personne.

Tout d'abord, il faut que notre controleur PersonneDialogueMapping garde l'instance de notre stage en attribut. La méthode a été implémentée dans le cours, mais pas utilisée. il manquait juste une ligne ici, dans MainClass.java :

	// Méthode qui va afficher la popup d'édition
	// ou de création d'une personne et initialiser son contrôleur
	public void affichePersonneDialogue(Personne personne, String titre) {
		try {
			FXMLLoader loader = new FXMLLoader();
			loader.setLocation(MainClass.class.getResource("view/PersonneDialogue.fxml"));
			AnchorPane page = (AnchorPane) loader.load();
			
			// Création d'un nouveau stage qui sera dépendant du stage principal
			Stage stageDialogue = new Stage();
			stageDialogue.setTitle(titre);
			stageDialogue.initModality(Modality.WINDOW_MODAL);
			
			// Avec cette instruction, notre fenêtre modifiée sera modale
			// par rapport à notre stage principal
			stageDialogue.initOwner(stagePrincipal);
			Scene scene = new Scene(page);
			stageDialogue.setScene(scene);
			
			// initialisation du contrôleur
			PersonneDialogueMapping controller = loader.getController();
			// ### La ligne manquante ###
			controller.setStage(stageDialogue);
			// On passe la personne avec laquelle nous souhaitons travailler
			// une existante ou une nouvelle
			controller.setPersonne(personne);
			controller.setMainClass(this);
			
			// Show the dialog and wait until the user closes it
			stageDialogue.showAndWait();
	
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

Ensuite, il faut implémenter notre méthode de modification dans PersonneMapping.java :

    @FXML
    public void editerPersonne() {
    int index = personneTable.getSelectionModel().getSelectedIndex();
    if(index >-1) {
        main.affichePersonneDialogue(personneTable.getItems().get(index), "Edition d'une personne");
        // ### Ici, on doit appeler la méthode "TabelView.refresh()" ###			
        personneTable.refresh();
	}else{
                Alert probleme = new Alert(AlertType.ERROR);
probleme.setTitle("Erreur");
probleme.setHeaderText("Veuillez sélectionner une ligne dans le tableau");
probleme.showAndWait(); }
}

Bien sûr, il ne faudra pas oublier de mapper cette méthode au bouton "Editer" dans SceneBuilder.

Si j'ai bien compris les résultats de mes petites recherches, dans notre méthode supprimerPersonne(), nous n'avions pas besoin de faire "refresh()" car  ObservableList.remove() envoie un event qui impose son conteneur TableView à se rafraichir. Mais dans la méthode editerPersonne(), nous accédons à notre Personne par le biais d'un getter, notre MainClass modifiera directement notre instance de Personne sans envoyer d'Event. Je ne suis pas certain d'avoir tout compris, car les attributs ObjectProperty de notre classe Personne implémentent Observable...

TableView.refresh() n'existe que depuis JavaFX 8u60. Si antérieur, il faudra passer par une suppression et repopulation explicite de notre TableView (ce que fait refresh(), en fait...), en forçant la Scene à redessiner notre TableView. Comme ceci :

	@FXML
	public void editerPersonne() {
		int index = personneTable.getSelectionModel().getSelectedIndex();
		if(index >-1) {
			main.affichePersonneDialogue(personneTable.getItems().get(index), "Edition d'une personne");
			ObservableList<Personne> personnes = personneTable.getItems();
			personneTable.setItems(null);
			personneTable.layout();
			personneTable.setItems(personnes);
		}
		else {
			Alert probleme = new Alert(AlertType.ERROR);
			probleme.setTitle("Erreur");
			probleme.setHeaderText("Veuillez sélectionner une ligne dans le tableau");
			probleme.showAndWait();
		}
	}



-
Edité par WaelGribaa 10 mai 2019 à 19:33:31

  • Partager sur Facebook
  • Partager sur Twitter
20 janvier 2020 à 21:20:05

Proposition pour la méthode manquante pour Editer (ou modifier) :

1) Dans la classe PersonneMapping :

@FXML

    public void editerPersonne() {

//On affiche la popup avec une personne existante

    int index = personneTable.getSelectionModel().getSelectedIndex();

//Si aucune ligne n'est sélectionnée, index vaudra -1

    if (index > -1) {

    PersonneDialogueMapping montest = new PersonneDialogueMapping();

    this.main.affichePersonneDialogue(personneTable.getItems().get(index), "Edition d'une personne");

// tester si l'édition a demandé une sauvegarde :

    if (montest.getSauvegardeStatus()) {

    System.out.println("Edition doit faire un remove du doublon");

    personneTable.getItems().remove(index);

// on force le TableView a se rafraichir (sinon bug sur dernier élément)

    personneTable.refresh();

montest.setSauvegardeStatus(); // on reset l'utilisation de la sauvegarde

   }

    else {

// Uniquement pour Debug :

    System.out.println("Edition annulée, pas de remove !!!");

   }

   }

    else {

    Alert probleme = new Alert(AlertType.ERROR);

    probleme.setTitle("Erreur");

probleme.setHeaderText("Veuillez sélectionnez une ligne dans le tableau");

    probleme.showAndWait();

   }   

    }

2) Dans la classe PersonneDialogueMapping :

   // pour la méthode editerPersonne() de PersonneMapping :

privatestaticbooleanmodifDone = false;


@FXML

//sauvegarde de la personne, que ce soit une édition ou une création

public void sauvegarder() {

if(controlerFormulaire()) {

personne.setNom(new SimpleStringProperty(nomFormulaire.getText()));

personne.setPrenom(new SimpleStringProperty(prenomFormulaire.getText()));

//Afin de pouvoir gérer la modification de date à la souris

//ou en modifiant le texte du composant directement

//On récupère la date au format texte pour la réinjecter 

//dans le composant

dateFormulaire.setValue(

dateFormulaire.getConverter()

.fromString(

//Date du composant au format texte

dateFormulaire.getEditor().getText()

)

);

personne.setDateDeNaissance(new SimpleObjectProperty<LocalDate>(dateFormulaire.getValue()));

personne.setSexe(new SimpleObjectProperty<Sexe>(sexeFormulaire.getValue()));

//S'il s'agit d'une création, on ajoute la personne dans le tableau

if(stageDialogue.getTitle().startsWith("Création")) {

main.getListDePersonne().add(personne);

}

// ------ Patch pour finaliser la méthode editerPersonne() non existante ----- //

else {

if(stageDialogue.getTitle().startsWith("Edition")) {

main.getListDePersonne().add(personne);

System.out.println("je suis dans sauvegarde partie Edition");

modifDone = true;

}

}

// --------------------------------------------------------------------------- //

//On ferme la boîte de dialogue

stageDialogue.close();

}

}

// ------- Acesseurs pour la méthode editerPersonne() de PersonneMapping ------- // 

public boolean getSauvegardeStatus() { return modifDone; }

public void setSauvegardeStatus() { modifDone = false; }

// ------------------------------------------------------------------------------ //

Voilà, c'est pas super propre, mais ça fonctionne bien.

  • Partager sur Facebook
  • Partager sur Twitter
20 janvier 2020 à 23:59:15

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter