Comment pouvoir interdire des doublons dans les lignes de ma Jtable [Résolu]

coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 2 nov. 2011 à 14:16 - Dernière réponse : cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention
- 11 nov. 2011 à 14:55
Bonjour à tous, dans mon application je dispose de deux (2) JTables A et B, l'idée est de pouvoir, en cliquant sur le bouton ajouter, copier la donnée de la ligne sélectionnée de A dans B, ce que je suis parvenu à faire sans problème, mais le hic est que la donnée copiée se place sur la première ligne de B, je voudrais qu'elle se place sur la dernière ligne, je veux dire après le dernier enregistrement de la JTable B. Aussi je voudrais pouvoir interdire d'avoir des doublons dans la table B,mes tentatives se sont chaque fois soldées par des échecs, quelqu'un pourrait-il m?aider ?

codes :

private javax.swing.JTable txtJtableRegDispo; 
private javax.swing.JTable txtJtableRegCharger;
private DefaultTableModel aModel,bModel;

//Méthodes de vérification de doublon
public boolean verif(Object[] val){
    boolean result=true;
    for(int k=0;k< txtJtableRegCharger.getModel().getRowCount();k++){
          if(txtJtableRegCharger.getModel().getValueAt(k, 0) == val){
              JOptionPane.showMessageDialog(null, val+" existe déjà", "Erreur", JOptionPane.ERROR_MESSAGE);
              result=false;
          }
        }
     return result;
}

private void CmdAjouterActionPerformed(java.awt.event.ActionEvent evt) {                                           
        // TODO add your handling code here:
// txtJtableRegDispo;  Registre (A);  txtJtableRegCharger  Registre (B)
       int i=txtJtableRegDispo.getSelectedRow();      
      int j=0;/* a ce niveau j'ai beau essayer de recuperer le nbr de ligne pour incrementé sans succès */
      Object [] valeur = {txtJtableRegDispo.getValueAt(i, 0)}; 
       bModel.insertRow(j,valeur); 
if(verif(valeur)==true ) 
        bModel.insertRow(j,valeur);   
j++ ;   
    }      
Afficher la suite 

24 réponses

Répondre au sujet
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 10 nov. 2011 à 09:33
+3
Utile
tu peux faire un truc comme ca
    private void CmdAjouterActionPerformed(java.awt.event.ActionEvent evt) {


       int i=txtJtableRegDispo.getSelectedRow();
       int c;
       Object [] valeur = {txtJtableRegDispo.getValueAt(i, 0)};
       txtJtableRegDispo.clearSelection();

           if ( isValueValide( valeur ) ){
           bModel.addRow(valeur);}
           else {/*tu peux faire un un msg d erreur si tu veux*/}

    }
    
    public boolean isValueValide( Object[] value )
    {
        int size = bModel.getRowCount();
        for ( int i = 0; i < size; i++ )
        {
            if ( value[0].equals( bModel.getValueAt(i, 0) ) ) return false;
        }
        return true;
    }


ou comme ca

        bModel = new DefaultTableModel()
        {
            public boolean isCellEditable(int row, int col)
            {
                return false;
            }

            @Override
            public void addRow(Object[] rowData)
            {
               if ( isValueValide( rowData ) ){
                super.addRow(rowData);}
               else {/*tu peux faire un un msg d erreur si tu veux*/}
            }
            
        };


mais ;o) c est pas super jolie ;o)
pour plus de liberté tu devrais quand meme faire ton propre model

class MonModel implements DefaultTableModel
{
//et la tu surcharge ou ajoute ce que tu veux ;o) ...

}


bon ;o) ca va etre dur de te macher plus le boulot ;o)

ceci dit ;o) .. pour afficher une seule colonne ;o) il est preferable d utiliser une JList plutot qu une JTable ;o)



GodConan ;o)
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_GodConan
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 2 nov. 2011 à 17:16
0
Utile
Bonjour,

Pour ajouter une ligne à une JTable, utilises cette méthode :

((DefaultTableModel)(table.getModel())).addRow(new String[]{"", "", ""});


Par contre, il faut que tu ais fait un setModel(new DefaultTableModel()) auparavant.

Pour ce qui est des doublons, ca peut être assez complexe à gérer comme tu le fais, étant donné que les doublons doivent être acceptés lors de la recopie de la ligne. Mais ca doit pouvoir se faire en utilisant les evenements focusLost.

