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 JavaDoc e = new ContainerEvent JavaDoc(this,
815                                                       ContainerEvent.COMPONENT_ADDED,
816                                                       comp);
817                 dispatchEvent(e);
818             }
819             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
820                                        this, HierarchyEvent.PARENT_CHANGED,
821                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
822
823             // If component is focus owner or parent container of focus owner check that after reparenting
824
// focus owner moved out if new container prohibit this kind of focus owner.
825
if (comp.isFocusOwner() && !comp.canBeFocusOwner()) {
826                 comp.transferFocus();
827             } else if (comp instanceof Container JavaDoc) {
828                 Component JavaDoc focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
829                 if (focusOwner != null && isParentOf(focusOwner) && !focusOwner.canBeFocusOwner()) {
830                     focusOwner.transferFocus();
831                 }
832             }
833         } else {
834             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
835                                        this, HierarchyEvent.HIERARCHY_CHANGED,
836                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
837         }
838
839         if (peer != null && layoutMgr == null && isVisible()) {
840             updateCursorImmediately();
841         }
842     }
843
844     /**
845      * Returns the z-order index of the component inside the container.
846      * The higher a component is in the z-order hierarchy, the lower
847      * its index. The component with the lowest z-order index is
848      * painted last, above all other child components.
849      *
850      * @param comp the component being queried
851      * @return the z-order index of the component; otherwise
852      * returns -1 if the component is <code>null</code
853      * or doesn't belong to the container
854      * @see #setComponentZOrder(java.awt.Component, int)
855      * @since 1.5
856      */

857     public final int getComponentZOrder(Component JavaDoc comp) {
858         if (comp == null) {
859             return -1;
860         }
861         synchronized(getTreeLock()) {
862             // Quick check - container should be immediate parent of the component
863
if (comp.parent != this) {
864                 return -1;
865             }
866             for (int i = 0; i < ncomponents; i++) {
867                 if (component[i] == comp) {
868                     return i;
869                 }
870             }
871         }
872         // To please javac
873
return -1;
874     }
875
876     /**
877      * Adds the specified component to the end of this container.
878      * Also notifies the layout manager to add the component to
879      * this container's layout using the specified constraints object.
880      * This is a convenience method for {@link #addImpl}.
881      * <p>
882      * Note: If a component has been added to a container that
883      * has been displayed, <code>validate</code> must be
884      * called on that container to display the new component.
885      * If multiple components are being added, you can improve
886      * efficiency by calling <code>validate</code> only once,
887      * after all the components have been added.
888      *
889      * @param comp the component to be added
890      * @param constraints an object expressing
891      * layout contraints for this component
892      * @see #addImpl
893      * @see #validate
894      * @see javax.swing.JComponent#revalidate()
895      * @see LayoutManager
896      * @since JDK1.1
897      */

898     public void add(Component JavaDoc comp, Object JavaDoc constraints) {
899     addImpl(comp, constraints, -1);
900     }
901
902     /**
903      * Adds the specified component to this container with the specified
904      * constraints at the specified index. Also notifies the layout
905      * manager to add the component to the this container's layout using
906      * the specified constraints object.
907      * This is a convenience method for {@link #addImpl}.
908      * <p>
909      * Note: If a component has been added to a container that
910      * has been displayed, <code>validate</code> must be
911      * called on that container to display the new component.
912      * If multiple components are being added, you can improve
913      * efficiency by calling <code>validate</code> only once,
914      * after all the components have been added.
915      *
916      * @param comp the component to be added
917      * @param constraints an object expressing layout contraints for this
918      * @param index the position in the container's list at which to insert
919      * the component; <code>-1</code> means insert at the end
920      * component
921      * @see #addImpl
922      * @see #validate
923      * @see javax.swing.JComponent#revalidate()
924      * @see #remove
925      * @see LayoutManager
926      */

927     public void add(Component JavaDoc comp, Object JavaDoc constraints, int index) {
928        addImpl(comp, constraints, index);
929     }
930
931     /**
932      * Adds the specified component to this container at the specified
933      * index. This method also notifies the layout manager to add
934      * the component to this container's layout using the specified
935      * constraints object via the <code>addLayoutComponent</code>
936      * method.
937      * <p>
938      * The constraints are
939      * defined by the particular layout manager being used. For
940      * example, the <code>BorderLayout</code> class defines five
941      * constraints: <code>BorderLayout.NORTH</code>,
942      * <code>BorderLayout.SOUTH</code>, <code>BorderLayout.EAST</code>,
943      * <code>BorderLayout.WEST</code>, and <code>BorderLayout.CENTER</code>.
944      * <p>
945      * The <code>GridBagLayout</code> class requires a
946      * <code>GridBagConstraints</code> object. Failure to pass
947      * the correct type of constraints object results in an
948      * <code>IllegalArgumentException</code>.
949      * <p>
950      * If the layout manager implements both the <code>LayoutManager</code>
951      * and <code>LayoutManager2</code> interfaces, the
952      * <code>LayoutManager2</code> methods are called.
953      * <p>
954      * Note that if the component already exists
955      * in this container or a child of this container,
956      * it is removed from that container before
957      * being added to this container.
958      * <p>
959      * This is the method to override if a program needs to track
960      * every add request to a container as all other add methods defer
961      * to this one. An overriding method should
962      * usually include a call to the superclass's version of the method:
963      * <p>
964      * <blockquote>
965      * <code>super.addImpl(comp, constraints, index)</code>
966      * </blockquote>
967      * <p>
968      * @param comp the component to be added
969      * @param constraints an object expressing layout constraints
970      * for this component
971      * @param index the position in the container's list at which to
972      * insert the component, where <code>-1</code>
973      * means append to the end
974      * @exception IllegalArgumentException if <code>index</code> is invalid
975      * @exception IllegalArgumentException if adding the container's parent
976      * to itself
977      * @throws IllegalArgumentException if <code>comp</code> has been added
978      * to the <code>Container</code> more than once
979      * @exception IllegalArgumentException if adding a window to a container
980      * @see #add(Component)
981      * @see #add(Component, int)
982      * @see #add(Component, java.lang.Object)
983      * @see LayoutManager
984      * @see LayoutManager2
985      * @since JDK1.1
986      */

