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 :

éditer une TableView<Object[]>


Sujet :

JavaFX

  1. #1
    Futur Membre du Club
    éditer une TableView<Object[]>
    Bonsoir tout le monde!!!!!! SVP j'aimerais savoir comment éditer une tableView.

    j'ai une requête SQL du genre:
    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
     
    public List<Object[]> NotesEtu(String fil,String sem,String ue, Integer anne){
     
             EntityManager em = fab.createEntityManager();
             String query;
             query ="select e , n from Etudiant e ,Semmestre s,Filiere   f,Annscolaire a ,Cours c, Notes n ,Inscription i, Programmerue g \n"
                     + "Where s.nomsem = '"+sem+"'\n"
                     + "AND f.libelle = '"+fil+"'\n"
                     + "AND a.idAnne = "+anne+"\n"
                     + "AND c.codecours = '"+ue+"'\n"  
                     + "AND e.idetu =n.idetu \n"
                     + "AND e.idetu =i.idEtudiant \n"
                     + "AND n.idetu =i.idEtudiant \n"
                     +"AND c.idcours =g.cour \n"
                     +"AND c.idcours =n.idcours \n"
                     +"AND n.idcours =g.cour\n"
                     +"AND g.semmestres = s.idsem \n"
                     +"AND g.filier = f.idfil \n"
                     +"AND i.fac = f.idfil \n"
                     +"AND i.fac = g.filier \n"
                     +"AND a.idAnne =n.annesco \n"
                     +"AND i.annee = n.annesco \n"
                     +"AND a.idAnne = i.annee \n";
     
     
             Query q;
             q = em.createQuery(query);
           return  (List<Object[]>) q.getResultList();
     
         }

    Et ensuite je l'affiche dans ma tableView (private TableView<Object[]> tabNotes en fessant :
    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
     
        public void genererNotesNomEeu() {
     
            noteNameEtu.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Etudiant nometu = (Etudiant) value[0];
                return new SimpleObjectProperty<>(nometu);
            });
            notePrrenomEtu.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Etudiant prenom = (Etudiant) value[0];
                return new SimpleObjectProperty<>(prenom);
            });
            note1.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Notes note1 = (Notes) value[1];
                return new SimpleObjectProperty<>(note1);
            });
            note2.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Notes note2 = (Notes) value[1];
                return new SimpleObjectProperty<>(note2);
            });
            noteExamen.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Notes noteE = (Notes) value[1];
                return new SimpleObjectProperty<>(noteE);
            });
     
            noteNameEtu.setCellFactory(tv -> new TableCell<Object[], Etudiant>() {
                public void updateItem(final Etudiant value, final boolean empty) {
                    super.updateItem(value, empty);
                    String text = null;
                    if (!empty && value != null) {
                        text = value.getNometu();
                    }
                    setText(text);
                }
            });
     
            notePrrenomEtu.setCellFactory(tv -> new TableCell<Object[], Etudiant>() {
                public void updateItem(final Etudiant value, final boolean empty) {
                    super.updateItem(value, empty);
                    String text = null;
                    if (!empty && value != null) {
                        text = value.getPrenometu();
                    }
                    setText(text);
                }
            });
            note1.setCellFactory(tv -> new TableCell<Object[], Notes>() {
                public void updateItem(final Notes value, final boolean empty) {
                    super.updateItem(value, empty);
                    String text = null;
                    if (!empty && value != null) {
                        text = "" + value.getDevoire1();
                    }
                    setText(text);
                }
            });
     
            note2.setCellFactory(tv -> new TableCell<Object[], Notes>() {
                public void updateItem(final Notes value, final boolean empty) {
                    super.updateItem(value, empty);
                    String text = null;
                    if (!empty && value != null) {
                        text = "" + value.getDevoire2();
                    }
                    setText(text);
                }
            });
            noteExamen.setCellFactory(tv -> new TableCell<Object[], Notes>() {
                public void updateItem(final Notes value, final boolean empty) {
                    super.updateItem(value, empty);
                    String text = null;
                    if (!empty && value != null) {
                        text = "" + value.getExamen();
                    }
                    setText(text);
                }
            });
     
     
    }

    jusque la tous marche bien et mon tableau s'affiche correctement avec les données mais je n'arrive pas a modifer la valeur d'une cellule mais j'ai ajouter tabNotes.setEditable(true);
    voici mon code:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    noteExamen.setOnEditCommit((TableColumn.CellEditEvent<Object[], Notes> t) ->
                        {
                return ( t.getTableView().getItems().get(
                        t.getTablePosition().getRow())
                        ).setDevoire1(t.getNewValue());
            }
                    );

    le setDevoire1 est souligné par netbeans!!!
    je vous en prie aider moi svp

  2. #2
    Rédacteur/Modérateur

    Si tu veux éditer la table et conserver les valeurs modifiées il va te falloir créer un objet modèle qui maintienne ses propriétés de manière permanente. Quand tu fais ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      noteNameEtu.setCellValueFactory(feature -> {
                final Object[] value = feature.getValue();
                final Etudiant nometu = (Etudiant) value[0];
                return new SimpleObjectProperty<>(nometu);
            });


    C'est très facile pour afficher les valeurs dans la table mais tu coup la propriété créée est liée à rien du tout et toute modification de sa valeur passe totalement inaperçue.

    Une première approche simple consiste, juste avant le return, à mettre en place un écouteur sur la propriété pour savoir quand elle a changé de valeur de manière faire quelque chose de la nouvelle valeur (ex: la stocker dans le tableau ou encore la commit dans la base).

    Une seconde approche plus complexe est de créer un objet disposants de propriété JavaFX appropriées qui viendra en remplacement de ton Object[] dans la table, cet objet sera donc le nouveau modèle de la table. Tu peux ensuite écouter chacune des propriété de cet objet pour faire l'action appropriée lors de sa modification.

    Perso je favoriserai plus la seconde méthode car même si elle demande de coder plus de trucs, elle a le mérite de permettre si tu es suffisamment attentif de désenregistrer les écouteurs quand tu nettoie ta table ce qui évite les fuites mémoire ; tandis que si tu y va de manière bourrine avec la première solution, tu créera plein d'écouteurs que tu désenregistres jamais et sera donc une source de rétention de références.

    Dans ton cas tu es parti sur une modification de l'éditeur, pourquoi pas, ca peut aussi fonctionner mais tu coup tu vas devoir modifier tous les éditeurs. En plus en faisant ça tu te places en amont de la validation du processus d'édition donc conceptuellement c'est pas vraiment le bon endroit.

    le setDevoire1 est souligné par netbeans!!!
    Ben setOnEditCommit() est sensé retourner une valeur, donc si tu appelles setDevoire1(t.getNewValue()) qui est de type void ça marchera sans doute pas. Faudrait couper l'instruction en deux.
    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

  3. #3
    Futur Membre du Club
    ok!!!! merci pouvez-vous me donner quelque instruction ou comment faire pour la seconde approche svp!!!!

  4. #4
    Rédacteur/Modérateur

    Créer un objet, on va dire EtudiantModel ou un truc du genre, vu ce que fait ta requête SQL, avec les propriétés JavaFX qu'il faut pour chacune des valeurs retournées dans ton Object[]. Rajouter une méthode qui va convertir ta List<Object[]> en List<EtudiantModel>. Changer le type de la table de TableView<Object[]> vers TableView<EtudiantModel> puis changer chacune des fabriques de valeur pour retourner directement la propriété de l'objet courant plutôt que de créer une nouvelle propriété fabriquée au vol.

    Note1 : si certaines propriétés ne sont pas sensées êtres éditables après la construction du modèle tu peux les définir en ReadOnlyObjectProperty<T> aussi.

    Note2 : dans le cas où tu as des nombres entiers, par exemple, l'objet étudiant devra avoir des ObjectProperty<Integer> au lieu de IntProperty tout simplement car la fabrique à value retourne des ObjectProperty<T>.

    Ensuite vérifier que tout s'affiche correctement dans la table.

    Ensuite activer les bon éditeurs pour les bons types.

    Et enfin écouter les propriété des objets de la liste et lancer la sauvegarde si besoin quand ces valeurs changent.
    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

  5. #5
    Futur Membre du Club
    crée un Objet de quel Type??
    ou vous voulez dire de crée une classe si c'est le cas j'aimerais savoir si ce que j'ai fait est bien????
    ou j'ai pas bien compris ce que vous voulez dire!!!!
    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
     
    public class ModelEtudiant implements Serializable {
     
     
        private ReadOnlyObjectProperty<Etudiant> id;
     
        private StringProperty nomEtu;
        private SimpleStringProperty prenom;
     
        private ObjectProperty<Double> note1;
        private ObjectProperty<Double> note2;
        private ObjectProperty<Double> examen;
     
        public void setPrenom(SimpleStringProperty prenom) {
            this.prenom = prenom;
        }
     
        public SimpleStringProperty getPrenom() {
            return prenom;
        }
     
     
     
     
        public void setNomEtu(SimpleStringProperty nomEtu) {
            this.nomEtu = nomEtu;
        }
     
        public void setId(ReadOnlyObjectProperty<Etudiant> id) {
            this.id = id;
        }
     
        public void setNote1(ObjectProperty<Double> note1) {
            this.note1 = note1;
        }
     
        public void setNote2(ObjectProperty<Double> note2) {
            this.note2 = note2;
        }
     
        public void setExament(ObjectProperty<Double> examen) {
            this.examen = examen;
        }
     
        public StringProperty getNomEtu() {
            return nomEtu;
        }
     
        public ReadOnlyObjectProperty<Etudiant> getId() {
            return id;
        }
     
        public ObjectProperty<Double> getNote1() {
            return note1;
        }
     
        public ObjectProperty<Double> getNote2() {
            return note2;
        }
     
        public ObjectProperty<Double> getExamen() {
            return examen;
        }
     
     
     
     
     
    }

  6. #6
    Rédacteur/Modérateur

    C'est bien ça ?

    Mais pourquoi avoir rendu Serializable un objet qui servira uniquement dans l'UI pour faire le lien entre la TableView et la couche qui se chargera de répercuter les modifications dans la base ?
    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

  7. #7
    Futur Membre du Club
    Bonsoir merci!!!!
    le Serializable c'était une erreur.

    la couche qui se chargera de répercuter les modifications dans la base ?
    pouvez-vous me donner une exemple svp!!!!!!!!

  8. #8
    Rédacteur/Modérateur

    Tu peux ensuite écouter chacune des propriété de cet objet pour faire l'action appropriée lors de sa modification.
    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

  9. #9
    Futur Membre du Club
    pouvez-vous me donner un exemple de code Svp!!!!!?

  10. #10
    Rédacteur/Modérateur



    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    machin.biduleProperty().addListener((obs, oldv, newv) -> faireUnTrucQuandLaValeurDeLaProprieteChange(machin.getId(), machin.biduleProperty().getName(), newv));
     
    [...]
     
     
    private void faireUnTrucQuandLaValeurDeLaProprieteChange(String id, String nom, Chose newv) {
       // Taper du code ici pour faire quelque chose
       [...]
    }
    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

  11. #11
    Futur Membre du Club
    je ne comprend pas expliquez moi svp!!!
    que représente machin?????

    dites moi si mes déclaration sont correctes
    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
     
    public class ModelEtudiant {
     
        private final ObjectProperty<Integer> id = new SimpleObjectProperty<>();
     
        public ObjectProperty<Integer> getId() {
            return id;
        }
        private final ReadOnlyObjectProperty<String> nomEtu = new SimpleObjectProperty<>();
        private ReadOnlyObjectProperty<String> prenom = new SimpleObjectProperty<>();
     
        private final ObjectProperty<Double> note1 = new SimpleObjectProperty<>();
        private final ObjectProperty<Double> note2 = new SimpleObjectProperty<>();
        private final ObjectProperty<Double> examen = new SimpleObjectProperty<>();
     
        public final String getNom() {
            return nomEtu.get();
        }
     
        public final String getPrenom() {
            return prenom.get();
        }
     
        public final Double getNote1() {
            return note1.get();
        }
     
        public final void setNote1(final Double value) {
            note1.set(value);
        }
     
        public final ObjectProperty<Double> note1Property() {
            return note1;
        }
        public final Double getNote2() {
            return note2.get();
        }
     
        public final void setNote2(final Double value) {
            note2.set(value);
        }
     
        public final ObjectProperty<Double> note2Property() {
            return note1;
        }
        public final Double getExamen() {
            return examen.get();
        }
     
        public final void setExamen(final Double value) {
            examen.set(value);
        }
     
        public final ObjectProperty<Double> ExamenProperty() {
            return examen;
        }
     
     
    }

  12. #12
    Rédacteur/Modérateur

    Citation Envoyé par makwili Voir le message
    je ne comprend pas expliquez moi svp!!!
    que représente machin?????


    Et monModelEtudiantAMoi c'est plus parlant ?
    Faut savoir faire preuve d'un peu d'imagination ou d’abstraction parfois, je ne suis pas ici pour te pondre une solution toute prête a l'emploi mais pour te guider dans la bonne direction.

    Pour le reste cela semble plutôt bien comme base. Je te conseillerai juste d'utiliser le constructeur de propriété qui prend un nom en paramètre, ça te permettrai plus facilement de faire la liaison après avec le code qui va reposter les modifs sur la base notamment si tu essaies de mutualiser le code sur plusieurs propriétés de même type pour eviter de devoir réécrire la même chose plusieurs fois (ex: ici note1 et note2 ou encore examen par exemple)

    On va finir par se retrouver avec quelques chose comme, par exemple :

    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
    private static final Predicate<ModelEtudiant> ACCEPT_ALL_PREDICATE = model -> true;
    private static final Comparator<ModelEtudiant> DEFAULT_COMPARATOR = (model1, model2) -> model1.getId().compareTo(model2.getId());
     
    private final ObservableList<ModelEtudiant> etudiantsObservable = FXCollections.observableArrayList();
    private final FilteredList<ModelEtudiant> etudiantsFiltered = new FiletedList(etudiantsObservable, ACCEPT_ALL_PREDICATE);
    private final SortedList<ModelEtudiant> etudiantsSorted = new SortedList(etudiantsFiltered , DEFAULT_COMPARATOR);
     
    [...]
     
    // La ou on construit l'UI.
    tableView.setItems(etudiantsSorted);
     
    [...]
     
    // La ou on rempli la table avec les valeurs provenant de la BD.
    final List<ModelEtudiant> etudiants = NotesEtu([...]).stream()
        .map(values -> {
           final ModelEtudiant  result = new ModelEtudiant(values);
           result.note1Property().addListener([...]); // Que faire quand note1 change.
           result.note2Property().addListener([...]); // Que faire quand note2 change.
           result.examenProperty().addListener([...]); // Que faire quand examen change.
           [...]
           return result;
        })
        .collect(Collectors.toList());
    etudiantsObservable.setAll(etudiants);


    A tiens, pourquoi l'utilisation de listes triées et filtrées dans ce code ?
    Probablement car tes utilisateurs te demanderont une fonction de tri et de recherche dans la liste de valeurs a un nomment ou un autre. Après TableView peut aussi faire du tri sur chaque colonne. Ici, par défaut, toutes les valeurs sont affichées et le tri est dans l'ordre croissant de l'Id mais ces propriétés sont configurables sur chacune des listes en question.
    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

  13. #13
    Futur Membre du Club
    Merci infiniment pour votre aide!!!!!!!!!

###raw>template_hook.ano_emploi###