Ce que tu peux faire est de gérer les ajouts dans ta tables en utilisant des JTextField avec un bouton ajouter plutôt que de recopier la dernière ligne. de cette manière, tu peux vérifier que ta table ne contient pas de doublons avant d'ajouter une ligne.
Commenter la réponse de cs_Julien39
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 2 nov. 2011 à 19:07
0
Utile
Bonsoir Julien39,j'ai un setModel() plus haut,je n'ai poster que la portion de code qui me semblait poser problème.Je ne sais pas si vous me comprenez ? Voici l'idée que je veux implémenter;la Jtable A est déjà remplie,elle contient déjà des lignes de données,lorsque je selectionne une ligne de cette Jtable et que je click sur Ajouter sa valeur est copiée dans la JTable B.Seulement mon code tel qu'il est ne me permet pas de gerer cette restriction.peut être que ma methode ne tourne pas rond.Et pourtant elle me semble correcte.

private void CmdAjouterActionPerformed(java.awt.event.ActionEvent evt) {                                             
    int i=txtJtableRegDispo.getSelectedRow();//recupération de l'indice de la ligne
    Object [] valeur = {txtJtableRegDispo.getValueAt(i, 0)}; //recupération de sa valeur
       if(verif(valeur)==true){//verification de doublon
           bModel.addRow(valeur);
        } 
}   


je vais l'assayer avec l'évenement focusLost comme vous l'avez dit comme vous le dite.Merci
Commenter la réponse de coolanso
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 3 nov. 2011 à 17:52
0
Utile
Je ne comprend pas vraiment ce que tu souhaites faire ici :

Object [] valeur = {txtJtableRegDispo.getValueAt(i, 0)};

Tu ne récupères que la première valeur de la ligne. Et ensuite, tu l'ajoutes au modele. Cependant, il faut que tu créé un tableau contenant toutes les valeurs de la ligne. Sinon, la dimention de la ligne n'est pas bonne.
Commenter la réponse de cs_Julien39
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 3 nov. 2011 à 17:54
0
Utile
Pour recréer ta ligne, tu peux utiliser la méthode getColumnCount() du modèle pour récupérer le nombre de lignes à copier.

Et ensuite, une boucle for qui permet de récupérer toutes les valeurs.
Commenter la réponse de cs_Julien39
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 3 nov. 2011 à 17:56
0
Utile
Et une dernière remarque :

Remplace cette ligne ;
if(verif(valeur)==true){//verification de doublon
par
if(verif(valeur)){//verification de doublon


Le ==true ne sert à rien et montre que tu n'as pas vraiment compris la gestion des booléens en java
Commenter la réponse de cs_Julien39
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 7 nov. 2011 à 08:00
0
Utile
Alors, tu t'en sort ?
Commenter la réponse de cs_Julien39
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 7 nov. 2011 à 12:08
0
Utile
salut ;o)

le probleme ;o) c est que si ta table est éditable ;o) ton model est de toute facon modifier a chaque saisie de valeur ;o) il est donc déja trop tard pour empecher à ce niveau l incrementation du model ;o) (puisque c est deja fait)
donc soit tu passes par un formulaire de saisie et sur la validation (ton bouton) tu incrementes (modifis) le model de la table; soit tu controle les doublons sur un datalistener et efface la mauvaise ligne (avec un petit message biensur ) soit encor mieux ;o) tu empeches carrement la saisie de mauvaise valeures au niveau du cellEditor ;o) mais c est un peu plus chaud ;o)


GodConan ;o)
Commenter la réponse de cs_GodConan
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 8 nov. 2011 à 14:53
0
Utile
Salut GodConan je crois que tu m'a pas tout à fait capté,non, ma table n'est pas éditable,pour précision,je dispose de 2 tables A et B.la table A est en fait déjà rempli par les données en bd.Il s'agit pour le futur utilisateur, compte tenu du fait qu'il n'aura pas besoin de tous les elements de la table A,de sélectionner dans celle-ci les données sur lesquelles il va travailler et de les copiées dans la table B.c'est là que le probmleme de doublon se pose.Je crois que ta proposition de controler les doublons sur un datalistener pourrait resoudre mon problème.
Quand tu dis
{soit encor mieux tu empeches carrement la saisie de mauvaise valeures au niveau du cellEditor ;o)}
je ne comprends pas trop,car il n'y pas de saisie a faire.c'est juste sélectionné la ligne clicquer sur ajouter pour que la ligne soit copiée dans la table B.Merci
Commenter la réponse de coolanso
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 8 nov. 2011 à 15:10
0
Utile
Je reviens sur une idée que j'ai déjà évoquée :

Ce que tu peux faire est de gérer les ajouts dans ta tables en utilisant des JTextField avec un bouton ajouter plutôt que de recopier la dernière ligne. de cette manière, tu peux vérifier que ta table ne contient pas de doublons avant d'ajouter une ligne.


