Java JTable设置列宽

Posted

技术标签:

【中文标题】Java JTable设置列宽【英文标题】:Java JTable setting Column Width 【发布时间】:2010-10-31 12:54:25 【问题描述】:

我有一个 JTable,我在其中设置列大小如下:

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

这很好用,但是当表格最大化时,我在最后一列的右侧得到了空白空间。调整大小时是否可以使最后一列调整到窗口的末尾?

我在文档中找到了AUTO_RESIZE_LAST_COLUMN 属性,但它不起作用。

编辑:JTableJScrollPane 中,它的首选大小已设置。

【问题讨论】:

【参考方案1】:

如果您在setPreferredWidth(400) 的最后一列而不是 调用setMinWidth(400),会发生什么情况?

JTable 的JavaDoc 中,请仔细阅读doLayout() 的文档。以下是一些选择位:

当由于调整封闭窗口的大小而调用该方法时, resizingColumn 为空。这意味着调整大小发生在 JTable 的“外部” 并且更改 - 或“增量” - 应该分发到所有列,无论 这个 JTable 的自动调整大小模式。

这可能是AUTO_RESIZE_LAST_COLUMN 没有帮助您的原因。

注意:当 JTable 对列的宽度进行调整时,它会尊重它们的列宽 绝对的最小值和最大值。

这表示您可能希望为除最后一列之外的所有列设置 Min == Max,然后在最后一列上设置 Min = Preferred 并且不设置 Max 或为 Max 设置一个非常大的值。

【讨论】:

setMinWidth(400) 仍然导致表格右侧为空 尝试添加 setMaxWidth(10000) 看看是否会有所不同。 删除行 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);这可能会阻止您调整大小。 如果您还没有设置 JTable 本身的最小和最大大小,您可能还想设置, 确保在应用表格模型之后调用 setMinWidth...这让我有一阵子绊倒了。【参考方案2】:

使用JTable.AUTO_RESIZE_OFF,表格不会为您更改任何列的大小,因此它将采用您的首选设置。如果您的目标是让列默认为您喜欢的大小,除了让最后一列填充窗格的其余部分,您可以选择使用 JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode,但与 @ 一起使用可能最有效987654323@ 而不是 TableColumn.setPreferredWidth() 除了最后一列。

一旦您对 AUTO_RESIZE_LAST_COLUMN 确实有效感到满意,您可以尝试组合使用 TableColumn.setMaxWidth()TableColumn.setMinWidth()

【讨论】:

当使用 AUTO_RESIZE_LAST_COLUMN 时,表格会调整大小以适应滚动窗格,我的目标是让表格具有一定的最小尺寸,但如果它大于我的最小尺寸,则使其增长。 如果你使用 TableColumn.setMinWidth() 而不是 TableColumn.setMaxWidth(),你可以有这种行为。 添加到我的最后一条评论:对表格中的每一列使用 TableColumn.setMinWidth(),包括最后一列。 设置最小和最大宽度解决了这个问题,但现在滚动条不见了。【参考方案3】:

JTable.AUTO_RESIZE_LAST_COLUMN 定义为“在所有调整大小操作期间,仅对最后一列应用调整”,这意味着您必须在代码末尾设置 autoresizemode,否则 setPreferredWidth() 不会有任何影响!

所以在你的情况下,这将是正确的方法:

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

【讨论】:

【参考方案4】:

使用这个方法

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;
    

或者扩展JTable类:

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;
        
    

然后

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

【讨论】:

【参考方案5】:

阅读克利奥帕特拉的评论(她第二次建议看javax.swing.JXTable,现在很抱歉我第一次没有看:)) 我建议你点击链接

我对同样的问题有这个解决方案:(但我建议你点击上面的链接) 在调整表格大小时,将表格列宽缩放到当前表格总宽度。 为此,我使用一个全局整数数组作为(相对)列宽):

private int[] columnWidths=null;

我使用这个函数来设置表格列宽:

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

设置我调用的数据时:

    setColumnWidths(this.columnWidths);

在更改时,我将 ComponentListener 设置为表的父级(在我的情况下,JScrollPane 是我的表的容器):

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

注意 JTable 表也是全局的:

private JTable table;

我在这里设置了监听器:

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

【讨论】:

据我所知,这是一个(非常脆弱的)hack:它不会在用户更改列宽时更新。同样,我建议您查看 JXTable 的源代码 - 它有一个附加属性 Horizo​​ntalScroll,如果列首选项的总和小于当前宽度,则触发填充可用宽度,否则显示水平滚动条 我知道它不会对用户手动更改表格宽度做出反应,这样它是一种黑客行为......但同样:它比上面建议的要好。但是你让我对 JXTable 很好奇......我会去那里看看! (很高兴再次走进你的桌子主题:)) 你是对的,在我的回答之上看到我的评论,我赞成你的评论! 至少这对我有用,我在我的案例中使用了这种方法和列权重原则。【参考方案6】:
fireTableStructureChanged();

将默认调整大小行为!如果在您设置列调整大小属性之后在代码中的某处调用此方法,您的所有设置都将被重置。这种副作用可能间接发生。 F.e.由于链接数据模型在设置属性后以调用此方法的方式发生更改。

【讨论】:

【参考方案7】:

不需要该选项,只需将最后一列的首选宽度设为最大值,它将占用所有额外空间。

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

【讨论】:

【参考方案8】:

此代码在没有 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);

【讨论】:

【参考方案9】:

使用此代码。它对我有用。我考虑了 3 列。更改代码的循环值。

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

【讨论】:

以上是关于Java JTable设置列宽的主要内容,如果未能解决你的问题,请参考以下文章

设置 JTable 列的原型值(用于自动宽度计算)

自动计算 JTable 中的列宽

如何使 JTable 自动调整大小和水平滚动?

如何在 JTable/JXTable 中设置列​​宽?

java swing JTable显示问题

java中如何把JTable设置为不可编辑