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

  1. #1
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    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 710
    Points : 4 791
    Points
    4 791
    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 expérimenté Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 340
    Points : 1 576
    Points
    1 576
    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...
    @ bientôt...

    Salut & @+ sur 3W!

  3. #3
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    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 710
    Points : 4 791
    Points
    4 791
    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 sénior
    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
    Points : 23 190
    Points
    23 190
    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 710
    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 710
    Points : 4 791
    Points
    4 791
    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 : 54
    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
    Points : 29 131
    Points
    29 131
    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 710
    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 710
    Points : 4 791
    Points
    4 791
    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 710
    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 710
    Points : 4 791
    Points
    4 791
    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/

  9. #9
    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 : 54
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    J'ai pas passé de temps sur le dimensionnement des "rowHeaders", parce que ce n'était pas l'objet de la discussion. Tu as trouvé une solution ? J'avoue que je n'ai pas d'idées à ce sujet et je ne sais pas pourquoi ça prend autant de largeur. Il serait intéressant aussi de pouvoir redimensionner la dernière colonne des headerRows comme s'il n'y avait qu'une seule JTable : pour l'instant, c'est frustrant : ça bloque.
    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.

  10. #10
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    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 710
    Points : 4 791
    Points
    4 791
    Par défaut
    Ah c'est gentil de me laisser contribuer !

    dans ta méthode createJTable
    juste avant de renvoyer le jscrollpane j'ai ajouté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            headerTable.setAutoResizeMode(headerTable.AUTO_RESIZE_OFF);
            headerTable.setPreferredScrollableViewportSize(headerTable.getPreferredSize());
    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/

  11. #11
    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 : 54
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Je savais que çà ce serait simple. En revanche, essaye de redimensionner la dernière colonne de rowHeaders... Si on l'agrandit, elle passe derrière la JTable principale, si on la réduit, on a une bande grise entre les headers et la principale... pas terrible...
    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.

  12. #12
    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 : 54
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    A priori, en ajoutant ça, ça devrait le faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    headerTable.addComponentListener(new ComponentAdapter() {
        @Override
        public void componentResized(ComponentEvent e) {
                    headerTable.setPreferredScrollableViewportSize(headerTable.getPreferredSize());
        }
    });
    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.

  13. #13
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    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 710
    Points : 4 791
    Points
    4 791
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    on a une bande grise entre les headers et la principale... pas terrible...
    C'est le passage secret vers Java version 12

    Sinon, ton code eaderTable.addComponentListener marche aussi.
    Bon, je crois qu'on est dans la finition là.

    Si on continue comme cela, il faudra en faire un tuto.
    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/

  14. #14
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Je savais que çà ce serait simple. En revanche, essaye de redimensionner la dernière colonne de rowHeaders... Si on l'agrandit, elle passe derrière la JTable principale, si on la réduit, on a une bande grise entre les headers et la principale... pas terrible...
    Une autre solution c'est de redéfinir getPreferredScrollableViewportSize() sur le composant header :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	@Override
    	public Dimension getPreferredScrollableViewportSize() {
    		return getPreferredSize();
    	}
    Ainsi sa taille sera toujours celle "préféré" (par défaut il y a une taille minimal assez grande sur les JTable).



    Sinon il faut aussi synchroniser les hauteurs de cellule, sinon on peut avoir des décrochage...



    J'ai fait une version qui semble fonctionner :
    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
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Dimension;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
     
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JViewport;
    import javax.swing.ScrollPaneConstants;
    import javax.swing.SwingUtilities;
    import javax.swing.border.Border;
    import javax.swing.table.TableColumnModel;
    import javax.swing.table.TableModel;
     
     
     
    public class JTablePlus extends JTable {
     
    	/**
             * JTable représentant les headers de colonnes.
             *
             */
    	private static class JTableRowHeader extends JTable implements PropertyChangeListener {
     
    		private final JTable mainTable;
     
    		public JTableRowHeader(JTable mainTable) {
    			super(mainTable.getModel());
    			this.mainTable = mainTable;
    			setColumnModel(createDefaultColumnModel());
    			setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    			setAutoCreateColumnsFromModel(false);
    			setAutoCreateRowSorter(false);
    			setSelectionModel(mainTable.getSelectionModel());
     
    			// On surveille certaines propriétées de la table principale :
    			mainTable.addPropertyChangeListener(this);
    		}
     
    		// On surchage les infos de dimensions des lignes,
    		// afin de s'aligner sur celles de la Table principale
    		@Override
    		public int getRowHeight() {
    			return this.mainTable.getRowHeight();
    		}
    		@Override
    		public int getRowHeight(int row) {
    			return this.mainTable.getRowHeight(row);
    		}
    		@Override
    		public int getRowMargin() {
    			return this.mainTable.getRowMargin();
    		}
     
    		// On force la dimension de ce header à sa taille préférée
    		@Override
    		public Dimension getPreferredScrollableViewportSize() {
    			return getPreferredSize();
    		}
     
    		// On surveille certains éléments de la table principal :
    		@Override
    		public void propertyChange(PropertyChangeEvent evt) {
    			switch(evt.getPropertyName()) {
    			case "model": setModel(this.mainTable.getModel()); break;
    			case "rowSorter": setRowSorter(this.mainTable.getRowSorter()); break;
    			case "selectionModel": setSelectionModel(this.mainTable.getSelectionModel()); break;
    			case "rowHeight": setRowHeight(this.mainTable.getRowHeight()); break;
    			default:
    				System.out.println(evt.getPropertyName());
    			}
    		}
    	}
     
     
    	private final JTableRowHeader rowHeader;
     
    	public JTablePlus() {
    		super();
    		this.rowHeader = new JTableRowHeader(this);
    	}
     
    	public JTablePlus(TableModel model) {
    		super(model);
    		this.rowHeader = new JTableRowHeader(this);
    	}
     
    	/**
             * Cette méthode permet de créer un ensemble de colonne "fixe",
             * à partir du modèle de la table principale.
             * Les 'n' premières colonnes sont passées dans le header de lignes.
             */
    	public void createRowHeaderFixedColumns(int n) {
    		TableColumnModel rowColumnModel = null;
    		if (n>0) {
    			TableColumnModel columnModel = getColumnModel();
    			rowColumnModel = createDefaultColumnModel();
     
    			for (int i=0; i<n && i<columnModel.getColumnCount(); i++) {
    				rowColumnModel.addColumn(columnModel.getColumn(i));
    			}
     
    			for (int i=0; i<rowColumnModel.getColumnCount(); i++) {
    				columnModel.removeColumn(rowColumnModel.getColumn(i));
    			}
    		}
    		setRowHeaderColumnModel(rowColumnModel);
    	}
     
    	/**
             * Cette méthode permet de spécifier un TableColumnModel spécifique pour les headers de colonnes.
             */
    	public void setRowHeaderColumnModel(TableColumnModel columnModel) {
    		if (columnModel==null) {
    			columnModel = createDefaultColumnModel();
    		}
    		this.rowHeader.setColumnModel(columnModel);
    	}
     
    	public TableColumnModel getRowHeaderColumnModel() {
    		return this.rowHeader.getColumnModel();
    	}
     
     
    	public void setRowHeaderSeparator(int width, Color color) {
    		// On met une bordure entre les headers et les autres colonnes :
    		Border border = BorderFactory.createMatteBorder(0, 0, 0, width,
    				color);
    		this.rowHeader.setBorder(border);
    		this.rowHeader.getTableHeader().setBorder(border);
    	}
     
    	@Override
    	public void setRowHeight(int row, int rowHeight) {
    		super.setRowHeight(row, rowHeight);
    		this.rowHeader.setRowHeight(row, rowHeight);
    	}
     
    	private void addOrRemoveRowHeader(boolean addRowHeader) {
    		Container parent = SwingUtilities.getUnwrappedParent(this);
    		if (parent instanceof JViewport) {
    			JViewport port = (JViewport) parent;
    			Container gp = port.getParent();
    			if (gp instanceof JScrollPane) {
    				JScrollPane scrollPane = (JScrollPane) gp;
    				// Make certain we are the viewPort's view and not, for
    				// example, the rowHeaderView of the scrollPane -
    				// an implementor of fixed columns might do this.
    				JViewport viewport = scrollPane.getViewport();
    				if (viewport == null
    						|| SwingUtilities.getUnwrappedView(viewport) != this) {
    					return;
    				}
     
    				JComponent rowHeaderView = null;
    				JComponent corner = null;
    				if (addRowHeader) {
    					rowHeaderView = this.rowHeader;
    					corner = this.rowHeader.getTableHeader();
    				}
    				scrollPane.setRowHeaderView(rowHeaderView);
    				scrollPane.setCorner(ScrollPaneConstants.UPPER_LEADING_CORNER,
    						corner);
    			}
    		}
    	}
     
     
    	@Override
    	protected void configureEnclosingScrollPane() {
    		super.configureEnclosingScrollPane();
    		addOrRemoveRowHeader(this.rowHeader!=null);
    	}
     
    	@Override
    	protected void unconfigureEnclosingScrollPane() {
    		super.configureEnclosingScrollPane();
    		addOrRemoveRowHeader(false);
    	}
     
    	/**
             * Ceci permet d'afficher la scrollbar horizontale si la JTable n'a pas
             * suffisamment d'espace, tout en permettant d'utiliser le
             * setAutoResizeMode().
             */
    	@Override
    	public boolean getScrollableTracksViewportWidth() {
    		return super.getScrollableTracksViewportWidth()
    				&& getPreferredSize().width < getParent().getWidth();
    	}
    }

    Exemple d'utilisation :
    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
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		// On crée la table :
    		JTablePlus table = new JTablePlus(createBigTableModel(400, 10));
    		table.setAutoCreateRowSorter(true);
    		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
     
    		// On fixe les 2 première colonnes :
    		table.createRowHeaderFixedColumns(2);
    		// que l'on sépare par une ligne de 6 pixels :
    		table.setRowHeaderSeparator(6, Color.LIGHT_GRAY);
     
    		table.setRowHeight(0, 40);
     
    		JScrollPane scrollPane = new JScrollPane(table);
    		frame.add(scrollPane);
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
     
    	public static DefaultTableModel createBigTableModel(final int rows,
    			final int cols) {
    		String[] names = new String[cols];
    		Object[][] data = new Object[rows][cols];
     
    		for (int j = 0; j < cols; j++) {
    			names[j] = "Col " + j;
    		}
    		for (int i = 0; i < rows; i++) {
    			for (int j = 0; j < cols; j++) {
    				data[i][j] = String.format("%04d-%04d", i, j);
    			}
    		}
     
    		return new DefaultTableModel(data, names);
    	}

    Mais il doit sûrement rester des propriétés à gérer...


    a++

  15. #15
    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 : 54
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    J'ai fait une version qui semble fonctionner :
    Merci, AdiGuba Bonne idée la ligne de séparation ! Ça donne envie d'y coller une splitbar pour pouvoir modifier le nombre de colonnes d'entête (à la Excel).
    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.

  16. #16
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 710
    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 710
    Points : 4 791
    Points
    4 791
    Par défaut
    Bon ben ... super !
    Avec ces nouvelles perspectives, je vais pouvoir simplifier mon code.

    Merci à tous les deux
    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