Sinon, tu vas devoir faire un renderer particulier avec la dernière ligne de ta table éditable et les autres non. Ce qui est possible mais les doublons seront plus difficiles à gérer.
Commenter la réponse de cs_Julien39
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 8 nov. 2011 à 15:12
0
Utile
si tu as 2 table c est encore plus simple ;o) ...

tu peux tout gerer au niveau des models de données...

tout tes enreg (au niveau de A, soit de ta bdd)ont une clé primaire ;o) donc tu fais suivre cette clé dans B (tu l affiches ou non, inutil de l afficher vu que faut pas la modifier) donc qd je dis dans B c est surtout au niveau du model que cela nous interresse ;o) et donc avant de faire passer tes enreg dans B il te suffi juste de controler si il est deja ou pas dans B ;o) la clé primaire identifiant les enreg de facon unique ;o) t es sur de pas te tromper ;o) ...

je ne sais pas comment tu geres tes model ;o) mais tu peux meme gerer ta table B ton SGBDD avec un model sur une table temporaire ou meme une vue ;o) ... généralement les SGBDR ;o) offrent des fonctionnalité un peu plus performante que le java sur les gros volume de données ;o)

GodConan ;o)
Commenter la réponse de cs_GodConan
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 8 nov. 2011 à 15:20
0
Utile
Je voyais les choses plus simplement, sans nécessairement utiliser les tables temporaires, ce n'est pas un drame si la vue est déconnectée un temps du modèle. enfin, c'est vrai que cette idée est intéressante.

Ton problème n'est toujours pas réglé depuis ?
Commenter la réponse de cs_Julien39
cs_Julien39 6449 Messages postés mardi 8 mars 2005Date d'inscription 15 mars 2018 Dernière intervention - 8 nov. 2011 à 15:21
0
Utile
@GodConan : ca fait plaisir de te revoir actif sur le réseau, je commençais à me sentir un peu seul...
Commenter la réponse de cs_Julien39
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 8 nov. 2011 à 15:34
0
Utile
;o) bcp de boulot... ;o) et période sans accés web ;o) c est le plus pénible ;o)

GodConan ;o)
Commenter la réponse de cs_GodConan
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 8 nov. 2011 à 17:35
0
Utile
Salut Godman,j'ai dû m'absenter un moment.je crois que de tes deux proposition,je prefere de loin la première,comme SGBD,j'ai MySQL 1.2.17,je ne sais pas si on peut écrire des procedures stockées avec cette version en particulier et avec MySQL meme en géneral.voici un peu les code de mes modele de table:

private javax.swing.JTable txtJtableRegDispo;
private javax.swing.JTable txtJtableRegCharger;
// code de la table contenant les données en BD
txtJtableRegDispo = new javax.swing.JTable();
String[] tableColumnsName = {"Liste des registres disponibles"};
aModel = new DefaultTableModel() 
{ 
public boolean isCellEditable(int row, int col)
{
 return false;   
}
}; 
txtJtableRegDispo.getSelectionModel().addListSelectionListener(new RowListener());
aModel.setColumnIdentifiers(tableColumnsName);
txtJtableRegDispo.setModel(aModel);

// code de la table contenant les données copiées depuis la 1ere table

txtJtableRegCharger = new javax.swing.JTable();
String[] tableColumnsName1 = {"Liste des registres àcharger"};
bModel = new DefaultTableModel() 
{ 
public boolean isCellEditable(int row, int col)
{
 return false;   
}
}; 
bModel.setColumnIdentifiers(tableColumnsName1);
txtJtableRegCharger.setModel(bModel);

//Methodes me permettant de remplir mon tableau avec les donnée en bd
public void ListeRegistre() {
        try {
            String Query = "SELECT * FROM registres ";//ici j'ajoutes le code du registre
            Connection connection = (Connection) DataBaseConnector.getConnection();
            PreparedStatement ps = (PreparedStatement) connection.prepareStatement(Query);
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData md = (ResultSetMetaData) rs.getMetaData();
            colNo = md.getColumnCount();
            while (rs.next()) {
                objects = new Object[colNo];
                for (int i = 0; i < colNo; i++) {
                    objects[i] = rs.getObject(i + 1);     
                }
                aModel.addRow(objects);
            }
            txtJtableRegDispo.repaint();

        } catch (SQLException ex) {
            Logger.getLogger(FormChoixRegistre1.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
si je te comprends tuvoudrais que j'associe chaque regitre à sa clé? mais mon problème va se situer au niveau de la copie,comment pouvoir utilier cette clé cachée afin d'effectuer les tests.Merci.je crois tu devrais plus t'ennuyer.merci pour ton aide.
Commenter la réponse de coolanso
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 8 nov. 2011 à 19:00
0
Utile
;o) moi aussi ;o) je ne suis pas en permanence ;o) devant le PC ;o) ...

