Impostazione Java JTable Larghezza colonna


95

Ho una tabella JTable in cui imposto la dimensione della colonna come segue:

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);

Funziona bene, ma quando la tabella è ingrandita, ottengo uno spazio vuoto a destra dell'ultima colonna. È possibile ridimensionare l'ultima colonna alla fine della finestra quando viene ridimensionata?

Ho trovato AUTO_RESIZE_LAST_COLUMNproprietà nei documenti ma non funziona.

Modifica: JTableè in una JScrollPanesua dimensione preferita è impostata.

Risposte:


45

Che cosa succede se si chiama setMinWidth(400)l'ultima colonna , invece di setPreferredWidth(400)?

In JavaDoc per JTable, leggi i documenti per doLayout()con molta attenzione. Ecco alcuni bit di scelta:

Quando il metodo viene chiamato come risultato del ridimensionamento di una finestra che lo racchiude, resizingColumn è nullo. Ciò significa che il ridimensionamento è stato eseguito "al di fuori" di JTable e la modifica - o "delta" - deve essere distribuita a tutte le colonne indipendentemente dalla modalità di ridimensionamento automatico di questa JTable.

Questo potrebbe essere il motivo per cui AUTO_RESIZE_LAST_COLUMNnon ti ha aiutato.

Nota: quando una JTable effettua delle regolazioni alle larghezze delle colonne, rispetta assolutamente i loro valori minimo e massimo.

Questo dice che potresti voler impostare Min == Max per tutte le colonne tranne le ultime, quindi impostare Min = Preferred sull'ultima colonna e non impostare Max o impostare un valore molto grande per Max.


1
setMinWidth (400) fa ancora vuoto il diritto della tabella
Hamza Yerlikaya

2
Prova ad aggiungere setMaxWidth (10000) per vedere se questo fa la differenza.
Eddie,

1
Rimuovere la riga table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); Ciò potrebbe impedire il ridimensionamento desiderato.
Eddie

Probabilmente vorrai anche impostare le dimensioni minime e massime sulla tabella JTable stessa, se non l'hai già fatto,
Eddie

3
Assicurati di eseguire la chiamata setMinWidth dopo aver applicato il modello di tabella ... Mi ha fatto inciampare una volta per un po '.
Brian Knoblauch

23

Con JTable.AUTO_RESIZE_OFF, la tabella non cambierà la dimensione di nessuna delle colonne per te, quindi prenderà la tua impostazione preferita. Se il tuo obiettivo è avere le colonne predefinite alla dimensione preferita, eccetto che l'ultima colonna riempia il resto del riquadro, hai la possibilità di utilizzare JTable.AUTO_RESIZE_LAST_COLUMNautoResizeMode, ma potrebbe essere più efficace se usato con TableColumn.setMaxWidth()invece di TableColumn. setPreferredWidth () per tutte le colonne tranne l'ultima.

Una volta che sei soddisfatto che AUTO_RESIZE_LAST_COLUMNeffettivamente funzioni, puoi sperimentare una combinazione di TableColumn.setMaxWidth()eTableColumn.setMinWidth()


1
Quando viene utilizzato AUTO_RESIZE_LAST_COLUMN, la tabella viene ridimensionata per adattarsi al riquadro di scorrimento, il mio obiettivo è di avere la tabella a una determinata dimensione minima ma farla crescere se è più grande della mia dimensione minima.
Hamza Yerlikaya,

Puoi avere questo comportamento se usi TableColumn.setMinWidth () invece di TableColumn.setMaxWidth ().
akf

da aggiungere al mio ultimo commento: usa TableColumn.setMinWidth () per ogni colonna nella tua tabella, inclusa l'ultima colonna.
akf

l'impostazione della larghezza minima e massima ha risolto il problema ma ora mancano le barre di scorrimento.
Hamza Yerlikaya

14

JTable.AUTO_RESIZE_LAST_COLUMNè definito come "Durante tutte le operazioni di ridimensionamento, applica le regolazioni solo all'ultima colonna", il che significa che devi impostare la modalità di ridimensionamento automatico alla fine del codice , altrimenti setPreferredWidth () non influirà su nulla!

Quindi nel tuo caso questo sarebbe il modo corretto:

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);

5

Usa questo metodo

