Bonjour,
Je me heurte à un problème d'héritage.
Voilà, je créée une application de style répertoire de personnes grâce à laquelle je souhaite afficher les attributs des Objets suivants :
- Personne
- Eleve extends Personne
- Professeur extends Personne
- Elu extends Personne
Bien sûr, la classe Personne détient tous les attributs qui sont communs aux classes filles, et les classes filles détiennent des attributs spécifiques. Mis à part un attribut nommé "instrument" qui est présent dans les classes filles Eleve et professeur et que j'ai décidé de mettre dans Personne (voir les constructeurs des classes filles plus bas dans ce message).
Je désire donc afficher ces objets dans une sorte de répertoire qui contiendra des champs issus de toutes les sous-classes (classes filles) de Personnes.
Pour préparer un jeu de données, j'ai créé plusieurs instances de chaque sous-classe de Personne dans le constructeur de la classe MainApp :
Mon problème se situe dans l'assignation des champs de chaque objet aux colonnes du répertoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 // The data as an observable list of Personne private ObservableList<Personne> personnes = FXCollections.observableArrayList(); public ObservableList<Personne> getPersonnes() {return personnes;} //CONSTRUCTEUR public MainApp() { // Add some sample data personnes.add(new Elu("nom1", "prenom1", 35, 1, null, null, null, null, null, null, "PRESIDENT")); personnes.add(new Eleve("nom2", "prenom2", 42, 2, null, null, null, null, null, null, "BATTERIE")); personnes.add(new Professeur("nom3", "prenom3", 17, 2, null, null, null, null, null, null, "PIANO", null)); personnes.add(new Elu("nom4", "prenom4", 8, 5, null, null, null, null, null, null, "TRESORIER")); personnes.add(new Eleve("nom5", "prenom5", 37, 4, null, null, null, null, null, null, "PIANO")); personnes.add(new Professeur("nom6", "prenom6", 29, 3, null, null, null, null, null, null, "BATTERIE", "SOLFEGE")); }
Cette assignation est décrite dans la méthode initialize() de la classe PersonneOverviewControleur que voici :
Ce qui se passe c'est qu'ayant créé un jeu de différentes sous classes de Personnes , lorsqu'il faut assigner un champs qui n'est pas présent dans la classe mère, je me retrouve avec une belle ClassCastException que voici !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 // Initializes the controller class. This method is automatically called // after the fxml file has been loaded. @FXML private void initialize() { // Initialize the personne table with the columns. nomColumn.setCellValueFactory(cellData -> cellData.getValue().nomProperty()); prenomColumn.setCellValueFactory(cellData -> cellData.getValue().prenomproperty()); instrumentColumn.setCellValueFactory(cellData -> cellData.getValue().instrumentProperty()); fonctionColumn.setCellValueFactory(cellData -> cellData.getValue().fonctionProperty()); matiereColumn.setCellValueFactory(cellData -> cellData.getValue().matiereproperty()); }
Donc pour résumer, je pense que les différentes Personne issues du jeu de données sont traitées une par une comme un for afin d'en extraire les différents attributs que je souhaite assigner aux champs. Mais lorsque le programme arrive à l'assignation d'un champs spécifique à une classe fille (par exemple Elu) alors qu'il est en train de traiter un autre classe fille qui ne contient pas ce champs (par exemple Eleve), une erreur est générée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: saubens.ecole.adherents.model.Eleve cannot be cast to saubens.ecole.adherents.model.Elu at saubens.ecole.adherents.view.PersonneOverviewControleur.lambda$3(PersonneOverviewControleur.java:70)
Alors, je pense qu'une solution aurait été de tester l'objet issu du jeu de données avant de l'assigner à une colonne mais je ne peux pas tester car la méthode initialize() est appelée par le .fxml (enfin d'après ce que j'ai compris ...) et je n'ai pas trouvé comment je peux appeler dans un if l'objet qui est traité dans initialize() ...
Merci de bien vouloir m'aider !
Voici toutes mes classes :
package : model, classe : Personne.java :
package : model, classe : Eleve.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 package saubens.ecole.adherents.model; import java.time.LocalDate; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class Personne { //ATTRIBUTS private final StringProperty nom; private final StringProperty prenom; private final IntegerProperty age; private final IntegerProperty anciennete; private final StringProperty genre; private final ObjectProperty<LocalDate> anniversaire; private final StringProperty adresse; private final StringProperty email; private final StringProperty tel1; private final StringProperty tel2; private final StringProperty instrument; //CONSTRUCTEURS public Personne() { this(null, null, 0, 0, null, null, null, null, null, null, null); } public Personne(String nom, String prenom, Integer age, Integer anciennete, String genre, LocalDate anniversaire, String adresse, String email, String tel1, String tel2, String instrument) { this.nom = new SimpleStringProperty(nom); this.prenom = new SimpleStringProperty(prenom); this.age = new SimpleIntegerProperty(age); this.anciennete = new SimpleIntegerProperty(anciennete); this.genre = new SimpleStringProperty(genre); //Attention, il faudra peut-être une classe utilitaire de conversion des jour (int), mois(int) et année(int) // -> LocalDate.of(int jour, int mois, int année)) this.anniversaire = new SimpleObjectProperty<LocalDate>(anniversaire); this.adresse = new SimpleStringProperty(adresse); this.email = new SimpleStringProperty(email); this.tel1 = new SimpleStringProperty(tel1); this.tel2 = new SimpleStringProperty(tel2); this.instrument = new SimpleStringProperty(instrument); } //ACCESSEURS public String getNom() {return nom.get();} public void setNom(String nom) {this.nom.set(nom);} public StringProperty nomProperty() {return nom;} public String getPrenom() {return prenom.get();} public void setPrenom(String prenom) {this.prenom.set(prenom);} public StringProperty prenomproperty() {return prenom;} public int getAge() {return age.get();} public void setAge(int age) {this.age.set(age);} public IntegerProperty ageProperty() {return age;} public int getAnciennete() {return anciennete.get();} public void setAnciennete(int anciennete) {this.anciennete.set(anciennete);} public IntegerProperty ancienneteProperty() {return anciennete;} public String getGenre() {return genre.get();} public void setGenre(String genre) {this.genre.set(genre);} public StringProperty genreProperty() {return genre;} public LocalDate getAnniversaire() {return anniversaire.get();} public void setAnniversaire(LocalDate anniversaire) {this.anniversaire.set(anniversaire);} public ObjectProperty<LocalDate> anniversaireProperty() {return anniversaire;} public String getAdresse() {return adresse.get();} public void setAdresse(String adresse) {this.adresse.set(adresse);} public StringProperty adresseProperty() {return adresse;} public String getEmail() {return email.get();} public void setEmail(String email) {this.email.set(email);} public StringProperty emailProperty() {return email;} public String getTel1() {return tel1.get();} public void setTel1(String tel) {this.tel1.set(tel);} public StringProperty tel1Property() {return tel1;} public String getTel2() {return tel2.get();} public void setTel2(String tel) {this.tel2.set(tel);} public StringProperty tel2Property() {return tel2;} public String getInstrument() {return instrument.get();} public void setInstrument(String instrument) {this.instrument.set(instrument);} public StringProperty instrumentProperty() {return instrument;} //METHODES }
package : model, classe : Elu.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 package saubens.ecole.adherents.model; import java.time.LocalDate; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class Eleve extends Personne{ //ATTRIBUTS protected final StringProperty instrument; //CONSTRUCTEURS public Eleve(String nom, String prenom, Integer age, Integer anciennete, String genre, LocalDate anniversaire, String adresse, String email, String tel1, String tel2, String instrument) { super(nom, prenom, age, anciennete, genre, anniversaire, adresse, email, tel1, tel2, instrument); this.instrument = new SimpleStringProperty(instrument); } //ACCESSEURS public String getInstrument() {return instrument.get();} public void setInstrument(String instrument) {this.instrument.set(instrument);} public StringProperty instrumentProperty() {return instrument;} }
package : model, classe : Professeur.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 package saubens.ecole.adherents.model; import java.time.LocalDate; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class Elu extends Personne{ //ATTRIBUTS private final StringProperty fonction; //CONSTRUCTEURS public Elu(String nom, String prenom, Integer age, Integer anciennete, String genre, LocalDate anniversaire, String adresse, String email, String tel1, String tel2, String fonction) { super(nom, prenom, age, anciennete, genre, anniversaire, adresse, email, tel1, tel2, null); this.fonction = new SimpleStringProperty(fonction); } //ACCESSEURS public String getFonction() {return fonction.get();} public void setFonction(String fonction) {this.fonction.set(fonction);} public StringProperty fonctionProperty() {return fonction;} }
package : view, classe : PersonneOverviewControleur.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 package saubens.ecole.adherents.model; import java.time.LocalDate; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; public class Professeur extends Personne{ //ATTRIBUTS private final StringProperty instrument; private final StringProperty matiere; //CONSTRUCTEURS public Professeur(String nom, String prenom, Integer age, Integer anciennete, String genre, LocalDate anniversaire, String adresse, String email, String tel1, String tel2, String instrument, String matiere) { super(nom, prenom, age, anciennete, genre, anniversaire, adresse, email, tel1, tel2, instrument); this.instrument = new SimpleStringProperty(instrument); this.matiere = new SimpleStringProperty(matiere); } //ACCESSEURS public String getInstrument() {return instrument.get();} public void setInstrument(String instrument) {this.instrument.set(instrument);} public StringProperty instrumentProperty() {return instrument;} public String getMatiere() {return matiere.get();} public void setMatiere(String matiere) {this.matiere.set(matiere);} public StringProperty matiereproperty() {return matiere;} }
package : view, classe : AdherentsOverview.fxml
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 package saubens.ecole.adherents.view; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn.CellDataFeatures; import javafx.scene.control.TableView; import saubens.ecole.adherents.MainApp; import saubens.ecole.adherents.model.Elu; import saubens.ecole.adherents.model.Personne; import saubens.ecole.adherents.model.Professeur; public class PersonneOverviewControleur { @FXML private TableView<Personne> personneTable; @FXML private TableColumn<Personne, String> nomColumn; @FXML private TableColumn<Personne, String> prenomColumn; @FXML private TableColumn<Personne, String> instrumentColumn; @FXML private TableColumn<Elu, String> fonctionColumn; @FXML private TableColumn<Professeur, String> matiereColumn; @FXML private Label nomLabel; @FXML private Label prenomLabel; @FXML private Label adresseLabel; @FXML private Label tel1Label; @FXML private Label tel2Label; @FXML private Label emailLabel; @FXML private Label genreLabel; @FXML private Label ageLabel; @FXML private Label ancienneteLabel; @FXML private Label anniversaireLabel; @FXML private Label instrumentLabel; @FXML private Label fonctionLabel; @FXML private Label matiereLabel; @FXML private Label distanceLabel; // Reference to the main application. private MainApp mainApp; // The constructor is called before the initialize() method. public PersonneOverviewControleur() {} // Initializes the controller class. This method is automatically called // after the fxml file has been loaded. @FXML private void initialize() { // Initialize the personne table with the columns. nomColumn.setCellValueFactory(cellData -> cellData.getValue().nomProperty()); prenomColumn.setCellValueFactory(cellData -> cellData.getValue().prenomproperty()); instrumentColumn.setCellValueFactory(cellData -> cellData.getValue().instrumentProperty()); fonctionColumn.setCellValueFactory(cellData -> cellData.getValue().fonctionProperty()); matiereColumn.setCellValueFactory(cellData -> cellData.getValue().matiereproperty()); } // Is called by the main application to give a reference back to itself. public void setMainApp(MainApp mainApp) { this.mainApp = mainApp; // Add observable list data to the table personneTable.setItems(mainApp.getPersonnes()); } }
package : view, classe : RootLayout.fxml
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 <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.CheckBox?> <?import javafx.scene.control.SplitPane?> <?import javafx.scene.control.TableColumn?> <?import javafx.scene.control.TableView?> <?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.Pane?> <AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.72" xmlns:fx="http://javafx.com/fxml/1" fx:controller="saubens.ecole.adherents.view.PersonneOverviewControleur"> <children> <SplitPane dividerPositions="0.3182957393483709" layoutX="87.0" layoutY="193.0" prefHeight="600.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <items> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> <children> <Pane layoutX="57.0" layoutY="33.0" prefHeight="90.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> <CheckBox layoutX="9.0" layoutY="9.0" mnemonicParsing="false" text="Eleves" /> <CheckBox layoutX="9.0" layoutY="36.0" mnemonicParsing="false" text="Professeurs" /> <CheckBox layoutX="9.0" layoutY="66.0" mnemonicParsing="false" text="Bureau" /> </children> </Pane> <TableView fx:id="personneTable" layoutX="17.0" layoutY="208.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="90.0"> <columns> <TableColumn fx:id="nomColumn" prefWidth="75.0" text="Nom" /> <TableColumn fx:id="prenomColumn" prefWidth="75.0" text="Prenom" /> <TableColumn fx:id="instrumentColumn" prefWidth="90.0" text="Instrument" /> <TableColumn fx:id="fonctionColumn" prefWidth="75.0" text="Fonction" /> <TableColumn fx:id="matiereColumn" prefWidth="75.0" text="Matière" /> </columns> </TableView> </children> </AnchorPane> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" /> </items> </SplitPane> </children> </AnchorPane>
classe : MainApp.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 <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Menu?> <?import javafx.scene.control.MenuBar?> <?import javafx.scene.control.MenuItem?> <?import javafx.scene.layout.BorderPane?> <BorderPane prefHeight="700.0" prefWidth="800.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.72"> <top> <MenuBar BorderPane.alignment="CENTER"> <menus> <Menu mnemonicParsing="false" text="File"> <items> <MenuItem mnemonicParsing="false" text="Close" /> </items> </Menu> <Menu mnemonicParsing="false" text="Edit"> <items> <MenuItem mnemonicParsing="false" text="Delete" /> </items> </Menu> <Menu mnemonicParsing="false" text="Help"> <items> <MenuItem mnemonicParsing="false" text="About" /> </items> </Menu> </menus> </MenuBar> </top> </BorderPane>
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
85
86
87
88
89
90
91
92
93
94
95 package saubens.ecole.adherents; import java.io.IOException; import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import saubens.ecole.adherents.model.Eleve; import saubens.ecole.adherents.model.Elu; import saubens.ecole.adherents.model.Personne; import saubens.ecole.adherents.model.Professeur; import saubens.ecole.adherents.view.PersonneOverviewControleur; public class MainApp extends Application { private Stage primaryStage; private BorderPane rootLayout; // The data as an observable list of Personne private ObservableList<Personne> personnes = FXCollections.observableArrayList(); public ObservableList<Personne> getPersonnes() {return personnes;} //CONSTRUCTEUR public MainApp() { // Add some sample data personnes.add(new Elu("nom1", "prenom1", 35, 1, null, null, null, null, null, null, "PRESIDENT")); personnes.add(new Eleve("nom2", "prenom2", 42, 2, null, null, null, null, null, null, "BATTERIE")); personnes.add(new Professeur("nom3", "prenom3", 17, 2, null, null, null, null, null, null, "PIANO", null)); personnes.add(new Elu("nom4", "prenom4", 8, 5, null, null, null, null, null, null, "TRESORIER")); personnes.add(new Eleve("nom5", "prenom5", 37, 4, null, null, null, null, null, null, "PIANO")); personnes.add(new Professeur("nom6", "prenom6", 29, 3, null, null, null, null, null, null, "BATTERIE", "SOLFEGE")); } @Override public void start(Stage primaryStage) { this.primaryStage = primaryStage; this.primaryStage.setTitle("Ecole de musique de Saubens"); initRootLayout(); showAdherentsOverview(); } // Initializes the root layout. public void initRootLayout() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml")); rootLayout = (BorderPane) loader.load(); // Show the scene containing the root layout. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } // Shows the adherents overview inside the root layout. public void showAdherentsOverview() { try { // Load adherents overview. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("view/AdherentsOverview.fxml")); AnchorPane adherentsOverview = (AnchorPane) loader.load(); // Set adherents overview into the center of root layout. rootLayout.setCenter(adherentsOverview); // Give the controller access to the main app. PersonneOverviewControleur controleur = loader.getController(); controleur.setMainApp(this); } catch (IOException e) { e.printStackTrace(); } } // Returns the main stage. public Stage getPrimaryStage() { return primaryStage; } public static void main(String[] args) { launch(args); } }
Partager