Java JTable设置列宽


95

我有一个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其首选大小设置。

Answers:


45

如果您呼叫而不是setMinWidth(400)最后一列会怎样?setPreferredWidth(400)

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

当由于封闭窗口的大小调整而调用该方法时,resizingColumn为null。这意味着调整大小已经在JTable的“外部”进行了,无论JTable的自动调整大小模式如何,更改(或“ delta”)都应分配给所有列。

这可能就是为什么AUTO_RESIZE_LAST_COLUMN没有帮助您的原因。

注意:当JTable调整列的宽度时,它将绝对遵守其最小值和最大值。

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


1
setMinWidth(400)仍会使表的右侧为空
Hamza Yerlikaya 2009年

2
尝试添加setMaxWidth(10000)看看是否有所不同。
Eddie 2009年

1
删除行table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 这可能会阻止调整所需大小。
Eddie 2009年

你可能也想在JTable中本身设定的最小和最大尺寸,如果你还没有,
埃迪

3
确保应用表格模型执行setMinWidth调用。
Brian Knoblauch

23

使用JTable.AUTO_RESIZE_OFF,表格将不会为您更改任何列的大小,因此它将采用您的首选设置。如果您的目标是使列的默认大小达到您的首选大小(最后一行填充窗格的其余部分除外),则可以选择使用JTable.AUTO_RESIZE_LAST_COLUMNautoResizeMode,但是当与TableColumn.setMaxWidth()代替TableColumn 一起使用时,它可能是最有效的。 setPreferredWidth()除最后一列外的所有列。

当您对AUTO_RESIZE_LAST_COLUMN实际可行感到满意后,就可以尝试结合使用TableColumn.setMaxWidth()TableColumn.setMinWidth()


1
当使用AUTO_RESIZE_LAST_COLUMN调整表的大小以适合滚动窗格时,我的目标是使表具有一定的最小大小,但如果它大于最小大小,则使其增大。
Hamza Yerlikaya 2009年

如果您使用TableColumn.setMinWidth()而不是TableColumn.setMaxWidth(),则会出现此行为。
akf

添加到我的最后一条评论:对表中的每一列(包括最后一列)使用TableColumn.setMinWidth()。
akf

设置最小和最大宽度都可以解决此问题,但是现在滚动条已丢失。
Hamza Yerlikaya 2009年

14

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

5

使用这个方法

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

4

阅读Kleopatra的话(她第二次建议看一下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);

1
据我所知,这是一个(非常脆弱的)hack:它不会在用户更改列宽时更新。再次,我建议您查看JXTable的源代码-它具有一个附加属性horizo​​ntalScroll,如果column prefs的总和小于当前宽度,则触发填充可用宽度,否则显示水平滚动条
kleopatra 2011年

我知道它不会对用户手动更改表格宽度产生反应,那样就很麻烦了……但是再说一遍:它比上面建议的要好。但是您让我对JXTable感到好奇。...我在那里看看!(很高兴再次与您讨论餐桌主题:))
michel.iamit 2011年

您说得对,请在我的回答上方看到我的评论,我赞成您的评论!
michel.iamit 2011年

至少这对我很有用,我将这种方法用于列权原则。
Solostaran13年

2
fireTableStructureChanged();

将默认调整大小行为!如果您在代码后的某个地方调用了此方法,则您确实设置了列调整大小属性后,所有设置都会被重置。这种副作用可以间接发生。在设置属性后,由于链接数据模型以一种调用此方法的方式更改的结果,Fe。


1

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

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

这段代码无需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

使用此代码。它为我工作。我考虑了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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.