O'Reilly logo

Swing Hacks by Chris Adamson, Joshua Marinacci

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Size Your Columns to Suit Your JTable’s Contents #21
Chapter 3, Tables and Trees
|
103
HACK
If it does, then we have a usability problem to discuss. By default, the col-
umns of a
JTable are all the same size. For this data, that’s obviously a terri-
ble decision—there’s far too much space reserved for the numbers in the
count column, and not nearly enough in the URL column. So, how are you
going to fix this?
If you said “turn on the horizontal scrollbar,” please close this book, grasp it
with both hands, and firmly smack yourself in the head with it. No, you are
not turning on the horizontal scrollbar! Use the pixels available to you
before you resort to the user-annoying desperation of horizontal scrolling. In
this case, the count column has lots of pixels to spare; you just need to real-
locate this extra space to the URL column.
Resetting Column Widths
What makes programmatic column resizing difficult for many Swing pro-
grammers is that they can’t even find the right methods to use. If all you ever
work with is
JTable (and maybe a few custom cell renderers), you’ll notice
that the JavaDoc for those classes says nothing about column widths. The
problem may be that the
JTable is so generous with helpful methods that
you’d never even notice that it’s made up of
TableColumn objects. Take a
look at that
TableColumn’s JavaDoc, and you’ll find getters and setters for
minimum, maximum, and preferred widths for columns.
As with components that defer to layout managers, the right property to
reset is the preferred width—let the column tell the
JTable how wide it
would like to be, but let the
JTable make the final decision based on the
information available to it (after all, there could be other columns contend-
ing for space, there might not be enough space for all the columns’ pre-
ferred size, etc.).
Given that the key to this hack will be calling
setPreferredWidth( ) on the
TableColumns, the obvious question is: what value should you use for the
preferred width? Here’s a strategy: assuming you already have the table data,
use the width of the widest item in the column. And how do you get that?
By using the table’s cell renderers to actually figure out how big each cell
should be.
ColumnResizer, shown in Example 3-1, has a single static method,
adjustColumnPreferredWidths( ), which takes a JTable as its only argument.
Yes, the name is a mouthful, but it’s helpful to express
exactly what the method does.
104
|
Chapter 3, Tables and Trees
#21 Size Your Columns to Suit Your JTable’s Contents
HACK
For each column in the table, the method goes through all the rows and
renders each cell. It keeps a running tally of the widest component in the
column, and after considering all the rows, it sends this maximum width to
setPreferredWidth( ).
Example 3-2 demonstrates a unit test class to exercise
ColumnResizer.
TestColumnResizer simply puts the JTable into a JFrame, pack( )s it, and shows
it. After a five-second delay, it calls
adjustColumnPreferredWidths() to reset
the preferred column widths, and it
revalidate( )s the table to get a repaint.
Example 3-1. Adjusting column sizes to suit their contents
public class ColumnResizer {
public static void adjustColumnPreferredWidths(JTable table) {
// strategy - get max width for cells in column and
// make that the preferred width
TableColumnModel columnModel = table.getColumnModel( );
for (int col=0; col<table.getColumnCount( ); col++) {
int maxwidth = 0;
for (int row=0; row<table.getRowCount( ); row++) {
TableCellRenderer rend =
table.getCellRenderer(row, col);
Object value = table.getValueAt (row, col);
Component comp =
rend.getTableCellRendererComponent (table,
value,
false,
false,
row,
col);
maxwidth = Math.max (comp.getPreferredSize( ).width,
maxwidth);
} // for row
TableColumn column = columnModel.getColumn (col);
column.setPreferredWidth (maxwidth);
} // for col
}
}
Example 3-2. Testing automatic column sizing
public class TestColumnResizer {
final static Object[][] TABLE_DATA = {
{new Integer(1), "ONJava", "http://www.onjava.com/"},
{new Integer(2), "Joshy's Site", "http://www.joshy.org/"},
{new Integer(3), "Anime Weekend Atlanta", "http://www.awa-con.com/"},
{new Integer(4), "QTJ book",
"http://www.oreilly.com/catalog/quicktimejvaadn/"}
};

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required