KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > Container


1 /*
2  * @(#)Container.java 1.267 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package java.awt;
8
9 import java.io.PrintStream JavaDoc;
10 import java.io.PrintWriter JavaDoc;
11 import java.awt.peer.ContainerPeer;
12 import java.awt.peer.ComponentPeer;
13 import java.awt.peer.LightweightPeer;
14 import sun.awt.PeerEvent;
15 import java.awt.event.ComponentEvent JavaDoc;
16 import java.awt.event.ContainerEvent JavaDoc;
17 import java.awt.event.FocusEvent JavaDoc;
18 import java.awt.event.HierarchyEvent JavaDoc;
19 import java.awt.event.InputEvent JavaDoc;
20 import java.awt.event.KeyEvent JavaDoc;
21 import java.awt.event.MouseEvent JavaDoc;
22 import java.awt.event.MouseWheelEvent JavaDoc;
23 import java.awt.event.ContainerListener JavaDoc;
24 import java.util.EventListener JavaDoc;
25 import java.io.ObjectStreamField JavaDoc;
26 import java.io.ObjectOutputStream JavaDoc;
27 import java.io.ObjectInputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.awt.event.AWTEventListener JavaDoc;
30 import java.awt.event.WindowAdapter JavaDoc;
31 import java.awt.event.WindowListener JavaDoc;
32 import java.awt.event.WindowEvent JavaDoc;
33 import java.awt.dnd.DropTarget JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.Set JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import javax.accessibility.*;
39 import java.beans.PropertyChangeListener JavaDoc;
40 import javax.swing.JRootPane JavaDoc;
41
42 import sun.awt.AppContext;
43 import sun.awt.DebugHelper;
44 import sun.awt.SunToolkit;
45 import sun.awt.dnd.SunDropTargetEvent;
46
47 /**
48  * A generic Abstract Window Toolkit(AWT) container object is a component
49  * that can contain other AWT components.
50  * <p>
51  * Components added to a container are tracked in a list. The order
52  * of the list will define the components' front-to-back stacking order
53  * within the container. If no index is specified when adding a
54  * component to a container, it will be added to the end of the list
55  * (and hence to the bottom of the stacking order).
56  * <p>
57  * <b>Note</b>: For details on the focus subsystem, see
58  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
59  * How to Use the Focus Subsystem</a>,
60  * a section in <em>The Java Tutorial</em>, and the
61  * <a HREF="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
62  * for more information.
63  *
64  * @version 1.267, 05/18/04
65  * @author Arthur van Hoff
66  * @author Sami Shaio
67  * @see #add(java.awt.Component, int)
68  * @see #getComponent(int)
69  * @see LayoutManager
70  * @since JDK1.0
71  */

