如何使 JTable 列的大小完全(或接近)适合内容?

How do I make a JTable column size exactly (or closely) fit contents?

我程序的输出在 JScrollPane 内的 JTextArea 中。看起来很恶心:

Created BinaryTree.java      in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\BinaryTree.java
Created DisplayStuff.java        in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\DisplayStuff.java
Created LinkedList.java      in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\LinkedList.java
Created Node.java        in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\Node.java
Created notes        in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\notes
Created TryBinaryTree.java       in     I:\Netbeans OLDIES but KEEPIES\BinaryTree\src\binarytree\TryBinaryTree.java

所以我考虑将输出放入 JTable,假设在执行结束时调整列大小并获得看起来更像电子表格的结果并因此更具可读性是一件简单的事情:

我以前从未使用过 JTable,所以我尝试了一个简单的程序,看看我是否可以制作 JTable。我做到了。这是:

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;

public class TestJTable 
{
  static void init()
  {
    fraFrame = new JFrame();
    fraFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        dftTableModel = new DefaultTableModel(0 , 4);
        tblOutput     = new JTable(dftTableModel);
        scrOutput     = new JScrollPane(tblOutput);
        colMdl        =     tblOutput.getColumnModel();

    fraFrame.add(scrOutput); // NOTE: add the SCROLL PANE, not table
    fraFrame.setVisible(true);
    fraFrame.pack();
  }

  public static void main(String[] args) 
  {
    init();
    tblOutput.doLayout();
    dftTableModel.addRow(new Object[]{"Action", "Filename", "", "Path"});
    for (int i = 0; i < 100; i++) 
    {
        String c0 = Utilities.Utilities.repeat("x", (int) (Math.random()*50));
        dftTableModel.addRow(new Object[]{((Math.sin(i)) > 0 ? "Updated" : "Created"), 
                                          c0, "in", c0});
        k = Math.max(k, c0.length());
    }
  }
  static int                  k;
  static JFrame               fraFrame ;
  static JTable               tblOutput; 
  static DefaultTableModel    dftTableModel; 
  static JScrollPane          scrOutput;
  static TableColumnModel     colMdl;
}

这是输出:

我希望能够完全按照我的意愿设置列的大小。

我用一个小时的大小、首选大小、table 大小、自动调整大小(而不是)让我在程序的不同部分以不同的组合尝试以下操作,none产生了令人满意的结果,尽管取出 pack 有所帮助:

    fraFrame.setSize(1400, 600);
    tblOutput.setSize(1500,400);
    colMdl.getColumn(0).setPreferredWidth(15);
    colMdl.getColumn(1).setPreferredWidth(10*k);
    colMdl.getColumn(2).setPreferredWidth(5);
    colMdl.getColumn(3).setPreferredWidth(10*k);

所以我要问的是:

(a) 具体来说,假设我知道 kFilename 中的字符数,并且 'Pathcolumns, how can I make the contents of those columns be exactly fit their columns? (I assumefont` 大小将进入图片。)

(b) 通常,如何更改 JTable 中的列大小?例如,一列总是显示 "in"。如何使列不超过该宽度?

编辑

感谢@camickr,很容易获得所需的输出,无论是在上面的测试程序中还是在真实的程序中,输出如下:

查看 Table Column Adjuster

您可以根据以下条件设置列宽:

  1. 栏目标题
  2. 列中每一行的数据
  3. 标题或数据中较大的一个

class 还支持其他功能,允许在数据更改时动态调整大小。

或者您可以使用提供的基本代码,它仅使用 JTable 的 prepareRenderer(...) 方法来确定最大宽度。

JTable table = new JTable( ... );
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );

for (int column = 0; column < table.getColumnCount(); column++)
{
    TableColumn tableColumn = table.getColumnModel().getColumn(column);
    int preferredWidth = tableColumn.getMinWidth();
    int maxWidth = tableColumn.getMaxWidth();

    for (int row = 0; row < table.getRowCount(); row++)
    {
        TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
        Component c = table.prepareRenderer(cellRenderer, row, column);
        int width = c.getPreferredSize().width + table.getIntercellSpacing().width;
        preferredWidth = Math.max(preferredWidth, width);

        //  We've exceeded the maximum width, no need to check other rows

        if (preferredWidth >= maxWidth)
        {
            preferredWidth = maxWidth;
            break;
        }
    }

    tableColumn.setPreferredWidth( preferredWidth );
}

编辑:

I was hoping that knowing the font size and number of characters

FontMetrics fm = table.getFontMetrics( table.getFont() );
int charWidth = fm.stringWidth("a");
System.out.println( charWidth );