987     protected void addImpl(Component JavaDoc comp, Object JavaDoc constraints, int index) {
988     synchronized (getTreeLock()) {
989         /* Check for correct arguments: index in bounds,
990          * comp cannot be one of this container's parents,
991          * and comp cannot be a window.
992          * comp and container must be on the same GraphicsDevice.
993          * if comp is container, all sub-components must be on
994          * same GraphicsDevice.
995          */

996         GraphicsConfiguration JavaDoc thisGC = this.getGraphicsConfiguration();
997
998         if (index > ncomponents || (index < 0 && index != -1)) {
999         throw new IllegalArgumentException JavaDoc(
1000              "illegal component position");
1001        }
1002        if (comp instanceof Container JavaDoc) {
1003            for (Container JavaDoc cn = this; cn != null; cn=cn.parent) {
1004                if (cn == comp) {
1005                throw new IllegalArgumentException JavaDoc(
1006                      "adding container's parent to itself");
1007                }
1008            }
1009            if (comp instanceof Window JavaDoc) {
1010                throw new IllegalArgumentException JavaDoc(
1011                       "adding a window to a container");
1012            }
1013        }
1014        if (thisGC != null) {
1015            comp.checkGD(thisGC.getDevice().getIDstring());
1016        }
1017
1018        /* Reparent the component and tidy up the tree's state. */
1019        if (comp.parent != null) {
1020        comp.parent.remove(comp);
1021                    if (index > ncomponents) {
1022                        throw new IllegalArgumentException JavaDoc("illegal component position");
1023                    }
1024            }
1025
1026        /* Add component to list; allocate new array if necessary. */
1027        if (ncomponents == component.length) {
1028        Component JavaDoc newcomponents[] = new Component JavaDoc[ncomponents * 2 + 1];
1029        System.arraycopy(component, 0, newcomponents, 0, ncomponents);
1030        component = newcomponents;
1031        }
1032        if (index == -1 || index == ncomponents) {
1033        component[ncomponents++] = comp;
1034        } else {
1035        System.arraycopy(component, index, component,
1036                 index + 1, ncomponents - index);
1037        component[index] = comp;
1038        ncomponents++;
1039        }
1040        comp.parent = this;
1041
1042        adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1043            comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1044        adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1045        comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1046            adjustDescendants(comp.countHierarchyMembers());
1047
1048        if (valid) {
1049        invalidate();
1050        }
1051        if (peer != null) {
1052        comp.addNotify();
1053        }
1054        
1055        /* Notify the layout manager of the added component. */
1056        if (layoutMgr != null) {
1057        if (layoutMgr instanceof LayoutManager2 JavaDoc) {
1058            ((LayoutManager2 JavaDoc)layoutMgr).addLayoutComponent(comp, constraints);
1059        } else if (constraints instanceof String JavaDoc) {
1060            layoutMgr.addLayoutComponent((String JavaDoc)constraints, comp);
1061        }
1062        }
1063            if (containerListener != null ||
1064                (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1065                Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1066                ContainerEvent JavaDoc e = new ContainerEvent JavaDoc(this,
1067                                     ContainerEvent.COMPONENT_ADDED,
1068                                     comp);
1069                dispatchEvent(e);
1070            }
1071
1072        comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
1073                       this, HierarchyEvent.PARENT_CHANGED,
1074                                       Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1075        if (peer != null && layoutMgr == null && isVisible()) {
1076                updateCursorImmediately();
1077        }
1078    }
1079    }
1080
1081    /**
1082     * Checks that all Components that this Container contains are on
1083     * the same GraphicsDevice as this Container. If not, throws an
1084     * IllegalArgumentException.
1085     */

1086    void checkGD(String JavaDoc stringID) {
1087        Component JavaDoc tempComp;
1088        for (int i = 0; i < component.length; i++) {
1089            tempComp= component[i];
1090            if (tempComp != null) {
1091                tempComp.checkGD(stringID);
1092            }
1093        }
1094    }
1095
1096    /**
1097     * Removes the component, specified by <code>index</code>,
1098     * from this container.
1099     * This method also notifies the layout manager to remove the
1100     * component from this container's layout via the
1101     * <code>removeLayoutComponent</code> method.
1102     *
1103     * @param index the index of the component to be removed
1104     * @see #add
1105     * @since JDK1.1
1106     */

1107    public void remove(int index) {
1108    synchronized (getTreeLock()) {
1109            if (index < 0 || index >= ncomponents) {
1110                throw new ArrayIndexOutOfBoundsException JavaDoc(index);
1111            }
1112            Component JavaDoc comp = component[index];
1113        if (peer != null) {
1114        comp.removeNotify();
1115        }
1116        if (layoutMgr != null) {
1117        layoutMgr.removeLayoutComponent(comp);
1118        }
1119
1120        adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1121            -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1122        adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1123        -comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1124            adjustDescendants(-(comp.countHierarchyMembers()));
1125
1126        comp.parent = null;
1127        System.arraycopy(component, index + 1,
1128                 component, index,
1129                 ncomponents - index - 1);
1130        component[--ncomponents] = null;
1131
1132        if (valid) {
1133        invalidate();
1134        }
1135            if (containerListener != null ||
1136                (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1137                Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1138                ContainerEvent JavaDoc e = new ContainerEvent JavaDoc(this,
1139                                     ContainerEvent.COMPONENT_REMOVED,
1140                                     comp);
1141                dispatchEvent(e);
1142            }
1143
1144        comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
1145                       this, HierarchyEvent.PARENT_CHANGED,
1146                                       Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1147        if (peer != null && layoutMgr == null && isVisible()) {
1148                updateCursorImmediately();
1149        }
1150    }
1151    }
1152
1153    /**
1154     * Removes the specified component from this container.
1155     * This method also notifies the layout manager to remove the
1156     * component from this container's layout via the
1157     * <code>removeLayoutComponent</code> method.
1158     *
1159     * @param comp the component to be removed
1160     * @see #add
1161     * @see #remove(int)
1162     */

1163    public void remove(Component JavaDoc comp) {
1164    synchronized (getTreeLock()) {
1165        if (comp.parent == this) {
1166            /* Search backwards, expect that more recent additions
1167         * are more likely to be removed.
1168                 */

1169        Component JavaDoc component[] = this.component;
1170        for (int i = ncomponents; --i >= 0; ) {
1171            if (component[i] == comp) {
1172                        remove(i);
1173            }
1174        }
1175        }
1176    }
1177    }
1178
1179    /**
1180     * Removes all the components from this container.
1181     * This method also notifies the layout manager to remove the
1182     * components from this container's layout via the
1183     * <code>removeLayoutComponent</code> method.
1184     * @see #add
1185     * @see #remove
1186     */

1187    public void removeAll() {
1188    synchronized (getTreeLock()) {
1189        adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1190                                    -listeningChildren);
1191        adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1192                            -listeningBoundsChildren);
1193            adjustDescendants(-descendantsCount);
1194
1195        while (ncomponents > 0) {
1196        Component JavaDoc comp = component[--ncomponents];
1197        component[ncomponents] = null;
1198
1199        if (peer != null) {
1200            comp.removeNotify();
1201        }
1202        if (layoutMgr != null) {
1203            layoutMgr.removeLayoutComponent(comp);
1204        }
1205        comp.parent = null;
1206                if (containerListener != null ||
1207                   (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1208                    Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1209                    ContainerEvent JavaDoc e = new ContainerEvent JavaDoc(this,
1210                                     ContainerEvent.COMPONENT_REMOVED,
1211                                     comp);
1212                    dispatchEvent(e);
1213                }
1214
1215        comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1216                       comp, this,
1217                       HierarchyEvent.PARENT_CHANGED,
1218                                           Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1219        }
1220        if (peer != null && layoutMgr == null && isVisible()) {
1221                updateCursorImmediately();
1222        }
1223        if (valid) {
1224        invalidate();
1225        }
1226    }
1227    }
1228
1229    // Should only be called while holding tree lock
1230
int numListening(long mask) {
1231        int superListening = super.numListening(mask);
1232
1233        if (mask == AWTEvent.HIERARCHY_EVENT_MASK) {
1234        if (dbg.on) {
1235            // Verify listeningChildren is correct
1236
int sum = 0;
1237        for (int i = 0; i < ncomponents; i++) {
1238            sum += component[i].numListening(mask);
1239        }
1240        dbg.assertion(listeningChildren == sum);
1241        }
1242        return listeningChildren + superListening;
1243    } else if (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
1244        if (dbg.on) {
1245            // Verify listeningBoundsChildren is correct
1246
int sum = 0;
1247        for (int i = 0; i < ncomponents; i++) {
1248            sum += component[i].numListening(mask);
1249        }
1250        dbg.assertion(listeningBoundsChildren == sum);
1251        }
1252        return listeningBoundsChildren + superListening;
1253    } else {
1254        if (dbg.on) {
1255            dbg.assertion(false);
1256        }
1257        return superListening;
1258    }
1259    }
1260
1261    // Should only be called while holding tree lock
1262
void adjustListeningChildren(long mask, int num) {
1263        if (dbg.on) {
1264        dbg.assertion(mask == AWTEvent.HIERARCHY_EVENT_MASK ||
1265               mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK ||
1266               mask == (AWTEvent.HIERARCHY_EVENT_MASK |
1267                AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1268    }
1269
1270        if (num == 0)
1271        return;
1272
1273    if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
1274        listeningChildren += num;
1275    }
1276    if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
1277        listeningBoundsChildren += num;
1278    }
1279
1280        adjustListeningChildrenOnParent(mask, num);
1281    }
1282
1283    // Should only be called while holding tree lock
1284
void adjustDescendants(int num) {
1285        if (num == 0)
1286            return;
1287
1288        descendantsCount += num;
1289        adjustDecendantsOnParent(num);
1290    }
1291
1292    // Should only be called while holding tree lock
1293
void adjustDecendantsOnParent(int num) {
1294        if (parent != null) {
1295            parent.adjustDescendants(num);
1296        }
1297    }
1298
1299    // Should only be called while holding tree lock
1300
int countHierarchyMembers() {
1301        if (dbg.on) {
1302            // Verify descendantsCount is correct
1303
int sum = 0;
1304            for (int i = 0; i < ncomponents; i++) {
1305                sum += component[i].countHierarchyMembers();
1306            }
1307            dbg.assertion(descendantsCount == sum);
1308        }
1309        return descendantsCount + 1;
1310    }
1311
1312    private int getListenersCount(int id, boolean enabledOnToolkit) {
1313        assert Thread.holdsLock(getTreeLock());
1314        if (enabledOnToolkit) {
1315            return descendantsCount;
1316        }
1317    switch (id) {
1318      case HierarchyEvent.HIERARCHY_CHANGED:
1319            return listeningChildren;
1320      case HierarchyEvent.ANCESTOR_MOVED:
1321      case HierarchyEvent.ANCESTOR_RESIZED:
1322            return listeningBoundsChildren;
1323      default:
1324            return 0;
1325        }
1326    }
1327
1328    final int createHierarchyEvents(int id, Component JavaDoc changed,
1329        Container JavaDoc changedParent, long changeFlags, boolean enabledOnToolkit)
1330    {
1331        assert Thread.holdsLock(getTreeLock());
1332        int listeners = getListenersCount(id, enabledOnToolkit);
1333
1334        for (int count = listeners, i = 0; count > 0; i++) {
1335        count -= component[i].createHierarchyEvents(id, changed,
1336                changedParent, changeFlags, enabledOnToolkit);
1337    }
1338    return listeners +
1339        super.createHierarchyEvents(id, changed, changedParent,
1340                    changeFlags, enabledOnToolkit);
1341    }
1342
1343    final void createChildHierarchyEvents(int id, long changeFlags,
1344        boolean enabledOnToolkit)
1345    {
1346        assert Thread.holdsLock(getTreeLock());
1347        if (ncomponents == 0) {
1348            return;
1349        }
1350        int listeners = getListenersCount(id, enabledOnToolkit);
1351
1352        for (int count = listeners, i = 0; count > 0; i++) {
1353            count -= component[i].createHierarchyEvents(id, this, parent,
1354                changeFlags, enabledOnToolkit);
1355        }
1356    }
1357
1358    /**
1359     * Gets the layout manager for this container.
1360     * @see #doLayout
1361     * @see #setLayout
1362     */

1363    public LayoutManager JavaDoc getLayout() {
1364    return layoutMgr;
1365    }
1366
1367    /**
1368     * Sets the layout manager for this container.
1369     * @param mgr the specified layout manager
1370     * @see #doLayout
1371     * @see #getLayout
1372     */

1373    public void setLayout(LayoutManager JavaDoc mgr) {
1374    layoutMgr = mgr;
1375    if (valid) {
1376        invalidate();
1377    }
1378    }
1379
1380    /**
1381     * Causes this container to lay out its components. Most programs
1382     * should not call this method directly, but should invoke
1383     * the <code>validate</code> method instead.
1384     * @see LayoutManager#layoutContainer
1385     * @see #setLayout
1386     * @see #validate
1387     * @since JDK1.1
1388     */

1389    public void doLayout() {
1390    layout();
1391    }
1392
1393    /**
1394     * @deprecated As of JDK version 1.1,
1395     * replaced by <code>doLayout()</code>.
1396     */

1397    @Deprecated JavaDoc
1398    public void layout() {
1399    LayoutManager JavaDoc layoutMgr = this.layoutMgr;
1400    if (layoutMgr != null) {
1401        layoutMgr.layoutContainer(this);
1402    }
1403    }
1404
1405    /**
1406     * Invalidates the container. The container and all parents
1407     * above it are marked as needing to be laid out. This method can
1408     * be called often, so it needs to execute quickly.
1409     * @see #validate
1410     * @see #layout
1411     * @see LayoutManager
1412     */

1413    public void invalidate() {
1414        LayoutManager JavaDoc layoutMgr = this.layoutMgr;
1415    if (layoutMgr instanceof LayoutManager2 JavaDoc) {
1416        LayoutManager2 JavaDoc lm = (LayoutManager2 JavaDoc) layoutMgr;
1417        lm.invalidateLayout(this);
1418    }
1419    super.invalidate();
1420    }
1421
1422    /**
1423     * Validates this container and all of its subcomponents.
1424     * <p>
1425     * The <code>validate</code> method is used to cause a container
1426     * to lay out its subcomponents again. It should be invoked when
1427     * this container's subcomponents are modified (added to or
1428     * removed from the container, or layout-related information
1429     * changed) after the container has been displayed.
1430     *
1431     * @see #add(java.awt.Component)
1432     * @see Component#invalidate
1433     * @see javax.swing.JComponent#revalidate()
1434     */

1435    public void validate() {
1436        /* Avoid grabbing lock unless really necessary. */
1437    if (!valid) {
1438        boolean updateCur = false;
1439        synchronized (getTreeLock()) {
1440        if (!valid && peer != null) {
1441            ContainerPeer p = null;
1442            if (peer instanceof ContainerPeer) {
1443            p = (ContainerPeer) peer;
1444            }
1445            if (p != null) {
1446            p.beginValidate();
1447            }
1448            validateTree();
1449            valid = true;
1450            if (p != null) {
1451            p.endValidate();
1452            updateCur = isVisible();
1453            }
1454        }
1455        }
1456        if (updateCur) {
1457                updateCursorImmediately();
1458        }
1459    }
1460    }
1461
1462    /**
1463     * Recursively descends the container tree and recomputes the
1464     * layout for any subtrees marked as needing it (those marked as
1465     * invalid). Synchronization should be provided by the method
1466     * that calls this one: <code>validate</code>.
1467     */

1468    protected void validateTree() {
1469    if (!valid) {
1470        if (peer instanceof ContainerPeer) {
1471        ((ContainerPeer)peer).beginLayout();
1472        }
1473        doLayout();
1474            Component JavaDoc component[] = this.component;
1475        for (int i = 0 ; i < ncomponents ; ++i) {
1476        Component JavaDoc comp = component[i];
1477        if ( (comp instanceof Container JavaDoc)
1478                && !(comp instanceof Window JavaDoc)
1479            && !comp.valid) {
1480            ((Container JavaDoc)comp).validateTree();
1481        } else {
1482            comp.validate();
1483        }
1484        }
1485        if (peer instanceof ContainerPeer) {
1486        ((ContainerPeer)peer).endLayout();
1487        }
1488    }
1489    valid = true;
1490    }
1491
1492    /**
1493     * Recursively descends the container tree and invalidates all
1494     * contained components.
1495     */

1496    void invalidateTree() {
1497        synchronized (getTreeLock()) {
1498        for (int i = 0; i < ncomponents; ++i) {
1499            Component JavaDoc comp = component[i];
1500        if (comp instanceof Container JavaDoc) {
1501            ((Container JavaDoc)comp).invalidateTree();
1502        }
1503        else {
1504            if (comp.valid) {
1505                comp.invalidate();
1506            }
1507        }
1508        }
1509        if (valid) {
1510            invalidate();
1511        }
1512    }
1513    }
1514
1515    /**
1516     * Sets the font of this container.
1517     * @param f The font to become this container's font.
1518     * @see Component#getFont
1519     * @since JDK1.0
1520     */

1521    public void setFont(Font JavaDoc f) {
1522        boolean shouldinvalidate = false;
1523
1524    Font JavaDoc oldfont = getFont();
1525    super.setFont(f);
1526    Font JavaDoc newfont = getFont();
1527    if (newfont != oldfont && (oldfont == null ||
1528                   !oldfont.equals(newfont))) {
1529        invalidateTree();
1530    }
1531    }
1532
1533    /**
1534     * Returns the preferred size of this container.
1535     * @return an instance of <code>Dimension</code> that represents
1536     * the preferred size of this container.
1537     * @see #getMinimumSize
1538     * @see #getLayout
1539     * @see LayoutManager#preferredLayoutSize(Container)
1540     * @see Component#getPreferredSize
1541     */

1542    public Dimension JavaDoc getPreferredSize() {
1543    return preferredSize();
1544    }
1545
1546    /**
1547     * @deprecated As of JDK version 1.1,
1548     * replaced by <code>getPreferredSize()</code>.
1549     */

1550    @Deprecated JavaDoc
1551    public Dimension JavaDoc preferredSize() {
1552    /* Avoid grabbing the lock if a reasonable cached size value
1553     * is available.
1554     */

1555        Dimension JavaDoc dim = prefSize;
1556        if (dim == null || !(isPreferredSizeSet() || isValid())) {
1557        synchronized (getTreeLock()) {
1558        prefSize = (layoutMgr != null) ?
1559            layoutMgr.preferredLayoutSize(this) :
1560            super.preferredSize();
1561                dim = prefSize;
1562            }
1563    }
1564        if (dim != null){
1565            return new Dimension JavaDoc(dim);
1566        }
1567        else{
1568            return dim;
1569        }
1570    }
1571
1572    /**
1573     * Returns the minimum size of this container.
1574     * @return an instance of <code>Dimension</code> that represents
1575     * the minimum size of this container.
1576     * @see #getPreferredSize
1577     * @see #getLayout
1578     * @see LayoutManager#minimumLayoutSize(Container)
1579     * @see Component#getMinimumSize
1580     * @since JDK1.1
1581     */

1582    public Dimension JavaDoc getMinimumSize() {
1583    return minimumSize();
1584    }
1585
1586    /**
1587     * @deprecated As of JDK version 1.1,
1588     * replaced by <code>getMinimumSize()</code>.
1589     */

1590    @Deprecated JavaDoc
1591    public Dimension JavaDoc minimumSize() {
1592    /* Avoid grabbing the lock if a reasonable cached size value
1593     * is available.
1594     */

1595        Dimension JavaDoc dim = minSize;
1596        if (dim == null || !(isMinimumSizeSet() || isValid())) {
1597        synchronized (getTreeLock()) {
1598        minSize = (layoutMgr != null) ?
1599            layoutMgr.minimumLayoutSize(this) :
1600            super.minimumSize();
1601                dim = minSize;
1602        }
1603    }
1604        if (dim != null){
1605            return new Dimension JavaDoc(dim);
1606        }
1607        else{
1608            return dim;
1609        }
1610    }
1611
1612    /**
1613     * Returns the maximum size of this container.
1614     * @see #getPreferredSize
1615     */

1616    public Dimension JavaDoc getMaximumSize() {
1617    /* Avoid grabbing the lock if a reasonable cached size value
1618     * is available.
1619     */

1620        Dimension JavaDoc dim = maxSize;
1621        if (dim == null || !(isMaximumSizeSet() || isValid())) {
1622        synchronized (getTreeLock()) {
1623               if (layoutMgr instanceof LayoutManager2 JavaDoc) {
1624                    LayoutManager2 JavaDoc lm = (LayoutManager2 JavaDoc) layoutMgr;
1625                    maxSize = lm.maximumLayoutSize(this);
1626               } else {
1627                    maxSize = super.getMaximumSize();
1628               }
1629               dim = maxSize;
1630            }
1631    }
1632        if (dim != null){
1633            return new Dimension JavaDoc(dim);
1634        }
1635        else{
1636            return dim;
1637        }
1638    }
1639
1640    /**
1641     * Returns the alignment along the x axis. This specifies how
1642     * the component would like to be aligned relative to other
1643     * components. The value should be a number between 0 and 1
1644     * where 0 represents alignment along the origin, 1 is aligned
1645     * the furthest away from the origin, 0.5 is centered, etc.
1646     */

1647    public float getAlignmentX() {
1648    float xAlign;
1649    if (layoutMgr instanceof LayoutManager2 JavaDoc) {
1650        synchronized (getTreeLock()) {
1651        LayoutManager2 JavaDoc lm = (LayoutManager2 JavaDoc) layoutMgr;
1652        xAlign = lm.getLayoutAlignmentX(this);
1653        }
1654    } else {
1655        xAlign = super.getAlignmentX();
1656    }
1657    return xAlign;
1658    }
1659
1660    /**
1661     * Returns the alignment along the y axis. This specifies how
1662     * the component would like to be aligned relative to other
1663     * components. The value should be a number between 0 and 1
1664     * where 0 represents alignment along the origin, 1 is aligned
1665     * the furthest away from the origin, 0.5 is centered, etc.
1666     */

1667    public float getAlignmentY() {
1668    float yAlign;
1669    if (layoutMgr instanceof LayoutManager2 JavaDoc) {
1670        synchronized (getTreeLock()) {
1671        LayoutManager2 JavaDoc lm = (LayoutManager2 JavaDoc) layoutMgr;
1672        yAlign = lm.getLayoutAlignmentY(this);
1673        }
1674    } else {
1675        yAlign = super.getAlignmentY();
1676    }
1677    return yAlign;
1678    }
1679
1680    /**
1681     * Paints the container. This forwards the paint to any lightweight
1682     * components that are children of this container. If this method is
1683     * reimplemented, super.paint(g) should be called so that lightweight
1684     * components are properly rendered. If a child component is entirely
1685     * clipped by the current clipping setting in g, paint() will not be
1686     * forwarded to that child.
1687     *
1688     * @param g the specified Graphics window
1689     * @see Component#update(Graphics)
1690     */

1691    public void paint(Graphics JavaDoc g) {
1692    if (isShowing()) {
1693        if (printing) {
1694            synchronized (this) {
1695            if (printing) {
1696                if (printingThreads.contains(Thread.currentThread())) {
1697                return;
1698            }
1699            }
1700        }
1701        }
1702
1703        // The container is showing on screen and
1704
// this paint() is not called from print().
1705
// Paint self and forward the paint to lightweight subcomponents.
1706

1707        // super.paint(); -- Don't bother, since it's a NOP.
1708

1709        GraphicsCallback.PaintCallback.getInstance().
1710            runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
1711    }
1712    }
1713
1714    /**
1715     * Updates the container. This forwards the update to any lightweight
1716     * components that are children of this container. If this method is
1717     * reimplemented, super.update(g) should be called so that lightweight
1718     * components are properly rendered. If a child component is entirely
1719     * clipped by the current clipping setting in g, update() will not be
1720     * forwarded to that child.
1721     *
1722     * @param g the specified Graphics window
1723     * @see Component#update(Graphics)
1724     */

1725    public void update(Graphics JavaDoc g) {
1726        if (isShowing()) {
1727            if (! (peer instanceof LightweightPeer)) {
1728                g.clearRect(0, 0, width, height);
1729            }
1730            paint(g);
1731        }
1732    }
1733
1734    /**
1735     * Prints the container. This forwards the print to any lightweight
1736     * components that are children of this container. If this method is
1737     * reimplemented, super.print(g) should be called so that lightweight
1738     * components are properly rendered. If a child component is entirely
1739     * clipped by the current clipping setting in g, print() will not be
1740     * forwarded to that child.
1741     *
1742     * @param g the specified Graphics window
1743     * @see Component#update(Graphics)
1744     */

1745    public void print(Graphics JavaDoc g) {
1746        if (isShowing()) {
1747        Thread JavaDoc t = Thread.currentThread();
1748        try {
1749            synchronized (this) {
1750            if (printingThreads == null) {
1751                printingThreads = new HashSet JavaDoc();
1752            }
1753            printingThreads.add(t);
1754            printing = true;
1755        }
1756        super.print(g); // By default, Component.print() calls paint()
1757
} finally {
1758            synchronized (this) {
1759            printingThreads.remove(t);
1760            printing = !printingThreads.isEmpty();
1761        }
1762        }
1763
1764        GraphicsCallback.PrintCallback.getInstance().
1765            runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
1766    }
1767    }
1768
1769    /**
1770     * Paints each of the components in this container.
1771     * @param g the graphics context.
1772     * @see Component#paint
1773     * @see Component#paintAll
1774     */

1775    public void paintComponents(Graphics JavaDoc g) {
1776        if (isShowing()) {
1777        GraphicsCallback.PaintAllCallback.getInstance().
1778            runComponents(component, g, GraphicsCallback.TWO_PASSES);
1779    }
1780    }
1781
1782    /**
1783     * Simulates the peer callbacks into java.awt for printing of
1784     * lightweight Containers.
1785     * @param g the graphics context to use for printing.
1786     * @see Component#printAll
1787     * @see #printComponents
1788     */

1789    void lightweightPaint(Graphics JavaDoc g) {
1790        super.lightweightPaint(g);
1791        paintHeavyweightComponents(g);
1792    }
1793
1794    /**
1795     * Prints all the heavyweight subcomponents.
1796     */

1797    void paintHeavyweightComponents(Graphics JavaDoc g) {
1798        if (isShowing()) {
1799        GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
1800            runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
1801                                            GraphicsCallback.HEAVYWEIGHTS);
1802    }
1803    }
1804
1805    /**
1806     * Prints each of the components in this container.
1807     * @param g the graphics context.
1808     * @see Component#print
1809     * @see Component#printAll
1810     */

