How can I set column widths in a JTable

M

Martin Gregorie

I have a Jtable that used to display a number of columns, which are
respectively:

Col Class Caption Length (chars)
1 String License 14
2 String Date 19 (ccyy-mm-dd hh:mm:ss)
3 String Licenseee up to 80
4 String E-mail up to 80
5 String Phone 19
6 Boolean Issued 6 (length of the heading)

None of these are editable because a separate pop-up window is used to
amend and manipulate each license. This is all working well, but all the
columns are of equal width. I'd like to fix the lengths of columns 1,2,5
and 6 on order to leave the maximum amount of space for columns 3 and 4
but can't work out how.

It looks as though I should use DefaultTableCellRenderer but I can't work
out how to tell it how wide each column should be. This topic isn't
covered in the 'How to use Tables' tutorial, so any pointers would be
much appreciated.
 
M

Martin Gregorie

"To customize initial column widths, you can invoke setPreferredWidth on
each of your table's columns."

<http://download.oracle.com/javase/tutorial/uiswing/components/ table.html>


Did that not work?

It did now. It was the method for getting the list of TableColumn objects
that had eluded me. Many thanks for your help.

BTW, what's the best method of building a custom cell renderer with just
a few tweaks, e.g. monospaced font? Would extending DefaultCellRenderer
be reasonable or is there a better way?
 
M

markspace

BTW, what's the best method of building a custom cell renderer with just
a few tweaks, e.g. monospaced font? Would extending DefaultCellRenderer
be reasonable or is there a better way?


Honestly I have no clue. I just read the tutorial after you posted.
Looking at the tutorial again, it seems that DefaultCellRederer is for
the whole table, and TableCellRenderer is for individual columns or
cells if you need finer grained control.

So unless your entire table is all monospaced text, I think you'll want
the latter.
 
M

Martin Gregorie

Honestly I have no clue. I just read the tutorial after you posted.
Looking at the tutorial again, it seems that DefaultCellRederer is for
the whole table, and TableCellRenderer is for individual columns or
cells if you need finer grained control.
Fair enough. Thanks to your help I now know that its easy to build and
install custom renderers if columns have different Objects in them. I had
assumed that you had to somehow diddle with the renderer if you wanted to
set different widths in columns using the same type of Object, e.g.
different amounts of data in Strings.

Now I know that's only partly true - if you just want to adjust column
widths in pixels you don't need to go near the renderer, but if you want
to set widths in terms of character counts then you need to extract a lot
of info from the renderer. The first thing you find is that, if the
default renderer is being used then getCellRenderer() will return null
rather than a reference to the default renderer. In this case you need to
instantiate a DefaultTableCellRenderer because there's quite a lot of
stuff you'll need from it to calculate the cell width: the Font and the
FontMetrics both come from the cell renderer. You need both to get the
FontRenderContext and *thats* where you get the character height and
width figures from.

It all reminds me of that old song about "the thigh bone's connected to
the hip bone....", but I digress.

So, after all that I thought I could at last calculate the column width
in pixels from maxCharacterWidth * char count, but that gives me a column
thats 220% of the required figure, i.e. a bloody great wide column, so
divide by 2.2. This magic number works correctly on screens with
different resolutions so its probably safe to use though I don't
understand why it is needed, let alone why it has to be 2.2.
So unless your entire table is all monospaced text, I think you'll want
the latter.
Yep, my next step will be to build a cell renderer using a fixed width
font and see what this does to the magic number.

I'm somewhat perplexed by all the hoops one needs to jump through to get
a character width in pixels just to set a column width. I say perplexed
because I'd have thought this was a common requirement for anybody laying
out a neatly formatted JTable or a dialogue using JTextFields to edit
fixed length character data. In the latter case simply setting the width
of a JTextField in characters and defaulting everything else always seems
to give a field that's considerably wider than you want.
 
J

John B. Matthews

Martin Gregorie said:
I have a Jtable that used to display a number of columns, which are
respectively:

Col Class Caption Length (chars)
1 String License 14
2 String Date 19 (ccyy-mm-dd hh:mm:ss)
3 String Licenseee up to 80
4 String E-mail up to 80
5 String Phone 19
6 Boolean Issued 6 (length of the heading)

None of these are editable because a separate pop-up window is used
to amend and manipulate each license. This is all working well, but
all the columns are of equal width. I'd like to fix the lengths of
columns 1,2,5 and 6 on order to leave the maximum amount of space for
columns 3 and 4 but can't work out how.

It looks as though I should use DefaultTableCellRenderer but I can't
work out how to tell it how wide each column should be. This topic
isn't covered in the 'How to use Tables' tutorial, so any pointers
would be much appreciated.

I haven't tried it, but this Table Column Adjuster may be worth a look:

<http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/>
 
M

Martin Gregorie

Yep, my next step will be to build a cell renderer using a fixed width
font and see what this does to the magic number.
OK, I built a Monospace renderer by extending DefaultTableCellRenderer
and adding code in the constructor to:
- extract the font size from the default font
- replaced that with "Monospace.bold" and the default font size (12pt)
using the Font constants for MONOSPACE and BOLD

This worked as expected, but had the unexpected effect of roughly
doubling the pixel width of the maximum width character. If I'd persisted
my magic number divisor (2.2) I needed to get sensible column widths
would have needed to be adjusted to something like 5 for the monospaced
fonts. This struck me as odd, since these fonts looked to be very much
the same width as the default Dialog.bold fonts.

Since the object of this faffing about with fixed width fonts was to get
rid of the magic number divisor if at all possible, I've left things as
they are, i.e. The JTable cells use 12pt Dialog.bold font and I use the
magic divisor of 2.2 when converting a number of characters into a column
width).

I'm happy with the appearance of the JTables, so thanks again for your
help. I've learnt quite a bit from this exercise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top