views:

53

answers:

1

Hello,

I was hoping someone could explain something to me as I found my solution, but I don't understand why it works. I wanted to set a default renderer by Class type to a whole table, not knowing at creation where objects will be in it.

I had declared a JTable and set the default renderer to that of my own, for the Calendar class so that any Calendars would give a meaningful representation, not just a toString() of themselves.

JTable table = new JTable();
table.setDefaultRenderer(Calendar.class, new MyRenderer());

public class MyRenderer extends DefaultTableCellRenderer{
    public MyRenderer() { super(); }
    @Override
    public void setValue(Object value){
            setText(makeCalendarToDate((GregorianCalendar)value));
    }
}

This would not work until I overrode the method getColumnClass as was done Here

According to sun's Documentation, it looks like getColumnClass should do exactly what was overridden in the example I gave above - why does it work when I override that method but not when I leave the stock implementation?

Now I can fill column's with Calendars pending they fill the 0th row, which is what I wanted, but what prevented me from doing that in the first place?

+2  A: 

JTable gets the column class from the model. The answer lies in the implementation of AbstractTableModel, assuming that's what you've based your table model on. In AbstractTableModel getColumnClass has been implemented like this: return Object.class; So, unless you override it, the column objects will always be handled as Object. This is not something the model will handle automatically. You just have to override getColumnClass, there's no way around that.

Carlos
What if I was using JTable's and not AbstractTableModel? Is it still implemented the same way?
Ryan
If you let JTable to take care of the model, it will use DefaultTableModel if I remember correctly. And DefaultTableModel is based on AbstractTableModel. I think all implementations that come with Swing work the same way and I doubt it would not be even possible to make this work automatically. You could check what getValueAt returns but that wouldn't work with null values.
Carlos
Great! While it sort of makes sense, the Documentation for AbstractTableModel matches what You say it should be, it just returns the Object class... however the documentation for JTable states it actually returns the Class of (0, i) but still always returns an Object class - any idea why that is? It states it should return any Class that's there.
Ryan
Well, in a way the documentation is correct. JTable returns the "correct" class of the column but only if the model returns the correct class. Maybe it could be mentioned that getColumnClass just delegates to getModel().getColumnClass and it is up to the model to return the desired value. But in general JTable does not care or know about its contents.Also, in the documentation "class of the column" is not necessarily meant to mean the actual class of the returned object rather than a class specified by the developer. It is perfectly possible that he wants to return something else on purpose.
Carlos