1811    public void printComponents(Graphics JavaDoc g) {
1812        if (isShowing()) {
1813        GraphicsCallback.PrintAllCallback.getInstance().
1814            runComponents(component, g, GraphicsCallback.TWO_PASSES);
1815    }
1816    }
1817
1818    /**
1819     * Simulates the peer callbacks into java.awt for printing of
1820     * lightweight Containers.
1821     * @param g the graphics context to use for printing.
1822     * @see Component#printAll
1823     * @see #printComponents
1824     */

1825    void lightweightPrint(Graphics JavaDoc g) {
1826        super.lightweightPrint(g);
1827        printHeavyweightComponents(g);
1828    }
1829
1830    /**
1831     * Prints all the heavyweight subcomponents.
1832     */

1833    void printHeavyweightComponents(Graphics JavaDoc g) {
1834        if (isShowing()) {
1835        GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
1836            runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS |
1837                                            GraphicsCallback.HEAVYWEIGHTS);
1838    }
1839    }
1840
1841    /**
1842     * Adds the specified container listener to receive container events
1843     * from this container.
1844     * If l is null, no exception is thrown and no action is performed.
1845     *
1846     * @param l the container listener
1847     *
1848     * @see #removeContainerListener
1849     * @see #getContainerListeners
1850     */

1851    public synchronized void addContainerListener(ContainerListener JavaDoc l) {
1852    if (l == null) {
1853        return;
1854    }
1855    containerListener = AWTEventMulticaster.add(containerListener, l);
1856        newEventsOnly = true;
1857    }
1858
1859    /**
1860     * Removes the specified container listener so it no longer receives
1861     * container events from this container.
1862     * If l is null, no exception is thrown and no action is performed.
1863     *
1864     * @param l the container listener
1865     *
1866     * @see #addContainerListener
1867     * @see #getContainerListeners
1868     */

1869    public synchronized void removeContainerListener(ContainerListener JavaDoc l) {
1870    if (l == null) {
1871        return;
1872    }
1873    containerListener = AWTEventMulticaster.remove(containerListener, l);
1874    }
1875
1876    /**
1877     * Returns an array of all the container listeners
1878     * registered on this container.
1879     *
1880     * @return all of this container's <code>ContainerListener</code>s
1881     * or an empty array if no container
1882     * listeners are currently registered
1883     *
1884     * @see #addContainerListener
1885     * @see #removeContainerListener
1886     * @since 1.4
1887     */

1888    public synchronized ContainerListener JavaDoc[] getContainerListeners() {
1889        return (ContainerListener JavaDoc[]) (getListeners(ContainerListener JavaDoc.class));
1890    }
1891
1892    /**
1893     * Returns an array of all the objects currently registered
1894     * as <code><em>Foo</em>Listener</code>s
1895     * upon this <code>Container</code>.
1896     * <code><em>Foo</em>Listener</code>s are registered using the
1897     * <code>add<em>Foo</em>Listener</code> method.
1898     *
1899     * <p>
1900     * You can specify the <code>listenerType</code> argument
1901     * with a class literal, such as
1902     * <code><em>Foo</em>Listener.class</code>.
1903     * For example, you can query a
1904     * <code>Container</code> <code>c</code>
1905     * for its container listeners with the following code:
1906     *
1907     * <pre>ContainerListener[] cls = (ContainerListener[])(c.getListeners(ContainerListener.class));</pre>
1908     *
1909     * If no such listeners exist, this method returns an empty array.
1910     *
1911     * @param listenerType the type of listeners requested; this parameter
1912     * should specify an interface that descends from
1913     * <code>java.util.EventListener</code>
1914     * @return an array of all objects registered as
1915     * <code><em>Foo</em>Listener</code>s on this container,
1916     * or an empty array if no such listeners have been added
1917     * @exception ClassCastException if <code>listenerType</code>
1918     * doesn't specify a class or interface that implements
1919     * <code>java.util.EventListener</code>
1920     *
1921     * @see #getContainerListeners
1922     *
1923     * @since 1.3
1924     */

1925    public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
1926    EventListener JavaDoc l = null;
1927    if (listenerType == ContainerListener JavaDoc.class) {
1928        l = containerListener;
1929    } else {
1930        return super.getListeners(listenerType);
1931    }
1932    return AWTEventMulticaster.getListeners(l, listenerType);
1933    }
1934
1935    // REMIND: remove when filtering is done at lower level
1936
boolean eventEnabled(AWTEvent JavaDoc e) {
1937        int id = e.getID();
1938
1939        if (id == ContainerEvent.COMPONENT_ADDED ||
1940            id == ContainerEvent.COMPONENT_REMOVED) {
1941            if ((eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1942                containerListener != null) {
1943                return true;
1944            }
1945            return false;
1946        }
1947        return super.eventEnabled(e);
1948    }
1949
1950    /**
1951     * Processes events on this container. If the event is a
1952     * <code>ContainerEvent</code>, it invokes the
1953     * <code>processContainerEvent</code> method, else it invokes
1954     * its superclass's <code>processEvent</code>.
1955     * <p>Note that if the event parameter is <code>null</code>
1956     * the behavior is unspecified and may result in an
1957     * exception.
1958     *
1959     * @param e the event
1960     */

1961    protected void processEvent(AWTEvent JavaDoc e) {
1962        if (e instanceof ContainerEvent JavaDoc) {
1963            processContainerEvent((ContainerEvent JavaDoc)e);
1964            return;
1965        }
1966    super.processEvent(e);
1967    }
1968
1969    /**
1970     * Processes container events occurring on this container by
1971     * dispatching them to any registered ContainerListener objects.
1972     * NOTE: This method will not be called unless container events
1973     * are enabled for this component; this happens when one of the
1974     * following occurs:
1975     * <ul>
1976     * <li>A ContainerListener object is registered via
1977     * <code>addContainerListener</code>
1978     * <li>Container events are enabled via <code>enableEvents</code>
1979     * </ul>
1980     * <p>Note that if the event parameter is <code>null</code>
1981     * the behavior is unspecified and may result in an
1982     * exception.
1983     *
1984     * @param e the container event
1985     * @see Component#enableEvents
1986     */

1987    protected void processContainerEvent(ContainerEvent JavaDoc e) {
1988        ContainerListener JavaDoc listener = containerListener;
1989        if (listener != null) {
1990            switch(e.getID()) {
1991              case ContainerEvent.COMPONENT_ADDED:
1992                listener.componentAdded(e);
1993                break;
1994              case ContainerEvent.COMPONENT_REMOVED:
1995                listener.componentRemoved(e);
1996                break;
1997            }
1998        }
1999    }
2000
2001    /*
2002     * Dispatches an event to this component or one of its sub components.
2003     * Create ANCESTOR_RESIZED and ANCESTOR_MOVED events in response to
2004     * COMPONENT_RESIZED and COMPONENT_MOVED events. We have to do this
2005     * here instead of in processComponentEvent because ComponentEvents
2006     * may not be enabled for this Container.
2007     * @param e the event
2008     */

2009    void dispatchEventImpl(AWTEvent JavaDoc e) {
2010        if ((dispatcher != null) && dispatcher.dispatchEvent(e)) {
2011            // event was sent to a lightweight component. The
2012
// native-produced event sent to the native container
2013
// must be properly disposed of by the peer, so it
2014
// gets forwarded. If the native host has been removed
2015
// as a result of the sending the lightweight event,
2016
// the peer reference will be null.
2017
e.consume();
2018            if (peer != null) {
2019                peer.handleEvent(e);
2020            }
2021            return;
2022        }
2023
2024        super.dispatchEventImpl(e);
2025 
2026        synchronized (getTreeLock()) {
2027            switch (e.getID()) {
2028              case ComponentEvent.COMPONENT_RESIZED:
2029                createChildHierarchyEvents(HierarchyEvent.ANCESTOR_RESIZED, 0,
2030                                           Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2031                break;
2032              case ComponentEvent.COMPONENT_MOVED:
2033                createChildHierarchyEvents(HierarchyEvent.ANCESTOR_MOVED, 0,
2034                                       Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2035                break;
2036              default:
2037                break;
2038            }
2039        }
2040    }
2041
2042    /*
2043     * Dispatches an event to this component, without trying to forward
2044     * it to any subcomponents
2045     * @param e the event
2046     */

2047    void dispatchEventToSelf(AWTEvent JavaDoc e) {
2048    super.dispatchEventImpl(e);
2049    }
2050
2051    /**
2052     * Fetchs the top-most (deepest) lightweight component that is interested
2053     * in receiving mouse events.
2054     */

2055    Component JavaDoc getMouseEventTarget(int x, int y, boolean includeSelf) {
2056        return getMouseEventTarget(x, y, includeSelf,
2057                                   MouseEventTargetFilter.FILTER,
2058                                   !SEARCH_HEAVYWEIGHTS);
2059    }
2060
2061    /**
2062     * Fetches the top-most (deepest) component to receive SunDropTargetEvents.
2063     */

2064    Component JavaDoc getDropTargetEventTarget(int x, int y, boolean includeSelf) {
2065        return getMouseEventTarget(x, y, includeSelf,
2066                                   DropTargetEventTargetFilter.FILTER,
2067                                   SEARCH_HEAVYWEIGHTS);
2068    }
2069
2070    /**
2071     * A private version of getMouseEventTarget which has two additional
2072     * controllable behaviors. This method searches for the top-most
2073     * descendant of this container that contains the given coordinates
2074     * and is accepted by the given filter. The search will be constrained to
2075     * lightweight descendants if the last argument is <code>false</code>.
2076     *
2077     * @param filter EventTargetFilter instance to determine whether the
2078     * given component is a valid target for this event.
2079     * @param searchHeavyweights if <code>false</false>, the method
2080     * will bypass heavyweight components during the search.
2081     */

2082    private Component JavaDoc getMouseEventTarget(int x, int y, boolean includeSelf,
2083                                          EventTargetFilter filter,
2084                                          boolean searchHeavyweights) {
2085        Component JavaDoc comp = null;
2086        if (searchHeavyweights) {
2087            comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2088                                           SEARCH_HEAVYWEIGHTS,
2089                                           searchHeavyweights);
2090        }
2091        
2092        if (comp == null || comp == this) {
2093            comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2094                                           !SEARCH_HEAVYWEIGHTS,
2095                                           searchHeavyweights);
2096        }
2097
2098        return comp;
2099    }
2100
2101    /**
2102     * A private version of getMouseEventTarget which has three additional
2103     * controllable behaviors. This method searches for the top-most
2104     * descendant of this container that contains the given coordinates
2105     * and is accepted by the given filter. The search will be constrained to
2106     * descendants of only lightweight children or only heavyweight children
2107     * of this container depending on searchHeavyweightChildren. The search will
2108     * be constrained to only lightweight descendants of the searched children
2109     * of this container if searchHeavyweightDescendants is <code>false</code>.
2110     *
2111     * @param filter EventTargetFilter instance to determine whether the
2112     * selected component is a valid target for this event.
2113     * @param searchHeavyweightChildren if <code>true</false>, the method
2114     * will bypass immediate lightweight children during the search.
2115     * If <code>false</code>, the methods will bypass immediate
2116     * heavyweight children during the search.
2117     * @param searchHeavyweightDescendants if <code>false</false>, the method
2118     * will bypass heavyweight descendants which are not immediate
2119     * children during the search. If <code>true</code>, the method
2120     * will traverse both lightweight and heavyweight descendants during
2121     * the search.
2122     */

2123    private Component JavaDoc getMouseEventTargetImpl(int x, int y, boolean includeSelf,
2124                                         EventTargetFilter filter,
2125                                         boolean searchHeavyweightChildren,
2126                                         boolean searchHeavyweightDescendants) {
2127        int ncomponents = this.ncomponents;
2128        Component JavaDoc component[] = this.component;
2129
2130        for (int i = 0 ; i < ncomponents ; i++) {
2131            Component JavaDoc comp = component[i];
2132            if (comp != null && comp.visible &&
2133                ((!searchHeavyweightChildren &&
2134                  comp.peer instanceof LightweightPeer) ||
2135                 (searchHeavyweightChildren &&
2136                  !(comp.peer instanceof LightweightPeer))) &&
2137                comp.contains(x - comp.x, y - comp.y)) {
2138
2139                // found a component that intersects the point, see if there is
2140
// a deeper possibility.
2141
if (comp instanceof Container JavaDoc) {
2142                    Container JavaDoc child = (Container JavaDoc) comp;
2143            Component JavaDoc deeper = child.getMouseEventTarget(x - child.x,
2144                                                                 y - child.y,
2145                                                                 includeSelf,
2146                                                                 filter,
2147                                                                 searchHeavyweightDescendants);
2148                    if (deeper != null) {
2149                        return deeper;
2150                    }
2151                } else {
2152                    if (filter.accept(comp)) {
2153                        // there isn't a deeper target, but this component is a
2154
// target
2155
return comp;
2156                    }
2157                }
2158            }
2159        }
2160    
2161        boolean isPeerOK;
2162        boolean isMouseOverMe;
2163    
2164        isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
2165        isMouseOverMe = contains(x,y);
2166
2167        // didn't find a child target, return this component if it's a possible
2168
// target
2169
if (isMouseOverMe && isPeerOK && filter.accept(this)) {
2170            return this;
2171        }
2172        // no possible target
2173
return null;
2174    }
2175
2176    static interface EventTargetFilter {
2177        boolean accept(final Component JavaDoc comp);
2178    }
2179
2180    static class MouseEventTargetFilter implements EventTargetFilter {
2181        static final EventTargetFilter FILTER = new MouseEventTargetFilter();
2182        
2183        private MouseEventTargetFilter() {}
2184
2185        public boolean accept(final Component JavaDoc comp) {
2186            return (comp.eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
2187                || (comp.eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
2188                || (comp.eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0
2189                || comp.mouseListener != null
2190                || comp.mouseMotionListener != null
2191                || comp.mouseWheelListener != null;
2192        }
2193    }
2194
2195    static class DropTargetEventTargetFilter implements EventTargetFilter {
2196        static final EventTargetFilter FILTER = new DropTargetEventTargetFilter();
2197        
2198        private DropTargetEventTargetFilter() {}
2199
2200        public boolean accept(final Component JavaDoc comp) {
2201            DropTarget JavaDoc dt = comp.getDropTarget();
2202            return dt != null && dt.isActive();
2203        }
2204    }
2205
2206    /**
2207     * This is called by lightweight components that want the containing
2208     * windowed parent to enable some kind of events on their behalf.
2209     * This is needed for events that are normally only dispatched to
2210     * windows to be accepted so that they can be forwarded downward to
2211     * the lightweight component that has enabled them.
2212     */

2213    void proxyEnableEvents(long events) {
2214    if (peer instanceof LightweightPeer) {
2215        // this container is lightweight.... continue sending it
2216
// upward.
2217
if (parent != null) {
2218        parent.proxyEnableEvents(events);
2219        }
2220    } else {
2221        // This is a native container, so it needs to host
2222
// one of it's children. If this function is called before
2223
// a peer has been created we don't yet have a dispatcher
2224
// because it has not yet been determined if this instance
2225
// is lightweight.
2226
if (dispatcher != null) {
2227        dispatcher.enableEvents(events);
2228        }
2229    }
2230    }
2231
2232    /**
2233     * @deprecated As of JDK version 1.1,
2234     * replaced by <code>dispatchEvent(AWTEvent e)</code>
2235     */

2236    @Deprecated JavaDoc
2237    public void deliverEvent(Event JavaDoc e) {
2238    Component JavaDoc comp = getComponentAt(e.x, e.y);
2239    if ((comp != null) && (comp != this)) {
2240        e.translate(-comp.x, -comp.y);
2241        comp.deliverEvent(e);
2242    } else {
2243        postEvent(e);
2244    }
2245    }
2246
2247    /**
2248     * Locates the component that contains the x,y position. The
2249     * top-most child component is returned in the case where there
2250     * is overlap in the components. This is determined by finding
2251     * the component closest to the index 0 that claims to contain
2252     * the given point via Component.contains(), except that Components
2253     * which have native peers take precedence over those which do not
2254     * (i.e., lightweight Components).
2255     *
2256     * @param x the <i>x</i> coordinate
2257     * @param y the <i>y</i> coordinate
2258     * @return null if the component does not contain the position.
2259     * If there is no child component at the requested point and the
2260     * point is within the bounds of the container the container itself
2261     * is returned; otherwise the top-most child is returned.
2262     * @see Component#contains
2263     * @since JDK1.1
2264     */

2265    public Component JavaDoc getComponentAt(int x, int y) {
2266        return locate(x, y);
2267    }
2268
2269    /**
2270     * @deprecated As of JDK version 1.1,
2271     * replaced by <code>getComponentAt(int, int)</code>.
2272     */

2273    @Deprecated JavaDoc
2274    public Component JavaDoc locate(int x, int y) {
2275    if (!contains(x, y)) {
2276        return null;
2277    }
2278    synchronized (getTreeLock()) {
2279        // Two passes: see comment in sun.awt.SunGraphicsCallback
2280
for (int i = 0 ; i < ncomponents ; i++) {
2281            Component JavaDoc comp = component[i];
2282        if (comp != null &&
2283            !(comp.peer instanceof LightweightPeer)) {
2284            if (comp.contains(x - comp.x, y - comp.y)) {
2285                return comp;
2286            }
2287        }
2288        }
2289        for (int i = 0 ; i < ncomponents ; i++) {
2290            Component JavaDoc comp = component[i];
2291        if (comp != null &&
2292            comp.peer instanceof LightweightPeer) {
2293            if (comp.contains(x - comp.x, y - comp.y)) {
2294                return comp;
2295            }
2296        }
2297        }
2298    }
2299    return this;
2300    }
2301
2302    /**
2303     * Gets the component that contains the specified point.
2304     * @param p the point.
2305     * @return returns the component that contains the point,
2306     * or <code>null</code> if the component does
2307     * not contain the point.
2308     * @see Component#contains
2309     * @since JDK1.1
2310     */

2311    public Component JavaDoc getComponentAt(Point JavaDoc p) {
2312    return getComponentAt(p.x, p.y);
2313    }
2314
2315    /**
2316     * Returns the position of the mouse pointer in this <code>Container</code>'s
2317     * coordinate space if the <code>Container</code> is under the mouse pointer,
2318     * otherwise returns <code>null</code>.
2319     * This method is similar to {@link Component#getMousePosition()} with the exception
2320     * that it can take the <code>Container</code>'s children into account.
2321     * If <code>allowChildren</code> is <code>false</code>, this method will return
2322     * a non-null value only if the mouse pointer is above the <code>Container</code>
2323     * directly, not above the part obscured by children.
2324     * If <code>allowChildren</code> is <code>true</code>, this method returns
2325     * a non-null value if the mouse pointer is above <code>Container</code> or any
2326     * of its descendants.
2327     *
2328     * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2329     * @param allowChildren true if children should be taken into account
2330     * @see Component#getMousePosition
2331     * @return mouse coordinates relative to this <code>Component</code>, or null
2332     * @since 1.5
2333     */

2334    public Point JavaDoc getMousePosition(boolean allowChildren) throws HeadlessException JavaDoc {
2335        if (GraphicsEnvironment.isHeadless()) {
2336            throw new HeadlessException JavaDoc();
2337        }
2338        PointerInfo JavaDoc pi = (PointerInfo JavaDoc)java.security.AccessController.doPrivileged(
2339            new java.security.PrivilegedAction JavaDoc() {
2340                public Object JavaDoc run() {
2341                    return MouseInfo.getPointerInfo();
2342                }
2343            }
2344        );
2345        synchronized (getTreeLock()) {
2346            Component JavaDoc inTheSameWindow = findUnderMouseInWindow(pi);
2347            if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) {
2348                return pointRelativeToComponent(pi.getLocation());
2349            }
2350            return null;
2351        }
2352    }
2353
2354    boolean isSameOrAncestorOf(Component JavaDoc comp, boolean allowChildren) {
2355        return this == comp || (allowChildren && isParentOf(comp));
2356    }
2357
2358    /**
2359     * Locates the visible child component that contains the specified
2360     * position. The top-most child component is returned in the case
2361     * where there is overlap in the components. If the containing child
2362     * component is a Container, this method will continue searching for
2363     * the deepest nested child component. Components which are not
2364     * visible are ignored during the search.<p>
2365     *
2366     * The findComponentAt method is different from getComponentAt in
2367     * that getComponentAt only searches the Container's immediate
2368     * children; if the containing component is a Container,
2369     * findComponentAt will search that child to find a nested component.
2370     *
2371     * @param x the <i>x</i> coordinate
2372     * @param y the <i>y</i> coordinate
2373     * @return null if the component does not contain the position.
2374     * If there is no child component at the requested point and the
2375     * point is within the bounds of the container the container itself
2376     * is returned.
2377     * @see Component#contains
2378     * @see #getComponentAt
2379     * @since 1.2
2380     */

2381    public Component JavaDoc findComponentAt(int x, int y) {
2382    synchronized (getTreeLock()) {
2383            return findComponentAt(x, y, true);
2384    }
2385    }
2386
2387    /**
2388     * Private version of findComponentAt which has a controllable
2389     * behavior. Setting 'ignoreEnabled' to 'false' bypasses disabled
2390     * Components during the search. This behavior is used by the
2391     * lightweight cursor support in sun.awt.GlobalCursorManager.
2392     * The cursor code calls this function directly via native code.
2393     *
2394     * The addition of this feature is temporary, pending the
2395     * adoption of new, public API which exports this feature.
2396     */

2397    final Component JavaDoc findComponentAt(int x, int y, boolean ignoreEnabled)
2398    {
2399        if (isRecursivelyVisible()){
2400            return findComponentAtImpl(x, y, ignoreEnabled);
2401        }
2402        return null;
2403    }
2404    
2405    final Component JavaDoc findComponentAtImpl(int x, int y, boolean ignoreEnabled){
2406        if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
2407        return null;
2408    }
2409    int ncomponents = this.ncomponents;
2410    Component JavaDoc component[] = this.component;
2411
2412    // Two passes: see comment in sun.awt.SunGraphicsCallback
2413
for (int i = 0 ; i < ncomponents ; i++) {
2414        Component JavaDoc comp = component[i];
2415            if (comp != null &&
2416        !(comp.peer instanceof LightweightPeer)) {
2417        if (comp instanceof Container JavaDoc) {
2418            comp = ((Container JavaDoc)comp).findComponentAtImpl(x - comp.x,
2419                                 y - comp.y,
2420                                                             ignoreEnabled);
2421        } else {
2422            comp = comp.locate(x - comp.x, y - comp.y);
2423        }
2424        if (comp != null && comp.visible &&
2425            (ignoreEnabled || comp.enabled))
2426        {
2427            return comp;
2428        }
2429        }
2430    }
2431    for (int i = 0 ; i < ncomponents ; i++) {
2432        Component JavaDoc comp = component[i];
2433            if (comp != null &&
2434        comp.peer instanceof LightweightPeer) {
2435        if (comp instanceof Container JavaDoc) {
2436            comp = ((Container JavaDoc)comp).findComponentAtImpl(x - comp.x,
2437                                 y - comp.y,
2438                                                             ignoreEnabled);
2439        } else {
2440            comp = comp.locate(x - comp.x, y - comp.y);
2441        }
2442        if (comp != null && comp.visible &&
2443            (ignoreEnabled || comp.enabled))
2444        {
2445            return comp;
2446        }
2447        }
2448    }
2449    return this;
2450    }
2451
2452    /**
2453     * Locates the visible child component that contains the specified
2454     * point. The top-most child component is returned in the case
2455     * where there is overlap in the components. If the containing child
2456     * component is a Container, this method will continue searching for
2457     * the deepest nested child component. Components which are not
2458     * visible are ignored during the search.<p>
2459     *
2460     * The findComponentAt method is different from getComponentAt in
2461     * that getComponentAt only searches the Container's immediate
2462     * children; if the containing component is a Container,
2463     * findComponentAt will search that child to find a nested component.
2464     *
2465     * @param p the point.
2466     * @return null if the component does not contain the position.
2467     * If there is no child component at the requested point and the
2468     * point is within the bounds of the container the container itself
2469     * is returned.
2470     * @see Component#contains
2471     * @see #getComponentAt
2472     * @since 1.2
2473     */

2474    public Component JavaDoc findComponentAt(Point JavaDoc p) {
2475        return findComponentAt(p.x, p.y);
2476    }
2477
2478    /**
2479     * Makes this Container displayable by connecting it to
2480     * a native screen resource. Making a container displayable will
2481     * cause all of its children to be made displayable.
2482     * This method is called internally by the toolkit and should
2483     * not be called directly by programs.
2484     * @see Component#isDisplayable
2485     * @see #removeNotify
2486     */

2487    public void addNotify() {
2488        synchronized (getTreeLock()) {
2489        // addNotify() on the children may cause proxy event enabling
2490
// on this instance, so we first call super.addNotify() and
2491
// possibly create an lightweight event dispatcher before calling
2492
// addNotify() on the children which may be lightweight.
2493
super.addNotify();
2494        if (! (peer instanceof LightweightPeer)) {
2495            dispatcher = new LightweightDispatcher(this);
2496        }
2497        int ncomponents = this.ncomponents;
2498            Component JavaDoc component[] = this.component;
2499        for (int i = 0 ; i < ncomponents ; i++) {
2500            component[i].addNotify();
2501        }
2502            // Update stacking order if native platform allows
2503
ContainerPeer cpeer = (ContainerPeer)peer;
2504            if (cpeer.isRestackSupported()) {
2505                cpeer.restack();
2506            }
2507
2508
2509        }
2510    }
2511
2512    /**
2513     * Makes this Container undisplayable by removing its connection
2514     * to its native screen resource. Making a container undisplayable
2515     * will cause all of its children to be made undisplayable.
2516     * This method is called by the toolkit internally and should
2517     * not be called directly by programs.
2518     * @see Component#isDisplayable
2519     * @see #addNotify
2520     */

2521    public void removeNotify() {
2522        synchronized (getTreeLock()) {
2523        int ncomponents = this.ncomponents;
2524            Component JavaDoc component[] = this.component;
2525            for (int i = ncomponents-1 ; i >= 0 ; i--) {
2526                if( component[i] != null )
2527            component[i].removeNotify();
2528        }
2529        if ( dispatcher != null ) {
2530        dispatcher.dispose();
2531        dispatcher = null;
2532        }
2533        super.removeNotify();
2534        }
2535    }
2536
2537    /**
2538     * Checks if the component is contained in the component hierarchy of
2539     * this container.
2540     * @param c the component
2541     * @return <code>true</code> if it is an ancestor;
2542     * <code>false</code> otherwise.
2543     * @since JDK1.1
2544     */

2545    public boolean isAncestorOf(Component JavaDoc c) {
2546    Container JavaDoc p;
2547    if (c == null || ((p = c.getParent()) == null)) {
2548        return false;
2549    }
2550    while (p != null) {
2551        if (p == this) {
2552        return true;
2553        }
2554        p = p.getParent();
2555    }
2556    return false;
2557    }
2558
2559    /*
2560     * The following code was added to support modal JInternalFrames
2561     * Unfortunately this code has to be added here so that we can get access to
2562     * some private AWT classes like SequencedEvent.
2563     *
2564     * The native container of the LW component has this field set
2565     * to tell it that it should block Mouse events for all LW
2566     * children except for the modal component.
2567     *
2568     * In the case of nested Modal components, we store the previous
2569     * modal component in the new modal components value of modalComp;
2570     */

2571
2572    transient Component JavaDoc modalComp;
2573    transient AppContext modalAppContext;
2574
2575    private void startLWModal() {
2576        // Store the app context on which this component is being shown.
2577
// Event dispatch thread of this app context will be sleeping until
2578
// we wake it by any event from hideAndDisposeHandler().
2579
modalAppContext = AppContext.getAppContext();
2580
2581        // keep the KeyEvents from being dispatched
2582
// until the focus has been transfered
2583
long time = Toolkit.getEventQueue().getMostRecentEventTime();
2584        Component JavaDoc predictedFocusOwner = (this instanceof javax.swing.JInternalFrame JavaDoc) ? ((javax.swing.JInternalFrame JavaDoc)(this)).getMostRecentFocusOwner() : null;
2585        if (predictedFocusOwner != null) {
2586            KeyboardFocusManager.getCurrentKeyboardFocusManager().
2587                enqueueKeyEvents(time, predictedFocusOwner);
2588        }
2589        // We have two mechanisms for blocking: 1. If we're on the
2590
// EventDispatchThread, start a new event pump. 2. If we're
2591
// on any other thread, call wait() on the treelock.
2592
final Container JavaDoc nativeContainer;
2593        synchronized (getTreeLock()) {
2594            nativeContainer = getHeavyweightContainer();
2595            if (nativeContainer.modalComp != null) {
2596                this.modalComp = nativeContainer.modalComp;
2597                nativeContainer.modalComp = this;
2598                return;
2599            }
2600            else {
2601                nativeContainer.modalComp = this;
2602            }
2603        }
2604
2605        Runnable JavaDoc pumpEventsForHierarchy = new Runnable JavaDoc() {
2606            public void run() {
2607                EventDispatchThread JavaDoc dispatchThread =
2608                    (EventDispatchThread JavaDoc)Thread.currentThread();
2609                dispatchThread.pumpEventsForHierarchy(
2610                        new Conditional JavaDoc() {
2611                        public boolean evaluate() {
2612                        return ((windowClosingException == null) && (nativeContainer.modalComp != null)) ;
2613                        }
2614                        }, Container.this);
2615            }
2616        };
2617
2618        if (EventQueue.isDispatchThread()) {
2619            SequencedEvent JavaDoc currentSequencedEvent =
2620                KeyboardFocusManager.getCurrentKeyboardFocusManager().
2621                getCurrentSequencedEvent();
2622            if (currentSequencedEvent != null) {
2623                currentSequencedEvent.dispose();
2624            }
2625
2626            pumpEventsForHierarchy.run();
2627        } else {
2628            synchronized (getTreeLock()) {
2629                Toolkit.getEventQueue().
2630                    postEvent(new PeerEvent(this,
2631                                pumpEventsForHierarchy,
2632                                PeerEvent.PRIORITY_EVENT));
2633                while (windowClosingException == null) {
2634                    try {
2635                        getTreeLock().wait();
2636                    } catch (InterruptedException JavaDoc e) {
2637                        break;
2638                    }
2639                }
2640            }
2641        }
2642        if (windowClosingException != null) {
2643            windowClosingException.fillInStackTrace();
2644            throw windowClosingException;
2645        }
2646        if (predictedFocusOwner != null) {
2647            KeyboardFocusManager.getCurrentKeyboardFocusManager().
2648                dequeueKeyEvents(time, predictedFocusOwner);
2649        }
2650    }
2651
2652    private void stopLWModal() {
2653        synchronized (getTreeLock()) {
2654            if (modalAppContext != null) {
2655                Container JavaDoc nativeContainer = getHeavyweightContainer();
2656                if(nativeContainer != null) {
2657                    if (this.modalComp != null) {
2658                        nativeContainer.modalComp = this.modalComp;
2659                        this.modalComp = null;
2660                        return;
2661                    }
2662                    else {
2663                        nativeContainer.modalComp = null;
2664                    }
2665                }
2666                // Wake up event dispatch thread on which the dialog was
2667
// initially shown
2668
SunToolkit.postEvent(modalAppContext,
2669                        new PeerEvent(this,
2670                                new WakingRunnable(),
2671                                PeerEvent.PRIORITY_EVENT));
2672            }
2673            EventQueue.invokeLater(new WakingRunnable());
2674            getTreeLock().notifyAll();
2675        }
2676    }
2677
2678    final static class WakingRunnable implements Runnable JavaDoc {
2679        public void run() {
2680        }
2681    }
2682
2683    /* End of JOptionPane support code */
2684
2685    /**
2686     * Returns a string representing the state of this <code>Container</code>.
2687     * This method is intended to be used only for debugging purposes, and the
2688     * content and format of the returned string may vary between
2689     * implementations. The returned string may be empty but may not be
2690     * <code>null</code>.
2691     *
2692     * @return the parameter string of this container
2693     */

2694    protected String JavaDoc paramString() {
2695    String JavaDoc str = super.paramString();
2696    LayoutManager JavaDoc layoutMgr = this.layoutMgr;
2697    if (layoutMgr != null) {
2698        str += ",layout=" + layoutMgr.getClass().getName();
2699    }
2700    return str;
2701    }
2702
2703    /**
2704     * Prints a listing of this container to the specified output
2705     * stream. The listing starts at the specified indentation.
2706     * <p>
2707     * The immediate children of the container are printed with
2708     * an indentation of <code>indent+1</code>. The children
2709     * of those children are printed at <code>indent+2</code>
2710     * and so on.
2711     *
2712     * @param out a print stream
2713     * @param indent the number of spaces to indent
2714     * @see Component#list(java.io.PrintStream, int)
2715     * @since JDK1.0
2716     */

2717    public void list(PrintStream JavaDoc out, int indent) {
2718    super.list(out, indent);
2719    int ncomponents = this.ncomponents;
2720        Component JavaDoc component[] = this.component;
2721    for (int i = 0 ; i < ncomponents ; i++) {
2722        Component JavaDoc comp = component[i];
2723        if (comp != null) {
2724        comp.list(out, indent+1);
2725        }
2726    }
2727    }
2728
2729    /**
2730     * Prints out a list, starting at the specified indentation,
2731     * to the specified print writer.
2732     * <p>
2733     * The immediate children of the container are printed with
2734     * an indentation of <code>indent+1</code>. The children
2735     * of those children are printed at <code>indent+2</code>
2736     * and so on.
2737     *
2738     * @param out a print writer
2739     * @param indent the number of spaces to indent
2740     * @see Component#list(java.io.PrintWriter, int)
2741     * @since JDK1.1
2742     */

2743    public void list(PrintWriter JavaDoc out, int indent) {
2744    super.list(out, indent);
2745    int ncomponents = this.ncomponents;
2746        Component JavaDoc component[] = this.component;
2747    for (int i = 0 ; i < ncomponents ; i++) {
2748        Component JavaDoc comp = component[i];
2749        if (comp != null) {
2750        comp.list(out, indent+1);
2751        }
2752    }
2753    }
2754
2755    /**
2756     * Sets the focus traversal keys for a given traversal operation for this
2757     * Container.
2758     * <p>
2759     * The default values for a Container's focus traversal keys are
2760     * implementation-dependent. Sun recommends that all implementations for a
2761     * particular native platform use the same default values. The
2762     * recommendations for Windows and Unix are listed below. These
2763     * recommendations are used in the Sun AWT implementations.
2764     *
2765     * <table border=1 summary="Recommended default values for a Container's focus traversal keys">
2766     * <tr>
2767     * <th>Identifier</th>
2768     * <th>Meaning</th>
2769     * <th>Default</th>
2770     * </tr>
2771     * <tr>
2772     * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
2773     * <td>Normal forward keyboard traversal</td>
2774     * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
2775     * </tr>
2776     * <tr>
2777     * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
2778     * <td>Normal reverse keyboard traversal</td>
2779     * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
2780     * </tr>
2781     * <tr>
2782     * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
2783     * <td>Go up one focus traversal cycle</td>
2784     * <td>none</td>
2785     * </tr>
2786     * <tr>
2787     * <td>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS<td>
2788     * <td>Go down one focus traversal cycle</td>
2789     * <td>none</td>
2790     * </tr>
2791     * </table>
2792     *
2793     * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
2794     * recommended.
2795     * <p>
2796     * Using the AWTKeyStroke API, client code can specify on which of two
2797     * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
2798     * operation will occur. Regardless of which KeyEvent is specified,
2799     * however, all KeyEvents related to the focus traversal key, including the
2800     * associated KEY_TYPED event, will be consumed, and will not be dispatched
2801     * to any Container. It is a runtime error to specify a KEY_TYPED event as
2802     * mapping to a focus traversal operation, or to map the same event to
2803     * multiple default focus traversal operations.
2804     * <p>
2805     * If a value of null is specified for the Set, this Container inherits the
2806     * Set from its parent. If all ancestors of this Container have null
2807     * specified for the Set, then the current KeyboardFocusManager's default
2808     * Set is used.
2809     *
2810     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2811     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2812     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2813     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2814     * @param keystrokes the Set of AWTKeyStroke for the specified operation
2815     * @see #getFocusTraversalKeys
2816     * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2817     * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2818     * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2819     * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2820     * @throws IllegalArgumentException if id is not one of
2821     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2822     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2823     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2824     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, or if keystrokes
2825     * contains null, or if any Object in keystrokes is not an
2826     * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
2827     * or if any keystroke already maps to another focus traversal
2828     * operation for this Container
2829     * @since 1.4
2830     * @beaninfo
2831     * bound: true
2832     */

2833    public void setFocusTraversalKeys(int id,
2834                      Set JavaDoc<? extends AWTKeyStroke JavaDoc> keystrokes)
2835    {
2836        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2837            throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
2838        }
2839          
2840        // Don't call super.setFocusTraversalKey. The Component parameter check
2841
// does not allow DOWN_CYCLE_TRAVERSAL_KEYS, but we do.
2842
setFocusTraversalKeys_NoIDCheck(id, keystrokes);
2843    }
2844
2845    /**
2846     * Returns the Set of focus traversal keys for a given traversal operation
2847     * for this Container. (See
2848     * <code>setFocusTraversalKeys</code> for a full description of each key.)
2849     * <p>
2850     * If a Set of traversal keys has not been explicitly defined for this
2851     * Container, then this Container's parent's Set is returned. If no Set
2852     * has been explicitly defined for any of this Container's ancestors, then
2853     * the current KeyboardFocusManager's default Set is returned.
2854     *
2855     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2856     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2857     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2858     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2859     * @return the Set of AWTKeyStrokes for the specified operation. The Set
2860     * will be unmodifiable, and may be empty. null will never be
2861     * returned.
2862     * @see #setFocusTraversalKeys
2863     * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2864     * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2865     * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2866     * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2867     * @throws IllegalArgumentException if id is not one of
2868     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2869     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2870     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2871     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2872     * @since 1.4
2873     */

2874    public Set JavaDoc<AWTKeyStroke JavaDoc> getFocusTraversalKeys(int id) {
2875        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2876        throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
2877    }
2878 
2879    // Don't call super.getFocusTraversalKey. The Component parameter check
2880
// does not allow DOWN_CYCLE_TRAVERSAL_KEY, but we do.
2881
return getFocusTraversalKeys_NoIDCheck(id);
2882    }
2883
2884    /**
2885     * Returns whether the Set of focus traversal keys for the given focus
2886     * traversal operation has been explicitly defined for this Container. If
2887     * this method returns <code>false</code>, this Container is inheriting the
2888     * Set from an ancestor, or from the current KeyboardFocusManager.
2889     *
2890     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2891     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2892     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2893     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2894     * @return <code>true</code> if the the Set of focus traversal keys for the
2895     * given focus traversal operation has been explicitly defined for
2896     * this Component; <code>false</code> otherwise.
2897     * @throws IllegalArgumentException if id is not one of
2898     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2899     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2900     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2901     * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2902     * @since 1.4
2903     */

