Bonjour,

Je rencontre actuellement un problème pour une application que je développe. J'utilise une classe 'Compose' qui entre autre me permet de stoker le nom d'un composé ainsi que l'évolution de sa concentration sous forme d'une liste Observable ('concentrationComposeList '). Mon but est de lister de manière dynamique dans un tableau les valeurs contenues dans la liste 'concentrationComposeList' pour chaque composé généré par l'utilisateur.

Chaque colonne de mon tableau 'table' correspond donc à un composé. Les différentes lignes du tableau listent les valeurs contenues dans concentrationComposeList.
La seul façon que j'ai trouvé pour faire ça c'est de générer une liste 'data' de listes et de l'afficher dans le tableau.

Voici la méthode suivie:
A partir de la liste 'composeList' contenant l'ensemble des composés générés, je génère des sous listes 'row'
Chaque sous liste 'row' correspond à une ligne du tableau et est formée par les différentes concentrations des différents composés pour un même index.

La liste 'data' généré en compilant toutes ces sous listes 'row' est affichée dans le tableau.
Cela fonction puisque je visualise bien les valeurs.

Mon problème en procédant de cette manière est que les valeurs contenues dans le tableau et donc contenues dans 'data' ne sont pas liées aux valeurs contenues dans ComposeList. Pour s'en assurer, j'ai fait un petit test modifiant une valeur, dans l'un des composés listés dans ComposeList, la modifications n'est pas reportée dans le tableau...

Je souhaite ajouter des fonctionnalités d'édition des cellules du tableau, et de copier / coller de leur contenu. Il est donc indispensable pour moi que les valeurs contenues dans ComposeList soient correctement liées au contenu du tableau.
J'ai donc besoin de votre aide pour faire ça de manière plus élégante, et surtout pour faire en sorte que les valeurs listées dans le tableau soient liés aux composés générés par l'utilisateur...

Merci d'avance pour votre aide...


Voici le code de la classe Compose utilisée pour stocker les différentes données :
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
 
package application;
 
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
 
/**
 * Création d'une classe Compose qui permet de stocker à la fois 
 * le nom d'un composé ainsi que l'évolution de sa concentration au cours du temps
 */
public class Compose{
	// Nom du composé
	private final StringProperty  nomCompose; 
 
	// Liste permettant de stocker la concentration au cours du temps du composé
	private ObservableList<DoubleProperty> concentrationComposeList = FXCollections.observableArrayList();
 
	public Compose(String nom){
		this.nomCompose = new SimpleStringProperty(nom);
 
		// Pour cet exemple, la liste est générée aléatoirement
		for (int i=0; i< Math.round(Math.random()*10+5); i++){
			concentrationComposeList.add(new SimpleDoubleProperty(Math.round(Math.random()*10)));
		}
	}
 
	public String getNomCompose() {
		return nomCompose.get();
	}
 
	public void setNomCompose(String nomCompose) {
		this.nomCompose.set(nomCompose);
	}
 
	 public StringProperty nomComposeProperty() {
	        return nomCompose;
	    }
 
 
 
	public ObservableList<DoubleProperty> getConcentrationComposeList() {
		return concentrationComposeList;
	}
 
	public void setConcentrationComposeList(ObservableList<DoubleProperty> concentrationComposeList) {
		this.concentrationComposeList = concentrationComposeList;
	}
}
Voici le code de ma classe principale
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
 
package application;
 
import java.text.NumberFormat;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Callback;
 
public class TableCopyPasteCellsTest extends Application {
 
	private final static ObservableList<Compose> composeList = FXCollections.observableArrayList();
 
	@SuppressWarnings("rawtypes")
	private static ObservableList<ObservableList> data;
 
	public static void main(String[] args) {
		launch(args);
	}
 
	static int minNumberValue; // Variable permettant de connaître le nombre de valeurs de la plus petite série de données affichée dans le tableau
	static int maxNumberValue; // Variable permettant de connaître le nombre de valeurs de la plus grande série de données affichée dans le tableau
 
 
	private static NumberFormat numberFormatter = NumberFormat.getNumberInstance();
 
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void start(Stage stage) {
 
		// Ajout de nouveaux composés tests à la liste data.
		composeList.add(new Compose("A"));
		composeList.add(new Compose("B"));
 
		// Création du tableau
		TableView table = new TableView<>();
		table.setPlaceholder(new Text("No content in table"));
 
		data = FXCollections.observableArrayList();
 
 
		// création des différentes colonnes.
		int i=0;
		for (Compose p: composeList){
			final int j=i;
			TableColumn col = new TableColumn(p.getNomCompose());
			col.setMinWidth(100);
 
			col.setEditable(true);
			col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
				public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
					// On vérifie que l'élément param.getValue().get(j) contient bien une valeur.
					// Cela évite les erreurs de type "java.lang.Null Point Exception" dans le cas où les listes n'ont pas les mêmes longueur.
					if (param.getValue().get(j) != null){
						return new SimpleStringProperty(param.getValue().get(j).toString());   
					}else {
						return new SimpleStringProperty("");
					}
				}                   
			});
 
			i++;
 
			table.getColumns().addAll(col);			
			table.setEditable(true);
		}
 
 
		// Calcul du nombre de valeurs min et max contenues dans les séries de données de l'ensemble des composés
		minNumberValue = composeList.get(0).getConcentrationComposeList().size();
		maxNumberValue = composeList.get(0).getConcentrationComposeList().size();
		for (Compose p: composeList){
			if (p.getConcentrationComposeList().size()<minNumberValue){
				minNumberValue = p.getConcentrationComposeList().size();
			}
 
			if (p.getConcentrationComposeList().size()>minNumberValue){
				maxNumberValue = p.getConcentrationComposeList().size();
			}
		}
		displayComposeList();
 
 
		// Ajout des données à la liste ObservableList data
		for (int j=0; j<maxNumberValue+1; j++){
			ObservableList<String> row = FXCollections.observableArrayList();
			row.clear();
			for (Compose p: composeList){
				if (p.getConcentrationComposeList().size() > j){
					row.add(String.valueOf(p.getConcentrationComposeList().get(j).get()));
				}else {
					row.add(null);
				}
 
			}
			data.add(row);
		}
 
		table.setItems(data);
 
		// test permettant de vérifier si les listes composeList et data sont liées ou non
		System.out.println(composeList.get(0).getConcentrationComposeList().get(0));
		System.out.println("Modification de la première valeur du tableau dans la liste des composés");
		composeList.get(0).getConcentrationComposeList().get(0).set(0);
		System.out.println(composeList.get(0).getConcentrationComposeList().get(0));
		System.out.println(data);
 
		BorderPane borderPane= new BorderPane();
		borderPane.setCenter(table);
 
 
		Scene scene = new Scene(borderPane);
 
		stage.setScene(scene);
		stage.show();
 
	}
 
	private void displayComposeList(){
 
		System.out.println("ComposeList : ");
		for (int j=0; j<maxNumberValue; j++){
			for (Compose p: composeList){
				if (p.getConcentrationComposeList().size() > j){
					System.out.print(p.getConcentrationComposeList().get(j).get()+"\t");
				}else {
					System.out.print("null"+"\t");
				}	
			}
			System.out.println("");
		}
	}
}