自动调整JTable列宽度

35
我希望我的JTable可以自动调整列宽以适应内容。我找到了TableColumnAdjuster类很有用。但是有一个小问题。假设我有5列,它们的内容非常短。在这种情况下,如果我使用自动调整器,它会根据其内容设置前四列的宽度,并将所有剩余的空间都分配给最后一列。请参见示例。

enter image description here

这里最后一列Balance占据了所有多余的空间。但是,如果我需要将该空间分配给中间的某一列怎么办?在上面的情况下,我需要将该空间分配给第三列name。我尝试修改TableColumnAdjuster类的adjustColumns()方法。但是,我无法让它正常工作。
我尝试使用column.setPreferredWidth()column.setWidth()来更改列大小。但似乎没有任何变化。如何有效地更改JTable的列大小。如果有其他替代方案或直接回答我的主要问题,那就更好了。谢谢!
6个回答

75

您可以尝试以下操作:

public void resizeColumnWidth(JTable table) {
    final TableColumnModel columnModel = table.getColumnModel();
    for (int column = 0; column < table.getColumnCount(); column++) {
        int width = 15; // Min width
        for (int row = 0; row < table.getRowCount(); row++) {
            TableCellRenderer renderer = table.getCellRenderer(row, column);
            Component comp = table.prepareRenderer(renderer, row, column);
            width = Math.max(comp.getPreferredSize().width +1 , width);
        }
        if(width > 300)
            width=300;
        columnModel.getColumn(column).setPreferredWidth(width);
    }
}

JTable

这个方法需要在调整大小方法之前执行。
如果你有:

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

JTable


这太棒了,最终我使用了它。在setPreferredColumnModel调用之前,我添加了一个检查,看起来像是“if(width > 300)width=300;”,它可以修复一些显示非常长的数据字段的情况。我建议将其添加到答案中 - 你还可以提取出最小/最大宽度(这将成为可选参数 - 实际上我现在要在我的代码库中这样做)。 (我希望我知道什么时候编辑类似于这样的内容到别人的答案是很酷的...由于它不是CW,我不想在没有许可的情况下更改内容。) - Bill K
嗨,@BillK 请随意编辑/添加代码... 如果您有的话,附上截图吧。 ;) - Paul Vargas
1
我还能否以某种方式评估标题,以确保其文本不会被截断? - xeruf
2
在上述代码的第9行后添加width = Math.max(width, table.getColumnModel().getColumn(column).getPreferredWidth());以评估标题。 - SomeDude
完美地工作了,就像预期的一样! - RafiAlhamd

4

没有自动调整单个列宽度大于其他列的选项。

也许你可以尝试以下方法:

tca = new TableColumnAdjuster( table, 0 );
tca.adjustColumns();
TableColumnModel tcm = table.getColumnModel();  
TableColumn tc = tcm.getColumn(1);
tc.setWidth(tc.getWidth() + 25);

这将允许您向第一列添加额外的空间。此额外空间仅在首次显示表格时添加。

另一个选项是使用:

table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

这将按比例为每列分配额外的空间。

1
这与所要求的相反。 "table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);"会均匀地调整所有列的大小,而不考虑内容长度。 - Shai Alon

4

setAutoResizeMode()会告诉你的表格如何调整大小。你可以尝试不同的选项来查看它们之间的区别。在我的情况下,我想特别调整两列的大小,并让程序自动决定如何调整其他列的大小。

jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
TableColumnModel colModel=jTable1.getColumnModel();
colModel.getColumn(1).setPreferredWidth(25);    
colModel.getColumn(2).setPreferredWidth(400);

1

稍微修改一下Paul Vargas的回答,你也可以考虑列标题的大小:

public static void resizeColumnWidth(JTable table) {
    final TableColumnModel columnModel = table.getColumnModel();
    for (int column = 0; column < table.getColumnCount(); column++) {
        // Account for header size
        double width = table.getTableHeader().getHeaderRect(column).getWidth();
        for (int row = 0; row < table.getRowCount(); row++) {
            TableCellRenderer renderer = table.getCellRenderer(row, column);
            Component comp = table.prepareRenderer(renderer, row, column);
            width = Math.max(comp.getPreferredSize().width + 1, width);
        }
        if (width > 300)
            width = 300;
        columnModel.getColumn(column).setPreferredWidth((int) width);
    }
}

0
你可以这样做:

JPanel jp = new JPanel();
jp.add(table);

jp.setLayout(new GridLayout(1,1)); /* little trick ;) and believe me that this step is important to the automatic all columns resize! A import is also needed for using GridLayout*/
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); // this is obvius part

0

稍微修改一下Paul Vargas的回答,你也可以考虑列标题的内容:

public static void resizeColumnWidth(JTable table)
{
      TableCellRenderer renderer;
      TableColumn column;
      Component component;
      Object header;
      int rowIndex, minWidth, width;

      column = table.
         getColumnModel().
         getColumn(colIndex);

      renderer = table.
         getTableHeader().
         getDefaultRenderer();

      header    = column.getHeaderValue();
      component = renderer.getTableCellRendererComponent(table, header, false, false, -1, colIndex);
      width     = component.getPreferredSize().width;
      minWidth  = Math.max(width, 0);

      for (rowIndex = table.getRowCount(); --rowIndex >= 0; )
      {
         renderer  = table.getCellRenderer(rowIndex, colIndex);
         component = table.prepareRenderer(renderer, rowIndex, colIndex);
         width     = component.getPreferredSize().width;
         minWidth  = Math.max(minWidth, width);
      }

      column.setPreferredWidth(minWidth);
    }

注意:这与Cardinal System的答案不同,因为此代码考虑了标题内容,而Cardinal System的答案仅考虑了标题大小。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接