【问题标题】:Java JTable setting Column WidthJava JTable设置列宽
【发布时间】: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 中,它的首选大小已设置。

【问题讨论】:

    标签: java swing size jtable


    【解决方案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);
              }
              

              【讨论】:

                猜你喜欢
                • 2012-09-15
                • 1970-01-01
                • 2013-02-16
                • 2013-10-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-10-27
                • 2013-06-19
                相关资源
                最近更新 更多