2904    public boolean areFocusTraversalKeysSet(int id) {
2905        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2906        throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
2907    }
2908 
2909    return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
2910    }
2911
2912    /**
2913     * Returns whether the specified Container is the focus cycle root of this
2914     * Container's focus traversal cycle. Each focus traversal cycle has only
2915     * a single focus cycle root and each Container which is not a focus cycle
2916     * root belongs to only a single focus traversal cycle. Containers which
2917     * are focus cycle roots belong to two cycles: one rooted at the Container
2918     * itself, and one rooted at the Container's nearest focus-cycle-root
2919     * ancestor. This method will return <code>true</code> for both such
2920     * Containers in this case.
2921     *
2922     * @param container the Container to be tested
2923     * @return <code>true</code> if the specified Container is a focus-cycle-
2924     * root of this Container; <code>false</code> otherwise
2925     * @see #isFocusCycleRoot()
2926     * @since 1.4
2927     */

2928    public boolean isFocusCycleRoot(Container JavaDoc container) {
2929        if (isFocusCycleRoot() && container == this) {
2930        return true;
2931    } else {
2932        return super.isFocusCycleRoot(container);
2933    }
2934    }
2935 
2936    private Container JavaDoc findTraversalRoot() {
2937    // I potentially have two roots, myself and my root parent
2938
// If I am the current root, then use me
2939
// If none of my parents are roots, then use me
2940
// If my root parent is the current root, then use my root parent
2941
// If neither I nor my root parent is the current root, then
2942
// use my root parent (a guess)
2943

2944    Container JavaDoc currentFocusCycleRoot = KeyboardFocusManager.
2945        getCurrentKeyboardFocusManager().getCurrentFocusCycleRoot();
2946    Container JavaDoc root;
2947    
2948    if (currentFocusCycleRoot == this) {
2949        root = this;
2950    } else {
2951        root = getFocusCycleRootAncestor();
2952        if (root == null) {
2953        root = this;
2954        }
2955    }
2956
2957    if (root != currentFocusCycleRoot) {
2958        KeyboardFocusManager.getCurrentKeyboardFocusManager().
2959        setGlobalCurrentFocusCycleRoot(root);
2960    }
2961    return root;
2962    }
2963
2964    final boolean containsFocus() {
2965        synchronized (getTreeLock()) {
2966            Component JavaDoc comp = KeyboardFocusManager.
2967                getCurrentKeyboardFocusManager().getFocusOwner();
2968            while (comp != null && !(comp instanceof Window JavaDoc) && comp != this)
2969            {
2970                comp = (Component JavaDoc) comp.getParent();
2971            }
2972            return (comp == this);
2973        }
2974    }
2975
2976    /**
2977     * Check if this component is the child of this container or its children.
2978     * Note: this function acquires treeLock
2979     * Note: this function traverses children tree only in one Window.
2980     * @param comp a component in test, must not be null
2981     */

2982    boolean isParentOf(Component JavaDoc comp) {
2983        synchronized(getTreeLock()) {
2984            while (comp != null && comp != this && !(comp instanceof Window JavaDoc)) {
2985                comp = comp.getParent();
2986            }
2987            return (comp == this);
2988        }
2989    }
2990
2991    void clearMostRecentFocusOwnerOnHide() {
2992        Component JavaDoc comp = null;
2993        Container JavaDoc window = this;
2994
2995        synchronized (getTreeLock()) {
2996            while (window != null && !(window instanceof Window JavaDoc)) {
2997                window = window.getParent();
2998            }
2999            if (window != null) {
3000                comp = KeyboardFocusManager.
3001                    getMostRecentFocusOwner((Window JavaDoc)window);
3002                while ((comp != null) && (comp != this) && !(comp instanceof Window JavaDoc)) {
3003                    comp = comp.getParent();
3004                }
3005            }
3006        }
3007
3008        if (comp == this) {
3009            KeyboardFocusManager.setMostRecentFocusOwner((Window JavaDoc)window, null);
3010        }
3011
3012        if (window != null) {
3013            Window JavaDoc myWindow = (Window JavaDoc)window;
3014            synchronized(getTreeLock()) {
3015                // This synchronized should always be the second in a pair (tree lock, KeyboardFocusManager.class)
3016
synchronized(KeyboardFocusManager JavaDoc.class) {
3017                    Component JavaDoc storedComp = myWindow.getTemporaryLostComponent();
3018                    if (isParentOf(storedComp) || storedComp == this) {
3019                        myWindow.setTemporaryLostComponent(null);
3020                    }
3021                }
3022            }
3023        }
3024    }
3025
3026    void clearCurrentFocusCycleRootOnHide() {
3027        KeyboardFocusManager JavaDoc kfm =
3028            KeyboardFocusManager.getCurrentKeyboardFocusManager();
3029        Container JavaDoc cont = kfm.getCurrentFocusCycleRoot();
3030
3031        synchronized (getTreeLock()) {
3032            while (this != cont && !(cont instanceof Window JavaDoc) && (cont != null)) {
3033                cont = cont.getParent();
3034            }
3035        }
3036
3037        if (cont == this) {
3038            kfm.setGlobalCurrentFocusCycleRoot(null);
3039        }
3040    }
3041
3042    boolean nextFocusHelper() {
3043        if (isFocusCycleRoot()) {
3044            Container JavaDoc root = findTraversalRoot();
3045            Component JavaDoc comp = this;
3046            Container JavaDoc anc;
3047            while (root != null &&
3048                   (anc = root.getFocusCycleRootAncestor()) != null &&
3049                   !(root.isShowing() &&
3050                     root.isFocusable() &&
3051                     root.isEnabled()))
3052            {
3053                comp = root;
3054                root = anc;
3055            }
3056            if (root != null) {
3057                FocusTraversalPolicy JavaDoc policy = root.getFocusTraversalPolicy();
3058                Component JavaDoc toFocus = policy.getComponentAfter(root, comp);
3059                if (toFocus == null) {
3060                    toFocus = policy.getDefaultComponent(root);
3061                }
3062                if (toFocus != null) {
3063                    return toFocus.requestFocus(false);
3064                }
3065            }
3066            return false;
3067        } else {
3068            // I only have one root, so the general case will suffice
3069
return super.nextFocusHelper();
3070        }
3071    }
3072 
3073    public void transferFocusBackward() {
3074        if (isFocusCycleRoot()) {
3075            Container JavaDoc root = findTraversalRoot();
3076            Component JavaDoc comp = this;
3077            while (root != null &&
3078                   !(root.isShowing() &&
3079                     root.isFocusable() &&
3080                     root.isEnabled()))
3081            {
3082                comp = root;
3083                root = comp.getFocusCycleRootAncestor();
3084            }
3085            if (root != null) {
3086                FocusTraversalPolicy JavaDoc policy = root.getFocusTraversalPolicy();
3087                Component JavaDoc toFocus = policy.getComponentBefore(root, comp);
3088                if (toFocus == null) {
3089                    toFocus = policy.getDefaultComponent(root);
3090                }
3091                if (toFocus != null) {
3092                    toFocus.requestFocus();
3093                }
3094            }
3095        } else {
3096            // I only have one root, so the general case will suffice
3097
super.transferFocusBackward();
3098        }
3099    }
3100
3101    /**
3102     * Sets the focus traversal policy that will manage keyboard traversal of
3103     * this Container's children, if this Container is a focus cycle root. If
3104     * the argument is null, this Container inherits its policy from its focus-
3105     * cycle-root ancestor. If the argument is non-null, this policy will be
3106     * inherited by all focus-cycle-root children that have no keyboard-
3107     * traversal policy of their own (as will, recursively, their focus-cycle-
3108     * root children).
3109     * <p>
3110     * If this Container is not a focus cycle root, the policy will be
3111     * remembered, but will not be used or inherited by this or any other
3112     * Containers until this Container is made a focus cycle root.
3113     *
3114     * @param policy the new focus traversal policy for this Container
3115     * @see #getFocusTraversalPolicy
3116     * @see #setFocusCycleRoot
3117     * @see #isFocusCycleRoot
3118     * @since 1.4
3119     * @beaninfo
3120     * bound: true
3121     */

3122    public void setFocusTraversalPolicy(FocusTraversalPolicy JavaDoc policy) {
3123        FocusTraversalPolicy JavaDoc oldPolicy;
3124    synchronized (this) {
3125        oldPolicy = this.focusTraversalPolicy;
3126        this.focusTraversalPolicy = policy;
3127    }
3128    firePropertyChange("focusTraversalPolicy", oldPolicy, policy);
3129    }
3130
3131    /**
3132     * Returns the focus traversal policy that will manage keyboard traversal
3133     * of this Container's children, or null if this Container is not a focus
3134     * cycle root. If no traversal policy has been explicitly set for this
3135     * Container, then this Container's focus-cycle-root ancestor's policy is
3136     * returned.
3137     *
3138     * @return this Container's focus traversal policy, or null if this
3139     * Container is not a focus cycle root.
3140     * @see #setFocusTraversalPolicy
3141     * @see #setFocusCycleRoot
3142     * @see #isFocusCycleRoot
3143     * @since 1.4
3144     */

3145    public FocusTraversalPolicy JavaDoc getFocusTraversalPolicy() {
3146        if (!isFocusTraversalPolicyProvider() && !isFocusCycleRoot()) {
3147        return null;
3148    }
3149 
3150    FocusTraversalPolicy JavaDoc policy = this.focusTraversalPolicy;
3151    if (policy != null) {
3152        return policy;
3153    }
3154 
3155    Container JavaDoc rootAncestor = getFocusCycleRootAncestor();
3156    if (rootAncestor != null) {
3157        return rootAncestor.getFocusTraversalPolicy();
3158    } else {
3159        return KeyboardFocusManager.getCurrentKeyboardFocusManager().
3160            getDefaultFocusTraversalPolicy();
3161    }
3162    }
3163
3164    /**
3165     * Returns whether the focus traversal policy has been explicitly set for
3166     * this Container. If this method returns <code>false</code>, this
3167     * Container will inherit its focus traversal policy from an ancestor.
3168     *
3169     * @return <code>true</code> if the focus traversal policy has been
3170     * explicitly set for this Container; <code>false</code> otherwise.
3171     * @since 1.4
3172     */

3173    public boolean isFocusTraversalPolicySet() {
3174        return (focusTraversalPolicy != null);
3175    }
3176
3177    /**
3178     * Sets whether this Container is the root of a focus traversal cycle. Once
3179     * focus enters a traversal cycle, typically it cannot leave it via focus
3180     * traversal unless one of the up- or down-cycle keys is pressed. Normal
3181     * traversal is limited to this Container, and all of this Container's
3182     * descendants that are not descendants of inferior focus cycle roots. Note
3183     * that a FocusTraversalPolicy may bend these restrictions, however. For
3184     * example, ContainerOrderFocusTraversalPolicy supports implicit down-cycle
3185     * traversal.
3186     * <p>
3187     * The alternative way to specify the traversal order of this Container's
3188     * children is to make this Container a
3189     * <a HREF="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy provider</a>.
3190     *
3191     * @param focusCycleRoot indicates whether this Container is the root of a
3192     * focus traversal cycle
3193     * @see #isFocusCycleRoot()
3194     * @see #setFocusTraversalPolicy
3195     * @see #getFocusTraversalPolicy
3196     * @see ContainerOrderFocusTraversalPolicy
3197     * @see #setFocusTraversalPolicyProvider
3198     * @since 1.4
3199     * @beaninfo
3200     * bound: true
3201     */

3202    public void setFocusCycleRoot(boolean focusCycleRoot) {
3203        boolean oldFocusCycleRoot;
3204    synchronized (this) {
3205        oldFocusCycleRoot = this.focusCycleRoot;
3206        this.focusCycleRoot = focusCycleRoot;
3207    }
3208    firePropertyChange("focusCycleRoot", oldFocusCycleRoot,
3209               focusCycleRoot);
3210    }
3211
3212    /**
3213     * Returns whether this Container is the root of a focus traversal cycle.
3214     * Once focus enters a traversal cycle, typically it cannot leave it via
3215     * focus traversal unless one of the up- or down-cycle keys is pressed.
3216     * Normal traversal is limited to this Container, and all of this
3217     * Container's descendants that are not descendants of inferior focus
3218     * cycle roots. Note that a FocusTraversalPolicy may bend these
3219     * restrictions, however. For example, ContainerOrderFocusTraversalPolicy
3220     * supports implicit down-cycle traversal.
3221     *
3222     * @return whether this Container is the root of a focus traversal cycle
3223     * @see #setFocusCycleRoot
3224     * @see #setFocusTraversalPolicy
3225     * @see #getFocusTraversalPolicy
3226     * @see ContainerOrderFocusTraversalPolicy
3227     * @since 1.4
3228     */

3229    public boolean isFocusCycleRoot() {
3230        return focusCycleRoot;
3231    }
3232
3233    /**
3234     * Sets whether this container will be used to provide focus
3235     * traversal policy. Container with this property as
3236     * <code>true</code> will be used to acquire focus traversal policy
3237     * instead of closest focus cycle root ancestor.
3238     * @param provide indicates whether this container will be used to
3239     * provide focus traversal policy
3240     * @see #setFocusTraversalPolicy
3241     * @see #getFocusTraversalPolicy
3242     * @see #isFocusTraversalPolicyProvider
3243     * @since 1.5
3244     * @beaninfo
3245     * bound: true
3246     */

3247    public final void setFocusTraversalPolicyProvider(boolean provider) {
3248        boolean oldProvider;
3249        synchronized(this) {
3250            oldProvider = focusTraversalPolicyProvider;
3251            focusTraversalPolicyProvider = provider;
3252        }
3253        firePropertyChange("focusTraversalPolicyProvider", oldProvider, provider);
3254    }
3255    
3256    /**
3257     * Returns whether this container provides focus traversal
3258     * policy. If this property is set to <code>true</code> then when
3259     * keyboard focus manager searches container hierarchy for focus
3260     * traversal policy and encounters this container before any other
3261     * container with this property as true or focus cycle roots then
3262     * its focus traversal policy will be used instead of focus cycle
3263     * root's policy.
3264     * @see #setFocusTraversalPolicy
3265     * @see #getFocusTraversalPolicy
3266     * @see #setFocusCycleRoot
3267     * @see #setFocusTraversalPolicyProvider
3268     * @return <code>true</code> if this container provides focus traversal
3269     * policy, <code>false</code> otherwise
3270     * @since 1.5
3271     * @beaninfo
3272     * bound: true
3273     */

3274    public final boolean isFocusTraversalPolicyProvider() {
3275        return focusTraversalPolicyProvider;
3276    }
3277
3278    /**
3279     * Transfers the focus down one focus traversal cycle. If this Container is
3280     * a focus cycle root, then the focus owner is set to this Container's
3281     * default Component to focus, and the current focus cycle root is set to
3282     * this Container. If this Container is not a focus cycle root, then no
3283     * focus traversal operation occurs.
3284     *
3285     * @see Component#requestFocus()
3286     * @see #isFocusCycleRoot
3287     * @see #setFocusCycleRoot
3288     * @since 1.4
3289     */

3290    public void transferFocusDownCycle() {
3291        if (isFocusCycleRoot()) {
3292        KeyboardFocusManager.getCurrentKeyboardFocusManager().
3293            setGlobalCurrentFocusCycleRoot(this);
3294        Component JavaDoc toFocus = getFocusTraversalPolicy().
3295            getDefaultComponent(this);
3296        if (toFocus != null) {
3297            toFocus.requestFocus();
3298        }
3299    }
3300    }
3301
3302    void preProcessKeyEvent(KeyEvent JavaDoc e) {
3303        Container JavaDoc parent = this.parent;
3304        if (parent != null) {
3305            parent.preProcessKeyEvent(e);
3306        }
3307    }
3308
3309    void postProcessKeyEvent(KeyEvent JavaDoc e) {
3310        Container JavaDoc parent = this.parent;
3311        if (parent != null) {
3312            parent.postProcessKeyEvent(e);
3313        }
3314    }
3315
3316    boolean postsOldMouseEvents() {
3317        return true;
3318    }
3319
3320    /**
3321     * Sets the <code>ComponentOrientation</code> property of this container
3322     * and all components contained within it.
3323     *
3324     * @param o the new component orientation of this container and
3325     * the components contained within it.
3326     * @exception NullPointerException if <code>orientation</code> is null.
3327     * @see Component#setComponentOrientation
3328     * @see Component#getComponentOrientation
3329     * @since 1.4
3330     */

3331    public void applyComponentOrientation(ComponentOrientation JavaDoc o) {
3332        super.applyComponentOrientation(o);
3333        
3334        for (int i = 0 ; i < ncomponents ; ++i) {
3335             component[i].applyComponentOrientation(o);
3336        }
3337    }
3338    
3339    /**
3340     * Adds a PropertyChangeListener to the listener list. The listener is
3341     * registered for all bound properties of this class, including the
3342     * following:
3343     * <ul>
3344     * <li>this Container's font ("font")</li>
3345     * <li>this Container's background color ("background")</li>
3346     * <li>this Container's foreground color ("foreground")</li>
3347     * <li>this Container's focusability ("focusable")</li>
3348     * <li>this Container's focus traversal keys enabled state
3349     * ("focusTraversalKeysEnabled")</li>
3350     * <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3351     * ("forwardFocusTraversalKeys")</li>
3352     * <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3353     * ("backwardFocusTraversalKeys")</li>
3354     * <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3355     * ("upCycleFocusTraversalKeys")</li>
3356     * <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3357     * ("downCycleFocusTraversalKeys")</li>
3358     * <li>this Container's focus traversal policy ("focusTraversalPolicy")
3359     * </li>
3360     * <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3361     * </ul>
3362     * Note that if this Container is inheriting a bound property, then no
3363     * event will be fired in response to a change in the inherited property.
3364     * <p>
3365     * If listener is null, no exception is thrown and no action is performed.
3366     *
3367     * @param listener the PropertyChangeListener to be added
3368     *
3369     * @see Component#removePropertyChangeListener
3370     * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
3371     */

3372    public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
3373    super.addPropertyChangeListener(listener);
3374    }
3375  
3376    /**
3377     * Adds a PropertyChangeListener to the listener list for a specific
3378     * property. The specified property may be user-defined, or one of the
3379     * following defaults:
3380     * <ul>
3381     * <li>this Container's font ("font")</li>
3382     * <li>this Container's background color ("background")</li>
3383     * <li>this Container's foreground color ("foreground")</li>
3384     * <li>this Container's focusability ("focusable")</li>
3385     * <li>this Container's focus traversal keys enabled state
3386     * ("focusTraversalKeysEnabled")</li>
3387     * <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3388     * ("forwardFocusTraversalKeys")</li>
3389     * <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3390     * ("backwardFocusTraversalKeys")</li>
3391     * <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3392     * ("upCycleFocusTraversalKeys")</li>
3393     * <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3394     * ("downCycleFocusTraversalKeys")</li>
3395     * <li>this Container's focus traversal policy ("focusTraversalPolicy")
3396     * </li>
3397     * <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3398     * <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3399     * <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3400     * </ul>
3401     * Note that if this Container is inheriting a bound property, then no
3402     * event will be fired in response to a change in the inherited property.
3403     * <p>
3404     * If listener is null, no exception is thrown and no action is performed.
3405     *
3406     * @param propertyName one of the property names listed above
3407     * @param listener the PropertyChangeListener to be added
3408     *
3409     * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
3410     * @see Component#removePropertyChangeListener
3411     */

3412    public void addPropertyChangeListener(String JavaDoc propertyName,
3413                      PropertyChangeListener JavaDoc listener) {
3414    super.addPropertyChangeListener(propertyName, listener);
3415    }
3416  
3417    // Serialization support. A Container is responsible for restoring the
3418
// parent fields of its component children.
3419

3420    /**
3421     * Container Serial Data Version.
3422     */

3423    private int containerSerializedDataVersion = 1;
3424  
3425    /**
3426     * Serializes this <code>Container</code> to the specified
3427     * <code>ObjectOutputStream</code>.
3428     * <ul>
3429     * <li>Writes default serializable fields to the stream.</li>
3430     * <li>Writes a list of serializable ContainerListener(s) as optional
3431     * data. The non-serializable ContainerListner(s) are detected and
3432     * no attempt is made to serialize them.</li>
3433     * <li>Write this Container's FocusTraversalPolicy if and only if it
3434     * is Serializable; otherwise, <code>null</code> is written.</li>
3435     * </ul>
3436     *
3437     * @param s the <code>ObjectOutputStream</code> to write
3438     * @serialData <code>null</code> terminated sequence of 0 or more pairs;
3439     * the pair consists of a <code>String</code> and <code>Object</code>;
3440     * the <code>String</code> indicates the type of object and
3441     * is one of the following:
3442     * <code>containerListenerK</code> indicating an
3443     * <code>ContainerListener</code> object;
3444     * the <code>Container</code>'s <code>FocusTraversalPolicy</code>,
3445     * or <code>null</code>
3446     *
3447     * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
3448     * @see Container#containerListenerK
3449     * @see #readObject(ObjectInputStream)
3450     */

