java - How to decorate a TableCellRenderer with Graphics related instructions? -
i'm implemting tablecellrenderer
s using decorator design-pattern. works nice , long need decorate returned component decorated renderer in such manner can performed inside scope of gettablecellrenderercomponent(..)
.
how can decorate returned component such cases need graphics
object in paint process? in particular - inside paintcomponent(graphics g)
method?
example, when want draw line simple setborder(..)
not suffice:
import java.awt.color; import java.awt.component; import javax.swing.jtable; import javax.swing.table.tablecellrenderer; import javax.swing.table.defaulttablecellrenderer; public class mytablecellrendererdecorator extends defaulttablecellrenderer { private tablecellrenderer decoratedrenderer; private component decoratedcomponent; public mytablecellrendererdecorator(tablecellrenderer decoratedrenderer) { super(); this.decoratedrenderer = decoratedrenderer; } @override public component gettablecellrenderercomponent(jtable table, object value, boolean isselected, boolean hasfocus, int row, int column) { this.decoratedcomponent = decoratedrenderer.gettablecellrenderercomponent(table, value, isselected, hasfocus, row, column); //an example decoration works fine decoratedcomponent.setbackground(color.red); return decoratedcomponent; } /** * code not executed, because paint called on returned component * gettablecellrenderercomponent() , not on jlabel in renderer subclasses. */ @override public void paintcomponent(graphics g) { decoratedcomponent.paint(g); //an example needed decoration in paintcomponent() rectangle bounds = g.getclipbounds(); g.setcolor(color.blue); g.drawline(0, 0, bounds.width, bounds.height); } }
i had 2 different solutions in mind:
1. introduce interface called decoratedtablecellrenderer
:
import javax.swing.table.tablecellrenderer; public interface decoratedtablecellrenderer extends tablecellrenderer { public void setpostpaintcomponentrunnable(runnable postpaintcomponentrunnable); }
so mytablecellrendererdecorator
receive decoratedtablecellrenderer
in constructor instead of simple tablecellrenderer
, , responsability decorating inside paintcomponent
moves decorated class. if assume renderer jcomponent
paints itself, can done overriding paintcomponent(..)
, applying postpaintcomponentrunnable.run()
after own paint code.
but, if want support such decoration renderers apply on tablecellrenderer
in may not able modify?
2. using java's reflection , dynamic proxy instantiate new componentui
delegate decoratedcomponent
, perform each method original componentui
object, decorated version of paint(graphics g, jcomponent c)
.
keep decoration responsibilty in decorating class, dynamic proxies hard read , maintain in perspective, happy if find more elegant idea.
as turns out, original sample code gave close correct because, in fact, returned component this
. is, gettablecellrenderercomponent
returns defaulttablecellrenderer called on, overridden methods in subclass of defaulttablecellrenderer called during painting of component.
here's code defaulttablecellrenderer shows i'm talking about:
public component gettablecellrenderercomponent(jtable table, object value, boolean isselected, boolean hasfocus, int row, int column) { //... return this; }
therefore, if override paint(graphics gfx)
method , call super classes gettablecellrenderercomponent
able draw whatever want in cell.
so gettablecellrenderercomponent
should read this:
@override public component gettablecellrenderercomponent(jtable table, object value, boolean isselected, boolean hasfocus, int row, int column) { jlabel component = super.gettablecellrenderercomponent(table, value, isselected, hasfocus, row, column); //an example decoration works fine component.setbackground(color.red); return component; }
and use paint
method in subclass of defaulttablecellrenderer instead of paintcomponent
this:
/** * code executed. */ @override public void paint(graphics g) { super.paint(g); //an example needed decoration in paintcomponent() rectangle bounds = g.getclipbounds(); g.setcolor(color.blue); g.drawline(0, 0, bounds.width, bounds.height); }
Comments
Post a Comment