donc si je résume : tu 2 JTables d une seule colonne chacune ?!! (pourquoi une boucle 'for ' pour remplir ta row?)

aucun prob avec la JTable A qui est rempli à partir de ta requete (sur la table registre)

par une methode Ajouter tu fais passer des selections de A vers B... et donc ton soucis : es ce bien que sur un 2nd ajout tu risques d avoir des doublons dans B??



GodConan ;o)
Commenter la réponse de cs_GodConan
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 9 nov. 2011 à 16:43
0
Utile
par une methode Ajouter tu fais passer des selections de A vers B... et donc ton soucis : es ce bien que sur un 2nd ajout tu risques d avoir des doublons dans B??

Mon souci est que je ne veux pas de doublon dans B.et je me demandais s'il n'y'avait pas dans les methodes de JTable,un evenment ou une methode dont l'implémentation me permettrai de gerer ceci.Sinon actuellement je penses à remplir un Arraylist des données de la table B et faire un control à chaque fois qu'il y'a mouvement de A vers B,mais je trouve que pour chaque click parcourir un à un mon arraylist à la recherche d'un doublon me prendrait assez de temps et rendrait mon application.Dis moi pourquoi cette méthode ne marche t-elle pas?

public boolean verif(Object[] val){
    boolean result=true;
    for(int k=0;k< txtJtableRegCharger.getModel().getRowCount();k++){
          if(txtJtableRegCharger.getModel().getValueAt(k, 0) == val){
              JOptionPane.showMessageDialog(null, val+" existe déjà", "Erreur", JOptionPane.ERROR_MESSAGE);
              result=false;
          }
        }
    
     return result;
}

 private void CmdAjouterActionPerformed(java.awt.event.ActionEvent evt) {                                           

        
       int i=txtJtableRegDispo.getSelectedRow();
       Object [] valeur = {txtJtableRegDispo.getValueAt(i, 0)}; 
       txtJtableRegDispo.clearSelection();
       if(verif(valeur)==true){
           bModel.addRow(valeur);
       }
              
    }          
Commenter la réponse de coolanso
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 9 nov. 2011 à 17:06
0
Utile
C est tous simple :
sur ta table B tu mets ton propre TableModel herité de DefaultTableModel ou tu surcharges 'addRow' pour y faire ton control de doublon avant d apeller la methode super avec ou sans les donnees ;o) voulu ... ;o)

Ainsi dansl action perform tu ne fait que le addRow ... le control se fait directement au niveau de la table, c est nettement plus logique ainsi ;o) (POO)

pour le control des doublon
tu peux scanner ton model (tu verras pour quelques milliers de lignes c est encore asser reactif) ;o) ou tu peux aussi utliser ;o) quelques astuces ;o) comme la hashmap ;o) ...


GodConan ;o)
Commenter la réponse de cs_GodConan
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 9 nov. 2011 à 18:46
0
Utile
salut GodConan,ma table B utilise dejà un DefaultTableModel()

private DefaultTableModel aModel,bModel;
bModel = new DefaultTableModel();

dois-je encore créer une classe une classe héritant de DefaultTableModel() du genre :

private class VerifDoublon extends DefaultTableModel{
     public void addRegistre(Object[] val) {
     }  
 }
et puis le definir dans le constructeur de DefaultTableModel comme ceci?
bModel = new DefaultTableModel(new VerifDoublon()) 
{ 
public boolean isCellEditable(int row, int col)
{
 return false;   
}
}; 
je l'ai fait ainsi,mais y'a erreur.Pour tout dire je ne vois vraiment pas comment y arriver.je suis a bout de refflection.
Commenter la réponse de coolanso
coolanso 75 Messages postés jeudi 12 août 2010Date d'inscription 5 juillet 2014 Dernière intervention - 9 nov. 2011 à 18:51
0
Utile
Aussi, pourquoi j'ai pas eu de problème pour le bouton retirer qui au click retire de B les lignes selectionnées,qui pourtant utilise aussi un DefaultTableModel.j'ai jamais galerer autant,satanée JTable.je me suis promis egalement d'y arriver.
Commenter la réponse de coolanso

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

comment pouvoir interdire des doublons dans les lignes de ma Jtable - page 2