72 public class Container extends Component JavaDoc {
73
74     /**
75      * The number of components in this container.
76      * This value can be null.
77      * @see #getComponent
78      * @see #getComponents
79      * @see #getComponentCount
80      */

81     int ncomponents;
82
83     /**
84      * The components in this container.
85      * @see #add
86      * @see #getComponents
87      */

88     Component JavaDoc component[] = new Component JavaDoc[0];
89
90     /**
91      * Layout manager for this container.
92      * @see #doLayout
93      * @see #setLayout
94      * @see #getLayout
95      */

96     LayoutManager JavaDoc layoutMgr;
97
98     /**
99      * Event router for lightweight components. If this container
100      * is native, this dispatcher takes care of forwarding and
101      * retargeting the events to lightweight components contained
102      * (if any).
103      */

104     private LightweightDispatcher dispatcher;
105
106     /**
107      * The focus traversal policy that will manage keyboard traversal of this
108      * Container's children, if this Container is a focus cycle root. If the
109      * value is null, this Container inherits its policy from its focus-cycle-
110      * root ancestor. If all such ancestors of this Container have null
111      * policies, then the current KeyboardFocusManager's default policy is
112      * used. If the value is non-null, this policy will be inherited by all
113      * focus-cycle-root children that have no keyboard-traversal policy of
114      * their own (as will, recursively, their focus-cycle-root children).
115      * <p>
116      * If this Container is not a focus cycle root, the value will be
117      * remembered, but will not be used or inherited by this or any other
118      * Containers until this Container is made a focus cycle root.
119      *
120      * @see #setFocusTraversalPolicy
121      * @see #getFocusTraversalPolicy
122      * @since 1.4
123      */

124     private transient FocusTraversalPolicy JavaDoc focusTraversalPolicy;
125  
126     /**
127      * Indicates whether this Component is the root of a focus traversal cycle.
128      * Once focus enters a traversal cycle, typically it cannot leave it via
129      * focus traversal unless one of the up- or down-cycle keys is pressed.
130      * Normal traversal is limited to this Container, and all of this
131      * Container's descendants that are not descendants of inferior focus cycle
132      * roots.
133      *
134      * @see #setFocusCycleRoot
135      * @see #isFocusCycleRoot
136      * @since 1.4
137      */

138     private boolean focusCycleRoot = false;
139  
140
141     /**
142      * Stores the value of focusTraversalPolicyProvider property.
143      * @since 1.5
144      * @see #setFocusTraversalPolicyProvider
145      */

146     private boolean focusTraversalPolicyProvider;
147  
148     // keeps track of the threads that are printing this component
149
private transient Set JavaDoc printingThreads;
150     // True if there is at least one thread that's printing this component
151
private transient boolean printing = false;
152
153     transient ContainerListener JavaDoc containerListener;
154
155     /* HierarchyListener and HierarchyBoundsListener support */
156     transient int listeningChildren;
157     transient int listeningBoundsChildren;
158     transient int descendantsCount;
159
160     /**
161      * JDK 1.1 serialVersionUID
162      */

163     private static final long serialVersionUID = 4613797578919906343L;
164
165     private static final DebugHelper dbg = DebugHelper.create(Container JavaDoc.class);
166
167     /**
168      * A constant which toggles one of the controllable behaviors
169      * of <code>getMouseEventTarget</code>. It is used to specify whether
170      * the method can return the Container on which it is originally called
171      * in case if none of its children are the current mouse event targets.
172      *
173      * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
174      */

175     static final boolean INCLUDE_SELF = true;
176
177     /**
178      * A constant which toggles one of the controllable behaviors
179      * of <code>getMouseEventTarget</code>. It is used to specify whether
180      * the method should search only lightweight components.
181      *
182      * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
183      */

184     static final boolean SEARCH_HEAVYWEIGHTS = true;
185
186     /**
187      * @serialField ncomponents int
188      * The number of components in this container.
189      * This value can be null.
190      * @serialField component Component[]
191      * The components in this container.
192      * @serialField layoutMgr LayoutManager
193      * Layout manager for this container.
194      * @serialField dispatcher LightweightDispatcher
195      * Event router for lightweight components. If this container
196      * is native, this dispatcher takes care of forwarding and
197      * retargeting the events to lightweight components contained
198      * (if any).
199      * @serialField maxSize Dimension
200      * Maximum size of this Container.
201      * @serialField focusCycleRoot boolean
202      * Indicates whether this Component is the root of a focus traversal cycle.
203      * Once focus enters a traversal cycle, typically it cannot leave it via
204      * focus traversal unless one of the up- or down-cycle keys is pressed.
205      * Normal traversal is limited to this Container, and all of this
206      * Container's descendants that are not descendants of inferior focus cycle
207      * roots.
208      * @serialField containerSerializedDataVersion int
209      * Container Serial Data Version.
210      * @serialField focusTraversalPolicyProvider boolean
211      * Stores the value of focusTraversalPolicyProvider property.
212      */

213     private static final ObjectStreamField JavaDoc[] serialPersistentFields = {
214         new ObjectStreamField JavaDoc("ncomponents", Integer.TYPE),
215         new ObjectStreamField JavaDoc("component", Component JavaDoc[].class),
216         new ObjectStreamField JavaDoc("layoutMgr", LayoutManager JavaDoc.class),
217         new ObjectStreamField JavaDoc("dispatcher", LightweightDispatcher.class),
218         new ObjectStreamField JavaDoc("maxSize", Dimension JavaDoc.class),
219         new ObjectStreamField JavaDoc("focusCycleRoot", Boolean.TYPE),
220         new ObjectStreamField JavaDoc("containerSerializedDataVersion", Integer.TYPE),
221         new ObjectStreamField JavaDoc("focusTraversalPolicyProvider", Boolean.TYPE),
222     };
223
224     static {
225         /* ensure that the necessary native libraries are loaded */
226     Toolkit.loadLibraries();
227         if (!GraphicsEnvironment.isHeadless()) {
228             initIDs();
229         }
230     }
231
232     /**
233      * Initialize JNI field and method IDs for fields that may be
234        called from C.
235      */

236     private static native void initIDs();
237
238     /**
239      * Constructs a new Container. Containers can be extended directly,
240      * but are lightweight in this case and must be contained by a parent
241      * somewhere higher up in the component tree that is native.
242      * (such as Frame for example).
243      */

244     public Container() {
245     }
246
247     void initializeFocusTraversalKeys() {
248     focusTraversalKeys = new Set JavaDoc[4];
249     }
250  
251     /**
252      * Gets the number of components in this panel.
253      * @return the number of components in this panel.
254      * @see #getComponent
255      * @since JDK1.1
256      */

257     public int getComponentCount() {
258     return countComponents();
259     }
260
261     /**
262      * @deprecated As of JDK version 1.1,
263      * replaced by getComponentCount().
264      */

265     @Deprecated JavaDoc
266     public int countComponents() {
267     return ncomponents;
268     }
269
270     /**
271      * Gets the nth component in this container.
272      * @param n the index of the component to get.
273      * @return the n<sup>th</sup> component in this container.
274      * @exception ArrayIndexOutOfBoundsException
275      * if the n<sup>th</sup> value does not exist.
276      */

277     public Component JavaDoc getComponent(int n) {
278     synchronized (getTreeLock()) {
279         if ((n < 0) || (n >= ncomponents)) {
280         throw new ArrayIndexOutOfBoundsException JavaDoc("No such child: " + n);
281         }
282         return component[n];
283     }
284     }
285
286     /**
287      * Gets all the components in this container.
288      * @return an array of all the components in this container.
289      */

290     public Component JavaDoc[] getComponents() {
291     return getComponents_NoClientCode();
292     }
293     // NOTE: This method may be called by privileged threads.
294
// This functionality is implemented in a package-private method
295
// to insure that it cannot be overridden by client subclasses.
296
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
297
final Component JavaDoc[] getComponents_NoClientCode() {
298     synchronized (getTreeLock()) {
299         Component JavaDoc list[] = new Component JavaDoc[ncomponents];
300         System.arraycopy(component, 0, list, 0, ncomponents);
301         return list;
302     }
303     } // getComponents_NoClientCode()
304

305     /**
306      * Determines the insets of this container, which indicate the size
307      * of the container's border.
308      * <p>
309      * A <code>Frame</code> object, for example, has a top inset that
310      * corresponds to the height of the frame's title bar.
311      * @return the insets of this container.
312      * @see Insets
313      * @see LayoutManager
314      * @since JDK1.1
315      */

316     public Insets JavaDoc getInsets() {
317         return insets();
318     }
319
320     /**
321      * @deprecated As of JDK version 1.1,
322      * replaced by <code>getInsets()</code>.
323      */

324     @Deprecated JavaDoc
325     public Insets JavaDoc insets() {
326     if (this.peer != null && this.peer instanceof ContainerPeer) {
327         ContainerPeer peer = (ContainerPeer)this.peer;
328         return (Insets JavaDoc)peer.insets().clone();
329     }
330     return new Insets JavaDoc(0, 0, 0, 0);
331     }
332
333     /**
334      * Appends the specified component to the end of this container.
335      * This is a convenience method for {@link #addImpl}.
336      * <p>
337      * Note: If a component has been added to a container that
338      * has been displayed, <code>validate</code> must be
339      * called on that container to display the new component.
340      * If multiple components are being added, you can improve
341      * efficiency by calling <code>validate</code> only once,
342      * after all the components have been added.
343      *
344      * @param comp the component to be added
345      * @see #addImpl
346      * @see #validate
347      * @see javax.swing.JComponent#revalidate()
348      * @return the component argument
349      */

350     public Component JavaDoc add(Component JavaDoc comp) {
351         addImpl(comp, null, -1);
352     return comp;
353     }
354
355     /**
356      * Adds the specified component to this container.
357      * This is a convenience method for {@link #addImpl}.
358      * <p>
359      * This method is obsolete as of 1.1. Please use the
360      * method <code>add(Component, Object)</code> instead.
361      * @see #add(Component, Object)
362      */

363     public Component JavaDoc add(String JavaDoc name, Component JavaDoc comp) {
364     addImpl(comp, name, -1);
365     return comp;
366     }
367
368     /**
369      * Adds the specified component to this container at the given
370      * position.
371      * This is a convenience method for {@link #addImpl}.
372      * <p>
373      * Note: If a component has been added to a container that
374      * has been displayed, <code>validate</code> must be
375      * called on that container to display the new component.
376      * If multiple components are being added, you can improve
377      * efficiency by calling <code>validate</code> only once,
378      * after all the components have been added.
379      *
380      * @param comp the component to be added
381      * @param index the position at which to insert the component,
382      * or <code>-1</code> to append the component to the end
383      * @return the component <code>comp</code>
384      * @see #addImpl
385      * @see #remove
386      * @see #validate
387      * @see javax.swing.JComponent#revalidate()
388      */

389     public Component JavaDoc add(Component JavaDoc comp, int index) {
390     addImpl(comp, null, index);
391     return comp;
392     }
393
394     void checkTreeLock() {
395         if (!Thread.holdsLock(getTreeLock())) {
396             throw new IllegalStateException JavaDoc("This function should be called while holding treeLock");
397         }
398     }
399     /**
400      * Checks that the component comp can be added to this container
401      * Checks : index in bounds of container's size,
402      * comp is not one of this container's parents,
403      * and comp is not a window.
404      * Comp and container must be on the same GraphicsDevice.
405      * if comp is container, all sub-components must be on
406      * same GraphicsDevice.
407      *
408      * @since 1.5
409      */

410     private void checkAdding(Component JavaDoc comp, int index) {
411         checkTreeLock();
412
413         GraphicsConfiguration JavaDoc thisGC = getGraphicsConfiguration();
414
415         if (index > ncomponents || index < 0) {
416             throw new IllegalArgumentException JavaDoc("illegal component position");
417         }
418         if (comp.parent == this) {
419             if (index == ncomponents) {
420                 throw new IllegalArgumentException JavaDoc("illegal component position " +
421                                                    index + " should be less then " + ncomponents);
422             }
423         }
424         if (comp instanceof Container JavaDoc) {
425             for (Container JavaDoc cn = this; cn != null; cn=cn.parent) {
426                 if (cn == comp) {
427                     throw new IllegalArgumentException JavaDoc("adding container's parent to itself");
428                 }
429             }
430
431             if (comp instanceof Window JavaDoc) {
432                 throw new IllegalArgumentException JavaDoc("adding a window to a container");
433             }
434         }
435         Window JavaDoc thisTopLevel = getContainingWindow();
436         Window JavaDoc compTopLevel = comp.getContainingWindow();
437         if (thisTopLevel != compTopLevel) {
438             throw new IllegalArgumentException JavaDoc("component and container should be in the same top-level window");
439         }
440         if (thisGC != null) {
441             comp.checkGD(thisGC.getDevice().getIDstring());
442         }
443     }
444
445     /**
446      * Removes component comp from this container without making unneccessary changes
447      * and generating unneccessary events. This function intended to perform optimized
448      * remove, for example, if newParent and current parent are the same it just changes
449      * index without calling removeNotify.
450      * Note: Should be called while holding treeLock
451      * @since: 1.5
452      */

453     private void removeDelicately(Component JavaDoc comp, Container JavaDoc newParent, int newIndex) {
454         checkTreeLock();
455
456         int index = getComponentZOrder(comp);
457         if (isRemoveNotifyNeeded(comp, this, newParent)) {
458             comp.removeNotify();
459         }
460         if (newParent != this) {
461             if (layoutMgr != null) {
462                 layoutMgr.removeLayoutComponent(comp);
463             }
464             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
465                                     -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
466             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
467                                     -comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
468             adjustDescendants(-(comp.countHierarchyMembers()));
469
470             comp.parent = null;
471             System.arraycopy(component, index + 1,
472                              component, index,
473                              ncomponents - index - 1);
474             component[--ncomponents] = null;
475
476             if (valid) {
477                 invalidate();
478             }
479         } else {
480             if (newIndex > index) { // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
481
if (newIndex-index > 0) {
482                     System.arraycopy(component, index+1, component, index, newIndex-index);
483                 }
484             } else { // 4->2: 012345 -> 014235
485
if (index-newIndex > 0) {
486                     System.arraycopy(component, newIndex, component, newIndex+1, index-newIndex);
487                 }
488             }
489             component[newIndex] = comp;
490         }
491         if (comp.parent == null) { // was actually removed
492
if (containerListener != null ||
493                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
494                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
495                 ContainerEvent JavaDoc e = new ContainerEvent JavaDoc(this,
496                                                       ContainerEvent.COMPONENT_REMOVED,
497                                                       comp);
498                 dispatchEvent(e);
499
500             }
501             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
502                                        this, HierarchyEvent.PARENT_CHANGED,
503                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
504             if (peer != null && layoutMgr == null && isVisible()) {
505                 updateCursorImmediately();
506             }
507         }
508     }
509
510     /**
511      * Checks whether this container can contain component which is focus owner.
512      * Verifies that container is enable and showing, and if it is focus cycle root
513      * its FTP allows component to be focus owner
514      * @since 1.5
515      */

516     boolean canContainFocusOwner(Component JavaDoc focusOwnerCandidate) {
517         if (!(isEnabled() && isDisplayable()
518               && isVisible() && isFocusable()))
519         {
520             return false;
521         }
522         if (isFocusCycleRoot()) {
523             FocusTraversalPolicy JavaDoc policy = getFocusTraversalPolicy();
524             if (policy instanceof DefaultFocusTraversalPolicy JavaDoc) {
525                 if (!((DefaultFocusTraversalPolicy JavaDoc)policy).accept(focusOwnerCandidate)) {
526                     return false;
527                 }
528             }
529         }
530         synchronized(getTreeLock()) {
531             if (parent != null) {
532                 return parent.canContainFocusOwner(focusOwnerCandidate);
533             }
534         }
535         return true;
536     }
537
538     /**
539      * Checks whether or not this container has heavyweight children.
540      * Note: Should be called while holding tree lock
541      * @return true if there is at least one heavyweight children in a container, false otherwise
542      * @since 1.5
543      */

544     private boolean hasHeavyweightChildren() {
545         checkTreeLock();
546         boolean res = true; // true while it is lightweight
547
for (int i = 0; i < getComponentCount() && res; i++) {
548             Component JavaDoc child = getComponent(i);
549             res &= child.isLightweight();
550             if (res && child instanceof Container JavaDoc) {
551                 res &= !((Container JavaDoc)child).hasHeavyweightChildren();
552             }
553         }
554         return !res;
555     }
556
557     /**
558      * Returns closest heavyweight component to this container. If this container is heavyweight
559      * returns this.
560      * @since 1.5
561      */

562     Container JavaDoc getHeavyweightContainer() {
563         checkTreeLock();
564         if (peer != null && !(peer instanceof LightweightPeer)) {
565             return this;
566         } else {
567             return getNativeContainer();
568         }
569     }
570
571     /**
572      * Detects whether or not remove from current parent and adding to new parent requires call of
573      * removeNotify on the component. Since removeNotify destroys native window this might (not)
574      * be required. For example, if new container and old containers are the same we don't need to
575      * destroy native window.
576      * @since: 1.5
577      */

578     private static boolean isRemoveNotifyNeeded(Component JavaDoc comp, Container JavaDoc oldContainer, Container JavaDoc newContainer) {
579         if (oldContainer == null) { // Component didn't have parent - no removeNotify
580
return false;
581         }
582         if (comp.peer == null) { // Component didn't have peer - no removeNotify
583
return false;
584         }
585         if (newContainer.peer == null) {
586             // Component has peer but new Container doesn't - call removeNotify
587
return true;
588         }
589
590         // If component is lightweight non-Container or lightweight Container with all but heavyweight
591
// children there is no need to call remove notify
592
if (comp.isLightweight()) {
593             if (comp instanceof Container JavaDoc) {
594                 // If it has heavyweight children then removeNotify is required
595
return ((Container JavaDoc)comp).hasHeavyweightChildren();
596             } else {
597                 // Just a lightweight
598
return false;
599             }
600         }
601
602         // All three components have peers, check for peer change
603
Container JavaDoc newNativeContainer = oldContainer.getHeavyweightContainer();
604         Container JavaDoc oldNativeContainer = newContainer.getHeavyweightContainer();
605         if (newNativeContainer != oldNativeContainer) {
606             // Native containers change - check whether or not current platform supports
607
// changing of widget hierarchy on native level without recreation.
608
return !comp.peer.isReparentSupported();
609         } else {
610             // if container didn't change we still might need to recreate component's window as
611
// changes to zorder should be reflected in native window stacking order and it might
612
// not be supported by the platform. This is important only for heavyweight child
613
return !comp.isLightweight() &&
614                 !((ContainerPeer)(newNativeContainer.peer)).isRestackSupported();
615         }
616     }
617
618     /**
619      * Moves the specified component to the specified z-order index in
620      * the container. The z-order determines the order that components
621      * are painted; the component with the highest z-order paints first
622      * and the component with the lowest z-order paints last.
623      * Where components overlap, the component with the lower
624      * z-order paints over the component with the higher z-order.
625      * <p>
626      * If the component is a child of some other container, it is
627      * removed from that container before being added to this container.
628      * The important difference between this method and
629      * <code>java.awt.Container.add(Component, int)</code> is that this method
630      * doesn't call <code>removeNotify</code> on the component while
631      * removing it from its previous container unless necessary and when
632      * allowed by the underlying native windowing system. This way, if the
633      * component has the keyboard focus, it maintains the focus when
634      * moved to the new position.
635      * <p>
636      * This property is guaranteed to apply only to lightweight
637      * non-<code>Container</code> components.
638      * <p>
639      * <b>Note</b>: Not all platforms support changing the z-order of
640      * heavyweight components from one container into another without
641      * the call to <code>removeNotify</code>. There is no way to detect
642      * whether a platform supports this, so developers shouldn't make
643      * any assumptions.
644      *
645      * @param comp the component to be moved
646      * @param index the position in the container's list to
647      * insert the component, where <code>getComponentCount()</code>
648      * appends to the end
649      * @exception NullPointerException if <code>comp</code> is
650      * <code>null</code>
651      * @exception IllegalArgumentException if <code>comp</code> is one of the
652      * container's parents
653      * @exception IllegalArgumentException if <code>index</code> is not in
654      * the range <code>[0, getComponentCount()]</code> for moving
655      * between containers, or not in the range
656      * <code>[0, getComponentCount()-1]</code> for moving inside
657      * a container
658      * @exception IllegalArgumentException if adding a container to itself
659      * @exception IllegalArgumentException if adding a <code>Window</code>
660      * to a container
661      * @see #getComponentZOrder(java.awt.Component)
662      * @since 1.5
663      */

664     public final void setComponentZOrder(Component JavaDoc comp, int index) {
665          synchronized (getTreeLock()) {
666              // Store parent because remove will clear it
667
Container JavaDoc curParent = comp.parent;
668              if (curParent == this && index == getComponentZOrder(comp)) {
669                  return;
670              }
671              checkAdding(comp, index);
672              if (curParent != null) {
673                  curParent.removeDelicately(comp, this, index);
674              }
675              
676              addDelicately(comp, curParent, index);
677          }
678     }
679
680     /**
681      * Traverses the tree of components and reparents children heavyweight component
682      * to new heavyweight parent.
683      * @since 1.5
684      */

685     private void reparentTraverse(ContainerPeer parentPeer, Container JavaDoc child) {
686         checkTreeLock();
687
688         for (int i = 0; i < child.getComponentCount(); i++) {
689             Component JavaDoc comp = child.getComponent(i);
690             if (comp.isLightweight()) {
691                 // If components is lightweight check if it is container
692
// If it is container it might contain heavyweight children we need to reparent
693
if (comp instanceof Container JavaDoc) {
694                     reparentTraverse(parentPeer, (Container JavaDoc)comp);
695                 }
696             } else {
697                 // Q: Need to update NativeInLightFixer?
698
comp.getPeer().reparent(parentPeer);
699             }
700         }
701     }
702
703     /**
704      * Reparents child component peer to this container peer.
705      * Container must be heavyweight.
706      * @since 1.5
707      */

708     private void reparentChild(Component JavaDoc comp) {
709         checkTreeLock();
710         if (comp == null) {
711             return;
712         }
713         if (comp.isLightweight()) {
714             // If component is lightweight container we need to reparent all its explicit heavyweight children
715
if (comp instanceof Container JavaDoc) {
716                 // Traverse component's tree till depth-first until encountering heavyweight component
717
reparentTraverse((ContainerPeer)getPeer(), (Container JavaDoc)comp);
718             }
719         } else {
720             comp.getPeer().reparent((ContainerPeer)getPeer());
721         }
722     }
723
724     /**
725      * Adds component to this container. Tries to minimize side effects of this adding -
726      * doesn't call remove notify if it is not required.
727      * @since 1.5
728      */

729     private void addDelicately(Component JavaDoc comp, Container JavaDoc curParent, int index) {
730         checkTreeLock();
731
732         // Check if moving between containers
733
if (curParent != this) {
734             /* Add component to list; allocate new array if necessary. */
735             if (ncomponents == component.length) {
736                 Component JavaDoc newcomponents[] = new Component JavaDoc[ncomponents * 2 + 1];
737                 System.arraycopy(component, 0, newcomponents, 0, ncomponents);
738                 component = newcomponents;
739             }
740             if (index == -1 || index == ncomponents) {
741                 component[ncomponents++] = comp;
742             } else {
743                 System.arraycopy(component, index, component,
744                                  index + 1, ncomponents - index);
745                 component[index] = comp;
746                 ncomponents++;
747             }
748             comp.parent = this;
749
750             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
751                                     comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
752             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
753                                     comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
754             adjustDescendants(comp.countHierarchyMembers());
755         } else {
756             if (index < ncomponents) {
757                 component[index] = comp;
758             }
759         }
760
761         if (valid) {
762             invalidate();
763         }
764         if (peer != null) {
765             if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
766
comp.addNotify();
767                 // New created peer creates component on top of the stacking order
768
Container JavaDoc newNativeContainer = getHeavyweightContainer();
769                 if (((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported()) {
770                     ((ContainerPeer)newNativeContainer.getPeer()).restack();
771                 }
772             } else { // Both container and child have peers, it means child peer should be reparented.
773
// In both cases we need to reparent native widgets.
774
Container JavaDoc newNativeContainer = getHeavyweightContainer();
775                 Container JavaDoc oldNativeContainer = curParent.getHeavyweightContainer();
776                 if (oldNativeContainer != newNativeContainer) {
777                     // Native container changed - need to reparent native widgets
778
newNativeContainer.reparentChild(comp);
779                 }
780                 // If component still has a peer and it is either container or heavyweight
781
// and restack is supported we have to restack native windows since order might have changed
782
if ((!comp.isLightweight() || (comp instanceof Container JavaDoc))
783                     && ((ContainerPeer)newNativeContainer.getPeer()).isRestackSupported())
784                 {
785                     ((ContainerPeer)newNativeContainer.getPeer()).restack();
786                 }
787                 if (!comp.isLightweight() && isLightweight()) {
788                     // If component is heavyweight and one of the containers is lightweight
789
// some NativeInLightFixer activity should be performed
790
if (!curParent.isLightweight()) {
791                         // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
792
// since addNotify does this
793
comp.nativeInLightFixer = new NativeInLightFixer();
794                     } else {
795                         // Component already has NativeInLightFixer - just reinstall it
796
// because hierarchy changed and he needs to rebuild list of parents to listen.
797
comp.nativeInLightFixer.install(this);
798                     }
799                 }
800             }
801         }
802         if (curParent != this) {
803             /* Notify the layout manager of the added component. */
804             if (layoutMgr != null) {
805                 if (layoutMgr instanceof LayoutManager2 JavaDoc) {
806                     ((LayoutManager2 JavaDoc)layoutMgr).addLayoutComponent(comp, null);
807                 } else {
808                     layoutMgr.addLayoutComponent(null, comp);
809                 }
810             }
811             if (containerListener != null ||
812                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
813                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
814                 ContainerEvent