The output from my program is in a JTextArea
inside a JScrollPane
. It looks nasty:
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
So I thought about putting the output into a JTable
, assuming it would be a simple matter to adjust column size at the end of execution and get results that look more like a spreadsheet and thus be more readable:
I'd never used JTable
before, so I tried a simple program to see if I could make a JTable
at all. I did. Here it is:
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;
}
And here's the output:
I want to be able to set the columns' sizes exactly as I want.
An hour of spinning my wheels with sizes, preferred sizes, table sizes, autoresizing (and not) led me to try the following in varying combinations at varying parts of the program, none producing satisfactory results, although taking out pack
helped somewhat:
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);
So it is that I have to ask:
(a) Specifically, given that I know that k
is the number of characters in the Filename
and 'Pathcolumns, how can I make the contents of those columns be exactly fit their columns? (I assume
font` size will enter the picture.)
(b) Generally, how do I change the column size in a JTable
? E.g., one column will always say "in". How to make the column be no wider than that?
EDIT
Thanks to @camickr, it was EASY to get the desired output, both in the test program above and in the real thing, output below:
Check out the Table Column Adjuster.
You can set the column width based on:
The class also supports other features to allow for dynamic resizing if the data is changed.
Or you can use the basic code provided which just uses the prepareRenderer(...)
method of the JTable to determine the maximum width.
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 );
}
Edit:
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 );