On Fri, 2006-02-24 at 00:10 +0100, Roman Kennke wrote:
> > Hi Lillian,
> > 
> > > - reshape in Component was fixed. invalidate() was only being called on
> > > the component if it has moved or has been resized. But the problem is
> > > that a component could be moved, because its parent moved, and the
> > > component would not know about it. 
> > > invalidate() should always be called on the component when reshape (or
> > > setBounds) is called. This way, all components are invalidated, in case
> > > they have been moved or resized because of their parent.
> > 
> > I don't understand this one. When a component has reshape() called, then
> > this has nothing to do with the parent beeing moved. If the parent
> > moves, the relative position to the children will not change. However,
> > the layout mechanism should update the relative child positions if
> > necessary. I think we do not need to call invalidate() if the component
> > has not moved or is not resized. However, if it is not removed or
> > resized, we can simply return from this method call anyway.
> 
> I really think you should revert this, except if you can come up with a
> testcase that shows that invalidate must be called when nothing really
> changes. The only thing that I could imagine that matters is that
> peer.setBounds could be called,

Yes, peer.setBounds does matter for heavyweight components in
lightweight containers.  The peers have no way of knowing that a
lightweight container has moved.  In our test case (MegaMek), a parent
lightweight container moves but doesn't change size.  setBounds is
called on its heavyweight children but the bounds that the children are
given are relative to their parent so they think that they haven't moved
when in fact they have.  If peer.setBounds isn't called then the peers
won't update their positions relative to their lightweight parent.
Lillian's gnu.testlet.java.awt.Container.LightweightContainer should
demonstrate the problem but it doesn't at the moment (see my comments on
mauve-patches).

The attached patch adds a clause to the early return condition which may
be more acceptable.

A clearer approach may be to invalidate heavyweight descendants of
lightweight containers in Container.invalidate.

You can see by this added complexity why giving lightweight containers
native representation is an attractive approach, for simplicity's sake.

Tom

2006-02-23  Thomas Fitzsimmons  <[EMAIL PROTECTED]>

        * java/awt/Component.java (reshape): Re-add early return condition
        but also check for lightweight parent.

Index: Component.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.102
diff -u -r1.102 Component.java
--- Component.java	23 Feb 2006 19:22:24 -0000	1.102
+++ Component.java	24 Feb 2006 01:24:15 -0000
@@ -1391,7 +1391,18 @@
     int oldwidth = this.width;
     int oldheight = this.height;
     
-   invalidate ();
+    // The peers have no knowledge of lightweight containers. If this is a
+    // heavyweight component in a lightweight container and setBounds has been
+    // called because our parent moved, we need to invalidate ourself so that
+    // peer.setBounds will be able to calculate new offset values by climbing
+    // the container tree.
+    Component p = getParent();
+    if (this.x == x && this.y == y && this.width == width
+        && this.height == height
+        && (p == null || !p.isLightweight()))
+      return;
+
+    invalidate ();
     
     this.x = x;
     this.y = y;

Reply via email to