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 :

Jtable et lignes + colonnes fixées


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Juin 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 7
    Par défaut Jtable et lignes + colonnes fixées
    Hi all,

    Je suis coincé avec un point douloureux sur des JTables.
    Je souhaite implémenter en Swing une des fonctionnalités d'Excel : celle de figer les volets.

    Si vous ne connaissez pas, il s'agit de diviser la feuille en 4 parties :
    - le coin supérieur gauche n'est jamais scrollable,
    - le coin inférieur gauche est scrollable verticalement uniquement,
    - le coin supérieur droit est scrollable horizontalement uniquement et
    - le coin inférieur droit est scrollable verticalement et horizontalement.

    En cherchant un peu sur le net, j'ai trouvé des tutos (http://www.java2s.com/Code/Java/Swin...umnExample.htm) qui m'a bien inspiré, mais je n'arrive pas à conclure.

    L'idée, c'est d'utiliser le JScrollPane et ses différentes zones de dessins.
    Voici le code la méthode qui crée mon composant :

    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
     
    final Object[][] data = new Object[50][50]; //tableau de 50*50
    final Object[] column = new Object[50];
     
    final int rowFixed = 8; 	//les 8 premières lignes seront fixées
    final int columnFixed = 2; 	// ainsi que les 2 premières colonnes
     
     
     
    /** 
     * Creates and return the DataGrid panel
     * @return JComponent : containing the grid
     */
    private JComponent getGridPanel()
    {
     
    	/******************************* Creation des données *****************************/
    	// entête de colonnes
    	for (int i = 0 ; i < 50 ; i++)
    	{
    		column[i] = "col_" + String.valueOf(i);
    	}
     
    	// données du tableau
    	for (int i = 0 ; i < 50 ; i++)
    	{
    		for (int j = 0 ; j < 50 ; j++)
    		{
    			data[i][j] = "R" + String.valueOf(i) + "C" + String.valueOf(j) ;
    		}
    	}
     
    	/******************************* Creation des Modèles du tableau *****************************/
    	// Model pour les lignes et colonnes fixées (coin sup gauche)
    	AbstractTableModel fixedRowColumnModel = new AbstractTableModel() 
    	{
    		public int getColumnCount() {
    			return columnFixed;	//on limite aux colonnes figées
    		}
     
    		public int getRowCount() {
    			return rowFixed; //on limite aux lignes figées
    		}
     
    		public String getColumnName(int col) {
    			return (String) column[col];
    		}
     
    		public Object getValueAt(int row, int col) {
    			return data[row][col];
    		}
    		public void setValueAt(Object obj, int row, int col) {
    			data[row][col] = obj;
    		}
    	};
     
    	// Model pour les lignes fixées (coin sup droit)
    	AbstractTableModel fixedRowModel = new AbstractTableModel()
    	{
    		public int getColumnCount() {
    			return column.length - columnFixed; // on ne compte que les colonnes de cette partie là
     
     
    		public int getRowCount() {
    			return rowFixed; 
    		}
     
    		public String getColumnName(int col) {
    			return (String) column[col + columnFixed]; //les indices de la zone commencent en 0,0, mais dans notre cas on tient compte de ce qui est figé
    		}
     
    		public Object getValueAt(int row, int col) {
    			return data[row][col + columnFixed];
    		}
     
    		public void setValueAt(Object obj, int row, int col) {
    			data[row][col + columnFixed] = obj;
    		}
     
    		public boolean CellEditable(int row, int col) {
    			return true;
    		}
    	};
     
    	// Model pour les colonnes fixées (coin inf gauche)
    	AbstractTableModel fixedColumnModel = new AbstractTableModel()
    	{
    		public int getColumnCount() {
    			return columnFixed;
    		}
     
    		public int getRowCount() {
    			return data.length - rowFixed ;
    		}
     
    		public String getColumnName(int col) {
    			return (String) column[col];
    		}
     
    		public Object getValueAt(int row, int col) {
    			return data[row + rowFixed][col];
    		}
     
    		public void setValueAt(Object obj, int row, int col) {
    			data[row + rowFixed][col] = obj;
    		}
     
    		  public boolean CellEditable(int row, int col) {
    			return true;
    		  }
    	  };	      
     
    	// Model pour le reste de la table (coin inf droit)
    	AbstractTableModel model = new AbstractTableModel() 
    	{
    		public int getColumnCount() {
    			return column.length - columnFixed;
    		}
     
    		public int getRowCount() {
    			return data.length - rowFixed;
    		}
     
    		public String getColumnName(int col) {
    			return (String) column[col + columnFixed];
    		}
     
    		public Object getValueAt(int row, int col) {
    			return data[row + rowFixed][col + columnFixed];
    		}
     
    		public void setValueAt(Object obj, int row, int col) {
    			data[row + rowFixed][col + columnFixed] = obj;
    		}
     
    		public boolean CellEditable(int row, int col) {
    		  return true;
    		}
    	};
     
     
    	/******************************* Creation des différentes tables *****************************/ 
    	JTable fixedRowColumnTable = new JTable(fixedRowColumnModel);
    	JTable fixedColumnTable = new JTable(fixedColumnModel);
    	JTable fixedRowTable = new JTable(fixedRowModel);
    	JTable table = new JTable(model);
     
    	// on souhaite faire apparaitre les scrollbars en cas de besoin : 
    	fixedRowColumnTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    	fixedRowTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    	fixedColumnTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    	table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
     
     
    	/******************************* La partie intéréssante ! *****************************/
    	//Le control complet : initialisé avec la partie inf droite
    	JScrollPane jsp = new JScrollPane(table);
     
    	// la partie sup gauche, completement figé
    	JViewport viewportRC = new JViewport();
    	viewportRC.setView(fixedRowColumnTable);
    	viewportRC.setPreferredSize(fixedRowColumnTable.getPreferredSize());
     
    	// la partie inf gauche droite
    	JViewport viewportC = new JViewport();
    	viewportC.setView(fixedColumnTable);
    	viewportC.setPreferredSize(fixedColumnTable.getPreferredSize());
     
    	// la partie sup droite
    	JViewport viewportR = new JViewport();
    	viewportR.setView(fixedRowTable);
    	viewportR.setPreferredSize(fixedRowTable.getPreferredSize());
     
     
    	/******************************* On affecte au JScrollPane *****************************/
    	jsp.setColumnHeader(viewportR); //on affecte en entête de colonnes les lignes figées
    	jsp.setRowHeader(viewportC); 	//on affecte en entête de lignes les colonnes figées
    	jsp.setCorner(JScrollPane.UPPER_LEFT_CORNER, viewportRC);	// et enfin l'intersection des Lignes/Colonnes figées, dans le coin sup gauche.
     
     
    	/******************************* et on se sauve *****************************/
    	return jsp;
    }
    ça se comporte relativement bien, sauf que je n'ai plus d'entêtes de colonnes (mais c'est bien normal, je les écrase avec mes tableaux, un petit renderer reglera le problème), mais surtout, voila le rendu affiché :



    On constate que les scrollbars sont bien positionnées, que ma zone sup gauche est bien positionnée, idem pour les 2 inférieures, mais alors la sup droite n'a pas bougé : c'est la ligne telle que construite au debut de la méthode.
    En débug, je constate que je ne passe jamais dans la méthode "getValueAt" du (AbstractTableModel)fixedRowModel.

    Et là où j'ai besoin de vous, c'est que je n'arrive pas à m'imaginer pourquoi....

    Any idea ?

    Notez bien que je suis nouveau (3 mois) en Java, j'ai éventuellement mal appréhendé ce point.

    Bonne soirée à tous,

    Manu.
    (Etant préssé par le temps, demain, j'essayerais de manipuler 2 grilles conjointements, avec chacune les 2 1eres colonnes figées, c'est une autre approche de ma problèmatique, mais j'aimerais bien avoir l'explication de ce point !)

  2. #2
    Membre du Club
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Juin 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 7
    Par défaut
    Hello,

    J'ai continué de chercher un peu, il semblerait qu'il ne soit pas évident d'avoir une entête à plusieurs lignes, mais du code existe (http://www.esus.com/javaindex/j2se/j...edheaders.html).
    Dans mon cas, je ne souhaitais pas aller plus avant dans cette solution avant de creuser l'autre piste d'hier : les 2 tables jointes.

    Du coup, j'ai choisi de gerer 2 JTables avec colonnes figées (voir l'exemple du post précédent). C'est un peu complexe de gérer les différents liens entre les composants, mais ça fonctionne !
    Je ne marque pas la question comme "Résolue" car elle ne l'est pas, mais cette méthode semble contourner mon problème.

    Toutefois, si quelqu'un avait une méthode simple pour résoudre mon point élégamment, il va sans dire que je suis preneur !

    Bonne fin de journée,

    Manu.

  3. #3
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Il te faut 2 Jtables obligatoirement, une placée dans le rowHeaderView du JScrollPane pour les colonnes fixes, une dans le JScrollPane pour les colonnes non fixes. Puis tu ajoutes le TableHeader de la JTable fixe dans le corner haut gauche de ton JScrollPane.


    Dans le genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    JScrollPane monScrollPane = new JScrollPane(maTableFlottante);
    monScrollPane.setRowHeaderView(maTableFixe);
    monScrollPane.setCorner(JScrollPane.UPPER_LEADING_CORNER,maTableFixe.getTableHeader());

  4. #4
    Membre du Club
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Juin 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 7
    Par défaut
    Hum, j'ai bien l'impression que ça donnerait le même résultat : je n'aurais rien en entête de colonnes (je suppose, je n'ai pas essayé le code).

    Cela dit, ta méthode semble plus simple et lisible pour arriver au même résultat que moi précédemment, avec le JViewPort !

    Bonne journée,

    Manu.

  5. #5
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Normalement il est censé y avoir les entêtes de colonnes avec ma méthode.

    C'est d'ailleurs le but du setCorner...

  6. #6
    Membre du Club
    Homme Profil pro
    Analyste programmeur
    Inscrit en
    Juin 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Analyste programmeur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 7
    Par défaut
    Ah yes OK, j'avais lu trop vite, et mal traduit le UPPER_LEADING_CORNER...
    Je n'ai effectivement pas cherché assez longtemps pour voir cette valeur, et le tuto que j'utilisais jusque là n'en parlait pas...

    Je ne pense pas modifier tout mon code pour l'instant, mais je le saurais pour la prochaine fois.

    Merci beaucoup,

    Manu

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

Discussions similaires

  1. [JTable] largeur de colonne differente selon la ligne
    Par Bideul dans le forum Composants
    Réponses: 5
    Dernier message: 30/11/2006, 11h53
  2. Tableau avec une ligne d'en-tête et une colonne fixe
    Par Invité dans le forum Mise en page CSS
    Réponses: 11
    Dernier message: 22/11/2006, 18h45
  3. Colonnes fixes lignes variables
    Par vid2006 dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 14/09/2006, 14h05
  4. 1ere colonne fixe Jtable ( JScrollpane )
    Par jdewalqu dans le forum Composants
    Réponses: 5
    Dernier message: 21/02/2006, 16h38
  5. JTable Largeur de colonne + retour à la ligne
    Par Invité dans le forum Composants
    Réponses: 7
    Dernier message: 02/02/2006, 23h05

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