public static void setColumnWidths(JTable table, int... widths) {
    TableColumnModel columnModel = table.getColumnModel();
    for (int i = 0; i < widths.length; i++) {
        if (i < columnModel.getColumnCount()) {
            columnModel.getColumn(i).setMaxWidth(widths[i]);
        }
        else break;
    }
}

Oppure estendi la JTableclasse:

public class Table extends JTable {
    public void setColumnWidths(int... widths) {
        for (int i = 0; i < widths.length; i++) {
            if (i < columnModel.getColumnCount()) {
                columnModel.getColumn(i).setMaxWidth(widths[i]);
            }
            else break;
        }
    }
}

E poi

table.setColumnWidths(30, 150, 100, 100);

4

Leggendo l'osservazione di Kleopatra (la sua seconda volta ha suggerito di dare un'occhiata a javax.swing.JXTable , e ora mi dispiace di non aver dato un'occhiata la prima volta :)) ti consiglio di seguire il link

Avevo questa soluzione per lo stesso problema: (ma ti suggerisco di seguire il link sopra) Quando ridimensiona la tabella, ridimensiona la larghezza delle colonne della tabella alla larghezza totale della tabella corrente. per fare questo utilizzo un array globale di int per le larghezze (relative) delle colonne):

private int[] columnWidths=null;

Uso questa funzione per impostare le larghezze delle colonne della tabella:

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);
    }

}

Quando imposto i dati chiamo:

    setColumnWidths(this.columnWidths);

e al cambio chiamo il ComponentListener impostato al genitore della tabella (nel mio caso il JScrollPane che è il contenitore della mia tabella):

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

nota che anche la tabella JTable è globale:

private JTable table;

E qui ho impostato l'ascoltatore:

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

1
per quanto posso vedere, questo è un trucco (molto fragile): non si aggiorna quando l'utente cambia la larghezza di una colonna. Ancora una volta, ti suggerirei di esaminare il codice sorgente di JXTable: ha una proprietà aggiuntiva horizontalScroll che attiva il riempimento della larghezza disponibile se la somma delle preferenze di colonna è inferiore alla larghezza corrente e mostra una barra di scorrimento orizzontale altrimenti
kleopatra

So che non reagisce all'utente che cambia manualmente le larghezze della tabella, in questo modo è un hack ... ma ancora: è meglio di quanto suggerito sopra. Ma mi hai incuriosito da JXTable .... darò un'occhiata lì! (e piacere di tornare da te su un argomento da tavolo :))
michel.iamit

Avevi ragione, vedi la mia osservazione in cima alla mia risposta, ho votato positivamente la tua osservazione!
michel.iamit

Almeno questo è stato utile per me, ho usato questo approccio per il mio caso con un principio del peso della colonna.
Solostaran14

2
fireTableStructureChanged();

imposterà il comportamento di ridimensionamento ! Se questo metodo viene chiamato da qualche parte nel codice DOPO aver impostato le proprietà di ridimensionamento della colonna, tutte le impostazioni verranno ripristinate. Questo effetto collaterale può verificarsi indirettamente. Fe come conseguenza della modifica del modello di dati collegati in un modo in cui viene chiamato questo metodo, dopo che le proprietà sono state impostate.


1

Non è necessaria l'opzione, basta impostare la larghezza preferita dell'ultima colonna al massimo e ci vorrà tutto lo spazio extra.

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(Integer.MAX_INT);

0

Questo codice funziona per me senza setAutoResizeModes.

        TableColumnModel columnModel = jTable1.getColumnModel();
        columnModel.getColumn(1).setPreferredWidth(170);
        columnModel.getColumn(1).setMaxWidth(170);
        columnModel.getColumn(2).setPreferredWidth(150);
        columnModel.getColumn(2).setMaxWidth(150);
        columnModel.getColumn(3).setPreferredWidth(40);
        columnModel.getColumn(3).setMaxWidth(40);

-1

Usa questo codice. Ha funzionato per me. Ho considerato per 3 colonne. Modificare il valore del ciclo per il codice.

TableColumn column = null;
for (int i = 0; i < 3; i++) {
    column = table.getColumnModel().getColumn(i);
    if (i == 0) 
        column.setMaxWidth(10);
    if (i == 2)
        column.setMaxWidth(50);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.