Configuração Java JTable da largura da coluna


95

Eu tenho uma JTable na qual defino o tamanho da coluna da seguinte maneira:

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

Isso funciona bem, mas quando a tabela é maximizada, recebo um espaço vazio à direita da última coluna. É possível redimensionar a última coluna para o final da janela quando redimensionada?

Encontrei um AUTO_RESIZE_LAST_COLUMNimóvel no docs, mas não funciona.

Editar: JTableestá em um JScrollPanetamanho de sua preferência definido.

Respostas:


45

O que acontece se você chamar setMinWidth(400)na última coluna em vez de setPreferredWidth(400)?

No JavaDoc para JTable, leia os documentos para com doLayout()muito cuidado. Aqui estão alguns bits de escolha:

Quando o método é chamado como resultado do redimensionamento de uma janela envolvente, o resizingColumn é nulo. Isso significa que o redimensionamento ocorreu "fora" do JTable e a alteração - ou "delta" - deve ser distribuída para todas as colunas, independentemente do modo de redimensionamento automático deste JTable.

Pode ser por isso AUTO_RESIZE_LAST_COLUMNque não o ajudou.

Nota: Quando uma JTable faz ajustes nas larguras das colunas, ela respeita seus valores mínimo e máximo de forma absoluta.

Isso indica que você pode querer definir Min == Max para todas as colunas, exceto as últimas, então definir Min = Preferred na última coluna e não definir Max ou definir um valor muito grande para Max.


1
setMinWidth (400) ainda faz com que a direita da tabela fique vazia
Hamza Yerlikaya

2
Experimente adicionar setMaxWidth (10000) para ver se isso faz diferença.
Eddie

1
Remova a linha table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); Isso pode impedir o redimensionamento que você deseja.
Eddie

Você provavelmente também deseja definir o tamanho mínimo e máximo no próprio JTable, se ainda não o fez,
Eddie

3
Certifique-se de fazer a chamada setMinWidth após aplicar o modelo de tabela ... Isso me tropeçou uma vez por um tempo.
Brian Knoblauch

23

Com JTable.AUTO_RESIZE_OFF, a tabela não alterará o tamanho de nenhuma das colunas para você, portanto, assumirá sua configuração preferida. Se o seu objetivo é que as colunas tenham o tamanho padrão de sua preferência, exceto que a última coluna preencha o resto do painel, você tem a opção de usar o JTable.AUTO_RESIZE_LAST_COLUMNautoResizeMode, mas pode ser mais eficaz quando usado com em TableColumn.setMaxWidth()vez de TableColumn. setPreferredWidth () para todas, exceto a última coluna.

Quando estiver satisfeito com o que de AUTO_RESIZE_LAST_COLUMNfato funciona, você pode experimentar uma combinação de TableColumn.setMaxWidth()eTableColumn.setMinWidth()


1
Quando AUTO_RESIZE_LAST_COLUMN é usado, a tabela é redimensionada para caber no painel de rolagem, meu objetivo é ter a tabela em um determinado tamanho mínimo, mas fazê-la crescer se for maior do que meu tamanho mínimo.
Hamza Yerlikaya

Você pode ter esse comportamento se usar TableColumn.setMinWidth () em vez de TableColumn.setMaxWidth ().
akf

para adicionar ao meu último comentário: use TableColumn.setMinWidth () para cada coluna em sua tabela, incluindo a última coluna.
akf

definir a largura mínima e máxima resolveu o problema, mas agora as barras de rolagem estão faltando.
Hamza Yerlikaya

14

JTable.AUTO_RESIZE_LAST_COLUMNé definido como "Durante todas as operações de redimensionamento, aplique ajustes apenas à última coluna", o que significa que você deve definir o modo automático no final do seu código , caso contrário setPreferredWidth () não afetará nada!

Portanto, no seu caso, esta seria a maneira correta:

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

Use este método

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

Ou estenda a JTableaula:

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 depois

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

4

Lendo a observação do Kleopatra (na segunda vez, ela sugeriu dar uma olhada em javax.swing.JXTable , e agora sinto muito não ter dado uma olhada na primeira vez :)) Sugiro que você siga o link

Eu tinha essa solução para o mesmo problema: (mas sugiro que você siga o link acima) Ao redimensionar a tabela, dimensione as larguras das colunas da tabela para a largura total da tabela atual. para fazer isso, uso uma matriz global de ints para as larguras de coluna (relativas)):

private int[] columnWidths=null;

Eu uso esta função para definir as larguras das colunas da tabela:

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

}

Ao definir os dados, eu chamo:

    setColumnWidths(this.columnWidths);

e ao mudar eu chamo o ComponentListener definido para o pai da tabela (no meu caso o JScrollPane que é o contêiner da minha tabela):

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

observe que a tabela JTable também é global:

private JTable table;

E aqui eu defino o ouvinte:

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

1
até onde posso ver, este é um hack (muito frágil): ele não atualiza quando o usuário altera a largura da coluna. Novamente, eu sugiro que você olhe para o código-fonte de JXTable - ele tem uma propriedade adicional horizontalScroll que dispara o preenchimento da largura disponível se a soma das preferências de coluna for menor que a largura atual e mostra uma barra de rolagem horizontal de outra forma
kleopatra

Eu sei que não reage ao usuário mudar a largura da mesa manualmente, dessa forma é um hack ... mas novamente: é melhor do que o sugerido acima. Mas você me deixou curioso para JXTable .... Vou dar uma olhada lá! (e bom
falar

Você estava certo, veja meu comentário além da minha resposta, eu votei a favor de seu comentário!
michel.iamit

Pelo menos isso foi útil para mim, usei essa abordagem para meu caso com um princípio de peso de coluna.
Solostaran14

2
fireTableStructureChanged();

irá padronizar o comportamento de redimensionamento ! Se este método for chamado em algum lugar do seu código DEPOIS de você definir as propriedades de redimensionamento da coluna, todas as suas configurações serão redefinidas. Este efeito colateral pode acontecer indiretamente. Fe como consequência do modelo de dados vinculado ser alterado de uma forma que este método é chamado, após as propriedades serem definidas.


1

Não há necessidade da opção, apenas faça com que a largura preferida da última coluna seja a máxima e ela ocupará todo o espaço 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

Este código funcionou para mim sem 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

Use este código. Funcionou para mim Eu considerei por 3 colunas. Altere o valor do loop para o seu código.

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);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.