简体   繁体   English

Java JTable 设置列宽

[英]Java JTable setting Column Width

I have a JTable in which I set the column size as follows:我有一个 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);

This works fine, but when the table is maximized, I get empty space to the right of the last column.这工作正常,但是当表格最大化时,我在最后一列的右侧获得空白空间。 Is it possible to make the last column resize to the end of the window when resized?调整大小时是否可以将最后一列调整到窗口的末尾?

I found AUTO_RESIZE_LAST_COLUMN property in docs but it does not work.我在文档中找到了AUTO_RESIZE_LAST_COLUMN属性,但它不起作用。

Edit: JTable is in a JScrollPane its prefered size is set.编辑: JTable位于JScrollPane其首选大小已设置。

What happens if you call setMinWidth(400) on the last column instead of setPreferredWidth(400) ?如果在最后一列调用setMinWidth(400)而不是setPreferredWidth(400)什么?

In the JavaDoc for JTable , read the docs for doLayout() very carefully.JTable的 JavaDoc 中,非常仔细地阅读doLayout()的文档。 Here are some choice bits:以下是一些选择位:

When the method is called as a result of the resizing of an enclosing window, the resizingColumn is null.当由于调整封闭窗口的大小而调用该方法时,resizingColumn 为空。 This means that resizing has taken place "outside" the JTable and the change - or "delta" - should be distributed to all of the columns regardless of this JTable's automatic resize mode.这意味着调整大小已发生在 JTable 的“外部”,并且无论此 JTable 的自动调整大小模式如何,更改(或“增量”)都应分布到所有列。

This might be why AUTO_RESIZE_LAST_COLUMN didn't help you.这可能就是AUTO_RESIZE_LAST_COLUMN没有帮助你的原因。

Note: When a JTable makes adjustments to the widths of the columns it respects their minimum and maximum values absolutely.注意:当 JTable 调整列的宽度时,它绝对尊重它们的最小值和最大值。

This says that you might want to set Min == Max for all but the last columns, then set Min = Preferred on the last column and either not set Max or set a very large value for Max.这表示您可能希望为除最后一列之外的所有列设置 Min == Max,然后在最后一列上设置 Min = Preferred,并且要么不设置 Max,要么为 Max 设置一个非常大的值。

With JTable.AUTO_RESIZE_OFF , the table will not change the size of any of the columns for you, so it will take your preferred setting.使用JTable.AUTO_RESIZE_OFF ,表不会为您更改任何列的大小,因此它将采用您的首选设置。 If it is your goal to have the columns default to your preferred size, except to have the last column fill the rest of the pane, You have the option of using the JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode, but it might be most effective when used with TableColumn.setMaxWidth() instead of TableColumn.setPreferredWidth() for all but the last column.如果您的目标是让列默认为您的首选大小,除了让最后一列填充窗格的其余部分,您可以选择使用JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode,但与TableColumn.setMaxWidth()使用时它可能最有效TableColumn.setMaxWidth()而不是 TableColumn.setPreferredWidth() 除了最后一列。

Once you are satisfied that AUTO_RESIZE_LAST_COLUMN does in fact work, you can experiment with a combination of TableColumn.setMaxWidth() and TableColumn.setMinWidth()一旦您对AUTO_RESIZE_LAST_COLUMN确实有效感到满意,您就可以试验TableColumn.setMaxWidth()TableColumn.setMinWidth()

JTable.AUTO_RESIZE_LAST_COLUMN is defined as "During all resize operations, apply adjustments to the last column only" which means you have to set the autoresizemode at the end of your code , otherwise setPreferredWidth() won't affect anything! JTable.AUTO_RESIZE_LAST_COLUMN定义为“在所有调整大小操作期间,仅对最后一列应用调整”这意味着您必须在代码末尾设置autoresizemode ,否则 setPreferredWidth() 不会影响任何内容!

So in your case this would be the correct way:所以在你的情况下,这将是正确的方法:

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

Use this method使用这个方法

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

Or extend the JTable class:或者扩展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;
        }
    }
}

And then进而

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

Reading the remark of Kleopatra (her 2nd time she suggested to have a look at javax.swing.JXTable , and now I Am sorry I didn't have a look the first time :) ) I suggest you follow the link阅读 Kleopatra 的评论(她第二次建议看一下javax.swing.JXTable ,现在很抱歉我第一次没有看:))我建议你点击链接

I had this solution for the same problem: (but I suggest you follow the link above) On resize the table, scale the table column widths to the current table total width.对于同样的问题,我有这个解决方案:(但我建议你按照上面的链接)在调整表格大小时,将表格列的宽度缩放到当前表格的总宽度。 to do this I use a global array of ints for the (relative) column widths):为此,我使用全局整数数组作为(相对)列宽):

private int[] columnWidths=null;

I use this function to set the table column widths:我使用这个函数来设置表格列宽:

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

When setting the data I call:设置数据时我调用:

    setColumnWidths(this.columnWidths);

and on changing I call the ComponentListener set to the parent of the table (in my case the JScrollPane that is the container of my table):在更改时,我将 ComponentListener 设置为表的父级(在我的情况下,JScrollPane 是我的表的容器):

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

note that the JTable table is also global:请注意,JTable 表也是全局的:

private JTable table;

And here I set the listener:在这里我设置了监听器:

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

will default the resize behavior !将默认调整大小行为 If this method is called somewhere in your code AFTER you did set the column resize properties all your settings will be reset.如果在您设置列调整大小属性后在代码中的某处调用此方法,则所有设置都将被重置。 This side effect can happen indirectly.这种副作用可以间接发生。 Fe as a consequence of the linked data model being changed in a way this method is called, after properties are set. Fe 作为链接数据模型的结果,在设置属性后以调用此方法的方式更改。

No need for the option, just make the preferred width of the last column the maximum and it will take all the extra space.不需要该选项,只需将最后一列的首选宽度设为最大值,它将占用所有额外空间。

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

This code is worked for me without setAutoResizeModes.此代码适用于没有 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);

Use this code.使用此代码。 It worked for me.它对我有用。 I considered for 3 columns.我考虑了 3 列。 Change the loop value for your code.更改代码的循环值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM