6616323: consider benefits of replacing a componen array with other collection from the awt.Container class
authordav
Wed, 18 Jun 2008 15:35:37 +0400
changeset 1172 a1d23c450f84
parent 1171 a2782dd9f312
child 1174 8defdb35db9f
6616323: consider benefits of replacing a componen array with other collection from the awt.Container class Reviewed-by: uta, art
jdk/src/share/classes/java/awt/Component.java
jdk/src/share/classes/java/awt/Container.java
jdk/src/share/classes/java/awt/ScrollPane.java
jdk/src/windows/native/sun/windows/awt_Container.cpp
jdk/src/windows/native/sun/windows/awt_Container.h
jdk/test/java/awt/Container/CheckZOrderChange/CheckZOrderChange.java
--- a/jdk/src/share/classes/java/awt/Component.java	Tue Jun 17 13:37:28 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Component.java	Wed Jun 18 15:35:37 2008 +0400
@@ -2141,7 +2141,7 @@
                     Toolkit.getEventQueue().postEvent(e);
                 }
             } else {
-                if (this instanceof Container && ((Container)this).ncomponents > 0) {
+                if (this instanceof Container && ((Container)this).countComponents() > 0) {
                     boolean enabledOnToolkit =
                         Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
                     if (resized) {
--- a/jdk/src/share/classes/java/awt/Container.java	Tue Jun 17 13:37:28 2008 +0400
+++ b/jdk/src/share/classes/java/awt/Container.java	Wed Jun 18 15:35:37 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,6 @@
 import java.util.Arrays;
 import java.util.EventListener;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.Set;
 
 import java.util.logging.*;
@@ -90,21 +88,14 @@
     private static final Logger log = Logger.getLogger("java.awt.Container");
     private static final Logger eventLog = Logger.getLogger("java.awt.event.Container");
 
-    /**
-     * The number of components in this container.
-     * This value can be null.
-     * @see #getComponent
-     * @see #getComponents
-     * @see #getComponentCount
-     */
-    int ncomponents;
+    private static final Component[] EMPTY_ARRAY = new Component[0];
 
     /**
      * The components in this container.
      * @see #add
      * @see #getComponents
      */
-    Component component[] = new Component[0];
+    private java.util.List<Component> component = new java.util.ArrayList<Component>();
 
     /**
      * Layout manager for this container.
@@ -290,7 +281,9 @@
      */
     @Deprecated
     public int countComponents() {
-        return ncomponents;
+        synchronized (getTreeLock()) {
+            return component.size();
+        }
     }
 
     /**
@@ -302,10 +295,10 @@
      */
     public Component getComponent(int n) {
         synchronized (getTreeLock()) {
-            if ((n < 0) || (n >= ncomponents)) {
+            if ((n < 0) || (n >= component.size())) {
                 throw new ArrayIndexOutOfBoundsException("No such child: " + n);
             }
-            return component[n];
+            return component.get(n);
         }
     }
 
@@ -322,7 +315,7 @@
     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
     final Component[] getComponents_NoClientCode() {
         synchronized (getTreeLock()) {
-            return Arrays.copyOf(component, ncomponents);
+            return component.toArray(EMPTY_ARRAY);
         }
     } // getComponents_NoClientCode()
 
@@ -422,6 +415,29 @@
     }
 
     /**
+     * Checks that the component
+     * isn't supposed to be added into itself.
+     */
+    private void checkAddToSelf(Component comp){
+        if (comp instanceof Container) {
+            for (Container cn = this; cn != null; cn=cn.parent) {
+                if (cn == comp) {
+                    throw new IllegalArgumentException("adding container's parent to itself");
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks that the component is not a Window instance.
+     */
+    private void checkNotAWindow(Component comp){
+        if (comp instanceof Window) {
+            throw new IllegalArgumentException("adding a window to a container");
+        }
+    }
+
+    /**
      * Checks that the component comp can be added to this container
      * Checks :  index in bounds of container's size,
      * comp is not one of this container's parents,
@@ -437,26 +453,18 @@
 
         GraphicsConfiguration thisGC = getGraphicsConfiguration();
 
-        if (index > ncomponents || index < 0) {
+        if (index > component.size() || index < 0) {
             throw new IllegalArgumentException("illegal component position");
         }
         if (comp.parent == this) {
-            if (index == ncomponents) {
+            if (index == component.size()) {
                 throw new IllegalArgumentException("illegal component position " +
-                                                   index + " should be less then " + ncomponents);
+                                                   index + " should be less then " + component.size());
             }
         }
-        if (comp instanceof Container) {
-            for (Container cn = this; cn != null; cn=cn.parent) {
-                if (cn == comp) {
-                    throw new IllegalArgumentException("adding container's parent to itself");
-                }
-            }
-
-            if (comp instanceof Window) {
-                throw new IllegalArgumentException("adding a window to a container");
-            }
-        }
+        checkAddToSelf(comp);
+        checkNotAWindow(comp);
+
         Window thisTopLevel = getContainingWindow();
         Window compTopLevel = comp.getContainingWindow();
         if (thisTopLevel != compTopLevel) {
@@ -495,25 +503,19 @@
             adjustDescendants(-(comp.countHierarchyMembers()));
 
             comp.parent = null;
-            System.arraycopy(component, index + 1,
-                             component, index,
-                             ncomponents - index - 1);
-            component[--ncomponents] = null;
+            component.remove(index);
 
             if (valid) {
                 invalidate();
             }
         } else {
-            if (newIndex > index) { // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
-                if (newIndex-index > 0) {
-                    System.arraycopy(component, index+1, component, index, newIndex-index);
-                }
-            } else { // 4->2: 012345 -> 014235
-                if (index-newIndex > 0) {
-                    System.arraycopy(component, newIndex, component, newIndex+1, index-newIndex);
-                }
-            }
-            component[newIndex] = comp;
+            // We should remove component and then
+            // add it by the newIndex without newIndex decrement if even we shift components to the left
+            // after remove. Consult the rules below:
+            // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
+            // 4->2: 012345 -> 014235
+            component.remove(index);
+            component.add(newIndex, comp);
         }
         if (comp.parent == null) { // was actually removed
             if (containerListener != null ||
@@ -779,17 +781,11 @@
 
         // Check if moving between containers
         if (curParent != this) {
-            /* Add component to list; allocate new array if necessary. */
-            if (ncomponents == component.length) {
-                component = Arrays.copyOf(component, ncomponents * 2 + 1);
-            }
-            if (index == -1 || index == ncomponents) {
-                component[ncomponents++] = comp;
+            //index == -1 means add to the end.
+            if (index == -1) {
+                component.add(comp);
             } else {
-                System.arraycopy(component, index, component,
-                                 index + 1, ncomponents - index);
-                component[index] = comp;
-                ncomponents++;
+                component.add(index, comp);
             }
             comp.parent = this;
 
@@ -799,8 +795,8 @@
                                     comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
             adjustDescendants(comp.countHierarchyMembers());
         } else {
-            if (index < ncomponents) {
-                component[index] = comp;
+            if (index < component.size()) {
+                component.set(index, comp);
             }
         }
 
@@ -901,14 +897,8 @@
             if (comp.parent != this) {
                 return -1;
             }
-            for (int i = 0; i < ncomponents; i++) {
-                if (component[i] == comp) {
-                    return i;
-                }
-            }
+            return component.indexOf(comp);
         }
-        // To please javac
-        return -1;
     }
 
     /**
@@ -1042,22 +1032,12 @@
              */
             GraphicsConfiguration thisGC = this.getGraphicsConfiguration();
 
-            if (index > ncomponents || (index < 0 && index != -1)) {
+            if (index > component.size() || (index < 0 && index != -1)) {
                 throw new IllegalArgumentException(
                           "illegal component position");
             }
-        if (comp instanceof Container) {
-            for (Container cn = this; cn != null; cn=cn.parent) {
-                if (cn == comp) {
-                throw new IllegalArgumentException(
-                      "adding container's parent to itself");
-                }
-            }
-            if (comp instanceof Window) {
-                throw new IllegalArgumentException(
-                       "adding a window to a container");
-            }
-        }
+            checkAddToSelf(comp);
+            checkNotAWindow(comp);
         if (thisGC != null) {
             comp.checkGD(thisGC.getDevice().getIDstring());
         }
@@ -1065,22 +1045,16 @@
             /* Reparent the component and tidy up the tree's state. */
             if (comp.parent != null) {
                 comp.parent.remove(comp);
-                    if (index > ncomponents) {
+                    if (index > component.size()) {
                         throw new IllegalArgumentException("illegal component position");
                     }
             }
 
-            /* Add component to list; allocate new array if necessary. */
-            if (ncomponents == component.length) {
-                component = Arrays.copyOf(component, ncomponents * 2 + 1);
-            }
-            if (index == -1 || index == ncomponents) {
-                component[ncomponents++] = comp;
+            //index == -1 means add to the end.
+            if (index == -1) {
+                component.add(comp);
             } else {
-                System.arraycopy(component, index, component,
-                                 index + 1, ncomponents - index);
-                component[index] = comp;
-                ncomponents++;
+                component.add(index, comp);
             }
             comp.parent = this;
 
@@ -1129,11 +1103,9 @@
      * IllegalArgumentException.
      */
     void checkGD(String stringID) {
-        Component tempComp;
-        for (int i = 0; i < component.length; i++) {
-            tempComp= component[i];
-            if (tempComp != null) {
-                tempComp.checkGD(stringID);
+        for (Component comp : component) {
+            if (comp != null) {
+                comp.checkGD(stringID);
             }
         }
     }
@@ -1163,10 +1135,10 @@
      */
     public void remove(int index) {
         synchronized (getTreeLock()) {
-            if (index < 0  || index >= ncomponents) {
+            if (index < 0  || index >= component.size()) {
                 throw new ArrayIndexOutOfBoundsException(index);
             }
-            Component comp = component[index];
+            Component comp = component.get(index);
             if (peer != null) {
                 comp.removeNotify();
             }
@@ -1181,10 +1153,7 @@
             adjustDescendants(-(comp.countHierarchyMembers()));
 
             comp.parent = null;
-            System.arraycopy(component, index + 1,
-                             component, index,
-                             ncomponents - index - 1);
-            component[--ncomponents] = null;
+            component.remove(index);
 
             if (valid) {
                 invalidate();
@@ -1229,14 +1198,9 @@
     public void remove(Component comp) {
         synchronized (getTreeLock()) {
             if (comp.parent == this)  {
-                /* Search backwards, expect that more recent additions
-                 * are more likely to be removed.
-                 */
-                Component component[] = this.component;
-                for (int i = ncomponents; --i >= 0; ) {
-                    if (component[i] == comp) {
-                        remove(i);
-                    }
+                int index = component.indexOf(comp);
+                if (index >= 0) {
+                    remove(index);
                 }
             }
         }
@@ -1258,9 +1222,8 @@
                                     -listeningBoundsChildren);
             adjustDescendants(-descendantsCount);
 
-            while (ncomponents > 0) {
-                Component comp = component[--ncomponents];
-                component[ncomponents] = null;
+            while (!component.isEmpty()) {
+                Component comp = component.remove(component.size()-1);
 
                 if (peer != null) {
                     comp.removeNotify();
@@ -1300,8 +1263,8 @@
             if (eventLog.isLoggable(Level.FINE)) {
                 // Verify listeningChildren is correct
                 int sum = 0;
-                for (int i = 0; i < ncomponents; i++) {
-                    sum += component[i].numListening(mask);
+                for (Component comp : component) {
+                    sum += comp.numListening(mask);
                 }
                 if (listeningChildren != sum) {
                     eventLog.log(Level.FINE, "Assertion (listeningChildren == sum) failed");
@@ -1312,8 +1275,8 @@
             if (eventLog.isLoggable(Level.FINE)) {
                 // Verify listeningBoundsChildren is correct
                 int sum = 0;
-                for (int i = 0; i < ncomponents; i++) {
-                    sum += component[i].numListening(mask);
+                for (Component comp : component) {
+                    sum += comp.numListening(mask);
                 }
                 if (listeningBoundsChildren != sum) {
                     eventLog.log(Level.FINE, "Assertion (listeningBoundsChildren == sum) failed");
@@ -1375,8 +1338,8 @@
         if (log.isLoggable(Level.FINE)) {
             // Verify descendantsCount is correct
             int sum = 0;
-            for (int i = 0; i < ncomponents; i++) {
-                sum += component[i].countHierarchyMembers();
+            for (Component comp : component) {
+                sum += comp.countHierarchyMembers();
             }
             if (descendantsCount != sum) {
                 log.log(Level.FINE, "Assertion (descendantsCount == sum) failed");
@@ -1408,7 +1371,7 @@
         int listeners = getListenersCount(id, enabledOnToolkit);
 
         for (int count = listeners, i = 0; count > 0; i++) {
-            count -= component[i].createHierarchyEvents(id, changed,
+            count -= component.get(i).createHierarchyEvents(id, changed,
                 changedParent, changeFlags, enabledOnToolkit);
         }
         return listeners +
@@ -1420,13 +1383,13 @@
         boolean enabledOnToolkit)
     {
         assert Thread.holdsLock(getTreeLock());
-        if (ncomponents == 0) {
+        if (component.isEmpty()) {
             return;
         }
         int listeners = getListenersCount(id, enabledOnToolkit);
 
         for (int count = listeners, i = 0; count > 0; i++) {
-            count -= component[i].createHierarchyEvents(id, this, parent,
+            count -= component.get(i).createHierarchyEvents(id, this, parent,
                 changeFlags, enabledOnToolkit);
         }
     }
@@ -1562,12 +1525,11 @@
                 ((ContainerPeer)peer).beginLayout();
             }
             doLayout();
-            Component component[] = this.component;
-            for (int i = 0 ; i < ncomponents ; ++i) {
-                Component comp = component[i];
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
                 if (   (comp instanceof Container)
-                    && !(comp instanceof Window)
-                    && !comp.valid) {
+                       && !(comp instanceof Window)
+                       && !comp.valid) {
                     ((Container)comp).validateTree();
                 } else {
                     comp.validate();
@@ -1586,8 +1548,8 @@
      */
     void invalidateTree() {
         synchronized (getTreeLock()) {
-            for (int i = 0; i < ncomponents; ++i) {
-                Component comp = component[i];
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
                 if (comp instanceof Container) {
                     ((Container)comp).invalidateTree();
                 }
@@ -1838,7 +1800,7 @@
             // super.paint(); -- Don't bother, since it's a NOP.
 
             GraphicsCallback.PaintCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS);
         }
     }
 
@@ -1893,7 +1855,7 @@
             }
 
             GraphicsCallback.PrintCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS);
         }
     }
 
@@ -1906,7 +1868,7 @@
     public void paintComponents(Graphics g) {
         if (isShowing()) {
             GraphicsCallback.PaintAllCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.TWO_PASSES);
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES);
         }
     }
 
@@ -1928,7 +1890,7 @@
     void paintHeavyweightComponents(Graphics g) {
         if (isShowing()) {
             GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
                                             GraphicsCallback.HEAVYWEIGHTS);
         }
     }
@@ -1942,7 +1904,7 @@
     public void printComponents(Graphics g) {
         if (isShowing()) {
             GraphicsCallback.PrintAllCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.TWO_PASSES);
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.TWO_PASSES);
         }
     }
 
@@ -1964,7 +1926,7 @@
     void printHeavyweightComponents(Graphics g) {
         if (isShowing()) {
             GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
-                runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
+                runComponents(component.toArray(EMPTY_ARRAY), g, GraphicsCallback.LIGHTWEIGHTS |
                                             GraphicsCallback.HEAVYWEIGHTS);
         }
     }
@@ -2260,11 +2222,9 @@
                                          boolean searchHeavyweightChildren,
                                          boolean searchHeavyweightDescendants) {
         synchronized (getTreeLock()) {
-            int ncomponents = this.ncomponents;
-            Component component[] = this.component;
-
-            for (int i = 0 ; i < ncomponents ; i++) {
-                Component comp = component[i];
+
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
                 if (comp != null && comp.visible &&
                     ((!searchHeavyweightChildren &&
                       comp.peer instanceof LightweightPeer) ||
@@ -2415,8 +2375,8 @@
         }
         synchronized (getTreeLock()) {
             // Two passes: see comment in sun.awt.SunGraphicsCallback
-            for (int i = 0 ; i < ncomponents ; i++) {
-                Component comp = component[i];
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
                 if (comp != null &&
                     !(comp.peer instanceof LightweightPeer)) {
                     if (comp.contains(x - comp.x, y - comp.y)) {
@@ -2424,8 +2384,8 @@
                     }
                 }
             }
-            for (int i = 0 ; i < ncomponents ; i++) {
-                Component comp = component[i];
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
                 if (comp != null &&
                     comp.peer instanceof LightweightPeer) {
                     if (comp.contains(x - comp.x, y - comp.y)) {
@@ -2544,43 +2504,43 @@
         if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
             return null;
         }
-        int ncomponents = this.ncomponents;
-        Component component[] = this.component;
 
         // Two passes: see comment in sun.awt.SunGraphicsCallback
-        for (int i = 0 ; i < ncomponents ; i++) {
-            Component comp = component[i];
-            if (comp != null &&
-                !(comp.peer instanceof LightweightPeer)) {
-                if (comp instanceof Container) {
-                    comp = ((Container)comp).findComponentAtImpl(x - comp.x,
-                                                             y - comp.y,
-                                                             ignoreEnabled);
-                } else {
-                    comp = comp.locate(x - comp.x, y - comp.y);
-                }
-                if (comp != null && comp.visible &&
-                    (ignoreEnabled || comp.enabled))
-                {
-                    return comp;
+        synchronized (getTreeLock()) {
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
+                if (comp != null &&
+                    !(comp.peer instanceof LightweightPeer)) {
+                    if (comp instanceof Container) {
+                        comp = ((Container)comp).findComponentAtImpl(x - comp.x,
+                                                                     y - comp.y,
+                                                                     ignoreEnabled);
+                    } else {
+                        comp = comp.locate(x - comp.x, y - comp.y);
+                    }
+                    if (comp != null && comp.visible &&
+                        (ignoreEnabled || comp.enabled))
+                        {
+                            return comp;
+                        }
                 }
             }
-        }
-        for (int i = 0 ; i < ncomponents ; i++) {
-            Component comp = component[i];
-            if (comp != null &&
-                comp.peer instanceof LightweightPeer) {
-                if (comp instanceof Container) {
-                    comp = ((Container)comp).findComponentAtImpl(x - comp.x,
-                                                             y - comp.y,
-                                                             ignoreEnabled);
-                } else {
-                    comp = comp.locate(x - comp.x, y - comp.y);
-                }
-                if (comp != null && comp.visible &&
-                    (ignoreEnabled || comp.enabled))
-                {
-                    return comp;
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
+                if (comp != null &&
+                    comp.peer instanceof LightweightPeer) {
+                    if (comp instanceof Container) {
+                        comp = ((Container)comp).findComponentAtImpl(x - comp.x,
+                                                                     y - comp.y,
+                                                                     ignoreEnabled);
+                    } else {
+                        comp = comp.locate(x - comp.x, y - comp.y);
+                    }
+                    if (comp != null && comp.visible &&
+                        (ignoreEnabled || comp.enabled))
+                        {
+                            return comp;
+                        }
                 }
             }
         }
@@ -2632,10 +2592,14 @@
             if (! (peer instanceof LightweightPeer)) {
                 dispatcher = new LightweightDispatcher(this);
             }
-            int ncomponents = this.ncomponents;
-            Component component[] = this.component;
-            for (int i = 0 ; i < ncomponents ; i++) {
-                component[i].addNotify();
+
+            // We shouldn't use iterator because of the Swing menu
+            // implementation specifics:
+            // the menu is being assigned as a child to JLayeredPane
+            // instead of particular component so always affect
+            // collection of component if menu is becoming shown or hidden.
+            for (int i = 0; i < component.size(); i++) {
+                component.get(i).addNotify();
             }
             // Update stacking order if native platform allows
             ContainerPeer cpeer = (ContainerPeer)peer;
@@ -2658,21 +2622,25 @@
      */
     public void removeNotify() {
         synchronized (getTreeLock()) {
-            int ncomponents = this.ncomponents;
-            Component component[] = this.component;
-            for (int i = ncomponents - 1; i >= 0; i--) {
-                if( component[i] != null ) {
+            // We shouldn't use iterator because of the Swing menu
+            // implementation specifics:
+            // the menu is being assigned as a child to JLayeredPane
+            // instead of particular component so always affect
+            // collection of component if menu is becoming shown or hidden.
+            for (int i = component.size()-1 ; i >= 0 ; i--) {
+                Component comp = component.get(i);
+                if (comp != null) {
                     // Fix for 6607170.
                     // We want to suppress focus change on disposal
                     // of the focused component. But because of focus
                     // is asynchronous, we should suppress focus change
                     // on every component in case it receives native focus
                     // in the process of disposal.
-                    component[i].setAutoFocusTransferOnDisposal(false);
-                    component[i].removeNotify();
-                    component[i].setAutoFocusTransferOnDisposal(true);
-                }
-            }
+                    comp.setAutoFocusTransferOnDisposal(false);
+                    comp.removeNotify();
+                    comp.setAutoFocusTransferOnDisposal(true);
+                 }
+             }
             // If some of the children had focus before disposal then it still has.
             // Auto-transfer focus to the next (or previous) component if auto-transfer
             // is enabled.
@@ -2683,7 +2651,7 @@
             }
             if ( dispatcher != null ) {
                 dispatcher.dispose();
-        dispatcher = null;
+                dispatcher = null;
             }
             super.removeNotify();
         }
@@ -2873,12 +2841,12 @@
      */
     public void list(PrintStream out, int indent) {
         super.list(out, indent);
-        int ncomponents = this.ncomponents;
-        Component component[] = this.component;
-        for (int i = 0 ; i < ncomponents ; i++) {
-            Component comp = component[i];
-            if (comp != null) {
-                comp.list(out, indent+1);
+        synchronized(getTreeLock()) {
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
+                if (comp != null) {
+                    comp.list(out, indent+1);
+                }
             }
         }
     }
@@ -2899,12 +2867,12 @@
      */
     public void list(PrintWriter out, int indent) {
         super.list(out, indent);
-        int ncomponents = this.ncomponents;
-        Component component[] = this.component;
-        for (int i = 0 ; i < ncomponents ; i++) {
-            Component comp = component[i];
-            if (comp != null) {
-                comp.list(out, indent+1);
+        synchronized(getTreeLock()) {
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
+                if (comp != null) {
+                    comp.list(out, indent+1);
+                }
             }
         }
     }
@@ -3414,9 +3382,11 @@
      */
     public void applyComponentOrientation(ComponentOrientation o) {
         super.applyComponentOrientation(o);
-
-        for (int i = 0 ; i < ncomponents ; ++i) {
-             component[i].applyComponentOrientation(o);
+        synchronized (getTreeLock()) {
+            for (int i = 0; i < component.size(); i++) {
+                Component comp = component.get(i);
+                comp.applyComponentOrientation(o);
+            }
         }
     }
 
@@ -3534,8 +3504,8 @@
      */
     private void writeObject(ObjectOutputStream s) throws IOException {
         ObjectOutputStream.PutField f = s.putFields();
-        f.put("ncomponents", ncomponents);
-        f.put("component", component);
+        f.put("ncomponents", component.size());
+        f.put("component", component.toArray(EMPTY_ARRAY));
         f.put("layoutMgr", layoutMgr);
         f.put("dispatcher", dispatcher);
         f.put("maxSize", maxSize);
@@ -3574,8 +3544,12 @@
         throws ClassNotFoundException, IOException
     {
         ObjectInputStream.GetField f = s.readFields();
-        ncomponents = f.get("ncomponents", 0);
-        component = (Component[])f.get("component", new Component[0]);
+        Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY);
+        int ncomponents = (Integer) f.get("ncomponents", 0);
+        component = new java.util.ArrayList<Component>(ncomponents);
+        for (int i = 0; i < ncomponents; ++i) {
+            component.add(tmpComponent[i]);
+        }
         layoutMgr = (LayoutManager)f.get("layoutMgr", null);
         dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
         // Old stream. Doesn't contain maxSize among Component's fields.
@@ -3585,16 +3559,14 @@
         focusCycleRoot = f.get("focusCycleRoot", false);
         containerSerializedDataVersion = f.get("containerSerializedDataVersion", 1);
         focusTraversalPolicyProvider = f.get("focusTraversalPolicyProvider", false);
-
-        Component component[] = this.component;
-        for(int i = 0; i < ncomponents; i++) {
-            component[i].parent = this;
+        java.util.List<Component> component = this.component;
+        for(Component comp : component) {
+            comp.parent = this;
             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
-                component[i].numListening(AWTEvent.HIERARCHY_EVENT_MASK));
+                                    comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
-                component[i].numListening(
-                    AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
-            adjustDescendants(component[i].countHierarchyMembers());
+                                    comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
+            adjustDescendants(comp.countHierarchyMembers());
         }
 
         Object keyOrNull;
--- a/jdk/src/share/classes/java/awt/ScrollPane.java	Tue Jun 17 13:37:28 2008 +0400
+++ b/jdk/src/share/classes/java/awt/ScrollPane.java	Wed Jun 18 15:35:37 2008 +0400
@@ -357,7 +357,7 @@
      */
     public void setScrollPosition(int x, int y) {
         synchronized (getTreeLock()) {
-            if (ncomponents <= 0) {
+            if (getComponentCount()==0) {
                 throw new NullPointerException("child is null");
             }
             hAdjustable.setValue(x);
@@ -393,10 +393,12 @@
      */
     @Transient
     public Point getScrollPosition() {
-        if (ncomponents <= 0) {
-            throw new NullPointerException("child is null");
+        synchronized (getTreeLock()) {
+            if (getComponentCount()==0) {
+                throw new NullPointerException("child is null");
+            }
+            return new Point(hAdjustable.getValue(), vAdjustable.getValue());
         }
-        return new Point(hAdjustable.getValue(), vAdjustable.getValue());
     }
 
     /**
@@ -486,26 +488,27 @@
      */
     @Deprecated
     public void layout() {
-        if (ncomponents > 0) {
-            Component c = getComponent(0);
-            Point p = getScrollPosition();
-            Dimension cs = calculateChildSize();
-            Dimension vs = getViewportSize();
-            Insets i = getInsets();
+        if (getComponentCount()==0) {
+            return;
+        }
+        Component c = getComponent(0);
+        Point p = getScrollPosition();
+        Dimension cs = calculateChildSize();
+        Dimension vs = getViewportSize();
+        Insets i = getInsets();
 
-            c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
-            ScrollPanePeer peer = (ScrollPanePeer)this.peer;
-            if (peer != null) {
-                peer.childResized(cs.width, cs.height);
-            }
+        c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
+        ScrollPanePeer peer = (ScrollPanePeer)this.peer;
+        if (peer != null) {
+            peer.childResized(cs.width, cs.height);
+        }
 
-            // update adjustables... the viewport size may have changed
-            // with the scrollbars coming or going so the viewport size
-            // is updated before the adjustables.
-            vs = getViewportSize();
-            hAdjustable.setSpan(0, cs.width, vs.width);
-            vAdjustable.setSpan(0, cs.height, vs.height);
-        }
+        // update adjustables... the viewport size may have changed
+        // with the scrollbars coming or going so the viewport size
+        // is updated before the adjustables.
+        vs = getViewportSize();
+        hAdjustable.setSpan(0, cs.width, vs.width);
+        vAdjustable.setSpan(0, cs.height, vs.height);
     }
 
     /**
@@ -515,20 +518,21 @@
      * @see Component#printAll
      */
     public void printComponents(Graphics g) {
-        if (ncomponents > 0) {
-            Component c = component[0];
-            Point p = c.getLocation();
-            Dimension vs = getViewportSize();
-            Insets i = getInsets();
+        if (getComponentCount()==0) {
+            return;
+        }
+        Component c = getComponent(0);
+        Point p = c.getLocation();
+        Dimension vs = getViewportSize();
+        Insets i = getInsets();
 
-            Graphics cg = g.create();
-            try {
-                cg.clipRect(i.left, i.top, vs.width, vs.height);
-                cg.translate(p.x, p.y);
-                c.printAll(cg);
-            } finally {
-                cg.dispose();
-            }
+        Graphics cg = g.create();
+        try {
+            cg.clipRect(i.left, i.top, vs.width, vs.height);
+            cg.translate(p.x, p.y);
+            c.printAll(cg);
+        } finally {
+            cg.dispose();
         }
     }
 
@@ -589,7 +593,7 @@
             default:
                 sdpStr = "invalid display policy";
         }
-        Point p = ncomponents > 0? getScrollPosition() : new Point(0,0);
+        Point p = (getComponentCount()>0)? getScrollPosition() : new Point(0,0);
         Insets i = getInsets();
         return super.paramString()+",ScrollPosition=("+p.x+","+p.y+")"+
             ",Insets=("+i.top+","+i.left+","+i.bottom+","+i.right+")"+
--- a/jdk/src/windows/native/sun/windows/awt_Container.cpp	Tue Jun 17 13:37:28 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Container.cpp	Wed Jun 18 15:35:37 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,6 @@
  * AwtContainer fields
  */
 
-jfieldID AwtContainer::ncomponentsID;
-jfieldID AwtContainer::componentID;
 jfieldID AwtContainer::layoutMgrID;
 jmethodID AwtContainer::findComponentAtMID;
 
@@ -45,18 +43,12 @@
 Java_java_awt_Container_initIDs(JNIEnv *env, jclass cls) {
     TRY;
 
-    AwtContainer::ncomponentsID = env->GetFieldID(cls, "ncomponents", "I");
-    AwtContainer::componentID =
-        env->GetFieldID(cls, "component", "[Ljava/awt/Component;");
-
     AwtContainer::layoutMgrID =
         env->GetFieldID(cls, "layoutMgr", "Ljava/awt/LayoutManager;");
 
     AwtContainer::findComponentAtMID =
         env->GetMethodID(cls, "findComponentAt", "(IIZ)Ljava/awt/Component;");
 
-    DASSERT(AwtContainer::ncomponentsID != NULL);
-    DASSERT(AwtContainer::componentID != NULL);
     DASSERT(AwtContainer::layoutMgrID != NULL);
     DASSERT(AwtContainer::findComponentAtMID);
 
--- a/jdk/src/windows/native/sun/windows/awt_Container.h	Tue Jun 17 13:37:28 2008 +0400
+++ b/jdk/src/windows/native/sun/windows/awt_Container.h	Wed Jun 18 15:35:37 2008 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-1999 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,8 +37,6 @@
 public:
 
     /* java.awt.Container field ids */
-    static jfieldID ncomponentsID;
-    static jfieldID componentID;
     static jfieldID layoutMgrID;
     static jmethodID findComponentAtMID;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Container/CheckZOrderChange/CheckZOrderChange.java	Wed Jun 18 15:35:37 2008 +0400
@@ -0,0 +1,48 @@
+/*
+   @test %I% %E%
+   @bug 2161766
+   @summary Component is missing after changing the z-order of the component & focus is not transfered in
+   @author  Andrei Dmitriev : area=awt.container
+   @run main CheckZOrderChange
+*/
+import java.awt.*;
+import java.awt.event.*;
+
+public class CheckZOrderChange {
+
+    private static Button content[] = new Button[]{new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Button("Button 4")};
+    private static Frame frame;
+
+    public static void main(String[] args) {
+
+        frame = new Frame("Test Frame");
+        frame.setLayout(new FlowLayout());
+
+        for (Button b: content){
+            frame.add(b);
+        }
+
+        frame.setSize(300, 300);
+        frame.setVisible(true);
+
+        /* INITIAL ZORDERS ARE*/
+        for (Button b: content){
+            System.out.println("frame.getComponentZOrder("+ b +") = " + frame.getComponentZOrder(b));
+        }
+
+        //Change the Z Order
+        frame.setComponentZOrder(content[0], 2);
+        System.out.println("ZOrder of button1 changed to 2");
+
+        if (frame.getComponentZOrder(content[0]) != 2 ||
+            frame.getComponentZOrder(content[1]) != 0 ||
+            frame.getComponentZOrder(content[2]) != 1 ||
+            frame.getComponentZOrder(content[3]) != 3)
+        {
+            for (Button b: content){
+                System.out.println("frame.getComponentZOrder("+ b +") = " + frame.getComponentZOrder(b));
+            }
+            throw new RuntimeException("TEST FAILED: getComponentZOrder did not return the correct value");
+        }
+    }
+}