Problème de binding - tableau dynamique
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:
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:
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("");
}
}
} |