Dates in JTable
I have about 9 columns which are added to my JTable.
I also have two date-columns. These look something like this:
Sat Apr 01 00:00:00 CEST 2006
How can I format the appearance of such a date. SimpleDateFormatter won't work I guess, because for sorting, it should still be stored as date and not as string.
Do I have to deal with the JTable renderer?
[383 byte] By [
sockena] at [2007-10-2 4:34:04]

You're right; your table model should store dates since that's the data type that it's modelling.
All you need to do is write a TableCellRenderer that converts Dates to a suitable format:
public class DateTableCellRenderer extends DefaultTableCellRenderer {
private Format format;
public DateTableCellRenderer(String pattern) {
this.format = new SimpleDateFormat(pattern);
}
public void setValue(Object value) {
setText(format.format(value));
}
}
You might also need to check for null values before formatting, depending on your data.
Just set this cell renderer on the corresponding table columns.
Hope this helps.
Thanks for the fast answer. Can you also tell me how I use the class now?If it's too complicated I simply go search formyself ;)
Mhh..ok, I now use the following three lines to apply the renderer:
[CODE]
int columnCount = jTable1.getColumnCount();
renderer = new DateTableCellRenderer("dd.MM.yyyy");
jTable1.setDefaultRenderer(model.getColumnClass(columnCount-1),renderer);
[/CODE]
I use the column-count, because it's always the second but last column which holds the dates..
Now I get an error:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
What am I doing wrong?
It may be a good idea to look in the Swing tutorial for customising table display - it's an interesting and important topic that relates to trees, lists and tables in Swing.
In brief, though, you have several options for setting the renderer for a column.
You can set it for a particular class of column. This will work if your table model implements the getColumnClass method properly and will apply the renderer to all columns of that class that don't have a cell renderer explicitly specified.
TableCellRenderer dateRenderer = new DateTableCellRenderer("dd-MMM-yyyy");
table.setDefaultRenderer(Date.class, dateRenderer);
A more explicit way is to set the cell renderer for a particular column in your table's column model. You'd need to do this for every column you want to use this rendering strategy but it's probably the best approach in the long run.
TableCellRenderer dateRenderer = new DateTableCellRenderer("dd-MMM-yyyy");
table.getColumnModel().getColumn(4).setCellRenderer(dateRenderer);
table.getColumnModel().getColumn(5).setCellRenderer(dateRenderer);
Note that in the example above it sets the cell renderer on columns 4 and 5. You may have noticed that you can change the order of columns on tables (e.g. by dragging them). Therefore the values 4 and 5 might not always be right (depending on when you set the renderers). There are better ways of identifying columns than merely using their index in the column model but this is probably beyond what you need to know at the moment.
Hope this helps.
Find out what getColumnClass is returning - if it's not Date.class then you shouldn't be using a date table cell renderer on it!
There's a good chance that your table model will return Object.class for all columns. Thus, you'll be setting the default renderer for all columns to a date cell renderer - most of them will therefore fail!
Either explicitly set the cell renderer on the columns you want or chance your table model to return Date.class for the date columns.
Hope this helps.
THANKS ALOT FOR YOUR HELP!!! You're a genius.I still have some minor things to correct, but I guess I will find a solutionThanks alot!
OK, I guess I'm just dumb then...
One of the 'small' problems I've mentioned..maybe I need some advice anyway:
It works fine with the dates when I create my JTable. It also works fine if I resize the window. But, as soon as I sort the table, it falls back to the old pattern..... why's that?
I guess that depends on how you're sorting your table!
Did you change your table model to return Date.class and set the default renderer for Date.class or did you set the renderer on the appropriate columns?
If you've wrapped your table model up in something that sorts it then it's possible that it doesn't pass the column types through correctly. If you set the default renderer, ensure that the column class for your date columns is still Date.class!!
I set the renderer for the appropriate column only...
Oh, and for sorting, I used the method from javaalmanac: http://javaalmanac.com/egs/javax.swing.table/Sorter.html
The error defenetly comes from this line:
System.out.println(jTable1.getColumnModel().getColumn(0));
Actually it shouldn't be 0, but this is only for testing... I get the follwing error, which is a little bit strange I think:
java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
Any idea? Otherwise I could print a larger portion of my code..
Well, I guess you've got an empty table column model for some reason - ie, one with no columns!Presumably this worked before you added sorting. What changes have you made to implement sorting?
I've added the following line
jTable1.setAutoCreateColumnsFromModel(false);
which obviously is the cause for the error... The strange thing though is, if I run
System.out.println("ColumnCount = " +model.getColumnCount());
System.out.println("RowCount = " +model.getRowCount());
It gives me 10 and 516... so it's not empty!?
The table model and the column model are different things.
Your table model could well have 10 columns and you could use a column model with any number of columns (eg, 0). The column model effectively says which of the table model's columns to show on-screen and in which order. You can think of the column model as being a particular view of the table's data.
When you use "auto create columns from model" it will remove all the columns from your column model and add new ones to match your table model's column definitions. Thus it will remove your customised column with the date renderer and replace it with a new default one.
This rebuilding of the table columns happens whenever the table structure is changed - something that your sorting add-on might do from time to time (although it probably shouldn't!!).
Hope this helps explain things a bit.
Yes that helps a bit, thanks. OK, so it's correct then to set AutoCreateColumnsFromModel to false, otherwise my settings are overwritten. I think it's easier with some code. I have this method, which I'm calling to set the data in the JTable:
public void update(Object[][] result, Object[] headers) {
model = new DefaultTableModel(result,headers);
jTable1.setModel(model);
int columnCount = model.getColumnCount();
jTable1.getColumnModel().getColumn(columnCount-2).setCellRenderer(renderer); //This line causes the error...
}
Am I missing something? I want to create the model with the new data (result) and the columnNames (headers). The data should be ok, since I've used it before...
I then set the model of the JTable to my new model and set the renderer for the second last column.
And that's where I get my error....
I guess you've already set the autoCreateColumns on the table by this point.
Your table will start with an empty table and column model (0 columns).
Therefore when you set the model on your table you'll update the table model (setModel) but since you've got autoCreateColumns set to false you won't get a corresponding column model created - it will still have zero columns!
Therefore you either want to create your own column model (my preferred approach) and set that on your table. Alternatively, you can set autoCreateColumns to true, call setModel and then set autoCreateColumns to false - that way you'll get a default column model created for you.
Let me say it like this: HALLELUJAH! It finally worked.. Man, you really made my day! ;-) ;-) If you lived in Switzerland I'd come over and give you a hug !Thanks alot for all the crystal clear explanations!
Glad I could help!Good luck with the rest of your application.