110 votes

Java JTable : réglage de la largeur des colonnes

J'ai un JTable dans lequel j'ai défini la taille des colonnes comme suit :

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);

Cela fonctionne bien, mais lorsque le tableau est agrandi, j'obtiens un espace vide à droite de la dernière colonne. Est-il possible de faire en sorte que la dernière colonne soit redimensionnée à la fin de la fenêtre lorsqu'elle est redimensionnée ?

J'ai trouvé AUTO_RESIZE_LAST_COLUMN dans la documentation, mais cela ne fonctionne pas.

Editar: JTable est dans un JScrollPane sa taille préférée est définie.

49voto

Eddie Points 27755

Que se passe-t-il si vous appelez setMinWidth(400) sur la dernière colonne au lieu de de setPreferredWidth(400) ?

Dans la JavaDoc pour JTable lisez les documents relatifs à [doLayout()](http://java.sun.com/javase/6/docs/api/javax/swing/JTable.html#doLayout()) très soigneusement. Voici quelques morceaux de choix :

Lorsque la méthode est appelée à la suite du redimensionnement d'une fenêtre englobante, le paramètre resizingColumn est nulle. Cela signifie que le redimensionnement a eu lieu "en dehors" de la JTable et que la modification - ou "delta" - doit être distribuée à toutes les colonnes, indépendamment de la méthode de redimensionnement automatique de ce JTable. le mode de redimensionnement automatique de ce JTable.

Cela pourrait être la raison pour laquelle AUTO_RESIZE_LAST_COLUMN ne vous a pas aidé.

Remarque : Lorsqu'un tableau JTable ajuste la largeur des colonnes, il respecte leurs valeurs minimale et maximale. valeurs minimales et maximales.

Cela signifie que vous pouvez définir Min == Max pour toutes les colonnes sauf la dernière, puis définir Min = Préféré sur la dernière colonne et soit ne pas définir Max, soit définir une valeur très élevée pour Max.

1 votes

SetMinWidth(400) fait que la partie droite du tableau est toujours vide.

2 votes

Essayez d'ajouter setMaxWidth(10000) pour voir si cela fait une différence.

1 votes

Supprimez la ligne table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF) ; Cela peut empêcher le redimensionnement que vous souhaitez.

24voto

akf Points 23518

Avec JTable.AUTO_RESIZE_OFF Dans ce cas, le tableau ne modifiera pas la taille des colonnes pour vous, il prendra donc votre paramètre préféré. Si vous souhaitez que les colonnes adoptent par défaut la taille que vous préférez, mais que la dernière colonne remplisse le reste du volet, vous pouvez utiliser l'option JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode, mais il pourrait être plus efficace lorsqu'il est utilisé avec TableColumn.setMaxWidth() au lieu de TableColumn.setPreferredWidth() pour toutes les colonnes sauf la dernière.

Une fois que vous êtes satisfait que AUTO_RESIZE_LAST_COLUMN fonctionne en fait, vous pouvez expérimenter avec une combinaison de TableColumn.setMaxWidth() y TableColumn.setMinWidth()

1 votes

Lorsque AUTO_RESIZE_LAST_COLUMN est utilisé, la table est redimensionnée pour s'adapter au volet de défilement. Mon objectif est d'avoir la table à une certaine taille minimale mais de l'agrandir si elle est plus grande que la taille minimale.

0 votes

Vous pouvez obtenir ce comportement si vous utilisez TableColumn.setMinWidth() au lieu de TableColumn.setMaxWidth().

0 votes

Pour ajouter à mon dernier commentaire : utilisez TableColumn.setMinWidth() pour chaque colonne de votre tableau, y compris la dernière colonne.

16voto

Rico Ocepek Points 39

JTable.AUTO_RESIZE_LAST_COLUMN est défini comme suit "Pendant toutes les opérations de redimensionnement, appliquer les ajustements à la dernière colonne seulement" ce qui signifie que vous devez définir le autoresizemode à la fin de votre code sinon setPreferredWidth() n'aura aucun effet !

Dans votre cas, ce serait donc la bonne méthode :

table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);

4voto