3451    private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
3452        ObjectOutputStream.PutField JavaDoc f = s.putFields();
3453        f.put("ncomponents", ncomponents);
3454        f.put("component", component);
3455        f.put("layoutMgr", layoutMgr);
3456        f.put("dispatcher", dispatcher);
3457        f.put("maxSize", maxSize);
3458        f.put("focusCycleRoot", focusCycleRoot);
3459        f.put("containerSerializedDataVersion", containerSerializedDataVersion);
3460        f.put("focusTraversalPolicyProvider", focusTraversalPolicyProvider);
3461        s.writeFields();
3462    
3463    AWTEventMulticaster.save(s, containerListenerK, containerListener);
3464    s.writeObject(null);
3465    
3466    if (focusTraversalPolicy instanceof java.io.Serializable JavaDoc) {
3467        s.writeObject(focusTraversalPolicy);
3468    } else {
3469        s.writeObject(null);
3470    }
3471    }
3472   
3473    /**
3474     * Deserializes this <code>Container</code> from the specified
3475     * <code>ObjectInputStream</code>.
3476     * <ul>
3477     * <li>Reads default serializable fields from the stream.</li>
3478     * <li>Reads a list of serializable ContainerListener(s) as optional
3479     * data. If the list is null, no Listeners are installed.</li>
3480     * <li>Reads this Container's FocusTraversalPolicy, which may be null,
3481     * as optional data.</li>
3482     * </ul>
3483     *
3484     * @param s the <code>ObjectInputStream</code> to read
3485     * @serial
3486     * @see #addContainerListener
3487     * @see #writeObject(ObjectOutputStream)
3488     */

3489    private void readObject(ObjectInputStream JavaDoc s)
3490    throws ClassNotFoundException JavaDoc, IOException JavaDoc
3491    {
3492        ObjectInputStream.GetField JavaDoc f = s.readFields();
3493        ncomponents = f.get("ncomponents", 0);
3494        component = (Component JavaDoc[])f.get("component", new Component JavaDoc[0]);
3495        layoutMgr = (LayoutManager JavaDoc)f.get("layoutMgr", null);
3496        dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
3497        // Old stream. Doesn't contain maxSize among Component's fields.
3498
if (maxSize == null) {
3499            maxSize = (Dimension JavaDoc)f.get("maxSize", null);
3500        }
3501        focusCycleRoot = f.get("focusCycleRoot", false);
3502        containerSerializedDataVersion = f.get("containerSerializedDataVersion", 1);
3503        focusTraversalPolicyProvider = f.get("focusTraversalPolicyProvider", false);
3504
3505    Component JavaDoc component[] = this.component;
3506    for(int i = 0; i < ncomponents; i++) {
3507        component[i].parent = this;
3508        adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
3509            component[i].numListening(AWTEvent.HIERARCHY_EVENT_MASK));
3510        adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3511                component[i].numListening(
3512                    AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
3513            adjustDescendants(component[i].countHierarchyMembers());
3514    }
3515   
3516    Object JavaDoc keyOrNull;
3517    while(null != (keyOrNull = s.readObject())) {
3518        String JavaDoc key = ((String JavaDoc)keyOrNull).intern();
3519        
3520        if (containerListenerK == key) {
3521        addContainerListener((ContainerListener JavaDoc)(s.readObject()));
3522        } else {
3523        // skip value for unrecognized key
3524
s.readObject();
3525        }
3526    }
3527  
3528    try {
3529        Object JavaDoc policy = s.readObject();
3530        if (policy instanceof FocusTraversalPolicy JavaDoc) {
3531        focusTraversalPolicy = (FocusTraversalPolicy JavaDoc)policy;
3532        }
3533    } catch (java.io.OptionalDataException JavaDoc e) {
3534        // JDK 1.1/1.2/1.3 instances will not have this optional data.
3535
// e.eof will be true to indicate that there is no more data
3536
// available for this object. If e.eof is not true, throw the
3537
// exception as it might have been caused by reasons unrelated to
3538
// focusTraversalPolicy.
3539

3540        if (!e.eof) {
3541        throw e;
3542        }
3543    }
3544    }
3545
3546    /*
3547     * --- Accessibility Support ---
3548     */

3549
3550    /**
3551     * Inner class of Container used to provide default support for
3552     * accessibility. This class is not meant to be used directly by
3553     * application developers, but is instead meant only to be
3554     * subclassed by container developers.
3555     * <p>
3556     * The class used to obtain the accessible role for this object,
3557     * as well as implementing many of the methods in the
3558     * AccessibleContainer interface.
3559     */

3560    protected class AccessibleAWTContainer extends AccessibleAWTComponent {
3561
3562        /**
3563         * JDK1.3 serialVersionUID
3564         */

3565        private static final long serialVersionUID = 5081320404842566097L;
3566
3567        /**
3568         * Returns the number of accessible children in the object. If all
3569         * of the children of this object implement <code>Accessible</code>,
3570         * then this method should return the number of children of this object.
3571         *
3572         * @return the number of accessible children in the object
3573         */

3574        public int getAccessibleChildrenCount() {
3575        return Container.this.getAccessibleChildrenCount();
3576        }
3577
3578        /**
3579         * Returns the nth <code>Accessible</code> child of the object.
3580         *
3581         * @param i zero-based index of child
3582         * @return the nth <code>Accessible</code> child of the object
3583         */

3584        public Accessible getAccessibleChild(int i) {
3585            return Container.this.getAccessibleChild(i);
3586        }
3587
3588        /**
3589         * Returns the <code>Accessible</code> child, if one exists,
3590         * contained at the local coordinate <code>Point</code>.
3591         *
3592         * @param p the point defining the top-left corner of the
3593         * <code>Accessible</code>, given in the coordinate space
3594         * of the object's parent
3595         * @return the <code>Accessible</code>, if it exists,
3596         * at the specified location; else <code>null</code>
3597         */

3598        public Accessible getAccessibleAt(Point JavaDoc p) {
3599            return Container.this.getAccessibleAt(p);
3600        }
3601
3602    protected ContainerListener JavaDoc accessibleContainerHandler = null;
3603
3604    /**
3605     * Fire <code>PropertyChange</code> listener, if one is registered,
3606     * when children are added or removed.
3607     */

3608    protected class AccessibleContainerHandler
3609        implements ContainerListener JavaDoc {
3610        public void componentAdded(ContainerEvent JavaDoc e) {
3611        Component JavaDoc c = e.getChild();
3612        if (c != null && c instanceof Accessible) {
3613            AccessibleAWTContainer.this.firePropertyChange(
3614            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3615            null, ((Accessible) c).getAccessibleContext());
3616        }
3617        }
3618        public void componentRemoved(ContainerEvent JavaDoc e) {
3619        Component JavaDoc c = e.getChild();
3620        if (c != null && c instanceof Accessible) {
3621            AccessibleAWTContainer.this.firePropertyChange(
3622            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3623            ((Accessible) c).getAccessibleContext(), null);
3624        }
3625        }
3626    }
3627
3628        /**
3629         * Adds a PropertyChangeListener to the listener list.
3630         *
3631         * @param listener the PropertyChangeListener to be added
3632         */

3633        public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
3634            if (accessibleContainerHandler == null) {
3635                accessibleContainerHandler = new AccessibleContainerHandler();
3636                Container.this.addContainerListener(accessibleContainerHandler);
3637            }
3638            super.addPropertyChangeListener(listener);
3639        }
3640
3641    } // inner class AccessibleAWTContainer
3642

3643    /**
3644     * Returns the <code>Accessible</code> child contained at the local
3645     * coordinate <code>Point</code>, if one exists. Otherwise
3646     * returns <code>null</code>.
3647     *
3648     * @param p the point defining the top-left corner of the
3649     * <code>Accessible</code>, given in the coordinate space
3650     * of the object's parent
3651     * @return the <code>Accessible</code> at the specified location,
3652     * if it exists; otherwise <code>null</code>
3653     */

3654    Accessible getAccessibleAt(Point JavaDoc p) {
3655        synchronized (getTreeLock()) {
3656            if (this instanceof Accessible) {
3657                Accessible a = (Accessible)this;
3658                AccessibleContext ac = a.getAccessibleContext();
3659                if (ac != null) {
3660                    AccessibleComponent acmp;
3661                    Point JavaDoc location;
3662                    int nchildren = ac.getAccessibleChildrenCount();
3663                    for (int i=0; i < nchildren; i++) {
3664                        a = ac.getAccessibleChild(i);
3665                        if ((a != null)) {
3666                            ac = a.getAccessibleContext();
3667                            if (ac != null) {
3668                                acmp = ac.getAccessibleComponent();
3669                                if ((acmp != null) && (acmp.isShowing())) {
3670                                    location = acmp.getLocation();
3671                                    Point JavaDoc np = new Point JavaDoc(p.x-location.x,
3672                                                         p.y-location.y);
3673                                    if (acmp.contains(np)){
3674                                        return a;
3675                                    }
3676                                }
3677                            }
3678                        }
3679                    }
3680                }
3681                return (Accessible)this;
3682            } else {
3683                Component JavaDoc ret = this;
3684                if (!this.contains(p.x,p.y)) {
3685                    ret = null;
3686                } else {
3687                    int ncomponents = this.getComponentCount();
3688                    for (int i=0; i < ncomponents; i++) {
3689                        Component JavaDoc comp = this.getComponent(i);
3690                        if ((comp != null) && comp.isShowing()) {
3691                            Point JavaDoc location = comp.getLocation();
3692                            if (comp.contains(p.x-location.x,p.y-location.y)) {
3693                                ret = comp;
3694                            }
3695                        }
3696                    }
3697                }
3698                if (ret instanceof Accessible) {
3699                    return (Accessible) ret;
3700                }
3701            }
3702            return null;
3703        }
3704    }
3705
3706    /**
3707     * Returns the number of accessible children in the object. If all
3708     * of the children of this object implement <code>Accessible</code>,
3709     * then this method should return the number of children of this object.
3710     *
3711     * @return the number of accessible children in the object
3712     */

3713    int getAccessibleChildrenCount() {
3714        synchronized (getTreeLock()) {
3715            int count = 0;
3716            Component JavaDoc[] children = this.getComponents();
3717            for (int i = 0; i < children.length; i++) {
3718                if (children[i] instanceof Accessible) {
3719                    count++;
3720                }
3721            }
3722            return count;
3723        }
3724    }
3725
3726    /**
3727     * Returns the nth <code>Accessible</code> child of the object.
3728     *
3729     * @param i zero-based index of child
3730     * @return the nth <code>Accessible</code> child of the object
3731     */

3732    Accessible getAccessibleChild(int i) {
3733        synchronized (getTreeLock()) {
3734            Component JavaDoc[] children = this.getComponents();
3735            int count = 0;
3736            for (int j = 0; j < children.length; j++) {
3737                if (children[j] instanceof Accessible) {
3738                    if (count == i) {
3739                        return (Accessible) children[j];
3740                    } else {
3741                        count++;
3742                    }
3743                }
3744            }
3745            return null;
3746        }
3747    }
3748
3749}
3750
3751
3752/**
3753 * Class to manage the dispatching of MouseEvents to the lightweight descendants
3754 * and SunDropTargetEvents to both lightweight and heavyweight descendants
3755 * contained by a native container.
3756 *
3757 * NOTE: the class name is not appropriate anymore, but we cannot change it
3758 * because we must keep serialization compatibility.
3759 *
3760 * @author Timothy Prinzing
3761 */

3762class LightweightDispatcher implements java.io.Serializable JavaDoc, AWTEventListener JavaDoc {
3763
3764    /*
3765     * JDK 1.1 serialVersionUID
3766     */

3767    private static final long serialVersionUID = 5184291520170872969L;
3768    /*
3769     * Our own mouse event for when we're dragged over from another hw
3770     * container
3771     */

3772    private static final int LWD_MOUSE_DRAGGED_OVER = 1500;
3773
3774    private static final DebugHelper dbg = DebugHelper.create(LightweightDispatcher.class);
3775
3776    LightweightDispatcher(Container JavaDoc nativeContainer) {
3777    this.nativeContainer = nativeContainer;
3778    mouseEventTarget = null;
3779    eventMask = 0;
3780    }
3781
3782    /*
3783     * Clean up any resources allocated when dispatcher was created;
3784     * should be called from Container.removeNotify
3785     */

3786    void dispose() {
3787    //System.out.println("Disposing lw dispatcher");
3788
stopListeningForOtherDrags();
3789        mouseEventTarget = null;
3790    }
3791
3792    /**
3793     * Enables events to subcomponents.
3794     */

3795    void enableEvents(long events) {
3796    eventMask |= events;
3797    }
3798
3799    /**
3800     * Dispatches an event to a sub-component if necessary, and
3801     * returns whether or not the event was forwarded to a
3802     * sub-component.
3803     *
3804     * @param e the event
3805     */

3806    boolean dispatchEvent(AWTEvent JavaDoc e) {
3807    boolean ret = false;
3808
3809        /*
3810         * Fix for BugTraq Id 4389284.
3811         * Dispatch SunDropTargetEvents regardless of eventMask value.
3812         * Do not update cursor on dispatching SunDropTargetEvents.
3813         */

3814        if (e instanceof SunDropTargetEvent) {
3815
3816            SunDropTargetEvent sdde = (SunDropTargetEvent) e;
3817            ret = processDropTargetEvent(sdde);
3818
3819        } else {
3820            if (e instanceof MouseEvent JavaDoc && (eventMask & MOUSE_MASK) != 0) {
3821                MouseEvent JavaDoc me = (MouseEvent JavaDoc) e;
3822                ret = processMouseEvent(me);
3823            }
3824
3825            if (e.getID() == MouseEvent.MOUSE_MOVED) {
3826                nativeContainer.updateCursorImmediately();
3827            }
3828        }
3829
3830    return ret;
3831    }
3832
3833    /* This method effectively returns whether or not a mouse button was down
3834     * just BEFORE the event happened. A better method name might be
3835     * wasAMouseButtonDownBeforeThisEvent().
3836     */

3837    private boolean isMouseGrab(MouseEvent JavaDoc e) {
3838        int modifiers = e.getModifiersEx();
3839        
3840        if(e.getID() == MouseEvent.MOUSE_PRESSED
3841            || e.getID() == MouseEvent.MOUSE_RELEASED)
3842        {
3843            switch (e.getButton()) {
3844            case MouseEvent.BUTTON1:
3845        modifiers ^= InputEvent.BUTTON1_DOWN_MASK;
3846                break;
3847            case MouseEvent.BUTTON2:
3848        modifiers ^= InputEvent.BUTTON2_DOWN_MASK;
3849                break;
3850            case MouseEvent.BUTTON3:
3851        modifiers ^= InputEvent.BUTTON3_DOWN_MASK;
3852                break;
3853            }
3854        }
3855        /* modifiers now as just before event */
3856        return ((modifiers & (InputEvent.BUTTON1_DOWN_MASK
3857                              | InputEvent.BUTTON2_DOWN_MASK
3858                              | InputEvent.BUTTON3_DOWN_MASK)) != 0);
3859    }
3860
3861    /**
3862     * This method attempts to distribute a mouse event to a lightweight
3863     * component. It tries to avoid doing any unnecessary probes down
3864     * into the component tree to minimize the overhead of determining
3865     * where to route the event, since mouse movement events tend to
3866     * come in large and frequent amounts.
3867     */

3868    private boolean processMouseEvent(MouseEvent JavaDoc e) {
3869    int id = e.getID();
3870    Component JavaDoc mouseOver = // sensitive to mouse events
3871
nativeContainer.getMouseEventTarget(e.getX(), e.getY(),
3872                                                Container.INCLUDE_SELF);
3873
3874    trackMouseEnterExit(mouseOver, e);
3875
3876    // 4508327 : MOUSE_CLICKED should only go to the recipient of
3877
// the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
3878
// MOUSE_CLICKED.
3879
if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
3880        mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
3881    }
3882
3883    if (mouseEventTarget != null) {
3884        switch (id) {
3885        case MouseEvent.MOUSE_ENTERED:
3886        case MouseEvent.MOUSE_EXITED:
3887        break;
3888        case MouseEvent.MOUSE_PRESSED:
3889        retargetMouseEvent(mouseEventTarget, id, e);
3890        break;
3891        case MouseEvent.MOUSE_RELEASED:
3892            retargetMouseEvent(mouseEventTarget, id, e);
3893        break;
3894        case MouseEvent.MOUSE_CLICKED:
3895        // 4508327: MOUSE_CLICKED should never be dispatched to a Component
3896
// other than that which received the MOUSE_PRESSED event. If the
3897
// mouse is now over a different Component, don't dispatch the event.
3898
// The previous fix for a similar problem was associated with bug
3899
// 4155217.
3900
if (mouseOver == mouseEventTarget) {
3901            retargetMouseEvent(mouseOver, id, e);
3902        }
3903        break;
3904        case MouseEvent.MOUSE_MOVED:
3905        retargetMouseEvent(mouseEventTarget, id, e);
3906        break;
3907        case MouseEvent.MOUSE_DRAGGED:
3908            if (isMouseGrab(e)) {
3909                retargetMouseEvent(mouseEventTarget, id, e);
3910            }
3911        break;
3912        case MouseEvent.MOUSE_WHEEL:
3913            // This may send it somewhere that doesn't have MouseWheelEvents
3914
// enabled. In this case, Component.dispatchEventImpl() will
3915
// retarget the event to a parent that DOES have the events enabled.
3916
if (dbg.on && mouseOver != null) {
3917                dbg.println("LD retargeting mouse wheel to " +
3918                                mouseOver.getName() + ", " +
3919                                mouseOver.getClass());
3920            }
3921            retargetMouseEvent(mouseOver, id, e);
3922        break;
3923        }
3924        e.consume();
3925    }
3926    return e.isConsumed();
3927    }
3928
3929    private boolean processDropTargetEvent(SunDropTargetEvent e) {
3930        int id = e.getID();
3931        int x = e.getX();
3932        int y = e.getY();
3933
3934        /*
3935         * Fix for BugTraq ID 4395290.
3936         * It is possible that SunDropTargetEvent's Point is outside of the
3937         * native container bounds. In this case we truncate coordinates.
3938         */

3939        if (!nativeContainer.contains(x, y)) {
3940            final Dimension JavaDoc d = nativeContainer.getSize();
3941            if (d.width <= x) {
3942                x = d.width - 1;
3943            } else if (x < 0) {
3944                x = 0;
3945            }
3946            if (d.height <= y) {
3947                y = d.height - 1;
3948            } else if (y < 0) {
3949                y = 0;
3950            }
3951        }
3952        Component JavaDoc mouseOver = // not necessarily sensitive to mouse events
3953
nativeContainer.getDropTargetEventTarget(x, y,
3954                                                     Container.INCLUDE_SELF);
3955        trackMouseEnterExit(mouseOver, e);
3956
3957        if (mouseOver != nativeContainer && mouseOver != null) {
3958            switch (id) {
3959            case SunDropTargetEvent.MOUSE_ENTERED:
3960            case SunDropTargetEvent.MOUSE_EXITED:
3961                break;
3962            default:
3963                retargetMouseEvent(mouseOver, id, e);
3964                e.consume();
3965                break;
3966            }
3967        }
3968        return e.isConsumed();
3969    }
3970
3971    /*
3972     * Generates enter/exit events as mouse moves over lw components
3973     * @param targetOver Target mouse is over (including native container)
3974     * @param e Mouse event in native container
3975     */

3976    private void trackMouseEnterExit(Component JavaDoc targetOver, MouseEvent JavaDoc e) {
3977    Component JavaDoc targetEnter = null;
3978    int id = e.getID();
3979
3980        if (e instanceof SunDropTargetEvent &&
3981            id == MouseEvent.MOUSE_ENTERED &&
3982            isMouseInNativeContainer == true) {
3983            // This can happen if a lightweight component which initiated the
3984
// drag has an associated drop target. MOUSE_ENTERED comes when the
3985
// mouse is in the native container already. To propagate this event
3986
// properly we should null out targetLastEntered.
3987
targetLastEntered = null;
3988        } else if ( id != MouseEvent.MOUSE_EXITED &&
3989         id != MouseEvent.MOUSE_DRAGGED &&
3990         id != LWD_MOUSE_DRAGGED_OVER &&
3991         isMouseInNativeContainer == false ) {
3992        // any event but an exit or drag means we're in the native container
3993
isMouseInNativeContainer = true;
3994        startListeningForOtherDrags();
3995    } else if ( id == MouseEvent.MOUSE_EXITED ) {
3996        isMouseInNativeContainer = false;
3997        stopListeningForOtherDrags();
3998    }
3999
4000    if (isMouseInNativeContainer) {
4001        targetEnter = targetOver;
4002    }
4003    
4004        if (targetLastEntered == targetEnter) {
4005            return;
4006        }
4007
4008        if (targetLastEntered != null) {
4009            retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED, e);
4010        }
4011        if (id == MouseEvent.MOUSE_EXITED) {
4012            // consume native exit event if we generate one
4013
e.consume();
4014        }
4015
4016        if (targetEnter != null) {
4017            retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
4018        }
4019        if (id == MouseEvent.MOUSE_ENTERED) {
4020            // consume native enter event if we generate one
4021
e.consume();
4022        }
4023
4024    targetLastEntered = targetEnter;
4025    }
4026
4027    /*
4028     * Listens to global mouse drag events so even drags originating
4029     * from other heavyweight containers will generate enter/exit
4030     * events in this container
4031     */

4032    private void startListeningForOtherDrags() {
4033    //System.out.println("Adding AWTEventListener");
4034
java.security.AccessController.doPrivileged(
4035        new java.security.PrivilegedAction JavaDoc() {
4036        public Object JavaDoc run() {
4037            nativeContainer.getToolkit().addAWTEventListener(
4038                LightweightDispatcher.this,
4039            AWTEvent.MOUSE_EVENT_MASK |
4040            AWTEvent.MOUSE_MOTION_EVENT_MASK);
4041            return null;
4042        }
4043        }
4044    );
4045    }
4046
4047    private void stopListeningForOtherDrags() {
4048    //System.out.println("Removing AWTEventListener");
4049
java.security.AccessController.doPrivileged(
4050        new java.security.PrivilegedAction JavaDoc() {
4051        public Object JavaDoc run() {
4052            nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this);
4053            return null;
4054        }
4055        }
4056    );
4057    }
4058
4059    /*
4060     * (Implementation of AWTEventListener)
4061     * Listen for drag events posted in other hw components so we can
4062     * track enter/exit regardless of where a drag originated
4063     */

4064    public void eventDispatched(AWTEvent JavaDoc e) {
4065    boolean isForeignDrag = (e instanceof MouseEvent JavaDoc) &&
4066                                !(e instanceof SunDropTargetEvent) &&
4067                (e.id == MouseEvent.MOUSE_DRAGGED) &&
4068                (e.getSource() != nativeContainer);
4069    
4070    if (!isForeignDrag) {
4071        // only interested in drags from other hw components
4072
return;
4073    }
4074
4075    MouseEvent JavaDoc srcEvent = (MouseEvent JavaDoc)e;
4076    MouseEvent JavaDoc me;
4077
4078    synchronized (nativeContainer.getTreeLock()) {
4079        Component JavaDoc srcComponent = srcEvent.getComponent();
4080
4081        // component may have disappeared since drag event posted
4082
// (i.e. Swing hierarchical menus)
4083
if ( !srcComponent.isShowing() ) {
4084        return;
4085        }
4086
4087        //
4088
// create an internal 'dragged-over' event indicating
4089
// we are being dragged over from another hw component
4090
//
4091
me = new MouseEvent JavaDoc(nativeContainer,
4092                   LWD_MOUSE_DRAGGED_OVER,
4093                   srcEvent.getWhen(),
4094                   srcEvent.getModifiersEx() | srcEvent.getModifiers(),
4095                   srcEvent.getX(),
4096                   srcEvent.getY(),
4097                   srcEvent.getClickCount(),
4098                   srcEvent.isPopupTrigger(),
4099                               srcEvent.getButton());
4100        ((AWTEvent JavaDoc)srcEvent).copyPrivateDataInto(me);
4101        // translate coordinates to this native container
4102
final Point JavaDoc ptSrcOrigin = srcComponent.getLocationOnScreen();
4103
4104            if (AppContext.getAppContext() != nativeContainer.appContext) {
4105                final MouseEvent JavaDoc mouseEvent = me;
4106                Runnable JavaDoc r = new Runnable JavaDoc() {
4107                        public void run() {
4108                            if (!nativeContainer.isShowing() ) {
4109                                return;
4110                            }
4111
4112                            Point JavaDoc ptDstOrigin = nativeContainer.getLocationOnScreen();
4113                            mouseEvent.translatePoint(ptSrcOrigin.x - ptDstOrigin.x,
4114                                              ptSrcOrigin.y - ptDstOrigin.y );
4115                            Component JavaDoc targetOver =
4116                                nativeContainer.getMouseEventTarget(mouseEvent.getX(),
4117                                                                    mouseEvent.getY(),
4118                                                                    Container.INCLUDE_SELF);
4119                            trackMouseEnterExit(targetOver, mouseEvent);
4120                        }
4121                    };
4122                SunToolkit.executeOnEventHandlerThread(nativeContainer, r);
4123                return;
4124            } else {
4125                if (!nativeContainer.isShowing() ) {
4126                    return;
4127                }
4128
4129                Point JavaDoc ptDstOrigin = nativeContainer.getLocationOnScreen();
4130                me.translatePoint( ptSrcOrigin.x - ptDstOrigin.x, ptSrcOrigin.y - ptDstOrigin.y );
4131            }
4132    }
4133    //System.out.println("Track event: " + me);
4134
// feed the 'dragged-over' event directly to the enter/exit
4135
// code (not a real event so don't pass it to dispatchEvent)
4136
Component JavaDoc targetOver =
4137            nativeContainer.getMouseEventTarget(me.getX(), me.getY(),
4138                                                Container.INCLUDE_SELF);
4139    trackMouseEnterExit(targetOver, me);
4140    }
4141
4142    /**
4143     * Sends a mouse event to the current mouse event recipient using
4144     * the given event (sent to the windowed host) as a srcEvent. If
4145     * the mouse event target is still in the component tree, the
4146     * coordinates of the event are translated to those of the target.
4147     * If the target has been removed, we don't bother to send the
4148     * message.
4149     */

4150    void retargetMouseEvent(Component JavaDoc target, int id, MouseEvent JavaDoc e) {
4151    if (target == null) {
4152        return; // mouse is over another hw component or target is disabled
4153
}
4154
4155        int x = e.getX(), y = e.getY();
4156        Component JavaDoc component;
4157
4158        for(component = target;
4159            component != null && component != nativeContainer;
4160            component = component.getParent()) {
4161            x -= component.x;
4162            y -= component.y;
4163        }
4164        MouseEvent JavaDoc retargeted;
4165        if (component != null) {
4166            if (e instanceof SunDropTargetEvent) {
4167                retargeted = new SunDropTargetEvent(target,
4168                                                    id,
4169                                                    x,
4170                                                    y,
4171                                                    ((SunDropTargetEvent)e).getDispatcher());
4172            } else if (id == MouseEvent.MOUSE_WHEEL) {
4173                retargeted = new MouseWheelEvent JavaDoc(target,
4174                                      id,
4175                                       e.getWhen(),
4176                                       e.getModifiersEx() | e.getModifiers(),
4177                                       x,
4178                                       y,
4179                                       e.getClickCount(),
4180                                       e.isPopupTrigger(),
4181                                       ((MouseWheelEvent JavaDoc)e).getScrollType(),
4182                                       ((MouseWheelEvent JavaDoc)e).getScrollAmount(),
4183                                       ((MouseWheelEvent JavaDoc)e).getWheelRotation());
4184            }
4185            else {
4186                retargeted = new MouseEvent JavaDoc(target,
4187                                            id,
4188                                            e.getWhen(),
4189                                            e.getModifiersEx() | e.getModifiers(),
4190                                            x,
4191                                            y,
4192                                            e.getClickCount(),
4193                                            e.isPopupTrigger(),
4194                                            e.getButton());
4195            }
4196
4197        ((AWTEvent JavaDoc)e).copyPrivateDataInto(retargeted);
4198
4199        if (target == nativeContainer) {
4200        // avoid recursively calling LightweightDispatcher...
4201
((Container JavaDoc)target).dispatchEventToSelf(retargeted);
4202        } else {
4203                assert AppContext.getAppContext() == target.appContext;
4204                
4205                if (nativeContainer.modalComp != null) {
4206                    if (((Container JavaDoc)nativeContainer.modalComp).isAncestorOf(target)) {
4207                        target.dispatchEvent(retargeted);
4208                    } else {
4209                        e.consume();
4210                    }
4211                } else {
4212                    target.dispatchEvent(retargeted);
4213                }
4214            }
4215        }
4216    }
4217    
4218    // --- member variables -------------------------------
4219

4220    /**
4221     * The windowed container that might be hosting events for
4222     * subcomponents.
4223     */

4224    private Container JavaDoc nativeContainer;
4225
4226    /**
4227     * This variable is not used, but kept for serialization compatibility
4228     */

4229    private Component JavaDoc focus;
4230
4231    /**
4232     * The current subcomponent being hosted by this windowed
4233     * component that has events being forwarded to it. If this
4234     * is null, there are currently no events being forwarded to
4235     * a subcomponent.
4236     */

4237    private transient Component JavaDoc mouseEventTarget;
4238
4239    /**
4240     * The last component entered
4241     */

4242    private transient Component JavaDoc targetLastEntered;
4243
4244    /**
4245     * Is the mouse over the native container
4246     */

4247    private transient boolean isMouseInNativeContainer = false;
4248
4249    /**
4250     * This variable is not used, but kept for serialization compatibility
4251     */

4252    private Cursor JavaDoc nativeCursor;
4253
4254    /**
4255     * The event mask for contained lightweight components. Lightweight
4256     * components need a windowed container to host window-related
4257     * events. This separate mask indicates events that have been
4258     * requested by contained lightweight components without effecting
4259     * the mask of the windowed component itself.
4260     */

4261    private long eventMask;
4262
4263    /**
4264     * The kind of events routed to lightweight components from windowed
4265     * hosts.
4266     */

4267    private static final long PROXY_EVENT_MASK =
4268        AWTEvent.FOCUS_EVENT_MASK |
4269        AWTEvent.KEY_EVENT_MASK |
4270        AWTEvent.MOUSE_EVENT_MASK |
4271        AWTEvent.MOUSE_MOTION_EVENT_MASK |
4272        AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4273
4274    private static final long MOUSE_MASK =
4275        AWTEvent.MOUSE_EVENT_MASK |
4276        AWTEvent.MOUSE_MOTION_EVENT_MASK |
4277        AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4278}
4279
Popular Tags