Java: Override table cell renderer, but with default background and properties
If you want to add a custom renderer, normally, you'd either extend some JComponent
(like JLabel
) and implement TableCellRenderer
, or you'd extend DefaultTableCellRenderer
. However, in either case, what I find is that the cell style is completely overridden.
What I'd really like is to be able to paint the default L&F background and then paint on top of it using other L&F defaults like foreground color and font.
So, here's what I tried to do. First, the class:
public class IntervalHeaderRenderer extends JLabel implements TableCellRenderer {
private TableCellRenderer delegate;
private Component component;
public IntervalHeaderRenderer(TableCellRenderer defaultRenderer)
{
this.delegate = defaultRenderer;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
component = delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// Maybe override some settings.
// You could make the label bold, for instance.
return component;
// return this;
}
@Override
public void paint(Graphics g) {
// What I really want to do is paint the original component
component.paint(g);
// And then draw on top of it.
}
}
And then I override the cell (header) renderer like this:
TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
table.getColumnModel().getColumn(1).setHeaderRenderer(new IntervalHeaderRenderer(renderer));
I'm basically just following the suggestions here: TableCellRenderer, Part 2 - How To Create A Custom Renderer
If I return component
, it renders as if I had overridden nothing. That is, I get the header with the label I had programmed with the chosen L&F background and style and everything. But, of co开发者_JAVA技巧urse, there no way to render my stuff afterwards.
On the other hand, if I return this
, then I get absolutely nothing. Mac native L&F gives me a white background, while Nimbus gives me a solid of some other color.
I'm clearly missing something. Are there other methods on the Component
that I need to override and forward to the original? How does the default component get drawn if not by overriding paint
? (I've also tried overriding paintComponent
. No difference.)
Is there another way to do this? I've thought about trying to drop a native styled JPanel
in there and then making a custom (transparent background) component its child, although I'm not sure about how to go about it, and I'm not really sure I'd get the native L&F table header background anyhow. In fact, I highly doubt I'd get the native header style, just the native JPanel
style.
Basically, I need a custom table header (and separately, the cells too, actually), but I want to avoid messing too much with the native L&F.
Thanks!
You might look at the approach taken in updateUI()
in SelectAllHeaderTest
, as well as the helpful caveats in the accepted answer.
Addendum: By way of explanation, note that the header's appearance falls under the aegis of the host platform's corresponding UI delegate, usually derived from TableHeaderUI
. You may want to confine your changes to the UIManager Defaults common to popular Look & Feel implementations. Also, don't override paint()
. I would avoid overriding paintComponent()
; and, if necessary, override paintIcon()
, as shown in TableSorter
.
Check the DefaultTableCellRenderer
source code, there you will see how the default behavior reads the defaults colors like:
fg = DefaultLookup.getColor(this, ui, "Table.dropCellForeground");
bg = DefaultLookup.getColor(this, ui, "Table.dropCellBackground");
精彩评论