IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Composants Java Discussion :

Synchroniser le classement dans deux JTables


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut Synchroniser le classement dans deux JTables
    J'ai une JTable comportant 26 colonnes dans un JScrollPane pour présenter un tableau de chiffre d'affaire.
    Les colonnes sont :
    - N° client
    - Nom du client
    - CA janv 2014
    - CA fev 2014
    .
    .
    .
    - CA dec 2015

    Pour bien voir le contenu des colonnes, j'ai mis setAutoResizeMode(TableExpress.AUTO_RESIZE_OFF)

    Pour bloquer les noms des clients à gauche (comme dans Excel) quand
    on va consulter le CA fin 2015 à droite, j'ai découpé la JTable en deux :
    - JTable "fixe" avec les colonnes N° et nom client placée dans le RowHeaderView du JScrollPane
    - JTable "centrale" avec toutes les colonnes de CA placée dans le JViewport du JScrollPane

    A ce stade, cela marche très bien : quand on se déplace vers la droite,
    on continue à bien voir le nom des clients et la synchronisation se fait aussi verticalement.

    Problème :
    L'utilisateur a besoin de classer les clients par CA croissant pour, par exemple, le mois de mars 2015
    j'ai donc ajouté : centrale.setAutoCreateRowSorter(true)
    ça marche pour la JTable "centrale" mais le classement n'est pas synchronisé avec la JTable "fixe" !

    J'ai bien essayé de truander le classement de la JTable "fixe" en reportant le RowSorter de la JTable "centrale" :
    fixed.setRowSorter(centrale.getRowSorter());
    ça marchouille plus ou moins au début et puis après,
    ça merdouille complètement quand l'utilisateur veut reclasser les clients en cliquant sur l'en-tête de la colonne dans la JTable "fixe"

    En résumé :

    Comment faire pour synchroniser le classement dans deux JTables comportant le même nombre de lignes ?
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  2. #2
    Membre Expert Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 343
    Par défaut
    Bonjour,

    comme je ne connais pas toutes les subtilités des composants JAVA, je pense que j'aurai bidouillé un système avec un champ dans la base de données alimentant la table.
    Par exemple, ce champ s'appellerait rang_table.
    Je mettrai un indice dans ce champ, en fonction de la position à laquelle on veut mettre l'objet constituant la ligne de JTable.
    Cet indice serait calculé en fonction d'un critère de tri: ordre alphabétique, ou autre...

    J'aurai pris soin de permettre à l'objet constituant une ligne de JTable, d'implémenter <Comparable>.
    A chaque changement de modèle de tri, l'indice serait recalculé, puis les objets seraient triés dans la surcharge compareTo qui s'appuierait sur le champ 'rang_table'.
    Enfin un fireTableDataChange sur les classes gérant le traitement des données des JTable devrait rafraîchir l'affichage selon le nouveau classement.

    Je ne sais pas si mon explication est claire, mais peut être quelle vous permettra de trouver une voir vers la solution...

  3. #3
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut
    C'est dans cette direction que je me dirige : une colonne cachée avec un indice dans les deux TableModel.
    Mais bon, je trouve cela assez moche car je vois gros comme une maison que je vais devoir mettre à jour le TableModel et non pas seulement l'affichage.

    Je n'ai trouvé aucune méthode dans JTable qui permette d'imposer un classement sur l'indice de la ligne du type :
    "Je veux la la ligne 7 de ma TableModel s'affiche à la ligne 3 dans ma JTable ..."

    Donc je vais essayer d'ajouter cette colonne fantôme et de déclencher le tri par programmation ...

    La suite au prochain numéro ...
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Le RowSorter fonctionne conjointement avec le TableModel.
    Si les deux JTable ont le même RowSorter, il faut qu'elles aient le même TableModel...



    a++

  5. #5
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut
    Salut.

    C'est maintenant ce que je suis en train de me dire.
    Le système des index va être infernal à mettre en place.

    Il sera plus simple d'avoir le même model partagé par les deux JTables ...
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il y une solution en affectant à la table entête un RowSorter qui encapsule le RowSorter de la table principal pour lui déléguer les traitements, sauf ceux qui réagissent aux notifications (qui sont déjà gérées par la table principale). Mais si elles ont le même modèle, c'est encore mieux oui, car elles peuvent avoir le même rowsorter.

    Voici un POC :

    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
    142
    143
    144
    145
    146
    public class Demo {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.getContentPane().add(createJTable());
     
    		frame.pack();
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static Component createJTable() {
    		JScrollPane scrollPane = new JScrollPane(); 
    		final DefaultTableModel tableModel = new DefaultTableModel(50, 26) {
     
    	        @Override
    	        public Class<?> getColumnClass(int columnIndex) {
    	            return Integer.class;
    	        }
     
    	    };
    	    for (int i = 0; i < tableModel.getRowCount(); i++) {
    	    	for(int j=0; j<tableModel.getColumnCount(); j++) {
    	    		int value;
    	    		switch(j) {
    	    		case 0:
    	    		case 2: // pour avoir la même valeur en 0 et 2 pour référence visuelle
    	    			value=i+1;
    	    			break;
    	    		default:
    	    			value=10000+(int)(Math.random()*42);
    	    		}
    		        tableModel.setValueAt(value, i, j);
    	    	}
    	    }
    		JTable mainTable = new JTable(tableModel);
    		JTable headerTable = new JTable(tableModel);
    		TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(tableModel);
    		mainTable.setRowSorter(rowSorter);
    		for(int i=0; i<2; i++) {
    			mainTable.removeColumn(mainTable.getColumnModel().getColumn(0));
    		}
    		mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
    		int nb=headerTable.getColumnCount()-2; 
    		for(int i=0; i<nb; i++) {
    			headerTable.removeColumn(headerTable.getColumnModel().getColumn(2));
    		}
    		scrollPane.setViewportView(mainTable);
    		headerTable.setAutoCreateRowSorter(false);
    		headerTable.setRowSorter(new HeaderRowSorter<>(rowSorter));
    		headerTable.setSelectionModel(mainTable.getSelectionModel());
    		headerTable.setUpdateSelectionOnSort(false);
    		scrollPane.setRowHeaderView(headerTable); 
    		scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, headerTable.getTableHeader());
    		return scrollPane;
    	}
     
    	public static class HeaderRowSorter<M> extends RowSorter<M> {
     
    	    private final RowSorter<M> rowSorter; 
     
    	    public HeaderRowSorter(RowSorter<M> rowSorter) {
    	        this.rowSorter = rowSorter;
    	        rowSorter.addRowSorterListener(e-> {
    	        	switch(e.getType()) {
    	        	case SORT_ORDER_CHANGED:
                        fireSortOrderChanged();
                        break;
    	        	case SORTED: 
                        fireRowSorterChanged(null);
                        break;
                    }
                });
    	    }
     
    	    @Override
    	    public M getModel() {
    	        return rowSorter.getModel();
    	    }
     
    	    @Override
    	    public void toggleSortOrder(int column) {
    	        rowSorter.toggleSortOrder(column);
    	    }
     
    	    @Override
    	    public int convertRowIndexToModel(int index) {
    	        return rowSorter.convertRowIndexToModel(index);
    	    }
     
    	    @Override
    	    public int convertRowIndexToView(int index) {
    	        return rowSorter.convertRowIndexToModel(index);
    	    }
     
    	    @Override
    	    public void setSortKeys(List<? extends SortKey> keys) { 
    	        rowSorter.setSortKeys(keys);
    	    }
     
    	    @Override
    	    public List<? extends SortKey> getSortKeys() {
    	        return rowSorter.getSortKeys();
    	    }
     
    	    @Override
    	    public int getViewRowCount() {
    	        return rowSorter.getViewRowCount();
    	    }
     
    	    @Override
    	    public int getModelRowCount() {
    	        return rowSorter.getModelRowCount();
    	    }
     
    	    @Override
    	    public void modelStructureChanged() { 
    	    }
     
    	    @Override
    	    public void allRowsChanged() { 
    	    }
     
    	    @Override
    	    public void rowsInserted(int firstRow, int endRow) { 
    	    }
     
    	    @Override
    	    public void rowsDeleted(int firstRow, int endRow) { 
    	    }
     
    	    @Override
    	    public void rowsUpdated(int firstRow, int endRow) { 
    	    }
     
    	    @Override
    	    public void rowsUpdated(int firstRow, int endRow, int column) { 
    	    }
     
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut
    Salut Joel

    Merci pour ce code.
    Par contre, je patauge un peu car je suis bloqué en Java 7 (obligation de chez le client) et il y a pas mal de truc qui ne marchent pas.

    Mais je vais voir le principe général et je te tiens au courant.
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  8. #8
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut
    Re-salut Joel

    Ton système fonctionne parfaitement !
    En plus c'est très propre : on ne duplique pas les données, on utilise qu'un seul DefaultTableModel, ça réagit bien même avec 5000 lignes !
    J'ai bien apprécié aussi la duplication de la colonne 0 sur la colonne 2 pour identification visuelle.

    Très beau boulot !
    Et merci aussi à adiGuba pour la piste du TableModel partagé.

    Sinon, j'ai pu redescendre l'exemple en Java 6 (parce qu'il y a des postes utilisateurs qui ... bon ... enfin bref.)
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Mettre deux JScrollPane dans un JTable
    Par pianetdi dans le forum Composants
    Réponses: 3
    Dernier message: 30/01/2014, 19h47
  2. Filtré par rapport a deux colonnes dans un JTable
    Par wagui26 dans le forum Débuter
    Réponses: 3
    Dernier message: 08/05/2012, 10h49
  3. Réponses: 2
    Dernier message: 07/02/2008, 18h08
  4. Rediriger deux pages dans deux frames
    Par Tapioca dans le forum ASP
    Réponses: 6
    Dernier message: 06/07/2004, 16h27
  5. [SQL][ACCESS]Compter le nombres d'enregistrement dans deux..
    Par pc152 dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 05/06/2004, 12h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo