jdk/src/share/classes/java/awt/Container.java
changeset 130 11eb29307cfb
parent 125 079ae88eaea9
child 441 f5da1014ed23
--- a/jdk/src/share/classes/java/awt/Container.java	Tue Mar 18 16:19:03 2008 +0300
+++ b/jdk/src/share/classes/java/awt/Container.java	Thu Mar 20 11:09:16 2008 +0300
@@ -832,16 +832,8 @@
                 }
                 if (!comp.isLightweight() && isLightweight()) {
                     // If component is heavyweight and one of the containers is lightweight
-                    // some NativeInLightFixer activity should be performed
-                    if (!curParent.isLightweight()) {
-                        // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
-                        // since addNotify does this
-                        comp.nativeInLightFixer = new NativeInLightFixer();
-                    } else {
-                        // Component already has NativeInLightFixer - just reinstall it
-                        // because hierarchy changed and he needs to rebuild list of parents to listen.
-                        comp.nativeInLightFixer.install(this);
-                    }
+                    // the location of the component should be fixed.
+                    comp.relocateComponent();
                 }
             }
         }
@@ -3953,6 +3945,83 @@
         }
     }
 
+    private void recursiveShowHeavyweightChildren() {
+        if (!hasHeavyweightDescendants() || !isVisible()) {
+            return;
+        }
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container) {
+                    ((Container)comp).recursiveShowHeavyweightChildren();
+                }
+            } else {
+                if (comp.isVisible()) {
+                    ComponentPeer peer = comp.getPeer();
+                    if (peer != null) {
+                        peer.show();
+                    }
+                }
+            }
+        }
+    }
+
+    private void recursiveHideHeavyweightChildren() {
+        if (!hasHeavyweightDescendants()) {
+            return;
+        }
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container) {
+                    ((Container)comp).recursiveHideHeavyweightChildren();
+                }
+            } else {
+                if (comp.isVisible()) {
+                    ComponentPeer peer = comp.getPeer();
+                    if (peer != null) {
+                        peer.hide();
+                    }
+                }
+            }
+        }
+    }
+
+    private void recursiveRelocateHeavyweightChildren(Point origin) {
+        for (int index = 0; index < getComponentCount(); index++) {
+            Component comp = getComponent(index);
+            if (comp.isLightweight()) {
+                if  (comp instanceof Container &&
+                        ((Container)comp).hasHeavyweightDescendants())
+                {
+                    final Point newOrigin = new Point(origin);
+                    newOrigin.translate(comp.getX(), comp.getY());
+                    ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
+                }
+            } else {
+                ComponentPeer peer = comp.getPeer();
+                if (peer != null) {
+                    peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
+                            comp.getWidth(), comp.getHeight(),
+                            ComponentPeer.SET_LOCATION);
+                }
+            }
+        }
+    }
+
+    /*
+     * Consider the heavyweight container hides or shows the HW descendants
+     * automatically. Therefore we care of LW containers' visibility only.
+     */
+    private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
+        if (!isLightweight()) {
+            return true;
+        }
+        return isVisible() && (getContainer() == null ||
+             getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
+    }
+
+    @Override
     void mixOnShowing() {
         synchronized (getTreeLock()) {
             if (mixingLog.isLoggable(Level.FINE)) {
@@ -3961,6 +4030,10 @@
 
             boolean isLightweight = isLightweight();
 
+            if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
+                recursiveShowHeavyweightChildren();
+            }
+
             if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
                 recursiveApplyCurrentShape();
             }
@@ -3969,6 +4042,42 @@
         }
     }
 
+    @Override
+    void mixOnHiding(boolean isLightweight) {
+        synchronized (getTreeLock()) {
+            if (mixingLog.isLoggable(Level.FINE)) {
+                mixingLog.fine("this = " + this +
+                        "; isLightweight=" + isLightweight);
+            }
+            if (isLightweight) {
+                recursiveHideHeavyweightChildren();
+            }
+            super.mixOnHiding(isLightweight);
+        }
+    }
+
+    @Override
+    void mixOnReshaping() {
+        synchronized (getTreeLock()) {
+            if (mixingLog.isLoggable(Level.FINE)) {
+                mixingLog.fine("this = " + this);
+            }
+            if (isLightweight() && hasHeavyweightDescendants()) {
+                final Point origin = new Point(getX(), getY());
+                for (Container cont = getContainer();
+                        cont != null && cont.isLightweight();
+                        cont = cont.getContainer())
+                {
+                    origin.translate(cont.getX(), cont.getY());
+                }
+
+                recursiveRelocateHeavyweightChildren(origin);
+            }
+            super.mixOnReshaping();
+        }
+    }
+
+    @Override
     void mixOnZOrderChanging(int oldZorder, int newZorder) {
         synchronized (getTreeLock()) {
             if (mixingLog.isLoggable(Level.FINE)) {