Lightweight Components not repainting after recent Classpath merge

Scott Gilbertson
Tue Feb 7 17:27:00 GMT 2006

> > The problem appears to be in the Classpath code:
> > needs to do what
> > java.awt.Component.repaint used to do.  Something like:
> >
> >   public void repaint(long tm, int x, int y, int width, int height)
> >   {
> >     Component p = comp.getParent ();
> >     if (p != null)
> >       p.repaint(0, x + comp.getX(), y + comp.getY(), width, height);
> >   }

> That doesn't make much sense, since the Component.repaint() calls into
> the peer repaint().

Sorry, I don't understand this statement.  Surely having Component.repaint
call the peer.repaint (so that the peer can send the required paint event to
the nearest heavyweight) is correct.  Isn't that what peers are for?

> While it would probably work (since you call repaint
> on the parent and this eventually bubbles up to the toplevel window), it
> is not really good.

It can confirm that the code above works, on both xlib and gtk peers, having
tried it.  By "toplevel" I assume you mean "nearest heavyweight parent".
The fundamental goal when painting a lightweight child is for the nearest
heavyweight parent to repaint the region containing the lightweight child
(possibly coalesced with other child components' regions).  So why is that
not good?

> The right thing to do IMO would be to send an UPDATE
> event to the event queue, something like what is done in Classpath's
> GtkComponentPeer seems more correct.

The code I proposed sends a PAINT event to the nearest heavyweight parent
(clipped to the child's region) when the caller asks for a repaint.  I claim
that's as correct as you can get.

My test program failed on GTK peers, which use the same peer class
(GLightweightPeer) as the XLIB peers and hence also fail to send a paint
event for a lightweight child repaint.  The GtkComponentPeer class is only
used for lightweights that are also Containers, and for heavyweights, as far
as I can tell, so the code you mention didn't run for non-Container
lightweight Components, as in my test program.

I don't know enough about gtk to say for sure, but I get the idea that the
gtk peers treat Containers as heavyweights, in that you can send them
events.  The xlib peers don't do that -- you have to find the nearest xlib
Drawable (generally the peer of a java.awt.Panel or java.awt.Frame) and send
the event there.

> This eventually triggers a call to
> update() (and thus paint() ) on your component which will have the
> desired effect.

I suspect there's a good answer to the following question, but it's not
coming to me: Why is it better to send send "update" when the caller asked
for "paint"?

More information about the Java mailing list