All the examples I can find of custom TableCellRenderers all seem extend DefaultTableCellRenderer. Nothing wrong with that, I guess, except that you do not get to extend the TableCellRenderer
functionality of whatever is the current Look&Feel. This is bad. Your TableCellRenderer
is then not L&F aware.
That is in fact exactly what I want to do: I want to create a custom TableCellRenderer
that is L&F aware, so rather than extending DefaultTableCellRenderer
it should extend (or decorate) whatever is the TableCellRenderer
which the L&F has installed by default for the given class type.
I can get to that by doing myJTable.getDefaultRenderer(...) but that will not give me a new instance of that class, it will simply return the L&F's 'master' table cell renderer to be used for that type of class. I started out with a solution that created a custom TableCellRenderer that wrapped the instance that I got from the mentioned method (effectively using a Decorator pattern) until I realized that I didn't have my own private instance of a renderer. If I mess with that instance of renderer I cannot do column-specific rendering as any change I do on that instance will affect more columns than intended.
So I've concluded that what I need to do is to create a completely new instance of the L&F's TableCellRenderer
for that class-type. (in my case class type = Object
). I believe I can get to the relevant class name from somewhere in UIManager
, but I wouldn't know which key to use. Secondly then - unfortunately - I believe I would have to use Reflection to actually instantiate an object of that TableCellRenderer class.
Are my assumptions correct, i.e. there's unfortunately no factory for TableCellRenderers? and how would I actually instantiate a new instance of my current L&F's TableCellRenderer
for class-type Object
? (I know how to use Reflection, if that's the only way)
UPDATE
As you may have guessed I'm testing with a proprietary L&F as well as the standard ones. This particulary proprietary L&F installs its own TableCellRenderers which is perfectly legal, IMO. The Java Synth L&F does the same. So I don't want to make this a question of a particular L&F.
Test: I create a table with two String
columns. I install my own custom cell renderer on one of the columns, but not the other. My custom renderer looks like this:
public class CustomCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
As you can see the custom renderer does nothing. Since it does nothing I should get the same rendering effect on both table columns. I don't! The reason is of course that by simply extending DefaultTableCellRenderer
I'll not 'inherit' the L&F's own TableCellRenderers should it have one/some. On many, many L&F's the above test will in fact render the two columns the same way, but that's more by chance. I want to do things the right way. The fact that extending DefaultTableCellRenderer
produces expected results with most L&Fs is not enough for me. :-)
We solved this Problem in like this:
If you don't create a new Instance for the TableCellRenderer you get funky effects, because you change the tables default instance.