michel.iamit Points 1542

Lecture de la remarque de Kleopatra (sa 2ème fois, elle a suggéré de jeter un coup d'œil à javax.swing.JXTable et maintenant je suis désolé de ne pas avoir jeté un coup d'oeil la première fois :) ) Je vous suggère de suivre le lien

J'ai eu cette solution pour le même problème : (mais je vous suggère de suivre le lien ci-dessus) Lors du redimensionnement du tableau, mettez la largeur des colonnes du tableau à l'échelle de la largeur totale du tableau actuel. Pour ce faire, j'utilise un tableau global d'ints pour les largeurs (relatives) des colonnes) :

private int[] columnWidths=null;

J'utilise cette fonction pour définir la largeur des colonnes du tableau :

public void setColumnWidths(int[] widths){
    int nrCols=table.getModel().getColumnCount();
    if(nrCols==0||widths==null){
        return;
    }
    this.columnWidths=widths.clone();

    //current width of the table:
    int totalWidth=table.getWidth();

    int totalWidthRequested=0;
    int nrRequestedWidths=columnWidths.length;
    int defaultWidth=(int)Math.floor((double)totalWidth/(double)nrCols);

    for(int col=0;col<nrCols;col++){
        int width = 0;
        if(columnWidths.length>col){
            width=columnWidths[col];
        }
        totalWidthRequested+=width;
    }
    //Note: for the not defined columns: use the defaultWidth
    if(nrRequestedWidths<nrCols){
        log.fine("Setting column widths: nr of columns do not match column widths requested");
        totalWidthRequested+=((nrCols-nrRequestedWidths)*defaultWidth);
    }
    //calculate the scale for the column width
    double factor=(double)totalWidth/(double)totalWidthRequested;

    for(int col=0;col<nrCols;col++){
        int width = defaultWidth;
        if(columnWidths.length>col){
            //scale the requested width to the current table width
            width=(int)Math.floor(factor*(double)columnWidths[col]);
        }
        table.getColumnModel().getColumn(col).setPreferredWidth(width);
        table.getColumnModel().getColumn(col).setWidth(width);
    }

}

Lors du réglage des données, j'appelle :

    setColumnWidths(this.columnWidths);

et lors du changement, j'appelle le ComponentListener défini sur le parent de la table (dans mon cas, le JScrollPane qui est le conteneur de ma table) :

public void componentResized(ComponentEvent componentEvent) {
    this.setColumnWidths(this.columnWidths);
}

Notez que la table JTable est également globale :

private JTable table;

Et c'est ici que je règle l'auditeur :

    scrollPane=new JScrollPane(table);
    scrollPane.addComponentListener(this);

1 votes

Pour autant que je puisse voir, il s'agit d'un hack (très fragile) : il ne se met pas à jour lorsque l'utilisateur change la largeur d'une colonne. Encore une fois, je vous suggère de regarder le code source de JXTable - il a une propriété supplémentaire horizontalScroll qui déclenche le remplissage de la largeur disponible si la somme des préfs de colonne est inférieure à la largeur actuelle et affiche une barre de défilement horizontale dans le cas contraire.

0 votes

Je sais qu'il ne réagit pas à la modification manuelle de la largeur des tables par l'utilisateur, en ce sens c'est un hack... mais encore une fois : c'est mieux que ce qui est suggéré ci-dessus. Mais vous avez éveillé ma curiosité pour JXTable..... Je vais y jeter un coup d'oeil ! (et c'est agréable de vous croiser à nouveau sur un sujet de table :) )

0 votes

Vous aviez raison, voir ma remarque au dessus de ma réponse, j'ai upvoted votre remarque !

2voto

count0 Points 1431
fireTableStructureChanged();

permettra de modifier par défaut le comportement de redimensionnement ! Si cette méthode est appelée quelque part dans votre code APRÈS que vous ayez défini les propriétés de redimensionnement des colonnes, tous vos paramètres seront réinitialisés. Cet effet secondaire peut se produire indirectement. Par exemple, si le modèle de données lié est modifié d'une manière telle que cette méthode est appelée, après que les propriétés ont été définies.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X