Source Code Cross Referenced for Container.java in  » 6.0-JDK-Core » AWT » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » AWT » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package java.awt;
0026
0027        import java.io.PrintStream;
0028        import java.io.PrintWriter;
0029        import java.awt.peer.ContainerPeer;
0030        import java.awt.peer.ComponentPeer;
0031        import java.awt.peer.LightweightPeer;
0032        import sun.awt.PeerEvent;
0033        import java.awt.event.ComponentEvent;
0034        import java.awt.event.ContainerEvent;
0035        import java.awt.event.FocusEvent;
0036        import java.awt.event.HierarchyEvent;
0037        import java.awt.event.InputEvent;
0038        import java.awt.event.KeyEvent;
0039        import java.awt.event.MouseEvent;
0040        import java.awt.event.MouseWheelEvent;
0041        import java.awt.event.ContainerListener;
0042        import java.util.EventListener;
0043        import java.io.ObjectStreamField;
0044        import java.io.ObjectOutputStream;
0045        import java.io.ObjectInputStream;
0046        import java.io.IOException;
0047        import java.awt.event.AWTEventListener;
0048        import java.awt.event.WindowAdapter;
0049        import java.awt.event.WindowListener;
0050        import java.awt.event.WindowEvent;
0051        import java.awt.dnd.DropTarget;
0052        import java.util.HashSet;
0053        import java.util.LinkedList;
0054        import java.util.Set;
0055        import java.util.Iterator;
0056        import java.util.Arrays;
0057        import javax.accessibility.*;
0058        import java.beans.PropertyChangeListener;
0059
0060        import sun.awt.AppContext;
0061        import sun.awt.DebugHelper;
0062        import sun.awt.SunToolkit;
0063        import sun.awt.dnd.SunDropTargetEvent;
0064        import sun.awt.CausedFocusEvent;
0065
0066        /**
0067         * A generic Abstract Window Toolkit(AWT) container object is a component 
0068         * that can contain other AWT components.
0069         * <p>
0070         * Components added to a container are tracked in a list.  The order
0071         * of the list will define the components' front-to-back stacking order 
0072         * within the container.  If no index is specified when adding a
0073         * component to a container, it will be added to the end of the list
0074         * (and hence to the bottom of the stacking order).
0075         * <p>
0076         * <b>Note</b>: For details on the focus subsystem, see
0077         * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
0078         * How to Use the Focus Subsystem</a>,
0079         * a section in <em>The Java Tutorial</em>, and the
0080         * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
0081         * for more information.
0082         *
0083         * @version 	1.295, 05/05/07
0084         * @author 	Arthur van Hoff
0085         * @author 	Sami Shaio
0086         * @see       #add(java.awt.Component, int)
0087         * @see       #getComponent(int)
0088         * @see       LayoutManager
0089         * @since     JDK1.0
0090         */
0091        public class Container extends Component {
0092
0093            /**
0094             * The number of components in this container.
0095             * This value can be null.
0096             * @see #getComponent
0097             * @see #getComponents
0098             * @see #getComponentCount
0099             */
0100            int ncomponents;
0101
0102            /** 
0103             * The components in this container.
0104             * @see #add
0105             * @see #getComponents
0106             */
0107            Component component[] = new Component[0];
0108
0109            /** 
0110             * Layout manager for this container.
0111             * @see #doLayout
0112             * @see #setLayout
0113             * @see #getLayout
0114             */
0115            LayoutManager layoutMgr;
0116
0117            /**
0118             * Event router for lightweight components.  If this container
0119             * is native, this dispatcher takes care of forwarding and 
0120             * retargeting the events to lightweight components contained
0121             * (if any).
0122             */
0123            private LightweightDispatcher dispatcher;
0124
0125            /**
0126             * The focus traversal policy that will manage keyboard traversal of this
0127             * Container's children, if this Container is a focus cycle root. If the
0128             * value is null, this Container inherits its policy from its focus-cycle-
0129             * root ancestor. If all such ancestors of this Container have null
0130             * policies, then the current KeyboardFocusManager's default policy is
0131             * used. If the value is non-null, this policy will be inherited by all
0132             * focus-cycle-root children that have no keyboard-traversal policy of
0133             * their own (as will, recursively, their focus-cycle-root children).
0134             * <p>
0135             * If this Container is not a focus cycle root, the value will be
0136             * remembered, but will not be used or inherited by this or any other
0137             * Containers until this Container is made a focus cycle root.
0138             *
0139             * @see #setFocusTraversalPolicy
0140             * @see #getFocusTraversalPolicy
0141             * @since 1.4
0142             */
0143            private transient FocusTraversalPolicy focusTraversalPolicy;
0144
0145            /**
0146             * Indicates whether this Component is the root of a focus traversal cycle.
0147             * Once focus enters a traversal cycle, typically it cannot leave it via
0148             * focus traversal unless one of the up- or down-cycle keys is pressed.
0149             * Normal traversal is limited to this Container, and all of this
0150             * Container's descendants that are not descendants of inferior focus cycle
0151             * roots.
0152             *
0153             * @see #setFocusCycleRoot
0154             * @see #isFocusCycleRoot
0155             * @since 1.4
0156             */
0157            private boolean focusCycleRoot = false;
0158
0159            /**
0160             * Stores the value of focusTraversalPolicyProvider property.
0161             * @since 1.5
0162             * @see #setFocusTraversalPolicyProvider
0163             */
0164            private boolean focusTraversalPolicyProvider;
0165
0166            // keeps track of the threads that are printing this component
0167            private transient Set printingThreads;
0168            // True if there is at least one thread that's printing this component
0169            private transient boolean printing = false;
0170
0171            transient ContainerListener containerListener;
0172
0173            /* HierarchyListener and HierarchyBoundsListener support */
0174            transient int listeningChildren;
0175            transient int listeningBoundsChildren;
0176            transient int descendantsCount;
0177
0178            /**
0179             * JDK 1.1 serialVersionUID 
0180             */
0181            private static final long serialVersionUID = 4613797578919906343L;
0182
0183            private static final DebugHelper dbg = DebugHelper
0184                    .create(Container.class);
0185
0186            /**
0187             * A constant which toggles one of the controllable behaviors 
0188             * of <code>getMouseEventTarget</code>. It is used to specify whether 
0189             * the method can return the Container on which it is originally called 
0190             * in case if none of its children are the current mouse event targets.
0191             * 
0192             * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
0193             */
0194            static final boolean INCLUDE_SELF = true;
0195
0196            /**
0197             * A constant which toggles one of the controllable behaviors 
0198             * of <code>getMouseEventTarget</code>. It is used to specify whether 
0199             * the method should search only lightweight components.
0200             * 
0201             * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
0202             */
0203            static final boolean SEARCH_HEAVYWEIGHTS = true;
0204
0205            /**
0206             * @serialField ncomponents                     int
0207             *       The number of components in this container.
0208             *       This value can be null.
0209             * @serialField component                       Component[]
0210             *       The components in this container.
0211             * @serialField layoutMgr                       LayoutManager
0212             *       Layout manager for this container.
0213             * @serialField dispatcher                      LightweightDispatcher
0214             *       Event router for lightweight components.  If this container
0215             *       is native, this dispatcher takes care of forwarding and
0216             *       retargeting the events to lightweight components contained
0217             *       (if any).
0218             * @serialField maxSize                         Dimension
0219             *       Maximum size of this Container.
0220             * @serialField focusCycleRoot                  boolean
0221             *       Indicates whether this Component is the root of a focus traversal cycle.
0222             *       Once focus enters a traversal cycle, typically it cannot leave it via
0223             *       focus traversal unless one of the up- or down-cycle keys is pressed.
0224             *       Normal traversal is limited to this Container, and all of this
0225             *       Container's descendants that are not descendants of inferior focus cycle
0226             *       roots.
0227             * @serialField containerSerializedDataVersion  int
0228             *       Container Serial Data Version.
0229             * @serialField focusTraversalPolicyProvider    boolean
0230             *       Stores the value of focusTraversalPolicyProvider property.
0231             */
0232            private static final ObjectStreamField[] serialPersistentFields = {
0233                    new ObjectStreamField("ncomponents", Integer.TYPE),
0234                    new ObjectStreamField("component", Component[].class),
0235                    new ObjectStreamField("layoutMgr", LayoutManager.class),
0236                    new ObjectStreamField("dispatcher",
0237                            LightweightDispatcher.class),
0238                    new ObjectStreamField("maxSize", Dimension.class),
0239                    new ObjectStreamField("focusCycleRoot", Boolean.TYPE),
0240                    new ObjectStreamField("containerSerializedDataVersion",
0241                            Integer.TYPE),
0242                    new ObjectStreamField("focusTraversalPolicyProvider",
0243                            Boolean.TYPE), };
0244
0245            static {
0246                /* ensure that the necessary native libraries are loaded */
0247                Toolkit.loadLibraries();
0248                if (!GraphicsEnvironment.isHeadless()) {
0249                    initIDs();
0250                }
0251            }
0252
0253            /**
0254             * Initialize JNI field and method IDs for fields that may be
0255               called from C.
0256             */
0257            private static native void initIDs();
0258
0259            /**
0260             * Constructs a new Container. Containers can be extended directly, 
0261             * but are lightweight in this case and must be contained by a parent
0262             * somewhere higher up in the component tree that is native.
0263             * (such as Frame for example).
0264             */
0265            public Container() {
0266            }
0267
0268            void initializeFocusTraversalKeys() {
0269                focusTraversalKeys = new Set[4];
0270            }
0271
0272            /** 
0273             * Gets the number of components in this panel.
0274             * @return    the number of components in this panel.
0275             * @see       #getComponent
0276             * @since     JDK1.1
0277             */
0278            public int getComponentCount() {
0279                return countComponents();
0280            }
0281
0282            /** 
0283             * @deprecated As of JDK version 1.1,
0284             * replaced by getComponentCount().
0285             */
0286            @Deprecated
0287            public int countComponents() {
0288                return ncomponents;
0289            }
0290
0291            /** 
0292             * Gets the nth component in this container.
0293             * @param      n   the index of the component to get.
0294             * @return     the n<sup>th</sup> component in this container.
0295             * @exception  ArrayIndexOutOfBoundsException  
0296             *                 if the n<sup>th</sup> value does not exist.     
0297             */
0298            public Component getComponent(int n) {
0299                synchronized (getTreeLock()) {
0300                    if ((n < 0) || (n >= ncomponents)) {
0301                        throw new ArrayIndexOutOfBoundsException(
0302                                "No such child: " + n);
0303                    }
0304                    return component[n];
0305                }
0306            }
0307
0308            /**
0309             * Gets all the components in this container.
0310             * @return    an array of all the components in this container.     
0311             */
0312            public Component[] getComponents() {
0313                return getComponents_NoClientCode();
0314            }
0315
0316            // NOTE: This method may be called by privileged threads.
0317            //       This functionality is implemented in a package-private method 
0318            //       to insure that it cannot be overridden by client subclasses. 
0319            //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0320            final Component[] getComponents_NoClientCode() {
0321                synchronized (getTreeLock()) {
0322                    return Arrays.copyOf(component, ncomponents);
0323                }
0324            } // getComponents_NoClientCode()
0325
0326            /**
0327             * Determines the insets of this container, which indicate the size 
0328             * of the container's border. 
0329             * <p>
0330             * A <code>Frame</code> object, for example, has a top inset that 
0331             * corresponds to the height of the frame's title bar. 
0332             * @return    the insets of this container.
0333             * @see       Insets
0334             * @see       LayoutManager
0335             * @since     JDK1.1
0336             */
0337            public Insets getInsets() {
0338                return insets();
0339            }
0340
0341            /**
0342             * @deprecated As of JDK version 1.1,
0343             * replaced by <code>getInsets()</code>.
0344             */
0345            @Deprecated
0346            public Insets insets() {
0347                ComponentPeer peer = this .peer;
0348                if (peer instanceof  ContainerPeer) {
0349                    ContainerPeer cpeer = (ContainerPeer) peer;
0350                    return (Insets) cpeer.insets().clone();
0351                }
0352                return new Insets(0, 0, 0, 0);
0353            }
0354
0355            /** 
0356             * Appends the specified component to the end of this container. 
0357             * This is a convenience method for {@link #addImpl}.
0358             * <p>
0359             * Note: If a component has been added to a container that
0360             * has been displayed, <code>validate</code> must be
0361             * called on that container to display the new component.
0362             * If multiple components are being added, you can improve
0363             * efficiency by calling <code>validate</code> only once,
0364             * after all the components have been added.
0365             *
0366             * @param     comp   the component to be added
0367             * @exception NullPointerException if {@code comp} is {@code null}
0368             * @see #addImpl
0369             * @see #validate
0370             * @see javax.swing.JComponent#revalidate()
0371             * @return    the component argument
0372             */
0373            public Component add(Component comp) {
0374                addImpl(comp, null, -1);
0375                return comp;
0376            }
0377
0378            /**
0379             * Adds the specified component to this container.
0380             * This is a convenience method for {@link #addImpl}.
0381             * <p>
0382             * This method is obsolete as of 1.1.  Please use the
0383             * method <code>add(Component, Object)</code> instead.
0384             * @exception NullPointerException if {@code comp} is {@code null}
0385             * @see #add(Component, Object)
0386             */
0387            public Component add(String name, Component comp) {
0388                addImpl(comp, name, -1);
0389                return comp;
0390            }
0391
0392            /** 
0393             * Adds the specified component to this container at the given 
0394             * position. 
0395             * This is a convenience method for {@link #addImpl}.
0396             * <p>
0397             * Note: If a component has been added to a container that
0398             * has been displayed, <code>validate</code> must be
0399             * called on that container to display the new component.
0400             * If multiple components are being added, you can improve
0401             * efficiency by calling <code>validate</code> only once,
0402             * after all the components have been added.
0403             *
0404             * @param     comp   the component to be added
0405             * @param     index    the position at which to insert the component, 
0406             *                   or <code>-1</code> to append the component to the end
0407             * @exception NullPointerException if {@code comp} is {@code null}
0408             * @exception IllegalArgumentException if {@code index} is invalid (see
0409             *            {@link #addImpl} for details)
0410             * @return    the component <code>comp</code>
0411             * @see #addImpl
0412             * @see #remove
0413             * @see #validate
0414             * @see javax.swing.JComponent#revalidate()
0415             */
0416            public Component add(Component comp, int index) {
0417                addImpl(comp, null, index);
0418                return comp;
0419            }
0420
0421            void checkTreeLock() {
0422                if (!Thread.holdsLock(getTreeLock())) {
0423                    throw new IllegalStateException(
0424                            "This function should be called while holding treeLock");
0425                }
0426            }
0427
0428            /**
0429             * Checks that the component comp can be added to this container
0430             * Checks :  index in bounds of container's size,
0431             * comp is not one of this container's parents,
0432             * and comp is not a window.
0433             * Comp and container must be on the same GraphicsDevice.
0434             * if comp is container, all sub-components must be on
0435             * same GraphicsDevice.
0436             *
0437             * @since 1.5
0438             */
0439            private void checkAdding(Component comp, int index) {
0440                checkTreeLock();
0441
0442                GraphicsConfiguration this GC = getGraphicsConfiguration();
0443
0444                if (index > ncomponents || index < 0) {
0445                    throw new IllegalArgumentException(
0446                            "illegal component position");
0447                }
0448                if (comp.parent == this ) {
0449                    if (index == ncomponents) {
0450                        throw new IllegalArgumentException(
0451                                "illegal component position " + index
0452                                        + " should be less then " + ncomponents);
0453                    }
0454                }
0455                if (comp instanceof  Container) {
0456                    for (Container cn = this ; cn != null; cn = cn.parent) {
0457                        if (cn == comp) {
0458                            throw new IllegalArgumentException(
0459                                    "adding container's parent to itself");
0460                        }
0461                    }
0462
0463                    if (comp instanceof  Window) {
0464                        throw new IllegalArgumentException(
0465                                "adding a window to a container");
0466                    }
0467                }
0468                Window this TopLevel = getContainingWindow();
0469                Window compTopLevel = comp.getContainingWindow();
0470                if (this TopLevel != compTopLevel) {
0471                    throw new IllegalArgumentException(
0472                            "component and container should be in the same top-level window");
0473                }
0474                if (this GC != null) {
0475                    comp.checkGD(this GC.getDevice().getIDstring());
0476                }
0477            }
0478
0479            /**
0480             * Removes component comp from this container without making unneccessary changes
0481             * and generating unneccessary events. This function intended to perform optimized
0482             * remove, for example, if newParent and current parent are the same it just changes
0483             * index without calling removeNotify.
0484             * Note: Should be called while holding treeLock
0485             * @since: 1.5
0486             */
0487            private void removeDelicately(Component comp, Container newParent,
0488                    int newIndex) {
0489                checkTreeLock();
0490
0491                int index = getComponentZOrder(comp);
0492                if (isRemoveNotifyNeeded(comp, this , newParent)) {
0493                    comp.removeNotify();
0494                }
0495                if (newParent != this ) {
0496                    if (layoutMgr != null) {
0497                        layoutMgr.removeLayoutComponent(comp);
0498                    }
0499                    adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
0500                            -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
0501                    adjustListeningChildren(
0502                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
0503                            -comp
0504                                    .numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
0505                    adjustDescendants(-(comp.countHierarchyMembers()));
0506
0507                    comp.parent = null;
0508                    System.arraycopy(component, index + 1, component, index,
0509                            ncomponents - index - 1);
0510                    component[--ncomponents] = null;
0511
0512                    if (valid) {
0513                        invalidate();
0514                    }
0515                } else {
0516                    if (newIndex > index) { // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
0517                        if (newIndex - index > 0) {
0518                            System.arraycopy(component, index + 1, component,
0519                                    index, newIndex - index);
0520                        }
0521                    } else { // 4->2: 012345 -> 014235
0522                        if (index - newIndex > 0) {
0523                            System.arraycopy(component, newIndex, component,
0524                                    newIndex + 1, index - newIndex);
0525                        }
0526                    }
0527                    component[newIndex] = comp;
0528                }
0529                if (comp.parent == null) { // was actually removed
0530                    if (containerListener != null
0531                            || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
0532                            || Toolkit
0533                                    .enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
0534                        ContainerEvent e = new ContainerEvent(this ,
0535                                ContainerEvent.COMPONENT_REMOVED, comp);
0536                        dispatchEvent(e);
0537
0538                    }
0539                    comp
0540                            .createHierarchyEvents(
0541                                    HierarchyEvent.HIERARCHY_CHANGED,
0542                                    comp,
0543                                    this ,
0544                                    HierarchyEvent.PARENT_CHANGED,
0545                                    Toolkit
0546                                            .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
0547                    if (peer != null && layoutMgr == null && isVisible()) {
0548                        updateCursorImmediately();
0549                    }
0550                }
0551            }
0552
0553            /**
0554             * Checks whether this container can contain component which is focus owner.
0555             * Verifies that container is enable and showing, and if it is focus cycle root
0556             * its FTP allows component to be focus owner
0557             * @since 1.5
0558             */
0559            boolean canContainFocusOwner(Component focusOwnerCandidate) {
0560                if (!(isEnabled() && isDisplayable() && isVisible() && isFocusable())) {
0561                    return false;
0562                }
0563                if (isFocusCycleRoot()) {
0564                    FocusTraversalPolicy policy = getFocusTraversalPolicy();
0565                    if (policy instanceof  DefaultFocusTraversalPolicy) {
0566                        if (!((DefaultFocusTraversalPolicy) policy)
0567                                .accept(focusOwnerCandidate)) {
0568                            return false;
0569                        }
0570                    }
0571                }
0572                synchronized (getTreeLock()) {
0573                    if (parent != null) {
0574                        return parent.canContainFocusOwner(focusOwnerCandidate);
0575                    }
0576                }
0577                return true;
0578            }
0579
0580            /**
0581             * Checks whether or not this container has heavyweight children.
0582             * Note: Should be called while holding tree lock
0583             * @return true if there is at least one heavyweight children in a container, false otherwise
0584             * @since 1.5
0585             */
0586            private boolean hasHeavyweightChildren() {
0587                checkTreeLock();
0588                boolean res = true; // true while it is lightweight
0589                for (int i = 0; i < getComponentCount() && res; i++) {
0590                    Component child = getComponent(i);
0591                    res &= child.isLightweight();
0592                    if (res && child instanceof  Container) {
0593                        res &= !((Container) child).hasHeavyweightChildren();
0594                    }
0595                }
0596                return !res;
0597            }
0598
0599            /**
0600             * Returns closest heavyweight component to this container. If this container is heavyweight
0601             * returns this.
0602             * @since 1.5
0603             */
0604            Container getHeavyweightContainer() {
0605                checkTreeLock();
0606                if (peer != null && !(peer instanceof  LightweightPeer)) {
0607                    return this ;
0608                } else {
0609                    return getNativeContainer();
0610                }
0611            }
0612
0613            /**
0614             * Detects whether or not remove from current parent and adding to new parent requires call of
0615             * removeNotify on the component. Since removeNotify destroys native window this might (not)
0616             * be required. For example, if new container and old containers are the same we don't need to
0617             * destroy native window.  
0618             * @since: 1.5
0619             */
0620            private static boolean isRemoveNotifyNeeded(Component comp,
0621                    Container oldContainer, Container newContainer) {
0622                if (oldContainer == null) { // Component didn't have parent - no removeNotify
0623                    return false;
0624                }
0625                if (comp.peer == null) { // Component didn't have peer - no removeNotify
0626                    return false;
0627                }
0628                if (newContainer.peer == null) {
0629                    // Component has peer but new Container doesn't - call removeNotify
0630                    return true;
0631                }
0632
0633                // If component is lightweight non-Container or lightweight Container with all but heavyweight
0634                // children there is no need to call remove notify
0635                if (comp.isLightweight()) {
0636                    if (comp instanceof  Container) {
0637                        // If it has heavyweight children then removeNotify is required
0638                        return ((Container) comp).hasHeavyweightChildren();
0639                    } else {
0640                        // Just a lightweight
0641                        return false;
0642                    }
0643                }
0644
0645                // All three components have peers, check for peer change
0646                Container newNativeContainer = oldContainer
0647                        .getHeavyweightContainer();
0648                Container oldNativeContainer = newContainer
0649                        .getHeavyweightContainer();
0650                if (newNativeContainer != oldNativeContainer) {
0651                    // Native containers change - check whether or not current platform supports
0652                    // changing of widget hierarchy on native level without recreation.
0653                    return !comp.peer.isReparentSupported();
0654                } else {
0655                    // if container didn't change we still might need to recreate component's window as
0656                    // changes to zorder should be reflected in native window stacking order and it might
0657                    // not be supported by the platform. This is important only for heavyweight child
0658                    return !comp.isLightweight()
0659                            && !((ContainerPeer) (newNativeContainer.peer))
0660                                    .isRestackSupported();
0661                }
0662            }
0663
0664            /**
0665             * Moves the specified component to the specified z-order index in
0666             * the container. The z-order determines the order that components
0667             * are painted; the component with the highest z-order paints first
0668             * and the component with the lowest z-order paints last.
0669             * Where components overlap, the component with the lower
0670             * z-order paints over the component with the higher z-order.
0671             * <p>
0672             * If the component is a child of some other container, it is 
0673             * removed from that container before being added to this container.
0674             * The important difference between this method and 
0675             * <code>java.awt.Container.add(Component, int)</code> is that this method
0676             * doesn't call <code>removeNotify</code> on the component while 
0677             * removing it from its previous container unless necessary and when 
0678             * allowed by the underlying native windowing system. This way, if the 
0679             * component has the keyboard focus, it maintains the focus when 
0680             * moved to the new position. 
0681             * <p>
0682             * This property is guaranteed to apply only to lightweight
0683             * non-<code>Container</code> components.
0684             * <p>
0685             * <b>Note</b>: Not all platforms support changing the z-order of
0686             * heavyweight components from one container into another without
0687             * the call to <code>removeNotify</code>. There is no way to detect
0688             * whether a platform supports this, so developers shouldn't make
0689             * any assumptions.
0690             *
0691             * @param     comp the component to be moved
0692             * @param     index the position in the container's list to
0693             *            insert the component, where <code>getComponentCount()</code>
0694             *            appends to the end
0695             * @exception NullPointerException if <code>comp</code> is
0696             *            <code>null</code>
0697             * @exception IllegalArgumentException if <code>comp</code> is one of the
0698             *            container's parents
0699             * @exception IllegalArgumentException if <code>index</code> is not in
0700             *            the range <code>[0, getComponentCount()]</code> for moving 
0701             *            between containers, or not in the range 
0702             *            <code>[0, getComponentCount()-1]</code> for moving inside
0703             *            a container
0704             * @exception IllegalArgumentException if adding a container to itself
0705             * @exception IllegalArgumentException if adding a <code>Window</code>
0706             *            to a container
0707             * @see #getComponentZOrder(java.awt.Component)
0708             * @since 1.5
0709             */
0710            public void setComponentZOrder(Component comp, int index) {
0711                synchronized (getTreeLock()) {
0712                    // Store parent because remove will clear it
0713                    Container curParent = comp.parent;
0714                    if (curParent == this  && index == getComponentZOrder(comp)) {
0715                        return;
0716                    }
0717                    checkAdding(comp, index);
0718                    if (curParent != null) {
0719                        curParent.removeDelicately(comp, this , index);
0720                    }
0721
0722                    addDelicately(comp, curParent, index);
0723                }
0724            }
0725
0726            /**
0727             * Traverses the tree of components and reparents children heavyweight component
0728             * to new heavyweight parent.
0729             * @since 1.5
0730             */
0731            private void reparentTraverse(ContainerPeer parentPeer,
0732                    Container child) {
0733                checkTreeLock();
0734
0735                for (int i = 0; i < child.getComponentCount(); i++) {
0736                    Component comp = child.getComponent(i);
0737                    if (comp.isLightweight()) {
0738                        // If components is lightweight check if it is container
0739                        // If it is container it might contain heavyweight children we need to reparent
0740                        if (comp instanceof  Container) {
0741                            reparentTraverse(parentPeer, (Container) comp);
0742                        }
0743                    } else {
0744                        // Q: Need to update NativeInLightFixer?
0745                        comp.getPeer().reparent(parentPeer);
0746                    }
0747                }
0748            }
0749
0750            /**
0751             * Reparents child component peer to this container peer. 
0752             * Container must be heavyweight.
0753             * @since 1.5
0754             */
0755            private void reparentChild(Component comp) {
0756                checkTreeLock();
0757                if (comp == null) {
0758                    return;
0759                }
0760                if (comp.isLightweight()) {
0761                    // If component is lightweight container we need to reparent all its explicit  heavyweight children
0762                    if (comp instanceof  Container) {
0763                        // Traverse component's tree till depth-first until encountering heavyweight component
0764                        reparentTraverse((ContainerPeer) getPeer(),
0765                                (Container) comp);
0766                    }
0767                } else {
0768                    comp.getPeer().reparent((ContainerPeer) getPeer());
0769                }
0770            }
0771
0772            /**
0773             * Adds component to this container. Tries to minimize side effects of this adding - 
0774             * doesn't call remove notify if it is not required. 
0775             * @since 1.5
0776             */
0777            private void addDelicately(Component comp, Container curParent,
0778                    int index) {
0779                checkTreeLock();
0780
0781                // Check if moving between containers
0782                if (curParent != this ) {
0783                    /* Add component to list; allocate new array if necessary. */
0784                    if (ncomponents == component.length) {
0785                        component = Arrays.copyOf(component,
0786                                ncomponents * 2 + 1);
0787                    }
0788                    if (index == -1 || index == ncomponents) {
0789                        component[ncomponents++] = comp;
0790                    } else {
0791                        System.arraycopy(component, index, component,
0792                                index + 1, ncomponents - index);
0793                        component[index] = comp;
0794                        ncomponents++;
0795                    }
0796                    comp.parent = this ;
0797
0798                    adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, comp
0799                            .numListening(AWTEvent.HIERARCHY_EVENT_MASK));
0800                    adjustListeningChildren(
0801                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
0802                            comp
0803                                    .numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
0804                    adjustDescendants(comp.countHierarchyMembers());
0805                } else {
0806                    if (index < ncomponents) {
0807                        component[index] = comp;
0808                    }
0809                }
0810
0811                if (valid) {
0812                    invalidate();
0813                }
0814                if (peer != null) {
0815                    if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
0816                        comp.addNotify();
0817                        // New created peer creates component on top of the stacking order
0818                        Container newNativeContainer = getHeavyweightContainer();
0819                        if (((ContainerPeer) newNativeContainer.getPeer())
0820                                .isRestackSupported()) {
0821                            ((ContainerPeer) newNativeContainer.getPeer())
0822                                    .restack();
0823                        }
0824                    } else { // Both container and child have peers, it means child peer should be reparented.
0825                        // In both cases we need to reparent native widgets.
0826                        Container newNativeContainer = getHeavyweightContainer();
0827                        Container oldNativeContainer = curParent
0828                                .getHeavyweightContainer();
0829                        if (oldNativeContainer != newNativeContainer) {
0830                            // Native container changed - need to reparent native widgets
0831                            newNativeContainer.reparentChild(comp);
0832                        }
0833                        // If component still has a peer and it is either container or heavyweight
0834                        // and restack is supported we have to restack native windows since order might have changed
0835                        if ((!comp.isLightweight() || (comp instanceof  Container))
0836                                && ((ContainerPeer) newNativeContainer
0837                                        .getPeer()).isRestackSupported()) {
0838                            ((ContainerPeer) newNativeContainer.getPeer())
0839                                    .restack();
0840                        }
0841                        if (!comp.isLightweight() && isLightweight()) {
0842                            // If component is heavyweight and one of the containers is lightweight
0843                            // some NativeInLightFixer activity should be performed
0844                            if (!curParent.isLightweight()) {
0845                                // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
0846                                // since addNotify does this
0847                                comp.nativeInLightFixer = new NativeInLightFixer();
0848                            } else {
0849                                // Component already has NativeInLightFixer - just reinstall it
0850                                // because hierarchy changed and he needs to rebuild list of parents to listen.
0851                                comp.nativeInLightFixer.install(this );
0852                            }
0853                        }
0854                    }
0855                }
0856                if (curParent != this ) {
0857                    /* Notify the layout manager of the added component. */
0858                    if (layoutMgr != null) {
0859                        if (layoutMgr instanceof  LayoutManager2) {
0860                            ((LayoutManager2) layoutMgr).addLayoutComponent(
0861                                    comp, null);
0862                        } else {
0863                            layoutMgr.addLayoutComponent(null, comp);
0864                        }
0865                    }
0866                    if (containerListener != null
0867                            || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
0868                            || Toolkit
0869                                    .enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
0870                        ContainerEvent e = new ContainerEvent(this ,
0871                                ContainerEvent.COMPONENT_ADDED, comp);
0872                        dispatchEvent(e);
0873                    }
0874                    comp
0875                            .createHierarchyEvents(
0876                                    HierarchyEvent.HIERARCHY_CHANGED,
0877                                    comp,
0878                                    this ,
0879                                    HierarchyEvent.PARENT_CHANGED,
0880                                    Toolkit
0881                                            .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
0882
0883                    // If component is focus owner or parent container of focus owner check that after reparenting
0884                    // focus owner moved out if new container prohibit this kind of focus owner.
0885                    if (comp.isFocusOwner() && !comp.canBeFocusOwner()) {
0886                        comp.transferFocus();
0887                    } else if (comp instanceof  Container) {
0888                        Component focusOwner = KeyboardFocusManager
0889                                .getCurrentKeyboardFocusManager()
0890                                .getFocusOwner();
0891                        if (focusOwner != null && isParentOf(focusOwner)
0892                                && !focusOwner.canBeFocusOwner()) {
0893                            focusOwner.transferFocus();
0894                        }
0895                    }
0896                } else {
0897                    comp
0898                            .createHierarchyEvents(
0899                                    HierarchyEvent.HIERARCHY_CHANGED,
0900                                    comp,
0901                                    this ,
0902                                    HierarchyEvent.HIERARCHY_CHANGED,
0903                                    Toolkit
0904                                            .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
0905                }
0906
0907                if (peer != null && layoutMgr == null && isVisible()) {
0908                    updateCursorImmediately();
0909                }
0910            }
0911
0912            /**
0913             * Returns the z-order index of the component inside the container. 
0914             * The higher a component is in the z-order hierarchy, the lower
0915             * its index.  The component with the lowest z-order index is
0916             * painted last, above all other child components.
0917             *
0918             * @param comp the component being queried
0919             * @return  the z-order index of the component; otherwise 
0920             *          returns -1 if the component is <code>null</code>
0921             *          or doesn't belong to the container 
0922             * @see #setComponentZOrder(java.awt.Component, int)
0923             * @since 1.5
0924             */
0925            public int getComponentZOrder(Component comp) {
0926                if (comp == null) {
0927                    return -1;
0928                }
0929                synchronized (getTreeLock()) {
0930                    // Quick check - container should be immediate parent of the component
0931                    if (comp.parent != this ) {
0932                        return -1;
0933                    }
0934                    for (int i = 0; i < ncomponents; i++) {
0935                        if (component[i] == comp) {
0936                            return i;
0937                        }
0938                    }
0939                }
0940                // To please javac
0941                return -1;
0942            }
0943
0944            /**
0945             * Adds the specified component to the end of this container.
0946             * Also notifies the layout manager to add the component to 
0947             * this container's layout using the specified constraints object.
0948             * This is a convenience method for {@link #addImpl}.
0949             * <p>
0950             * Note: If a component has been added to a container that
0951             * has been displayed, <code>validate</code> must be
0952             * called on that container to display the new component.
0953             * If multiple components are being added, you can improve
0954             * efficiency by calling <code>validate</code> only once,
0955             * after all the components have been added.
0956             *
0957             * @param     comp the component to be added
0958             * @param     constraints an object expressing 
0959             *                  layout contraints for this component
0960             * @exception NullPointerException if {@code comp} is {@code null}
0961             * @see #addImpl
0962             * @see #validate
0963             * @see javax.swing.JComponent#revalidate()
0964             * @see       LayoutManager
0965             * @since     JDK1.1
0966             */
0967            public void add(Component comp, Object constraints) {
0968                addImpl(comp, constraints, -1);
0969            }
0970
0971            /**
0972             * Adds the specified component to this container with the specified
0973             * constraints at the specified index.  Also notifies the layout 
0974             * manager to add the component to the this container's layout using 
0975             * the specified constraints object.
0976             * This is a convenience method for {@link #addImpl}.
0977             * <p>
0978             * Note: If a component has been added to a container that
0979             * has been displayed, <code>validate</code> must be
0980             * called on that container to display the new component.
0981             * If multiple components are being added, you can improve
0982             * efficiency by calling <code>validate</code> only once,
0983             * after all the components have been added.
0984             *
0985             * @param comp the component to be added
0986             * @param constraints an object expressing layout contraints for this
0987             * @param index the position in the container's list at which to insert
0988             * the component; <code>-1</code> means insert at the end
0989             * component
0990             * @exception NullPointerException if {@code comp} is {@code null}
0991             * @exception IllegalArgumentException if {@code index} is invalid (see
0992             *            {@link #addImpl} for details)
0993             * @see #addImpl
0994             * @see #validate
0995             * @see javax.swing.JComponent#revalidate()
0996             * @see #remove
0997             * @see LayoutManager
0998             */
0999            public void add(Component comp, Object constraints, int index) {
1000                addImpl(comp, constraints, index);
1001            }
1002
1003            /**
1004             * Adds the specified component to this container at the specified
1005             * index. This method also notifies the layout manager to add 
1006             * the component to this container's layout using the specified 
1007             * constraints object via the <code>addLayoutComponent</code>
1008             * method.
1009             * <p>
1010             * The constraints are
1011             * defined by the particular layout manager being used.  For 
1012             * example, the <code>BorderLayout</code> class defines five
1013             * constraints: <code>BorderLayout.NORTH</code>,
1014             * <code>BorderLayout.SOUTH</code>, <code>BorderLayout.EAST</code>,
1015             * <code>BorderLayout.WEST</code>, and <code>BorderLayout.CENTER</code>.
1016             * <p>
1017             * The <code>GridBagLayout</code> class requires a
1018             * <code>GridBagConstraints</code> object.  Failure to pass
1019             * the correct type of constraints object results in an
1020             * <code>IllegalArgumentException</code>.
1021             * <p>
1022             * If the current layout manager implements {@code LayoutManager2}, then
1023             * {@link LayoutManager2#addLayoutComponent(Component,Object)} is invoked on
1024             * it. If the current layout manager does not implement
1025             * {@code LayoutManager2}, and constraints is a {@code String}, then
1026             * {@link LayoutManager#addLayoutComponent(String,Component)} is invoked on it.
1027             * <p>
1028             * If the component is not an ancestor of this container and has a non-null
1029             * parent, it is removed from its current parent before it is added to this
1030             * container.
1031             * <p>
1032             * This is the method to override if a program needs to track 
1033             * every add request to a container as all other add methods defer
1034             * to this one. An overriding method should 
1035             * usually include a call to the superclass's version of the method:
1036             * <p>
1037             * <blockquote>
1038             * <code>super.addImpl(comp, constraints, index)</code>
1039             * </blockquote>
1040             * <p>
1041             * @param     comp       the component to be added
1042             * @param     constraints an object expressing layout constraints 
1043             *                 for this component
1044             * @param     index the position in the container's list at which to
1045             *                 insert the component, where <code>-1</code> 
1046             *                 means append to the end
1047             * @exception IllegalArgumentException if {@code index} is invalid;
1048             *            if {@code comp} is a child of this container, the valid
1049             *            range is {@code [-1, getComponentCount()-1]}; if component is
1050             *            not a child of this container, the valid range is 
1051             *            {@code [-1, getComponentCount()]}
1052             *
1053             * @exception IllegalArgumentException if {@code comp} is an ancestor of
1054             *                                     this container
1055             * @exception IllegalArgumentException if adding a window to a container
1056             * @exception NullPointerException if {@code comp} is {@code null}
1057             * @see       #add(Component)       
1058             * @see       #add(Component, int)       
1059             * @see       #add(Component, java.lang.Object)       
1060             * @see       LayoutManager
1061             * @see       LayoutManager2
1062             * @since     JDK1.1
1063             */
1064            protected void addImpl(Component comp, Object constraints, int index) {
1065                synchronized (getTreeLock()) {
1066                    /* Check for correct arguments:  index in bounds,
1067                     * comp cannot be one of this container's parents,
1068                     * and comp cannot be a window.
1069                     * comp and container must be on the same GraphicsDevice.
1070                     * if comp is container, all sub-components must be on
1071                     * same GraphicsDevice.
1072                     */
1073                    GraphicsConfiguration this GC = this 
1074                            .getGraphicsConfiguration();
1075
1076                    if (index > ncomponents || (index < 0 && index != -1)) {
1077                        throw new IllegalArgumentException(
1078                                "illegal component position");
1079                    }
1080                    if (comp instanceof  Container) {
1081                        for (Container cn = this ; cn != null; cn = cn.parent) {
1082                            if (cn == comp) {
1083                                throw new IllegalArgumentException(
1084                                        "adding container's parent to itself");
1085                            }
1086                        }
1087                        if (comp instanceof  Window) {
1088                            throw new IllegalArgumentException(
1089                                    "adding a window to a container");
1090                        }
1091                    }
1092                    if (this GC != null) {
1093                        comp.checkGD(this GC.getDevice().getIDstring());
1094                    }
1095
1096                    /* Reparent the component and tidy up the tree's state. */
1097                    if (comp.parent != null) {
1098                        comp.parent.remove(comp);
1099                        if (index > ncomponents) {
1100                            throw new IllegalArgumentException(
1101                                    "illegal component position");
1102                        }
1103                    }
1104
1105                    /* Add component to list; allocate new array if necessary. */
1106                    if (ncomponents == component.length) {
1107                        component = Arrays.copyOf(component,
1108                                ncomponents * 2 + 1);
1109                    }
1110                    if (index == -1 || index == ncomponents) {
1111                        component[ncomponents++] = comp;
1112                    } else {
1113                        System.arraycopy(component, index, component,
1114                                index + 1, ncomponents - index);
1115                        component[index] = comp;
1116                        ncomponents++;
1117                    }
1118                    comp.parent = this ;
1119
1120                    adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK, comp
1121                            .numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1122                    adjustListeningChildren(
1123                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1124                            comp
1125                                    .numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1126                    adjustDescendants(comp.countHierarchyMembers());
1127
1128                    if (valid) {
1129                        invalidate();
1130                    }
1131                    if (peer != null) {
1132                        comp.addNotify();
1133                    }
1134
1135                    /* Notify the layout manager of the added component. */
1136                    if (layoutMgr != null) {
1137                        if (layoutMgr instanceof  LayoutManager2) {
1138                            ((LayoutManager2) layoutMgr).addLayoutComponent(
1139                                    comp, constraints);
1140                        } else if (constraints instanceof  String) {
1141                            layoutMgr.addLayoutComponent((String) constraints,
1142                                    comp);
1143                        }
1144                    }
1145                    if (containerListener != null
1146                            || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
1147                            || Toolkit
1148                                    .enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1149                        ContainerEvent e = new ContainerEvent(this ,
1150                                ContainerEvent.COMPONENT_ADDED, comp);
1151                        dispatchEvent(e);
1152                    }
1153
1154                    comp
1155                            .createHierarchyEvents(
1156                                    HierarchyEvent.HIERARCHY_CHANGED,
1157                                    comp,
1158                                    this ,
1159                                    HierarchyEvent.PARENT_CHANGED,
1160                                    Toolkit
1161                                            .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1162                    if (peer != null && layoutMgr == null && isVisible()) {
1163                        updateCursorImmediately();
1164                    }
1165                }
1166            }
1167
1168            /**
1169             * Checks that all Components that this Container contains are on
1170             * the same GraphicsDevice as this Container.  If not, throws an
1171             * IllegalArgumentException.
1172             */
1173            void checkGD(String stringID) {
1174                Component tempComp;
1175                for (int i = 0; i < component.length; i++) {
1176                    tempComp = component[i];
1177                    if (tempComp != null) {
1178                        tempComp.checkGD(stringID);
1179                    }
1180                }
1181            }
1182
1183            /** 
1184             * Removes the component, specified by <code>index</code>, 
1185             * from this container. 
1186             * This method also notifies the layout manager to remove the
1187             * component from this container's layout via the
1188             * <code>removeLayoutComponent</code> method.
1189             *
1190             * <p>
1191             * Note: If a component has been removed from a container that
1192             * had been displayed, {@link #validate} must be
1193             * called on that container to reflect changes.
1194             * If multiple components are being removed, you can improve
1195             * efficiency by calling {@link #validate} only once,
1196             * after all the components have been removed.
1197             *
1198             * @param     index   the index of the component to be removed
1199             * @throws ArrayIndexOutOfBoundsException if {@code index} is not in
1200             *         range {@code [0, getComponentCount()-1]}
1201             * @see #add
1202             * @see #validate
1203             * @see #getComponentCount
1204             * @since JDK1.1
1205             */
1206            public void remove(int index) {
1207                synchronized (getTreeLock()) {
1208                    if (index < 0 || index >= ncomponents) {
1209                        throw new ArrayIndexOutOfBoundsException(index);
1210                    }
1211                    Component comp = component[index];
1212                    if (peer != null) {
1213                        comp.removeNotify();
1214                    }
1215                    if (layoutMgr != null) {
1216                        layoutMgr.removeLayoutComponent(comp);
1217                    }
1218
1219                    adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1220                            -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1221                    adjustListeningChildren(
1222                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1223                            -comp
1224                                    .numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1225                    adjustDescendants(-(comp.countHierarchyMembers()));
1226
1227                    comp.parent = null;
1228                    System.arraycopy(component, index + 1, component, index,
1229                            ncomponents - index - 1);
1230                    component[--ncomponents] = null;
1231
1232                    if (valid) {
1233                        invalidate();
1234                    }
1235                    if (containerListener != null
1236                            || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
1237                            || Toolkit
1238                                    .enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1239                        ContainerEvent e = new ContainerEvent(this ,
1240                                ContainerEvent.COMPONENT_REMOVED, comp);
1241                        dispatchEvent(e);
1242                    }
1243
1244                    comp
1245                            .createHierarchyEvents(
1246                                    HierarchyEvent.HIERARCHY_CHANGED,
1247                                    comp,
1248                                    this ,
1249                                    HierarchyEvent.PARENT_CHANGED,
1250                                    Toolkit
1251                                            .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1252                    if (peer != null && layoutMgr == null && isVisible()) {
1253                        updateCursorImmediately();
1254                    }
1255                }
1256            }
1257
1258            /** 
1259             * Removes the specified component from this container.
1260             * This method also notifies the layout manager to remove the
1261             * component from this container's layout via the
1262             * <code>removeLayoutComponent</code> method.
1263             *
1264             * <p>
1265             * Note: If a component has been removed from a container that
1266             * had been displayed, {@link #validate} must be
1267             * called on that container to reflect changes.
1268             * If multiple components are being removed, you can improve
1269             * efficiency by calling {@link #validate} only once,
1270             * after all the components have been removed.
1271             *
1272             * @param comp the component to be removed
1273             * @see #add
1274             * @see #validate
1275             * @see #remove(int)
1276             */
1277            public void remove(Component comp) {
1278                synchronized (getTreeLock()) {
1279                    if (comp.parent == this ) {
1280                        /* Search backwards, expect that more recent additions
1281                         * are more likely to be removed.
1282                         */
1283                        Component component[] = this .component;
1284                        for (int i = ncomponents; --i >= 0;) {
1285                            if (component[i] == comp) {
1286                                remove(i);
1287                            }
1288                        }
1289                    }
1290                }
1291            }
1292
1293            /** 
1294             * Removes all the components from this container.
1295             * This method also notifies the layout manager to remove the
1296             * components from this container's layout via the
1297             * <code>removeLayoutComponent</code> method.
1298             * @see #add
1299             * @see #remove
1300             */
1301            public void removeAll() {
1302                synchronized (getTreeLock()) {
1303                    adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1304                            -listeningChildren);
1305                    adjustListeningChildren(
1306                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1307                            -listeningBoundsChildren);
1308                    adjustDescendants(-descendantsCount);
1309
1310                    while (ncomponents > 0) {
1311                        Component comp = component[--ncomponents];
1312                        component[ncomponents] = null;
1313
1314                        if (peer != null) {
1315                            comp.removeNotify();
1316                        }
1317                        if (layoutMgr != null) {
1318                            layoutMgr.removeLayoutComponent(comp);
1319                        }
1320                        comp.parent = null;
1321                        if (containerListener != null
1322                                || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
1323                                || Toolkit
1324                                        .enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1325                            ContainerEvent e = new ContainerEvent(this ,
1326                                    ContainerEvent.COMPONENT_REMOVED, comp);
1327                            dispatchEvent(e);
1328                        }
1329
1330                        comp
1331                                .createHierarchyEvents(
1332                                        HierarchyEvent.HIERARCHY_CHANGED,
1333                                        comp,
1334                                        this ,
1335                                        HierarchyEvent.PARENT_CHANGED,
1336                                        Toolkit
1337                                                .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1338                    }
1339                    if (peer != null && layoutMgr == null && isVisible()) {
1340                        updateCursorImmediately();
1341                    }
1342                    if (valid) {
1343                        invalidate();
1344                    }
1345                }
1346            }
1347
1348            // Should only be called while holding tree lock
1349            int numListening(long mask) {
1350                int super Listening = super .numListening(mask);
1351
1352                if (mask == AWTEvent.HIERARCHY_EVENT_MASK) {
1353                    if (dbg.on) {
1354                        // Verify listeningChildren is correct
1355                        int sum = 0;
1356                        for (int i = 0; i < ncomponents; i++) {
1357                            sum += component[i].numListening(mask);
1358                        }
1359                        dbg.assertion(listeningChildren == sum);
1360                    }
1361                    return listeningChildren + super Listening;
1362                } else if (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
1363                    if (dbg.on) {
1364                        // Verify listeningBoundsChildren is correct
1365                        int sum = 0;
1366                        for (int i = 0; i < ncomponents; i++) {
1367                            sum += component[i].numListening(mask);
1368                        }
1369                        dbg.assertion(listeningBoundsChildren == sum);
1370                    }
1371                    return listeningBoundsChildren + super Listening;
1372                } else {
1373                    if (dbg.on) {
1374                        dbg.assertion(false);
1375                    }
1376                    return super Listening;
1377                }
1378            }
1379
1380            // Should only be called while holding tree lock
1381            void adjustListeningChildren(long mask, int num) {
1382                if (dbg.on) {
1383                    dbg
1384                            .assertion(mask == AWTEvent.HIERARCHY_EVENT_MASK
1385                                    || mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK
1386                                    || mask == (AWTEvent.HIERARCHY_EVENT_MASK | AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1387                }
1388
1389                if (num == 0)
1390                    return;
1391
1392                if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
1393                    listeningChildren += num;
1394                }
1395                if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
1396                    listeningBoundsChildren += num;
1397                }
1398
1399                adjustListeningChildrenOnParent(mask, num);
1400            }
1401
1402            // Should only be called while holding tree lock
1403            void adjustDescendants(int num) {
1404                if (num == 0)
1405                    return;
1406
1407                descendantsCount += num;
1408                adjustDecendantsOnParent(num);
1409            }
1410
1411            // Should only be called while holding tree lock
1412            void adjustDecendantsOnParent(int num) {
1413                if (parent != null) {
1414                    parent.adjustDescendants(num);
1415                }
1416            }
1417
1418            // Should only be called while holding tree lock
1419            int countHierarchyMembers() {
1420                if (dbg.on) {
1421                    // Verify descendantsCount is correct
1422                    int sum = 0;
1423                    for (int i = 0; i < ncomponents; i++) {
1424                        sum += component[i].countHierarchyMembers();
1425                    }
1426                    dbg.assertion(descendantsCount == sum);
1427                }
1428                return descendantsCount + 1;
1429            }
1430
1431            private int getListenersCount(int id, boolean enabledOnToolkit) {
1432                assert Thread.holdsLock(getTreeLock());
1433                if (enabledOnToolkit) {
1434                    return descendantsCount;
1435                }
1436                switch (id) {
1437                case HierarchyEvent.HIERARCHY_CHANGED:
1438                    return listeningChildren;
1439                case HierarchyEvent.ANCESTOR_MOVED:
1440                case HierarchyEvent.ANCESTOR_RESIZED:
1441                    return listeningBoundsChildren;
1442                default:
1443                    return 0;
1444                }
1445            }
1446
1447            final int createHierarchyEvents(int id, Component changed,
1448                    Container changedParent, long changeFlags,
1449                    boolean enabledOnToolkit) {
1450                assert Thread.holdsLock(getTreeLock());
1451                int listeners = getListenersCount(id, enabledOnToolkit);
1452
1453                for (int count = listeners, i = 0; count > 0; i++) {
1454                    count -= component[i].createHierarchyEvents(id, changed,
1455                            changedParent, changeFlags, enabledOnToolkit);
1456                }
1457                return listeners
1458                        + super .createHierarchyEvents(id, changed,
1459                                changedParent, changeFlags, enabledOnToolkit);
1460            }
1461
1462            final void createChildHierarchyEvents(int id, long changeFlags,
1463                    boolean enabledOnToolkit) {
1464                assert Thread.holdsLock(getTreeLock());
1465                if (ncomponents == 0) {
1466                    return;
1467                }
1468                int listeners = getListenersCount(id, enabledOnToolkit);
1469
1470                for (int count = listeners, i = 0; count > 0; i++) {
1471                    count -= component[i].createHierarchyEvents(id, this ,
1472                            parent, changeFlags, enabledOnToolkit);
1473                }
1474            }
1475
1476            /** 
1477             * Gets the layout manager for this container.  
1478             * @see #doLayout
1479             * @see #setLayout
1480             */
1481            public LayoutManager getLayout() {
1482                return layoutMgr;
1483            }
1484
1485            /** 
1486             * Sets the layout manager for this container.
1487             * @param mgr the specified layout manager
1488             * @see #doLayout
1489             * @see #getLayout
1490             */
1491            public void setLayout(LayoutManager mgr) {
1492                layoutMgr = mgr;
1493                if (valid) {
1494                    invalidate();
1495                }
1496            }
1497
1498            /** 
1499             * Causes this container to lay out its components.  Most programs 
1500             * should not call this method directly, but should invoke 
1501             * the <code>validate</code> method instead.
1502             * @see LayoutManager#layoutContainer
1503             * @see #setLayout
1504             * @see #validate
1505             * @since JDK1.1
1506             */
1507            public void doLayout() {
1508                layout();
1509            }
1510
1511            /** 
1512             * @deprecated As of JDK version 1.1,
1513             * replaced by <code>doLayout()</code>.
1514             */
1515            @Deprecated
1516            public void layout() {
1517                LayoutManager layoutMgr = this .layoutMgr;
1518                if (layoutMgr != null) {
1519                    layoutMgr.layoutContainer(this );
1520                }
1521            }
1522
1523            /**
1524             * Invalidates the container.  The container and all parents
1525             * above it are marked as needing to be laid out.  This method can
1526             * be called often, so it needs to execute quickly.
1527             *
1528             * <p> If the {@code LayoutManager} installed on this container is
1529             * an instance of {@code LayoutManager2}, then
1530             * {@link LayoutManager2#invalidateLayout(Container)} is invoked on
1531             * it supplying this {@code Container} as the argument.
1532             *
1533             * @see #validate
1534             * @see #layout
1535             * @see LayoutManager
1536             * @see LayoutManager2#invalidateLayout(Container)
1537             */
1538            public void invalidate() {
1539                LayoutManager layoutMgr = this .layoutMgr;
1540                if (layoutMgr instanceof  LayoutManager2) {
1541                    LayoutManager2 lm = (LayoutManager2) layoutMgr;
1542                    lm.invalidateLayout(this );
1543                }
1544                super .invalidate();
1545            }
1546
1547            /** 
1548             * Validates this container and all of its subcomponents.
1549             * <p>
1550             * The <code>validate</code> method is used to cause a container
1551             * to lay out its subcomponents again. It should be invoked when
1552             * this container's subcomponents are modified (added to or
1553             * removed from the container, or layout-related information
1554             * changed) after the container has been displayed.
1555             *
1556             * <p>If this {@code Container} is not valid, this method invokes
1557             * the {@code validateTree} method and marks this {@code Container}
1558             * as valid. Otherwise, no action is performed.
1559             *
1560             * @see #add(java.awt.Component)
1561             * @see Component#invalidate
1562             * @see javax.swing.JComponent#revalidate()
1563             * @see #validateTree
1564             */
1565            public void validate() {
1566                /* Avoid grabbing lock unless really necessary. */
1567                if (!valid) {
1568                    boolean updateCur = false;
1569                    synchronized (getTreeLock()) {
1570                        if (!valid && peer != null) {
1571                            ContainerPeer p = null;
1572                            if (peer instanceof  ContainerPeer) {
1573                                p = (ContainerPeer) peer;
1574                            }
1575                            if (p != null) {
1576                                p.beginValidate();
1577                            }
1578                            validateTree();
1579                            valid = true;
1580                            if (p != null) {
1581                                p.endValidate();
1582                                updateCur = isVisible();
1583                            }
1584                        }
1585                    }
1586                    if (updateCur) {
1587                        updateCursorImmediately();
1588                    }
1589                }
1590            }
1591
1592            /**
1593             * Recursively descends the container tree and recomputes the
1594             * layout for any subtrees marked as needing it (those marked as
1595             * invalid).  Synchronization should be provided by the method
1596             * that calls this one:  <code>validate</code>.
1597             *
1598             * @see #doLayout
1599             * @see #validate
1600             */
1601            protected void validateTree() {
1602                if (!valid) {
1603                    if (peer instanceof  ContainerPeer) {
1604                        ((ContainerPeer) peer).beginLayout();
1605                    }
1606                    doLayout();
1607                    Component component[] = this .component;
1608                    for (int i = 0; i < ncomponents; ++i) {
1609                        Component comp = component[i];
1610                        if ((comp instanceof  Container)
1611                                && !(comp instanceof  Window) && !comp.valid) {
1612                            ((Container) comp).validateTree();
1613                        } else {
1614                            comp.validate();
1615                        }
1616                    }
1617                    if (peer instanceof  ContainerPeer) {
1618                        ((ContainerPeer) peer).endLayout();
1619                    }
1620                }
1621                valid = true;
1622            }
1623
1624            /**
1625             * Recursively descends the container tree and invalidates all
1626             * contained components.
1627             */
1628            void invalidateTree() {
1629                synchronized (getTreeLock()) {
1630                    for (int i = 0; i < ncomponents; ++i) {
1631                        Component comp = component[i];
1632                        if (comp instanceof  Container) {
1633                            ((Container) comp).invalidateTree();
1634                        } else {
1635                            if (comp.valid) {
1636                                comp.invalidate();
1637                            }
1638                        }
1639                    }
1640                    if (valid) {
1641                        invalidate();
1642                    }
1643                }
1644            }
1645
1646            /**
1647             * Sets the font of this container.
1648             * @param f The font to become this container's font.
1649             * @see Component#getFont
1650             * @since JDK1.0
1651             */
1652            public void setFont(Font f) {
1653                boolean shouldinvalidate = false;
1654
1655                Font oldfont = getFont();
1656                super .setFont(f);
1657                Font newfont = getFont();
1658                if (newfont != oldfont
1659                        && (oldfont == null || !oldfont.equals(newfont))) {
1660                    invalidateTree();
1661                }
1662            }
1663
1664            /**
1665             * Returns the preferred size of this container.  If the preferred size has
1666             * not been set explicitly by {@link Component#setPreferredSize(Dimension)}
1667             * and this {@code Container} has a {@code non-null} {@link LayoutManager},
1668             * then {@link LayoutManager#preferredLayoutSize(Container)}
1669             * is used to calculate the preferred size.
1670             *
1671             * <p>Note: some implementations may cache the value returned from the
1672             * {@code LayoutManager}.  Implementations that cache need not invoke
1673             * {@code preferredLayoutSize} on the {@code LayoutManager} every time
1674             * this method is invoked, rather the {@code LayoutManager} will only
1675             * be queried after the {@code Container} becomes invalid.
1676             *
1677             * @return    an instance of <code>Dimension</code> that represents
1678             *                the preferred size of this container.
1679             * @see       #getMinimumSize
1680             * @see       #getMaximumSize
1681             * @see       #getLayout
1682             * @see       LayoutManager#preferredLayoutSize(Container)
1683             * @see       Component#getPreferredSize
1684             */
1685            public Dimension getPreferredSize() {
1686                return preferredSize();
1687            }
1688
1689            /** 
1690             * @deprecated As of JDK version 1.1,
1691             * replaced by <code>getPreferredSize()</code>.
1692             */
1693            @Deprecated
1694            public Dimension preferredSize() {
1695                /* Avoid grabbing the lock if a reasonable cached size value
1696                 * is available.
1697                 */
1698                Dimension dim = prefSize;
1699                if (dim == null || !(isPreferredSizeSet() || isValid())) {
1700                    synchronized (getTreeLock()) {
1701                        prefSize = (layoutMgr != null) ? layoutMgr
1702                                .preferredLayoutSize(this ) : super 
1703                                .preferredSize();
1704                        dim = prefSize;
1705                    }
1706                }
1707                if (dim != null) {
1708                    return new Dimension(dim);
1709                } else {
1710                    return dim;
1711                }
1712            }
1713
1714            /**
1715             * Returns the minimum size of this container.  If the minimum size has
1716             * not been set explicitly by {@link Component#setMinimumSize(Dimension)}
1717             * and this {@code Container} has a {@code non-null} {@link LayoutManager},
1718             * then {@link LayoutManager#minimumLayoutSize(Container)}
1719             * is used to calculate the minimum size.
1720             *
1721             * <p>Note: some implementations may cache the value returned from the
1722             * {@code LayoutManager}.  Implementations that cache need not invoke
1723             * {@code minimumLayoutSize} on the {@code LayoutManager} every time
1724             * this method is invoked, rather the {@code LayoutManager} will only
1725             * be queried after the {@code Container} becomes invalid.
1726             *
1727             * @return    an instance of <code>Dimension</code> that represents
1728             *                the minimum size of this container.
1729             * @see       #getPreferredSize
1730             * @see       #getMaximumSize
1731             * @see       #getLayout
1732             * @see       LayoutManager#minimumLayoutSize(Container)
1733             * @see       Component#getMinimumSize
1734             * @since     JDK1.1
1735             */
1736            public Dimension getMinimumSize() {
1737                return minimumSize();
1738            }
1739
1740            /** 
1741             * @deprecated As of JDK version 1.1,
1742             * replaced by <code>getMinimumSize()</code>.
1743             */
1744            @Deprecated
1745            public Dimension minimumSize() {
1746                /* Avoid grabbing the lock if a reasonable cached size value
1747                 * is available.
1748                 */
1749                Dimension dim = minSize;
1750                if (dim == null || !(isMinimumSizeSet() || isValid())) {
1751                    synchronized (getTreeLock()) {
1752                        minSize = (layoutMgr != null) ? layoutMgr
1753                                .minimumLayoutSize(this ) : super .minimumSize();
1754                        dim = minSize;
1755                    }
1756                }
1757                if (dim != null) {
1758                    return new Dimension(dim);
1759                } else {
1760                    return dim;
1761                }
1762            }
1763
1764            /** 
1765             * Returns the maximum size of this container.  If the maximum size has
1766             * not been set explicitly by {@link Component#setMaximumSize(Dimension)}
1767             * and the {@link LayoutManager} installed on this {@code Container}
1768             * is an instance of {@link LayoutManager2}, then
1769             * {@link LayoutManager2#maximumLayoutSize(Container)}
1770             * is used to calculate the maximum size.
1771             *
1772             * <p>Note: some implementations may cache the value returned from the
1773             * {@code LayoutManager2}.  Implementations that cache need not invoke
1774             * {@code maximumLayoutSize} on the {@code LayoutManager2} every time
1775             * this method is invoked, rather the {@code LayoutManager2} will only
1776             * be queried after the {@code Container} becomes invalid.
1777             *
1778             * @return    an instance of <code>Dimension</code> that represents
1779             *                the maximum size of this container.
1780             * @see       #getPreferredSize
1781             * @see       #getMinimumSize
1782             * @see       #getLayout
1783             * @see       LayoutManager2#maximumLayoutSize(Container)
1784             * @see       Component#getMaximumSize
1785             */
1786            public Dimension getMaximumSize() {
1787                /* Avoid grabbing the lock if a reasonable cached size value
1788                 * is available.
1789                 */
1790                Dimension dim = maxSize;
1791                if (dim == null || !(isMaximumSizeSet() || isValid())) {
1792                    synchronized (getTreeLock()) {
1793                        if (layoutMgr instanceof  LayoutManager2) {
1794                            LayoutManager2 lm = (LayoutManager2) layoutMgr;
1795                            maxSize = lm.maximumLayoutSize(this );
1796                        } else {
1797                            maxSize = super .getMaximumSize();
1798                        }
1799                        dim = maxSize;
1800                    }
1801                }
1802                if (dim != null) {
1803                    return new Dimension(dim);
1804                } else {
1805                    return dim;
1806                }
1807            }
1808
1809            /**
1810             * Returns the alignment along the x axis.  This specifies how
1811             * the component would like to be aligned relative to other 
1812             * components.  The value should be a number between 0 and 1
1813             * where 0 represents alignment along the origin, 1 is aligned
1814             * the furthest away from the origin, 0.5 is centered, etc.
1815             */
1816            public float getAlignmentX() {
1817                float xAlign;
1818                if (layoutMgr instanceof  LayoutManager2) {
1819                    synchronized (getTreeLock()) {
1820                        LayoutManager2 lm = (LayoutManager2) layoutMgr;
1821                        xAlign = lm.getLayoutAlignmentX(this );
1822                    }
1823                } else {
1824                    xAlign = super .getAlignmentX();
1825                }
1826                return xAlign;
1827            }
1828
1829            /**
1830             * Returns the alignment along the y axis.  This specifies how
1831             * the component would like to be aligned relative to other 
1832             * components.  The value should be a number between 0 and 1
1833             * where 0 represents alignment along the origin, 1 is aligned
1834             * the furthest away from the origin, 0.5 is centered, etc.
1835             */
1836            public float getAlignmentY() {
1837                float yAlign;
1838                if (layoutMgr instanceof  LayoutManager2) {
1839                    synchronized (getTreeLock()) {
1840                        LayoutManager2 lm = (LayoutManager2) layoutMgr;
1841                        yAlign = lm.getLayoutAlignmentY(this );
1842                    }
1843                } else {
1844                    yAlign = super .getAlignmentY();
1845                }
1846                return yAlign;
1847            }
1848
1849            /** 
1850             * Paints the container. This forwards the paint to any lightweight
1851             * components that are children of this container. If this method is
1852             * reimplemented, super.paint(g) should be called so that lightweight
1853             * components are properly rendered. If a child component is entirely
1854             * clipped by the current clipping setting in g, paint() will not be
1855             * forwarded to that child.
1856             *
1857             * @param g the specified Graphics window
1858             * @see   Component#update(Graphics)
1859             */
1860            public void paint(Graphics g) {
1861                if (isShowing()) {
1862                    synchronized (this ) {
1863                        if (printing) {
1864                            if (printingThreads
1865                                    .contains(Thread.currentThread())) {
1866                                return;
1867                            }
1868                        }
1869                    }
1870
1871                    // The container is showing on screen and
1872                    // this paint() is not called from print().
1873                    // Paint self and forward the paint to lightweight subcomponents.
1874
1875                    // super.paint(); -- Don't bother, since it's a NOP.
1876
1877                    GraphicsCallback.PaintCallback.getInstance().runComponents(
1878                            component, g, GraphicsCallback.LIGHTWEIGHTS);
1879                }
1880            }
1881
1882            /** 
1883             * Updates the container.  This forwards the update to any lightweight
1884             * components that are children of this container.  If this method is
1885             * reimplemented, super.update(g) should be called so that lightweight
1886             * components are properly rendered.  If a child component is entirely
1887             * clipped by the current clipping setting in g, update() will not be
1888             * forwarded to that child.
1889             *
1890             * @param g the specified Graphics window
1891             * @see   Component#update(Graphics)
1892             */
1893            public void update(Graphics g) {
1894                if (isShowing()) {
1895                    if (!(peer instanceof  LightweightPeer)) {
1896                        g.clearRect(0, 0, width, height);
1897                    }
1898                    paint(g);
1899                }
1900            }
1901
1902            /** 
1903             * Prints the container. This forwards the print to any lightweight
1904             * components that are children of this container. If this method is
1905             * reimplemented, super.print(g) should be called so that lightweight
1906             * components are properly rendered. If a child component is entirely
1907             * clipped by the current clipping setting in g, print() will not be
1908             * forwarded to that child.
1909             *
1910             * @param g the specified Graphics window
1911             * @see   Component#update(Graphics)
1912             */
1913            public void print(Graphics g) {
1914                if (isShowing()) {
1915                    Thread t = Thread.currentThread();
1916                    try {
1917                        synchronized (this ) {
1918                            if (printingThreads == null) {
1919                                printingThreads = new HashSet();
1920                            }
1921                            printingThreads.add(t);
1922                            printing = true;
1923                        }
1924                        super .print(g); // By default, Component.print() calls paint()
1925                    } finally {
1926                        synchronized (this ) {
1927                            printingThreads.remove(t);
1928                            printing = !printingThreads.isEmpty();
1929                        }
1930                    }
1931
1932                    GraphicsCallback.PrintCallback.getInstance().runComponents(
1933                            component, g, GraphicsCallback.LIGHTWEIGHTS);
1934                }
1935            }
1936
1937            /** 
1938             * Paints each of the components in this container.
1939             * @param     g   the graphics context.
1940             * @see       Component#paint
1941             * @see       Component#paintAll
1942             */
1943            public void paintComponents(Graphics g) {
1944                if (isShowing()) {
1945                    GraphicsCallback.PaintAllCallback.getInstance()
1946                            .runComponents(component, g,
1947                                    GraphicsCallback.TWO_PASSES);
1948                }
1949            }
1950
1951            /**
1952             * Simulates the peer callbacks into java.awt for printing of
1953             * lightweight Containers.
1954             * @param     g   the graphics context to use for printing.
1955             * @see       Component#printAll
1956             * @see       #printComponents
1957             */
1958            void lightweightPaint(Graphics g) {
1959                super .lightweightPaint(g);
1960                paintHeavyweightComponents(g);
1961            }
1962
1963            /**
1964             * Prints all the heavyweight subcomponents.
1965             */
1966            void paintHeavyweightComponents(Graphics g) {
1967                if (isShowing()) {
1968                    GraphicsCallback.PaintHeavyweightComponentsCallback
1969                            .getInstance().runComponents(
1970                                    component,
1971                                    g,
1972                                    GraphicsCallback.LIGHTWEIGHTS
1973                                            | GraphicsCallback.HEAVYWEIGHTS);
1974                }
1975            }
1976
1977            /** 
1978             * Prints each of the components in this container. 
1979             * @param     g   the graphics context.
1980             * @see       Component#print
1981             * @see       Component#printAll
1982             */
1983            public void printComponents(Graphics g) {
1984                if (isShowing()) {
1985                    GraphicsCallback.PrintAllCallback.getInstance()
1986                            .runComponents(component, g,
1987                                    GraphicsCallback.TWO_PASSES);
1988                }
1989            }
1990
1991            /**
1992             * Simulates the peer callbacks into java.awt for printing of
1993             * lightweight Containers.
1994             * @param     g   the graphics context to use for printing.
1995             * @see       Component#printAll
1996             * @see       #printComponents
1997             */
1998            void lightweightPrint(Graphics g) {
1999                super .lightweightPrint(g);
2000                printHeavyweightComponents(g);
2001            }
2002
2003            /**
2004             * Prints all the heavyweight subcomponents.
2005             */
2006            void printHeavyweightComponents(Graphics g) {
2007                if (isShowing()) {
2008                    GraphicsCallback.PrintHeavyweightComponentsCallback
2009                            .getInstance().runComponents(
2010                                    component,
2011                                    g,
2012                                    GraphicsCallback.LIGHTWEIGHTS
2013                                            | GraphicsCallback.HEAVYWEIGHTS);
2014                }
2015            }
2016
2017            /**
2018             * Adds the specified container listener to receive container events
2019             * from this container.
2020             * If l is null, no exception is thrown and no action is performed.
2021             * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
2022             * >AWT Threading Issues</a> for details on AWT's threading model.
2023             *
2024             * @param    l the container listener
2025             *
2026             * @see #removeContainerListener
2027             * @see #getContainerListeners
2028             */
2029            public synchronized void addContainerListener(ContainerListener l) {
2030                if (l == null) {
2031                    return;
2032                }
2033                containerListener = AWTEventMulticaster.add(containerListener,
2034                        l);
2035                newEventsOnly = true;
2036            }
2037
2038            /**
2039             * Removes the specified container listener so it no longer receives
2040             * container events from this container.
2041             * If l is null, no exception is thrown and no action is performed.
2042             * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
2043             * >AWT Threading Issues</a> for details on AWT's threading model.
2044             *
2045             * @param 	l the container listener
2046             *
2047             * @see #addContainerListener
2048             * @see #getContainerListeners
2049             */
2050            public synchronized void removeContainerListener(ContainerListener l) {
2051                if (l == null) {
2052                    return;
2053                }
2054                containerListener = AWTEventMulticaster.remove(
2055                        containerListener, l);
2056            }
2057
2058            /**
2059             * Returns an array of all the container listeners
2060             * registered on this container.
2061             *
2062             * @return all of this container's <code>ContainerListener</code>s
2063             *         or an empty array if no container
2064             *         listeners are currently registered
2065             *
2066             * @see #addContainerListener
2067             * @see #removeContainerListener
2068             * @since 1.4
2069             */
2070            public synchronized ContainerListener[] getContainerListeners() {
2071                return (ContainerListener[]) (getListeners(ContainerListener.class));
2072            }
2073
2074            /**
2075             * Returns an array of all the objects currently registered
2076             * as <code><em>Foo</em>Listener</code>s
2077             * upon this <code>Container</code>.
2078             * <code><em>Foo</em>Listener</code>s are registered using the
2079             * <code>add<em>Foo</em>Listener</code> method.
2080             *
2081             * <p>
2082             * You can specify the <code>listenerType</code> argument
2083             * with a class literal, such as
2084             * <code><em>Foo</em>Listener.class</code>.
2085             * For example, you can query a
2086             * <code>Container</code> <code>c</code>
2087             * for its container listeners with the following code:
2088             *
2089             * <pre>ContainerListener[] cls = (ContainerListener[])(c.getListeners(ContainerListener.class));</pre>
2090             *
2091             * If no such listeners exist, this method returns an empty array.
2092             *
2093             * @param listenerType the type of listeners requested; this parameter
2094             *          should specify an interface that descends from
2095             *          <code>java.util.EventListener</code>
2096             * @return an array of all objects registered as
2097             *          <code><em>Foo</em>Listener</code>s on this container,
2098             *          or an empty array if no such listeners have been added
2099             * @exception ClassCastException if <code>listenerType</code>
2100             *          doesn't specify a class or interface that implements
2101             *          <code>java.util.EventListener</code>
2102             *
2103             * @see #getContainerListeners
2104             *
2105             * @since 1.3
2106             */
2107            public <T extends EventListener> T[] getListeners(
2108                    Class<T> listenerType) {
2109                EventListener l = null;
2110                if (listenerType == ContainerListener.class) {
2111                    l = containerListener;
2112                } else {
2113                    return super .getListeners(listenerType);
2114                }
2115                return AWTEventMulticaster.getListeners(l, listenerType);
2116            }
2117
2118            // REMIND: remove when filtering is done at lower level
2119            boolean eventEnabled(AWTEvent e) {
2120                int id = e.getID();
2121
2122                if (id == ContainerEvent.COMPONENT_ADDED
2123                        || id == ContainerEvent.COMPONENT_REMOVED) {
2124                    if ((eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0
2125                            || containerListener != null) {
2126                        return true;
2127                    }
2128                    return false;
2129                }
2130                return super .eventEnabled(e);
2131            }
2132
2133            /**
2134             * Processes events on this container. If the event is a
2135             * <code>ContainerEvent</code>, it invokes the
2136             * <code>processContainerEvent</code> method, else it invokes 
2137             * its superclass's <code>processEvent</code>.
2138             * <p>Note that if the event parameter is <code>null</code>
2139             * the behavior is unspecified and may result in an
2140             * exception.
2141             *
2142             * @param e the event
2143             */
2144            protected void processEvent(AWTEvent e) {
2145                if (e instanceof  ContainerEvent) {
2146                    processContainerEvent((ContainerEvent) e);
2147                    return;
2148                }
2149                super .processEvent(e);
2150            }
2151
2152            /** 
2153             * Processes container events occurring on this container by
2154             * dispatching them to any registered ContainerListener objects.
2155             * NOTE: This method will not be called unless container events
2156             * are enabled for this component; this happens when one of the
2157             * following occurs:
2158             * <ul>
2159             * <li>A ContainerListener object is registered via
2160             *     <code>addContainerListener</code>
2161             * <li>Container events are enabled via <code>enableEvents</code>
2162             * </ul>
2163             * <p>Note that if the event parameter is <code>null</code>
2164             * the behavior is unspecified and may result in an
2165             * exception.
2166             *
2167             * @param e the container event
2168             * @see Component#enableEvents
2169             */
2170            protected void processContainerEvent(ContainerEvent e) {
2171                ContainerListener listener = containerListener;
2172                if (listener != null) {
2173                    switch (e.getID()) {
2174                    case ContainerEvent.COMPONENT_ADDED:
2175                        listener.componentAdded(e);
2176                        break;
2177                    case ContainerEvent.COMPONENT_REMOVED:
2178                        listener.componentRemoved(e);
2179                        break;
2180                    }
2181                }
2182            }
2183
2184            /*
2185             * Dispatches an event to this component or one of its sub components.
2186             * Create ANCESTOR_RESIZED and ANCESTOR_MOVED events in response to
2187             * COMPONENT_RESIZED and COMPONENT_MOVED events. We have to do this
2188             * here instead of in processComponentEvent because ComponentEvents
2189             * may not be enabled for this Container.
2190             * @param e the event
2191             */
2192            void dispatchEventImpl(AWTEvent e) {
2193                if ((dispatcher != null) && dispatcher.dispatchEvent(e)) {
2194                    // event was sent to a lightweight component.  The
2195                    // native-produced event sent to the native container
2196                    // must be properly disposed of by the peer, so it 
2197                    // gets forwarded.  If the native host has been removed
2198                    // as a result of the sending the lightweight event, 
2199                    // the peer reference will be null.
2200                    e.consume();
2201                    if (peer != null) {
2202                        peer.handleEvent(e);
2203                    }
2204                    return;
2205                }
2206
2207                super .dispatchEventImpl(e);
2208
2209                synchronized (getTreeLock()) {
2210                    switch (e.getID()) {
2211                    case ComponentEvent.COMPONENT_RESIZED:
2212                        createChildHierarchyEvents(
2213                                HierarchyEvent.ANCESTOR_RESIZED,
2214                                0,
2215                                Toolkit
2216                                        .enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2217                        break;
2218                    case ComponentEvent.COMPONENT_MOVED:
2219                        createChildHierarchyEvents(
2220                                HierarchyEvent.ANCESTOR_MOVED,
2221                                0,
2222                                Toolkit
2223                                        .enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2224                        break;
2225                    default:
2226                        break;
2227                    }
2228                }
2229            }
2230
2231            /*
2232             * Dispatches an event to this component, without trying to forward
2233             * it to any subcomponents
2234             * @param e the event
2235             */
2236            void dispatchEventToSelf(AWTEvent e) {
2237                super .dispatchEventImpl(e);
2238            }
2239
2240            /**
2241             * Fetchs the top-most (deepest) lightweight component that is interested
2242             * in receiving mouse events.
2243             */
2244            Component getMouseEventTarget(int x, int y, boolean includeSelf) {
2245                return getMouseEventTarget(x, y, includeSelf,
2246                        MouseEventTargetFilter.FILTER, !SEARCH_HEAVYWEIGHTS);
2247            }
2248
2249            /**
2250             * Fetches the top-most (deepest) component to receive SunDropTargetEvents.
2251             */
2252            Component getDropTargetEventTarget(int x, int y, boolean includeSelf) {
2253                return getMouseEventTarget(x, y, includeSelf,
2254                        DropTargetEventTargetFilter.FILTER, SEARCH_HEAVYWEIGHTS);
2255            }
2256
2257            /**
2258             * A private version of getMouseEventTarget which has two additional 
2259             * controllable behaviors. This method searches for the top-most 
2260             * descendant of this container that contains the given coordinates   
2261             * and is accepted by the given filter. The search will be constrained to
2262             * lightweight descendants if the last argument is <code>false</code>.
2263             *
2264             * @param filter EventTargetFilter instance to determine whether the
2265             *        given component is a valid target for this event. 
2266             * @param searchHeavyweights if <code>false</code>, the method 
2267             *        will bypass heavyweight components during the search. 
2268             */
2269            private Component getMouseEventTarget(int x, int y,
2270                    boolean includeSelf, EventTargetFilter filter,
2271                    boolean searchHeavyweights) {
2272                Component comp = null;
2273                if (searchHeavyweights) {
2274                    comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2275                            SEARCH_HEAVYWEIGHTS, searchHeavyweights);
2276                }
2277
2278                if (comp == null || comp == this ) {
2279                    comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2280                            !SEARCH_HEAVYWEIGHTS, searchHeavyweights);
2281                }
2282
2283                return comp;
2284            }
2285
2286            /**
2287             * A private version of getMouseEventTarget which has three additional 
2288             * controllable behaviors. This method searches for the top-most 
2289             * descendant of this container that contains the given coordinates   
2290             * and is accepted by the given filter. The search will be constrained to
2291             * descendants of only lightweight children or only heavyweight children 
2292             * of this container depending on searchHeavyweightChildren. The search will
2293             * be constrained to only lightweight descendants of the searched children
2294             * of this container if searchHeavyweightDescendants is <code>false</code>. 
2295             *
2296             * @param filter EventTargetFilter instance to determine whether the
2297             *        selected component is a valid target for this event. 
2298             * @param searchHeavyweightChildren if <code>true</code>, the method 
2299             *        will bypass immediate lightweight children during the search.
2300             *        If <code>false</code>, the methods will bypass immediate
2301             *        heavyweight children during the search. 
2302             * @param searchHeavyweightDescendants if <code>false</code>, the method 
2303             *        will bypass heavyweight descendants which are not immediate
2304             *        children during the search. If <code>true</code>, the method
2305             *        will traverse both lightweight and heavyweight descendants during
2306             *        the search.
2307             */
2308            private Component getMouseEventTargetImpl(int x, int y,
2309                    boolean includeSelf, EventTargetFilter filter,
2310                    boolean searchHeavyweightChildren,
2311                    boolean searchHeavyweightDescendants) {
2312                int ncomponents = this .ncomponents;
2313                Component component[] = this .component;
2314
2315                for (int i = 0; i < ncomponents; i++) {
2316                    Component comp = component[i];
2317                    if (comp != null
2318                            && comp.visible
2319                            && ((!searchHeavyweightChildren && comp.peer instanceof  LightweightPeer) || (searchHeavyweightChildren && !(comp.peer instanceof  LightweightPeer)))
2320                            && comp.contains(x - comp.x, y - comp.y)) {
2321
2322                        // found a component that intersects the point, see if there is 
2323                        // a deeper possibility.
2324                        if (comp instanceof  Container) {
2325                            Container child = (Container) comp;
2326                            Component deeper = child.getMouseEventTarget(x
2327                                    - child.x, y - child.y, includeSelf,
2328                                    filter, searchHeavyweightDescendants);
2329                            if (deeper != null) {
2330                                return deeper;
2331                            }
2332                        } else {
2333                            if (filter.accept(comp)) {
2334                                // there isn't a deeper target, but this component is a
2335                                // target
2336                                return comp;
2337                            }
2338                        }
2339                    }
2340                }
2341
2342                boolean isPeerOK;
2343                boolean isMouseOverMe;
2344
2345                isPeerOK = (peer instanceof  LightweightPeer) || includeSelf;
2346                isMouseOverMe = contains(x, y);
2347
2348                // didn't find a child target, return this component if it's a possible
2349                // target
2350                if (isMouseOverMe && isPeerOK && filter.accept(this )) {
2351                    return this ;
2352                }
2353                // no possible target
2354                return null;
2355            }
2356
2357            static interface EventTargetFilter {
2358                boolean accept(final Component comp);
2359            }
2360
2361            static class MouseEventTargetFilter implements  EventTargetFilter {
2362                static final EventTargetFilter FILTER = new MouseEventTargetFilter();
2363
2364                private MouseEventTargetFilter() {
2365                }
2366
2367                public boolean accept(final Component comp) {
2368                    return (comp.eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
2369                            || (comp.eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
2370                            || (comp.eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0
2371                            || comp.mouseListener != null
2372                            || comp.mouseMotionListener != null
2373                            || comp.mouseWheelListener != null;
2374                }
2375            }
2376
2377            static class DropTargetEventTargetFilter implements 
2378                    EventTargetFilter {
2379                static final EventTargetFilter FILTER = new DropTargetEventTargetFilter();
2380
2381                private DropTargetEventTargetFilter() {
2382                }
2383
2384                public boolean accept(final Component comp) {
2385                    DropTarget dt = comp.getDropTarget();
2386                    return dt != null && dt.isActive();
2387                }
2388            }
2389
2390            /**
2391             * This is called by lightweight components that want the containing
2392             * windowed parent to enable some kind of events on their behalf.
2393             * This is needed for events that are normally only dispatched to 
2394             * windows to be accepted so that they can be forwarded downward to 
2395             * the lightweight component that has enabled them.
2396             */
2397            void proxyEnableEvents(long events) {
2398                if (peer instanceof  LightweightPeer) {
2399                    // this container is lightweight.... continue sending it
2400                    // upward.
2401                    if (parent != null) {
2402                        parent.proxyEnableEvents(events);
2403                    }
2404                } else {
2405                    // This is a native container, so it needs to host
2406                    // one of it's children.  If this function is called before
2407                    // a peer has been created we don't yet have a dispatcher
2408                    // because it has not yet been determined if this instance
2409                    // is lightweight.
2410                    if (dispatcher != null) {
2411                        dispatcher.enableEvents(events);
2412                    }
2413                }
2414            }
2415
2416            /**
2417             * @deprecated As of JDK version 1.1,
2418             * replaced by <code>dispatchEvent(AWTEvent e)</code>
2419             */
2420            @Deprecated
2421            public void deliverEvent(Event e) {
2422                Component comp = getComponentAt(e.x, e.y);
2423                if ((comp != null) && (comp != this )) {
2424                    e.translate(-comp.x, -comp.y);
2425                    comp.deliverEvent(e);
2426                } else {
2427                    postEvent(e);
2428                }
2429            }
2430
2431            /**
2432             * Locates the component that contains the x,y position.  The
2433             * top-most child component is returned in the case where there
2434             * is overlap in the components.  This is determined by finding
2435             * the component closest to the index 0 that claims to contain
2436             * the given point via Component.contains(), except that Components
2437             * which have native peers take precedence over those which do not
2438             * (i.e., lightweight Components).
2439             *
2440             * @param x the <i>x</i> coordinate
2441             * @param y the <i>y</i> coordinate
2442             * @return null if the component does not contain the position.
2443             * If there is no child component at the requested point and the 
2444             * point is within the bounds of the container the container itself 
2445             * is returned; otherwise the top-most child is returned.
2446             * @see Component#contains
2447             * @since JDK1.1
2448             */
2449            public Component getComponentAt(int x, int y) {
2450                return locate(x, y);
2451            }
2452
2453            /**
2454             * @deprecated As of JDK version 1.1,
2455             * replaced by <code>getComponentAt(int, int)</code>.
2456             */
2457            @Deprecated
2458            public Component locate(int x, int y) {
2459                if (!contains(x, y)) {
2460                    return null;
2461                }
2462                synchronized (getTreeLock()) {
2463                    // Two passes: see comment in sun.awt.SunGraphicsCallback
2464                    for (int i = 0; i < ncomponents; i++) {
2465                        Component comp = component[i];
2466                        if (comp != null
2467                                && !(comp.peer instanceof  LightweightPeer)) {
2468                            if (comp.contains(x - comp.x, y - comp.y)) {
2469                                return comp;
2470                            }
2471                        }
2472                    }
2473                    for (int i = 0; i < ncomponents; i++) {
2474                        Component comp = component[i];
2475                        if (comp != null
2476                                && comp.peer instanceof  LightweightPeer) {
2477                            if (comp.contains(x - comp.x, y - comp.y)) {
2478                                return comp;
2479                            }
2480                        }
2481                    }
2482                }
2483                return this ;
2484            }
2485
2486            /**
2487             * Gets the component that contains the specified point.
2488             * @param      p   the point.
2489             * @return     returns the component that contains the point,
2490             *                 or <code>null</code> if the component does 
2491             *                 not contain the point. 
2492             * @see        Component#contains 
2493             * @since      JDK1.1 
2494             */
2495            public Component getComponentAt(Point p) {
2496                return getComponentAt(p.x, p.y);
2497            }
2498
2499            /**
2500             * Returns the position of the mouse pointer in this <code>Container</code>'s
2501             * coordinate space if the <code>Container</code> is under the mouse pointer,
2502             * otherwise returns <code>null</code>.
2503             * This method is similar to {@link Component#getMousePosition()} with the exception
2504             * that it can take the <code>Container</code>'s children into account.
2505             * If <code>allowChildren</code> is <code>false</code>, this method will return
2506             * a non-null value only if the mouse pointer is above the <code>Container</code>
2507             * directly, not above the part obscured by children.
2508             * If <code>allowChildren</code> is <code>true</code>, this method returns
2509             * a non-null value if the mouse pointer is above <code>Container</code> or any
2510             * of its descendants.
2511             *
2512             * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2513             * @param     allowChildren true if children should be taken into account
2514             * @see       Component#getMousePosition
2515             * @return    mouse coordinates relative to this <code>Component</code>, or null
2516             * @since     1.5
2517             */
2518            public Point getMousePosition(boolean allowChildren)
2519                    throws HeadlessException {
2520                if (GraphicsEnvironment.isHeadless()) {
2521                    throw new HeadlessException();
2522                }
2523                PointerInfo pi = (PointerInfo) java.security.AccessController
2524                        .doPrivileged(new java.security.PrivilegedAction() {
2525                            public Object run() {
2526                                return MouseInfo.getPointerInfo();
2527                            }
2528                        });
2529                synchronized (getTreeLock()) {
2530                    Component inTheSameWindow = findUnderMouseInWindow(pi);
2531                    if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) {
2532                        return pointRelativeToComponent(pi.getLocation());
2533                    }
2534                    return null;
2535                }
2536            }
2537
2538            boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
2539                return this  == comp || (allowChildren && isParentOf(comp));
2540            }
2541
2542            /**
2543             * Locates the visible child component that contains the specified
2544             * position.  The top-most child component is returned in the case 
2545             * where there is overlap in the components.  If the containing child 
2546             * component is a Container, this method will continue searching for 
2547             * the deepest nested child component.  Components which are not
2548             * visible are ignored during the search.<p>
2549             *
2550             * The findComponentAt method is different from getComponentAt in
2551             * that getComponentAt only searches the Container's immediate
2552             * children; if the containing component is a Container, 
2553             * findComponentAt will search that child to find a nested component.
2554             *
2555             * @param x the <i>x</i> coordinate
2556             * @param y the <i>y</i> coordinate
2557             * @return null if the component does not contain the position.
2558             * If there is no child component at the requested point and the 
2559             * point is within the bounds of the container the container itself 
2560             * is returned.
2561             * @see Component#contains
2562             * @see #getComponentAt
2563             * @since 1.2
2564             */
2565            public Component findComponentAt(int x, int y) {
2566                synchronized (getTreeLock()) {
2567                    return findComponentAt(x, y, true);
2568                }
2569            }
2570
2571            /**
2572             * Private version of findComponentAt which has a controllable
2573             * behavior. Setting 'ignoreEnabled' to 'false' bypasses disabled
2574             * Components during the search. This behavior is used by the
2575             * lightweight cursor support in sun.awt.GlobalCursorManager.
2576             * The cursor code calls this function directly via native code.
2577             *
2578             * The addition of this feature is temporary, pending the
2579             * adoption of new, public API which exports this feature.
2580             */
2581            final Component findComponentAt(int x, int y, boolean ignoreEnabled) {
2582                if (isRecursivelyVisible()) {
2583                    return findComponentAtImpl(x, y, ignoreEnabled);
2584                }
2585                return null;
2586            }
2587
2588            final Component findComponentAtImpl(int x, int y,
2589                    boolean ignoreEnabled) {
2590                if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
2591                    return null;
2592                }
2593                int ncomponents = this .ncomponents;
2594                Component component[] = this .component;
2595
2596                // Two passes: see comment in sun.awt.SunGraphicsCallback
2597                for (int i = 0; i < ncomponents; i++) {
2598                    Component comp = component[i];
2599                    if (comp != null && !(comp.peer instanceof  LightweightPeer)) {
2600                        if (comp instanceof  Container) {
2601                            comp = ((Container) comp).findComponentAtImpl(x
2602                                    - comp.x, y - comp.y, ignoreEnabled);
2603                        } else {
2604                            comp = comp.locate(x - comp.x, y - comp.y);
2605                        }
2606                        if (comp != null && comp.visible
2607                                && (ignoreEnabled || comp.enabled)) {
2608                            return comp;
2609                        }
2610                    }
2611                }
2612                for (int i = 0; i < ncomponents; i++) {
2613                    Component comp = component[i];
2614                    if (comp != null && comp.peer instanceof  LightweightPeer) {
2615                        if (comp instanceof  Container) {
2616                            comp = ((Container) comp).findComponentAtImpl(x
2617                                    - comp.x, y - comp.y, ignoreEnabled);
2618                        } else {
2619                            comp = comp.locate(x - comp.x, y - comp.y);
2620                        }
2621                        if (comp != null && comp.visible
2622                                && (ignoreEnabled || comp.enabled)) {
2623                            return comp;
2624                        }
2625                    }
2626                }
2627                return this ;
2628            }
2629
2630            /**
2631             * Locates the visible child component that contains the specified
2632             * point.  The top-most child component is returned in the case 
2633             * where there is overlap in the components.  If the containing child 
2634             * component is a Container, this method will continue searching for 
2635             * the deepest nested child component.  Components which are not
2636             * visible are ignored during the search.<p>
2637             *
2638             * The findComponentAt method is different from getComponentAt in
2639             * that getComponentAt only searches the Container's immediate
2640             * children; if the containing component is a Container, 
2641             * findComponentAt will search that child to find a nested component.
2642             *
2643             * @param      p   the point.
2644             * @return null if the component does not contain the position.
2645             * If there is no child component at the requested point and the 
2646             * point is within the bounds of the container the container itself 
2647             * is returned.
2648             * @see Component#contains
2649             * @see #getComponentAt
2650             * @since 1.2
2651             */
2652            public Component findComponentAt(Point p) {
2653                return findComponentAt(p.x, p.y);
2654            }
2655
2656            /** 
2657             * Makes this Container displayable by connecting it to
2658             * a native screen resource.  Making a container displayable will
2659             * cause all of its children to be made displayable.
2660             * This method is called internally by the toolkit and should
2661             * not be called directly by programs.
2662             * @see Component#isDisplayable
2663             * @see #removeNotify
2664             */
2665            public void addNotify() {
2666                synchronized (getTreeLock()) {
2667                    // addNotify() on the children may cause proxy event enabling
2668                    // on this instance, so we first call super.addNotify() and
2669                    // possibly create an lightweight event dispatcher before calling
2670                    // addNotify() on the children which may be lightweight.
2671                    super .addNotify();
2672                    if (!(peer instanceof  LightweightPeer)) {
2673                        dispatcher = new LightweightDispatcher(this );
2674                    }
2675                    int ncomponents = this .ncomponents;
2676                    Component component[] = this .component;
2677                    for (int i = 0; i < ncomponents; i++) {
2678                        component[i].addNotify();
2679                    }
2680                    // Update stacking order if native platform allows
2681                    ContainerPeer cpeer = (ContainerPeer) peer;
2682                    if (cpeer.isRestackSupported()) {
2683                        cpeer.restack();
2684                    }
2685
2686                }
2687            }
2688
2689            /** 
2690             * Makes this Container undisplayable by removing its connection
2691             * to its native screen resource.  Making a container undisplayable
2692             * will cause all of its children to be made undisplayable. 
2693             * This method is called by the toolkit internally and should
2694             * not be called directly by programs.
2695             * @see Component#isDisplayable
2696             * @see #addNotify
2697             */
2698            public void removeNotify() {
2699                synchronized (getTreeLock()) {
2700                    int ncomponents = this .ncomponents;
2701                    Component component[] = this .component;
2702                    for (int i = ncomponents - 1; i >= 0; i--) {
2703                        if (component[i] != null)
2704                            component[i].removeNotify();
2705                    }
2706                    if (dispatcher != null) {
2707                        dispatcher.dispose();
2708                        dispatcher = null;
2709                    }
2710                    super .removeNotify();
2711                }
2712            }
2713
2714            /**
2715             * Checks if the component is contained in the component hierarchy of
2716             * this container.
2717             * @param c the component
2718             * @return     <code>true</code> if it is an ancestor; 
2719             *             <code>false</code> otherwise.
2720             * @since      JDK1.1
2721             */
2722            public boolean isAncestorOf(Component c) {
2723                Container p;
2724                if (c == null || ((p = c.getParent()) == null)) {
2725                    return false;
2726                }
2727                while (p != null) {
2728                    if (p == this ) {
2729                        return true;
2730                    }
2731                    p = p.getParent();
2732                }
2733                return false;
2734            }
2735
2736            /*
2737             * The following code was added to support modal JInternalFrames
2738             * Unfortunately this code has to be added here so that we can get access to
2739             * some private AWT classes like SequencedEvent.
2740             *
2741             * The native container of the LW component has this field set
2742             * to tell it that it should block Mouse events for all LW
2743             * children except for the modal component. 
2744             *
2745             * In the case of nested Modal components, we store the previous
2746             * modal component in the new modal components value of modalComp; 
2747             */
2748
2749            transient Component modalComp;
2750            transient AppContext modalAppContext;
2751
2752            private void startLWModal() {
2753                // Store the app context on which this component is being shown.
2754                // Event dispatch thread of this app context will be sleeping until
2755                // we wake it by any event from hideAndDisposeHandler().
2756                modalAppContext = AppContext.getAppContext();
2757
2758                // keep the KeyEvents from being dispatched
2759                // until the focus has been transfered
2760                long time = Toolkit.getEventQueue().getMostRecentEventTime();
2761                Component predictedFocusOwner = (Component.isInstanceOf(this ,
2762                        "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame) (this ))
2763                        .getMostRecentFocusOwner()
2764                        : null;
2765                if (predictedFocusOwner != null) {
2766                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
2767                            .enqueueKeyEvents(time, predictedFocusOwner);
2768                }
2769                // We have two mechanisms for blocking: 1. If we're on the
2770                // EventDispatchThread, start a new event pump. 2. If we're
2771                // on any other thread, call wait() on the treelock.
2772                final Container nativeContainer;
2773                synchronized (getTreeLock()) {
2774                    nativeContainer = getHeavyweightContainer();
2775                    if (nativeContainer.modalComp != null) {
2776                        this .modalComp = nativeContainer.modalComp;
2777                        nativeContainer.modalComp = this ;
2778                        return;
2779                    } else {
2780                        nativeContainer.modalComp = this ;
2781                    }
2782                }
2783
2784                Runnable pumpEventsForHierarchy = new Runnable() {
2785                    public void run() {
2786                        EventDispatchThread dispatchThread = (EventDispatchThread) Thread
2787                                .currentThread();
2788                        dispatchThread.pumpEventsForHierarchy(
2789                                new Conditional() {
2790                                    public boolean evaluate() {
2791                                        return ((windowClosingException == null) && (nativeContainer.modalComp != null));
2792                                    }
2793                                }, Container.this );
2794                    }
2795                };
2796
2797                if (EventQueue.isDispatchThread()) {
2798                    SequencedEvent currentSequencedEvent = KeyboardFocusManager
2799                            .getCurrentKeyboardFocusManager()
2800                            .getCurrentSequencedEvent();
2801                    if (currentSequencedEvent != null) {
2802                        currentSequencedEvent.dispose();
2803                    }
2804
2805                    pumpEventsForHierarchy.run();
2806                } else {
2807                    synchronized (getTreeLock()) {
2808                        Toolkit.getEventQueue().postEvent(
2809                                new PeerEvent(this , pumpEventsForHierarchy,
2810                                        PeerEvent.PRIORITY_EVENT));
2811                        while ((windowClosingException == null)
2812                                && (nativeContainer.modalComp != null)) {
2813                            try {
2814                                getTreeLock().wait();
2815                            } catch (InterruptedException e) {
2816                                break;
2817                            }
2818                        }
2819                    }
2820                }
2821                if (windowClosingException != null) {
2822                    windowClosingException.fillInStackTrace();
2823                    throw windowClosingException;
2824                }
2825                if (predictedFocusOwner != null) {
2826                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
2827                            .dequeueKeyEvents(time, predictedFocusOwner);
2828                }
2829            }
2830
2831            private void stopLWModal() {
2832                synchronized (getTreeLock()) {
2833                    if (modalAppContext != null) {
2834                        Container nativeContainer = getHeavyweightContainer();
2835                        if (nativeContainer != null) {
2836                            if (this .modalComp != null) {
2837                                nativeContainer.modalComp = this .modalComp;
2838                                this .modalComp = null;
2839                                return;
2840                            } else {
2841                                nativeContainer.modalComp = null;
2842                            }
2843                        }
2844                        // Wake up event dispatch thread on which the dialog was 
2845                        // initially shown
2846                        SunToolkit.postEvent(modalAppContext, new PeerEvent(
2847                                this , new WakingRunnable(),
2848                                PeerEvent.PRIORITY_EVENT));
2849                    }
2850                    EventQueue.invokeLater(new WakingRunnable());
2851                    getTreeLock().notifyAll();
2852                }
2853            }
2854
2855            final static class WakingRunnable implements  Runnable {
2856                public void run() {
2857                }
2858            }
2859
2860            /* End of JOptionPane support code */
2861
2862            /**
2863             * Returns a string representing the state of this <code>Container</code>.
2864             * This method is intended to be used only for debugging purposes, and the 
2865             * content and format of the returned string may vary between 
2866             * implementations. The returned string may be empty but may not be 
2867             * <code>null</code>.
2868             *
2869             * @return    the parameter string of this container
2870             */
2871            protected String paramString() {
2872                String str = super .paramString();
2873                LayoutManager layoutMgr = this .layoutMgr;
2874                if (layoutMgr != null) {
2875                    str += ",layout=" + layoutMgr.getClass().getName();
2876                }
2877                return str;
2878            }
2879
2880            /**
2881             * Prints a listing of this container to the specified output 
2882             * stream. The listing starts at the specified indentation. 
2883             * <p>
2884             * The immediate children of the container are printed with
2885             * an indentation of <code>indent+1</code>.  The children
2886             * of those children are printed at <code>indent+2</code>
2887             * and so on.
2888             *
2889             * @param    out      a print stream
2890             * @param    indent   the number of spaces to indent
2891             * @see      Component#list(java.io.PrintStream, int)
2892             * @since    JDK1.0
2893             */
2894            public void list(PrintStream out, int indent) {
2895                super .list(out, indent);
2896                int ncomponents = this .ncomponents;
2897                Component component[] = this .component;
2898                for (int i = 0; i < ncomponents; i++) {
2899                    Component comp = component[i];
2900                    if (comp != null) {
2901                        comp.list(out, indent + 1);
2902                    }
2903                }
2904            }
2905
2906            /**
2907             * Prints out a list, starting at the specified indentation,
2908             * to the specified print writer.
2909             * <p>
2910             * The immediate children of the container are printed with
2911             * an indentation of <code>indent+1</code>.  The children
2912             * of those children are printed at <code>indent+2</code>
2913             * and so on.
2914             *
2915             * @param    out      a print writer
2916             * @param    indent   the number of spaces to indent
2917             * @see      Component#list(java.io.PrintWriter, int)
2918             * @since    JDK1.1
2919             */
2920            public void list(PrintWriter out, int indent) {
2921                super .list(out, indent);
2922                int ncomponents = this .ncomponents;
2923                Component component[] = this .component;
2924                for (int i = 0; i < ncomponents; i++) {
2925                    Component comp = component[i];
2926                    if (comp != null) {
2927                        comp.list(out, indent + 1);
2928                    }
2929                }
2930            }
2931
2932            /**
2933             * Sets the focus traversal keys for a given traversal operation for this
2934             * Container.
2935             * <p>
2936             * The default values for a Container's focus traversal keys are
2937             * implementation-dependent. Sun recommends that all implementations for a
2938             * particular native platform use the same default values. The
2939             * recommendations for Windows and Unix are listed below. These
2940             * recommendations are used in the Sun AWT implementations.
2941             *
2942             * <table border=1 summary="Recommended default values for a Container's focus traversal keys">
2943             * <tr>
2944             *    <th>Identifier</th>
2945             *    <th>Meaning</th>
2946             *    <th>Default</th>
2947             * </tr>
2948             * <tr>
2949             *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
2950             *    <td>Normal forward keyboard traversal</td>
2951             *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
2952             * </tr>
2953             * <tr>
2954             *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
2955             *    <td>Normal reverse keyboard traversal</td>
2956             *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
2957             * </tr>
2958             * <tr>
2959             *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
2960             *    <td>Go up one focus traversal cycle</td>
2961             *    <td>none</td>
2962             * </tr>
2963             * <tr>
2964             *    <td>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS<td>
2965             *    <td>Go down one focus traversal cycle</td>
2966             *    <td>none</td>
2967             * </tr>
2968             * </table>
2969             *
2970             * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
2971             * recommended.
2972             * <p>
2973             * Using the AWTKeyStroke API, client code can specify on which of two
2974             * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
2975             * operation will occur. Regardless of which KeyEvent is specified,
2976             * however, all KeyEvents related to the focus traversal key, including the
2977             * associated KEY_TYPED event, will be consumed, and will not be dispatched
2978             * to any Container. It is a runtime error to specify a KEY_TYPED event as
2979             * mapping to a focus traversal operation, or to map the same event to
2980             * multiple default focus traversal operations.
2981             * <p>
2982             * If a value of null is specified for the Set, this Container inherits the
2983             * Set from its parent. If all ancestors of this Container have null
2984             * specified for the Set, then the current KeyboardFocusManager's default
2985             * Set is used.
2986             *
2987             * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2988             *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2989             *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2990             *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2991             * @param keystrokes the Set of AWTKeyStroke for the specified operation
2992             * @see #getFocusTraversalKeys
2993             * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2994             * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2995             * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2996             * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2997             * @throws IllegalArgumentException if id is not one of
2998             *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2999             *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3000             *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3001             *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, or if keystrokes
3002             *         contains null, or if any Object in keystrokes is not an
3003             *         AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
3004             *         or if any keystroke already maps to another focus traversal
3005             *         operation for this Container
3006             * @since 1.4
3007             * @beaninfo
3008             *       bound: true
3009             */
3010            public void setFocusTraversalKeys(int id,
3011                    Set<? extends AWTKeyStroke> keystrokes) {
3012                if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3013                    throw new IllegalArgumentException(
3014                            "invalid focus traversal key identifier");
3015                }
3016
3017                // Don't call super.setFocusTraversalKey. The Component parameter check
3018                // does not allow DOWN_CYCLE_TRAVERSAL_KEYS, but we do.
3019                setFocusTraversalKeys_NoIDCheck(id, keystrokes);
3020            }
3021
3022            /**
3023             * Returns the Set of focus traversal keys for a given traversal operation
3024             * for this Container. (See
3025             * <code>setFocusTraversalKeys</code> for a full description of each key.)
3026             * <p>
3027             * If a Set of traversal keys has not been explicitly defined for this
3028             * Container, then this Container's parent's Set is returned. If no Set
3029             * has been explicitly defined for any of this Container's ancestors, then
3030             * the current KeyboardFocusManager's default Set is returned.
3031             *
3032             * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3033             *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3034             *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3035             *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3036             * @return the Set of AWTKeyStrokes for the specified operation. The Set
3037             *         will be unmodifiable, and may be empty. null will never be
3038             *         returned.
3039             * @see #setFocusTraversalKeys
3040             * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3041             * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3042             * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3043             * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
3044             * @throws IllegalArgumentException if id is not one of
3045             *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3046             *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3047             *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3048             *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3049             * @since 1.4
3050             */
3051            public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
3052                if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3053                    throw new IllegalArgumentException(
3054                            "invalid focus traversal key identifier");
3055                }
3056
3057                // Don't call super.getFocusTraversalKey. The Component parameter check
3058                // does not allow DOWN_CYCLE_TRAVERSAL_KEY, but we do.
3059                return getFocusTraversalKeys_NoIDCheck(id);
3060            }
3061
3062            /**
3063             * Returns whether the Set of focus traversal keys for the given focus
3064             * traversal operation has been explicitly defined for this Container. If
3065             * this method returns <code>false</code>, this Container is inheriting the
3066             * Set from an ancestor, or from the current KeyboardFocusManager.
3067             *
3068             * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3069             *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3070             *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3071             *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3072             * @return <code>true</code> if the the Set of focus traversal keys for the
3073             *         given focus traversal operation has been explicitly defined for
3074             *         this Component; <code>false</code> otherwise.
3075             * @throws IllegalArgumentException if id is not one of
3076             *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3077             *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3078             *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3079             *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3080             * @since 1.4
3081             */
3082            public boolean areFocusTraversalKeysSet(int id) {
3083                if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3084                    throw new IllegalArgumentException(
3085                            "invalid focus traversal key identifier");
3086                }
3087
3088                return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
3089            }
3090
3091            /**
3092             * Returns whether the specified Container is the focus cycle root of this
3093             * Container's focus traversal cycle. Each focus traversal cycle has only
3094             * a single focus cycle root and each Container which is not a focus cycle
3095             * root belongs to only a single focus traversal cycle. Containers which
3096             * are focus cycle roots belong to two cycles: one rooted at the Container
3097             * itself, and one rooted at the Container's nearest focus-cycle-root
3098             * ancestor. This method will return <code>true</code> for both such
3099             * Containers in this case.
3100             *
3101             * @param container the Container to be tested
3102             * @return <code>true</code> if the specified Container is a focus-cycle-
3103             *         root of this Container; <code>false</code> otherwise
3104             * @see #isFocusCycleRoot()
3105             * @since 1.4
3106             */
3107            public boolean isFocusCycleRoot(Container container) {
3108                if (isFocusCycleRoot() && container == this ) {
3109                    return true;
3110                } else {
3111                    return super .isFocusCycleRoot(container);
3112                }
3113            }
3114
3115            private Container findTraversalRoot() {
3116                // I potentially have two roots, myself and my root parent
3117                // If I am the current root, then use me
3118                // If none of my parents are roots, then use me
3119                // If my root parent is the current root, then use my root parent
3120                // If neither I nor my root parent is the current root, then
3121                // use my root parent (a guess)
3122
3123                Container currentFocusCycleRoot = KeyboardFocusManager
3124                        .getCurrentKeyboardFocusManager()
3125                        .getCurrentFocusCycleRoot();
3126                Container root;
3127
3128                if (currentFocusCycleRoot == this ) {
3129                    root = this ;
3130                } else {
3131                    root = getFocusCycleRootAncestor();
3132                    if (root == null) {
3133                        root = this ;
3134                    }
3135                }
3136
3137                if (root != currentFocusCycleRoot) {
3138                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
3139                            .setGlobalCurrentFocusCycleRoot(root);
3140                }
3141                return root;
3142            }
3143
3144            final boolean containsFocus() {
3145                final Component focusOwner = KeyboardFocusManager
3146                        .getCurrentKeyboardFocusManager().getFocusOwner();
3147                return isParentOf(focusOwner);
3148            }
3149
3150            /**
3151             * Check if this component is the child of this container or its children.
3152             * Note: this function acquires treeLock
3153             * Note: this function traverses children tree only in one Window.
3154             * @param comp a component in test, must not be null
3155             */
3156            private boolean isParentOf(Component comp) {
3157                synchronized (getTreeLock()) {
3158                    while (comp != null && comp != this 
3159                            && !(comp instanceof  Window)) {
3160                        comp = comp.getParent();
3161                    }
3162                    return (comp == this );
3163                }
3164            }
3165
3166            void clearMostRecentFocusOwnerOnHide() {
3167                boolean reset = false;
3168                Window window = null;
3169
3170                synchronized (getTreeLock()) {
3171                    window = getContainingWindow();
3172                    if (window != null) {
3173                        Component comp = KeyboardFocusManager
3174                                .getMostRecentFocusOwner(window);
3175                        reset = ((comp == this ) || isParentOf(comp));
3176                        // This synchronized should always be the second in a pair
3177                        // (tree lock, KeyboardFocusManager.class)
3178                        synchronized (KeyboardFocusManager.class) {
3179                            Component storedComp = window
3180                                    .getTemporaryLostComponent();
3181                            if (isParentOf(storedComp) || storedComp == this ) {
3182                                window.setTemporaryLostComponent(null);
3183                            }
3184                        }
3185                    }
3186                }
3187
3188                if (reset) {
3189                    KeyboardFocusManager.setMostRecentFocusOwner(window, null);
3190                }
3191            }
3192
3193            void clearCurrentFocusCycleRootOnHide() {
3194                KeyboardFocusManager kfm = KeyboardFocusManager
3195                        .getCurrentKeyboardFocusManager();
3196                Container cont = kfm.getCurrentFocusCycleRoot();
3197
3198                if (cont == this  || isParentOf(cont)) {
3199                    kfm.setGlobalCurrentFocusCycleRoot(null);
3200                }
3201            }
3202
3203            final Container getTraversalRoot() {
3204                if (isFocusCycleRoot()) {
3205                    return findTraversalRoot();
3206                }
3207
3208                return super .getTraversalRoot();
3209            }
3210
3211            /**
3212             * Sets the focus traversal policy that will manage keyboard traversal of
3213             * this Container's children, if this Container is a focus cycle root. If
3214             * the argument is null, this Container inherits its policy from its focus-
3215             * cycle-root ancestor. If the argument is non-null, this policy will be 
3216             * inherited by all focus-cycle-root children that have no keyboard-
3217             * traversal policy of their own (as will, recursively, their focus-cycle-
3218             * root children).
3219             * <p>
3220             * If this Container is not a focus cycle root, the policy will be
3221             * remembered, but will not be used or inherited by this or any other
3222             * Containers until this Container is made a focus cycle root.
3223             *
3224             * @param policy the new focus traversal policy for this Container
3225             * @see #getFocusTraversalPolicy
3226             * @see #setFocusCycleRoot
3227             * @see #isFocusCycleRoot
3228             * @since 1.4
3229             * @beaninfo
3230             *       bound: true
3231             */
3232            public void setFocusTraversalPolicy(FocusTraversalPolicy policy) {
3233                FocusTraversalPolicy oldPolicy;
3234                synchronized (this ) {
3235                    oldPolicy = this .focusTraversalPolicy;
3236                    this .focusTraversalPolicy = policy;
3237                }
3238                firePropertyChange("focusTraversalPolicy", oldPolicy, policy);
3239            }
3240
3241            /**
3242             * Returns the focus traversal policy that will manage keyboard traversal
3243             * of this Container's children, or null if this Container is not a focus
3244             * cycle root. If no traversal policy has been explicitly set for this
3245             * Container, then this Container's focus-cycle-root ancestor's policy is
3246             * returned. 
3247             *
3248             * @return this Container's focus traversal policy, or null if this
3249             *         Container is not a focus cycle root.
3250             * @see #setFocusTraversalPolicy
3251             * @see #setFocusCycleRoot
3252             * @see #isFocusCycleRoot
3253             * @since 1.4
3254             */
3255            public FocusTraversalPolicy getFocusTraversalPolicy() {
3256                if (!isFocusTraversalPolicyProvider() && !isFocusCycleRoot()) {
3257                    return null;
3258                }
3259
3260                FocusTraversalPolicy policy = this .focusTraversalPolicy;
3261                if (policy != null) {
3262                    return policy;
3263                }
3264
3265                Container rootAncestor = getFocusCycleRootAncestor();
3266                if (rootAncestor != null) {
3267                    return rootAncestor.getFocusTraversalPolicy();
3268                } else {
3269                    return KeyboardFocusManager
3270                            .getCurrentKeyboardFocusManager()
3271                            .getDefaultFocusTraversalPolicy();
3272                }
3273            }
3274
3275            /**
3276             * Returns whether the focus traversal policy has been explicitly set for
3277             * this Container. If this method returns <code>false</code>, this
3278             * Container will inherit its focus traversal policy from an ancestor.
3279             *
3280             * @return <code>true</code> if the focus traversal policy has been
3281             *         explicitly set for this Container; <code>false</code> otherwise.
3282             * @since 1.4
3283             */
3284            public boolean isFocusTraversalPolicySet() {
3285                return (focusTraversalPolicy != null);
3286            }
3287
3288            /**
3289             * Sets whether this Container is the root of a focus traversal cycle. Once
3290             * focus enters a traversal cycle, typically it cannot leave it via focus
3291             * traversal unless one of the up- or down-cycle keys is pressed. Normal
3292             * traversal is limited to this Container, and all of this Container's
3293             * descendants that are not descendants of inferior focus cycle roots. Note
3294             * that a FocusTraversalPolicy may bend these restrictions, however. For
3295             * example, ContainerOrderFocusTraversalPolicy supports implicit down-cycle
3296             * traversal.
3297             * <p>
3298             * The alternative way to specify the traversal order of this Container's 
3299             * children is to make this Container a 
3300             * <a href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy provider</a>.  
3301             *
3302             * @param focusCycleRoot indicates whether this Container is the root of a
3303             *        focus traversal cycle
3304             * @see #isFocusCycleRoot()
3305             * @see #setFocusTraversalPolicy
3306             * @see #getFocusTraversalPolicy
3307             * @see ContainerOrderFocusTraversalPolicy
3308             * @see #setFocusTraversalPolicyProvider
3309             * @since 1.4
3310             * @beaninfo
3311             *       bound: true
3312             */
3313            public void setFocusCycleRoot(boolean focusCycleRoot) {
3314                boolean oldFocusCycleRoot;
3315                synchronized (this ) {
3316                    oldFocusCycleRoot = this .focusCycleRoot;
3317                    this .focusCycleRoot = focusCycleRoot;
3318                }
3319                firePropertyChange("focusCycleRoot", oldFocusCycleRoot,
3320                        focusCycleRoot);
3321            }
3322
3323            /**
3324             * Returns whether this Container is the root of a focus traversal cycle.
3325             * Once focus enters a traversal cycle, typically it cannot leave it via
3326             * focus traversal unless one of the up- or down-cycle keys is pressed.
3327             * Normal traversal is limited to this Container, and all of this
3328             * Container's descendants that are not descendants of inferior focus
3329             * cycle roots. Note that a FocusTraversalPolicy may bend these
3330             * restrictions, however. For example, ContainerOrderFocusTraversalPolicy
3331             * supports implicit down-cycle traversal.
3332             *
3333             * @return whether this Container is the root of a focus traversal cycle
3334             * @see #setFocusCycleRoot
3335             * @see #setFocusTraversalPolicy
3336             * @see #getFocusTraversalPolicy
3337             * @see ContainerOrderFocusTraversalPolicy
3338             * @since 1.4
3339             */
3340            public boolean isFocusCycleRoot() {
3341                return focusCycleRoot;
3342            }
3343
3344            /**
3345             * Sets whether this container will be used to provide focus
3346             * traversal policy. Container with this property as
3347             * <code>true</code> will be used to acquire focus traversal policy
3348             * instead of closest focus cycle root ancestor.
3349             * @param provider indicates whether this container will be used to
3350             *                provide focus traversal policy
3351             * @see #setFocusTraversalPolicy
3352             * @see #getFocusTraversalPolicy     
3353             * @see #isFocusTraversalPolicyProvider
3354             * @since 1.5
3355             * @beaninfo
3356             *        bound: true
3357             */
3358            public final void setFocusTraversalPolicyProvider(boolean provider) {
3359                boolean oldProvider;
3360                synchronized (this ) {
3361                    oldProvider = focusTraversalPolicyProvider;
3362                    focusTraversalPolicyProvider = provider;
3363                }
3364                firePropertyChange("focusTraversalPolicyProvider", oldProvider,
3365                        provider);
3366            }
3367
3368            /**
3369             * Returns whether this container provides focus traversal
3370             * policy. If this property is set to <code>true</code> then when
3371             * keyboard focus manager searches container hierarchy for focus
3372             * traversal policy and encounters this container before any other
3373             * container with this property as true or focus cycle roots then
3374             * its focus traversal policy will be used instead of focus cycle
3375             * root's policy.
3376             * @see #setFocusTraversalPolicy
3377             * @see #getFocusTraversalPolicy     
3378             * @see #setFocusCycleRoot
3379             * @see #setFocusTraversalPolicyProvider
3380             * @return <code>true</code> if this container provides focus traversal
3381             *         policy, <code>false</code> otherwise
3382             * @since 1.5
3383             * @beaninfo
3384             *        bound: true
3385             */
3386            public final boolean isFocusTraversalPolicyProvider() {
3387                return focusTraversalPolicyProvider;
3388            }
3389
3390            /**
3391             * Transfers the focus down one focus traversal cycle. If this Container is
3392             * a focus cycle root, then the focus owner is set to this Container's
3393             * default Component to focus, and the current focus cycle root is set to
3394             * this Container. If this Container is not a focus cycle root, then no
3395             * focus traversal operation occurs.
3396             *
3397             * @see       Component#requestFocus()
3398             * @see       #isFocusCycleRoot
3399             * @see       #setFocusCycleRoot
3400             * @since     1.4
3401             */
3402            public void transferFocusDownCycle() {
3403                if (isFocusCycleRoot()) {
3404                    KeyboardFocusManager.getCurrentKeyboardFocusManager()
3405                            .setGlobalCurrentFocusCycleRoot(this );
3406                    Component toFocus = getFocusTraversalPolicy()
3407                            .getDefaultComponent(this );
3408                    if (toFocus != null) {
3409                        toFocus
3410                                .requestFocus(CausedFocusEvent.Cause.TRAVERSAL_DOWN);
3411                    }
3412                }
3413            }
3414
3415            void preProcessKeyEvent(KeyEvent e) {
3416                Container parent = this .parent;
3417                if (parent != null) {
3418                    parent.preProcessKeyEvent(e);
3419                }
3420            }
3421
3422            void postProcessKeyEvent(KeyEvent e) {
3423                Container parent = this .parent;
3424                if (parent != null) {
3425                    parent.postProcessKeyEvent(e);
3426                }
3427            }
3428
3429            boolean postsOldMouseEvents() {
3430                return true;
3431            }
3432
3433            /**
3434             * Sets the <code>ComponentOrientation</code> property of this container
3435             * and all components contained within it.
3436             *
3437             * @param o the new component orientation of this container and
3438             *        the components contained within it.
3439             * @exception NullPointerException if <code>orientation</code> is null.
3440             * @see Component#setComponentOrientation
3441             * @see Component#getComponentOrientation
3442             * @since 1.4
3443             */
3444            public void applyComponentOrientation(ComponentOrientation o) {
3445                super .applyComponentOrientation(o);
3446
3447                for (int i = 0; i < ncomponents; ++i) {
3448                    component[i].applyComponentOrientation(o);
3449                }
3450            }
3451
3452            /**
3453             * Adds a PropertyChangeListener to the listener list. The listener is
3454             * registered for all bound properties of this class, including the
3455             * following:
3456             * <ul>
3457             *    <li>this Container's font ("font")</li>
3458             *    <li>this Container's background color ("background")</li>
3459             *    <li>this Container's foreground color ("foreground")</li>
3460             *    <li>this Container's focusability ("focusable")</li>
3461             *    <li>this Container's focus traversal keys enabled state
3462             *        ("focusTraversalKeysEnabled")</li>
3463             *    <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3464             *        ("forwardFocusTraversalKeys")</li>
3465             *    <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3466             *        ("backwardFocusTraversalKeys")</li>
3467             *    <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3468             *        ("upCycleFocusTraversalKeys")</li>
3469             *    <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3470             *        ("downCycleFocusTraversalKeys")</li>
3471             *    <li>this Container's focus traversal policy ("focusTraversalPolicy")
3472             *        </li>
3473             *    <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3474             * </ul>
3475             * Note that if this Container is inheriting a bound property, then no
3476             * event will be fired in response to a change in the inherited property.
3477             * <p>
3478             * If listener is null, no exception is thrown and no action is performed.
3479             *
3480             * @param    listener  the PropertyChangeListener to be added
3481             *
3482             * @see Component#removePropertyChangeListener
3483             * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
3484             */
3485            public void addPropertyChangeListener(
3486                    PropertyChangeListener listener) {
3487                super .addPropertyChangeListener(listener);
3488            }
3489
3490            /**
3491             * Adds a PropertyChangeListener to the listener list for a specific
3492             * property. The specified property may be user-defined, or one of the
3493             * following defaults:
3494             * <ul>
3495             *    <li>this Container's font ("font")</li>
3496             *    <li>this Container's background color ("background")</li>
3497             *    <li>this Container's foreground color ("foreground")</li>
3498             *    <li>this Container's focusability ("focusable")</li>
3499             *    <li>this Container's focus traversal keys enabled state
3500             *        ("focusTraversalKeysEnabled")</li>
3501             *    <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3502             *        ("forwardFocusTraversalKeys")</li>
3503             *    <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3504             *        ("backwardFocusTraversalKeys")</li>
3505             *    <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3506             *        ("upCycleFocusTraversalKeys")</li>
3507             *    <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3508             *        ("downCycleFocusTraversalKeys")</li>
3509             *    <li>this Container's focus traversal policy ("focusTraversalPolicy")
3510             *        </li>
3511             *    <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3512             *    <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3513             *    <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3514             * </ul>
3515             * Note that if this Container is inheriting a bound property, then no
3516             * event will be fired in response to a change in the inherited property.
3517             * <p>
3518             * If listener is null, no exception is thrown and no action is performed.
3519             *
3520             * @param propertyName one of the property names listed above
3521             * @param listener the PropertyChangeListener to be added
3522             *
3523             * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
3524             * @see Component#removePropertyChangeListener
3525             */
3526            public void addPropertyChangeListener(String propertyName,
3527                    PropertyChangeListener listener) {
3528                super .addPropertyChangeListener(propertyName, listener);
3529            }
3530
3531            // Serialization support. A Container is responsible for restoring the
3532            // parent fields of its component children. 
3533
3534            /**
3535             * Container Serial Data Version.
3536             */
3537            private int containerSerializedDataVersion = 1;
3538
3539            /**
3540             * Serializes this <code>Container</code> to the specified
3541             * <code>ObjectOutputStream</code>.
3542             * <ul>
3543             *    <li>Writes default serializable fields to the stream.</li>
3544             *    <li>Writes a list of serializable ContainerListener(s) as optional
3545             *        data. The non-serializable ContainerListner(s) are detected and
3546             *        no attempt is made to serialize them.</li>
3547             *    <li>Write this Container's FocusTraversalPolicy if and only if it
3548             *        is Serializable; otherwise, <code>null</code> is written.</li>
3549             * </ul>
3550             *
3551             * @param s the <code>ObjectOutputStream</code> to write
3552             * @serialData <code>null</code> terminated sequence of 0 or more pairs;
3553             *   the pair consists of a <code>String</code> and <code>Object</code>;
3554             *   the <code>String</code> indicates the type of object and
3555             *   is one of the following:
3556             *   <code>containerListenerK</code> indicating an
3557             *     <code>ContainerListener</code> object;
3558             *   the <code>Container</code>'s <code>FocusTraversalPolicy</code>,
3559             *     or <code>null</code>
3560             *
3561             * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
3562             * @see Container#containerListenerK
3563             * @see #readObject(ObjectInputStream)
3564             */
3565            private void writeObject(ObjectOutputStream s) throws IOException {
3566                ObjectOutputStream.PutField f = s.putFields();
3567                f.put("ncomponents", ncomponents);
3568                f.put("component", component);
3569                f.put("layoutMgr", layoutMgr);
3570                f.put("dispatcher", dispatcher);
3571                f.put("maxSize", maxSize);
3572                f.put("focusCycleRoot", focusCycleRoot);
3573                f.put("containerSerializedDataVersion",
3574                        containerSerializedDataVersion);
3575                f.put("focusTraversalPolicyProvider",
3576                        focusTraversalPolicyProvider);
3577                s.writeFields();
3578
3579                AWTEventMulticaster.save(s, containerListenerK,
3580                        containerListener);
3581                s.writeObject(null);
3582
3583                if (focusTraversalPolicy instanceof  java.io.Serializable) {
3584                    s.writeObject(focusTraversalPolicy);
3585                } else {
3586                    s.writeObject(null);
3587                }
3588            }
3589
3590            /**
3591             * Deserializes this <code>Container</code> from the specified
3592             * <code>ObjectInputStream</code>.
3593             * <ul>
3594             *    <li>Reads default serializable fields from the stream.</li>
3595             *    <li>Reads a list of serializable ContainerListener(s) as optional
3596             *        data. If the list is null, no Listeners are installed.</li>
3597             *    <li>Reads this Container's FocusTraversalPolicy, which may be null,
3598             *        as optional data.</li>
3599             * </ul>
3600             *
3601             * @param s the <code>ObjectInputStream</code> to read
3602             * @serial
3603             * @see #addContainerListener
3604             * @see #writeObject(ObjectOutputStream)
3605             */
3606            private void readObject(ObjectInputStream s)
3607                    throws ClassNotFoundException, IOException {
3608                ObjectInputStream.GetField f = s.readFields();
3609                ncomponents = f.get("ncomponents", 0);
3610                component = (Component[]) f.get("component", new Component[0]);
3611                layoutMgr = (LayoutManager) f.get("layoutMgr", null);
3612                dispatcher = (LightweightDispatcher) f.get("dispatcher", null);
3613                // Old stream. Doesn't contain maxSize among Component's fields.
3614                if (maxSize == null) {
3615                    maxSize = (Dimension) f.get("maxSize", null);
3616                }
3617                focusCycleRoot = f.get("focusCycleRoot", false);
3618                containerSerializedDataVersion = f.get(
3619                        "containerSerializedDataVersion", 1);
3620                focusTraversalPolicyProvider = f.get(
3621                        "focusTraversalPolicyProvider", false);
3622
3623                Component component[] = this .component;
3624                for (int i = 0; i < ncomponents; i++) {
3625                    component[i].parent = this ;
3626                    adjustListeningChildren(
3627                            AWTEvent.HIERARCHY_EVENT_MASK,
3628                            component[i]
3629                                    .numListening(AWTEvent.HIERARCHY_EVENT_MASK));
3630                    adjustListeningChildren(
3631                            AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3632                            component[i]
3633                                    .numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
3634                    adjustDescendants(component[i].countHierarchyMembers());
3635                }
3636
3637                Object keyOrNull;
3638                while (null != (keyOrNull = s.readObject())) {
3639                    String key = ((String) keyOrNull).intern();
3640
3641                    if (containerListenerK == key) {
3642                        addContainerListener((ContainerListener) (s
3643                                .readObject()));
3644                    } else {
3645                        // skip value for unrecognized key
3646                        s.readObject();
3647                    }
3648                }
3649
3650                try {
3651                    Object policy = s.readObject();
3652                    if (policy instanceof  FocusTraversalPolicy) {
3653                        focusTraversalPolicy = (FocusTraversalPolicy) policy;
3654                    }
3655                } catch (java.io.OptionalDataException e) {
3656                    // JDK 1.1/1.2/1.3 instances will not have this optional data.
3657                    // e.eof will be true to indicate that there is no more data
3658                    // available for this object. If e.eof is not true, throw the
3659                    // exception as it might have been caused by reasons unrelated to 
3660                    // focusTraversalPolicy.
3661
3662                    if (!e.eof) {
3663                        throw e;
3664                    }
3665                }
3666            }
3667
3668            /*
3669             * --- Accessibility Support ---
3670             */
3671
3672            /**
3673             * Inner class of Container used to provide default support for
3674             * accessibility.  This class is not meant to be used directly by
3675             * application developers, but is instead meant only to be
3676             * subclassed by container developers.
3677             * <p>
3678             * The class used to obtain the accessible role for this object,
3679             * as well as implementing many of the methods in the
3680             * AccessibleContainer interface.
3681             * @since 1.3
3682             */
3683            protected class AccessibleAWTContainer extends
3684                    AccessibleAWTComponent {
3685
3686                /**
3687                 * JDK1.3 serialVersionUID
3688                 */
3689                private static final long serialVersionUID = 5081320404842566097L;
3690
3691                /**
3692                 * Returns the number of accessible children in the object.  If all
3693                 * of the children of this object implement <code>Accessible</code>,
3694                 * then this method should return the number of children of this object.
3695                 *
3696                 * @return the number of accessible children in the object
3697                 */
3698                public int getAccessibleChildrenCount() {
3699                    return Container.this .getAccessibleChildrenCount();
3700                }
3701
3702                /**
3703                 * Returns the nth <code>Accessible</code> child of the object.
3704                 *
3705                 * @param i zero-based index of child
3706                 * @return the nth <code>Accessible</code> child of the object
3707                 */
3708                public Accessible getAccessibleChild(int i) {
3709                    return Container.this .getAccessibleChild(i);
3710                }
3711
3712                /**
3713                 * Returns the <code>Accessible</code> child, if one exists,
3714                 * contained at the local coordinate <code>Point</code>.
3715                 *
3716                 * @param p the point defining the top-left corner of the 
3717                 *    <code>Accessible</code>, given in the coordinate space
3718                 *    of the object's parent
3719                 * @return the <code>Accessible</code>, if it exists,
3720                 *    at the specified location; else <code>null</code>
3721                 */
3722                public Accessible getAccessibleAt(Point p) {
3723                    return Container.this .getAccessibleAt(p);
3724                }
3725
3726                protected ContainerListener accessibleContainerHandler = null;
3727
3728                /**
3729                 * Fire <code>PropertyChange</code> listener, if one is registered,
3730                 * when children are added or removed.
3731                 * @since 1.3
3732                 */
3733                protected class AccessibleContainerHandler implements 
3734                        ContainerListener {
3735                    public void componentAdded(ContainerEvent e) {
3736                        Component c = e.getChild();
3737                        if (c != null && c instanceof  Accessible) {
3738                            AccessibleAWTContainer.this 
3739                                    .firePropertyChange(
3740                                            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3741                                            null, ((Accessible) c)
3742                                                    .getAccessibleContext());
3743                        }
3744                    }
3745
3746                    public void componentRemoved(ContainerEvent e) {
3747                        Component c = e.getChild();
3748                        if (c != null && c instanceof  Accessible) {
3749                            AccessibleAWTContainer.this 
3750                                    .firePropertyChange(
3751                                            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3752                                            ((Accessible) c)
3753                                                    .getAccessibleContext(),
3754                                            null);
3755                        }
3756                    }
3757                }
3758
3759                /**
3760                 * Adds a PropertyChangeListener to the listener list.
3761                 *
3762                 * @param listener  the PropertyChangeListener to be added
3763                 */
3764                public void addPropertyChangeListener(
3765                        PropertyChangeListener listener) {
3766                    if (accessibleContainerHandler == null) {
3767                        accessibleContainerHandler = new AccessibleContainerHandler();
3768                        Container.this 
3769                                .addContainerListener(accessibleContainerHandler);
3770                    }
3771                    super .addPropertyChangeListener(listener);
3772                }
3773
3774            } // inner class AccessibleAWTContainer
3775
3776            /**
3777             * Returns the <code>Accessible</code> child contained at the local
3778             * coordinate <code>Point</code>, if one exists.  Otherwise
3779             * returns <code>null</code>.
3780             *
3781             * @param p the point defining the top-left corner of the 
3782             *    <code>Accessible</code>, given in the coordinate space
3783             *    of the object's parent
3784             * @return the <code>Accessible</code> at the specified location,
3785             *    if it exists; otherwise <code>null</code>
3786             */
3787            Accessible getAccessibleAt(Point p) {
3788                synchronized (getTreeLock()) {
3789                    if (this  instanceof  Accessible) {
3790                        Accessible a = (Accessible) this ;
3791                        AccessibleContext ac = a.getAccessibleContext();
3792                        if (ac != null) {
3793                            AccessibleComponent acmp;
3794                            Point location;
3795                            int nchildren = ac.getAccessibleChildrenCount();
3796                            for (int i = 0; i < nchildren; i++) {
3797                                a = ac.getAccessibleChild(i);
3798                                if ((a != null)) {
3799                                    ac = a.getAccessibleContext();
3800                                    if (ac != null) {
3801                                        acmp = ac.getAccessibleComponent();
3802                                        if ((acmp != null)
3803                                                && (acmp.isShowing())) {
3804                                            location = acmp.getLocation();
3805                                            Point np = new Point(p.x
3806                                                    - location.x, p.y
3807                                                    - location.y);
3808                                            if (acmp.contains(np)) {
3809                                                return a;
3810                                            }
3811                                        }
3812                                    }
3813                                }
3814                            }
3815                        }
3816                        return (Accessible) this ;
3817                    } else {
3818                        Component ret = this ;
3819                        if (!this .contains(p.x, p.y)) {
3820                            ret = null;
3821                        } else {
3822                            int ncomponents = this .getComponentCount();
3823                            for (int i = 0; i < ncomponents; i++) {
3824                                Component comp = this .getComponent(i);
3825                                if ((comp != null) && comp.isShowing()) {
3826                                    Point location = comp.getLocation();
3827                                    if (comp.contains(p.x - location.x, p.y
3828                                            - location.y)) {
3829                                        ret = comp;
3830                                    }
3831                                }
3832                            }
3833                        }
3834                        if (ret instanceof  Accessible) {
3835                            return (Accessible) ret;
3836                        }
3837                    }
3838                    return null;
3839                }
3840            }
3841
3842            /**
3843             * Returns the number of accessible children in the object.  If all
3844             * of the children of this object implement <code>Accessible</code>,
3845             * then this method should return the number of children of this object.
3846             *
3847             * @return the number of accessible children in the object
3848             */
3849            int getAccessibleChildrenCount() {
3850                synchronized (getTreeLock()) {
3851                    int count = 0;
3852                    Component[] children = this .getComponents();
3853                    for (int i = 0; i < children.length; i++) {
3854                        if (children[i] instanceof  Accessible) {
3855                            count++;
3856                        }
3857                    }
3858                    return count;
3859                }
3860            }
3861
3862            /**
3863             * Returns the nth <code>Accessible</code> child of the object.
3864             *
3865             * @param i zero-based index of child
3866             * @return the nth <code>Accessible</code> child of the object
3867             */
3868            Accessible getAccessibleChild(int i) {
3869                synchronized (getTreeLock()) {
3870                    Component[] children = this .getComponents();
3871                    int count = 0;
3872                    for (int j = 0; j < children.length; j++) {
3873                        if (children[j] instanceof  Accessible) {
3874                            if (count == i) {
3875                                return (Accessible) children[j];
3876                            } else {
3877                                count++;
3878                            }
3879                        }
3880                    }
3881                    return null;
3882                }
3883            }
3884
3885        }
3886
3887        /**
3888         * Class to manage the dispatching of MouseEvents to the lightweight descendants
3889         * and SunDropTargetEvents to both lightweight and heavyweight descendants
3890         * contained by a native container.
3891         *
3892         * NOTE: the class name is not appropriate anymore, but we cannot change it
3893         * because we must keep serialization compatibility.
3894         * 
3895         * @author Timothy Prinzing
3896         */
3897        class LightweightDispatcher implements  java.io.Serializable,
3898                AWTEventListener {
3899
3900            /*
3901             * JDK 1.1 serialVersionUID 
3902             */
3903            private static final long serialVersionUID = 5184291520170872969L;
3904            /*
3905             * Our own mouse event for when we're dragged over from another hw
3906             * container
3907             */
3908            private static final int LWD_MOUSE_DRAGGED_OVER = 1500;
3909
3910            private static final DebugHelper dbg = DebugHelper
3911                    .create(LightweightDispatcher.class);
3912
3913            LightweightDispatcher(Container nativeContainer) {
3914                this .nativeContainer = nativeContainer;
3915                mouseEventTarget = null;
3916                eventMask = 0;
3917            }
3918
3919            /*
3920             * Clean up any resources allocated when dispatcher was created;
3921             * should be called from Container.removeNotify
3922             */
3923            void dispose() {
3924                //System.out.println("Disposing lw dispatcher");
3925                stopListeningForOtherDrags();
3926                mouseEventTarget = null;
3927            }
3928
3929            /**
3930             * Enables events to subcomponents.
3931             */
3932            void enableEvents(long events) {
3933                eventMask |= events;
3934            }
3935
3936            /**
3937             * Dispatches an event to a sub-component if necessary, and
3938             * returns whether or not the event was forwarded to a 
3939             * sub-component.
3940             *
3941             * @param e the event
3942             */
3943            boolean dispatchEvent(AWTEvent e) {
3944                boolean ret = false;
3945
3946                /*
3947                 * Fix for BugTraq Id 4389284.
3948                 * Dispatch SunDropTargetEvents regardless of eventMask value.
3949                 * Do not update cursor on dispatching SunDropTargetEvents.
3950                 */
3951                if (e instanceof  SunDropTargetEvent) {
3952
3953                    SunDropTargetEvent sdde = (SunDropTargetEvent) e;
3954                    ret = processDropTargetEvent(sdde);
3955
3956                } else {
3957                    if (e instanceof  MouseEvent
3958                            && (eventMask & MOUSE_MASK) != 0) {
3959                        MouseEvent me = (MouseEvent) e;
3960                        ret = processMouseEvent(me);
3961                    }
3962
3963                    if (e.getID() == MouseEvent.MOUSE_MOVED) {
3964                        nativeContainer.updateCursorImmediately();
3965                    }
3966                }
3967
3968                return ret;
3969            }
3970
3971            /* This method effectively returns whether or not a mouse button was down
3972             * just BEFORE the event happened.  A better method name might be
3973             * wasAMouseButtonDownBeforeThisEvent().
3974             */
3975            private boolean isMouseGrab(MouseEvent e) {
3976                int modifiers = e.getModifiersEx();
3977
3978                if (e.getID() == MouseEvent.MOUSE_PRESSED
3979                        || e.getID() == MouseEvent.MOUSE_RELEASED) {
3980                    switch (e.getButton()) {
3981                    case MouseEvent.BUTTON1:
3982                        modifiers ^= InputEvent.BUTTON1_DOWN_MASK;
3983                        break;
3984                    case MouseEvent.BUTTON2:
3985                        modifiers ^= InputEvent.BUTTON2_DOWN_MASK;
3986                        break;
3987                    case MouseEvent.BUTTON3:
3988                        modifiers ^= InputEvent.BUTTON3_DOWN_MASK;
3989                        break;
3990                    }
3991                }
3992                /* modifiers now as just before event */
3993                return ((modifiers & (InputEvent.BUTTON1_DOWN_MASK
3994                        | InputEvent.BUTTON2_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) != 0);
3995            }
3996
3997            /**
3998             * This method attempts to distribute a mouse event to a lightweight
3999             * component.  It tries to avoid doing any unnecessary probes down
4000             * into the component tree to minimize the overhead of determining
4001             * where to route the event, since mouse movement events tend to
4002             * come in large and frequent amounts.
4003             */
4004            private boolean processMouseEvent(MouseEvent e) {
4005                int id = e.getID();
4006                Component mouseOver = // sensitive to mouse events
4007                nativeContainer.getMouseEventTarget(e.getX(), e.getY(),
4008                        Container.INCLUDE_SELF);
4009
4010                trackMouseEnterExit(mouseOver, e);
4011
4012                // 4508327 : MOUSE_CLICKED should only go to the recipient of 
4013                // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
4014                // MOUSE_CLICKED.
4015                if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
4016                    mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver
4017                            : null;
4018                }
4019
4020                if (mouseEventTarget != null) {
4021                    switch (id) {
4022                    case MouseEvent.MOUSE_ENTERED:
4023                    case MouseEvent.MOUSE_EXITED:
4024                        break;
4025                    case MouseEvent.MOUSE_PRESSED:
4026                        retargetMouseEvent(mouseEventTarget, id, e);
4027                        break;
4028                    case MouseEvent.MOUSE_RELEASED:
4029                        retargetMouseEvent(mouseEventTarget, id, e);
4030                        break;
4031                    case MouseEvent.MOUSE_CLICKED:
4032                        // 4508327: MOUSE_CLICKED should never be dispatched to a Component
4033                        // other than that which received the MOUSE_PRESSED event.  If the
4034                        // mouse is now over a different Component, don't dispatch the event.
4035                        // The previous fix for a similar problem was associated with bug
4036                        // 4155217.
4037                        if (mouseOver == mouseEventTarget) {
4038                            retargetMouseEvent(mouseOver, id, e);
4039                        }
4040                        break;
4041                    case MouseEvent.MOUSE_MOVED:
4042                        retargetMouseEvent(mouseEventTarget, id, e);
4043                        break;
4044                    case MouseEvent.MOUSE_DRAGGED:
4045                        if (isMouseGrab(e)) {
4046                            retargetMouseEvent(mouseEventTarget, id, e);
4047                        }
4048                        break;
4049                    case MouseEvent.MOUSE_WHEEL:
4050                        // This may send it somewhere that doesn't have MouseWheelEvents
4051                        // enabled.  In this case, Component.dispatchEventImpl() will
4052                        // retarget the event to a parent that DOES have the events enabled.
4053                        if (dbg.on && mouseOver != null) {
4054                            dbg.println("LD retargeting mouse wheel to "
4055                                    + mouseOver.getName() + ", "
4056                                    + mouseOver.getClass());
4057                        }
4058                        retargetMouseEvent(mouseOver, id, e);
4059                        break;
4060                    }
4061                    e.consume();
4062                }
4063                return e.isConsumed();
4064            }
4065
4066            private boolean processDropTargetEvent(SunDropTargetEvent e) {
4067                int id = e.getID();
4068                int x = e.getX();
4069                int y = e.getY();
4070
4071                /*
4072                 * Fix for BugTraq ID 4395290.
4073                 * It is possible that SunDropTargetEvent's Point is outside of the
4074                 * native container bounds. In this case we truncate coordinates.
4075                 */
4076                if (!nativeContainer.contains(x, y)) {
4077                    final Dimension d = nativeContainer.getSize();
4078                    if (d.width <= x) {
4079                        x = d.width - 1;
4080                    } else if (x < 0) {
4081                        x = 0;
4082                    }
4083                    if (d.height <= y) {
4084                        y = d.height - 1;
4085                    } else if (y < 0) {
4086                        y = 0;
4087                    }
4088                }
4089                Component mouseOver = // not necessarily sensitive to mouse events
4090                nativeContainer.getDropTargetEventTarget(x, y,
4091                        Container.INCLUDE_SELF);
4092                trackMouseEnterExit(mouseOver, e);
4093
4094                if (mouseOver != nativeContainer && mouseOver != null) {
4095                    switch (id) {
4096                    case SunDropTargetEvent.MOUSE_ENTERED:
4097                    case SunDropTargetEvent.MOUSE_EXITED:
4098                        break;
4099                    default:
4100                        retargetMouseEvent(mouseOver, id, e);
4101                        e.consume();
4102                        break;
4103                    }
4104                }
4105                return e.isConsumed();
4106            }
4107
4108            /*
4109             * Generates enter/exit events as mouse moves over lw components
4110             * @param targetOver	Target mouse is over (including native container)
4111             * @param e			Mouse event in native container
4112             */
4113            private void trackMouseEnterExit(Component targetOver, MouseEvent e) {
4114                Component targetEnter = null;
4115                int id = e.getID();
4116
4117                if (e instanceof  SunDropTargetEvent
4118                        && id == MouseEvent.MOUSE_ENTERED
4119                        && isMouseInNativeContainer == true) {
4120                    // This can happen if a lightweight component which initiated the
4121                    // drag has an associated drop target. MOUSE_ENTERED comes when the
4122                    // mouse is in the native container already. To propagate this event
4123                    // properly we should null out targetLastEntered.
4124                    targetLastEntered = null;
4125                } else if (id != MouseEvent.MOUSE_EXITED
4126                        && id != MouseEvent.MOUSE_DRAGGED
4127                        && id != LWD_MOUSE_DRAGGED_OVER
4128                        && isMouseInNativeContainer == false) {
4129                    // any event but an exit or drag means we're in the native container
4130                    isMouseInNativeContainer = true;
4131                    startListeningForOtherDrags();
4132                } else if (id == MouseEvent.MOUSE_EXITED) {
4133                    isMouseInNativeContainer = false;
4134                    stopListeningForOtherDrags();
4135                }
4136
4137                if (isMouseInNativeContainer) {
4138                    targetEnter = targetOver;
4139                }
4140
4141                if (targetLastEntered == targetEnter) {
4142                    return;
4143                }
4144
4145                if (targetLastEntered != null) {
4146                    retargetMouseEvent(targetLastEntered,
4147                            MouseEvent.MOUSE_EXITED, e);
4148                }
4149                if (id == MouseEvent.MOUSE_EXITED) {
4150                    // consume native exit event if we generate one
4151                    e.consume();
4152                }
4153
4154                if (targetEnter != null) {
4155                    retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
4156                }
4157                if (id == MouseEvent.MOUSE_ENTERED) {
4158                    // consume native enter event if we generate one
4159                    e.consume();
4160                }
4161
4162                targetLastEntered = targetEnter;
4163            }
4164
4165            /*
4166             * Listens to global mouse drag events so even drags originating
4167             * from other heavyweight containers will generate enter/exit
4168             * events in this container
4169             */
4170            private void startListeningForOtherDrags() {
4171                //System.out.println("Adding AWTEventListener");
4172                java.security.AccessController
4173                        .doPrivileged(new java.security.PrivilegedAction() {
4174                            public Object run() {
4175                                nativeContainer
4176                                        .getToolkit()
4177                                        .addAWTEventListener(
4178                                                LightweightDispatcher.this ,
4179                                                AWTEvent.MOUSE_EVENT_MASK
4180                                                        | AWTEvent.MOUSE_MOTION_EVENT_MASK);
4181                                return null;
4182                            }
4183                        });
4184            }
4185
4186            private void stopListeningForOtherDrags() {
4187                //System.out.println("Removing AWTEventListener");
4188                java.security.AccessController
4189                        .doPrivileged(new java.security.PrivilegedAction() {
4190                            public Object run() {
4191                                nativeContainer.getToolkit()
4192                                        .removeAWTEventListener(
4193                                                LightweightDispatcher.this );
4194                                return null;
4195                            }
4196                        });
4197            }
4198
4199            /*
4200             * (Implementation of AWTEventListener)
4201             * Listen for drag events posted in other hw components so we can
4202             * track enter/exit regardless of where a drag originated
4203             */
4204            public void eventDispatched(AWTEvent e) {
4205                boolean isForeignDrag = (e instanceof  MouseEvent)
4206                        && !(e instanceof  SunDropTargetEvent)
4207                        && (e.id == MouseEvent.MOUSE_DRAGGED)
4208                        && (e.getSource() != nativeContainer);
4209
4210                if (!isForeignDrag) {
4211                    // only interested in drags from other hw components
4212                    return;
4213                }
4214
4215                MouseEvent srcEvent = (MouseEvent) e;
4216                MouseEvent me;
4217
4218                synchronized (nativeContainer.getTreeLock()) {
4219                    Component srcComponent = srcEvent.getComponent();
4220
4221                    // component may have disappeared since drag event posted
4222                    // (i.e. Swing hierarchical menus)
4223                    if (!srcComponent.isShowing()) {
4224                        return;
4225                    }
4226
4227                    // see 5083555
4228                    // check if srcComponent is in any modal blocked window
4229                    Component c = nativeContainer;
4230                    while ((c != null) && !(c instanceof  Window)) {
4231                        c = c.getParent_NoClientCode();
4232                    }
4233                    if ((c == null) || ((Window) c).isModalBlocked()) {
4234                        return;
4235                    }
4236
4237                    //
4238                    // create an internal 'dragged-over' event indicating
4239                    // we are being dragged over from another hw component
4240                    //
4241                    me = new MouseEvent(
4242                            nativeContainer,
4243                            LWD_MOUSE_DRAGGED_OVER,
4244                            srcEvent.getWhen(),
4245                            srcEvent.getModifiersEx() | srcEvent.getModifiers(),
4246                            srcEvent.getX(), srcEvent.getY(), srcEvent
4247                                    .getXOnScreen(), srcEvent.getYOnScreen(),
4248                            srcEvent.getClickCount(),
4249                            srcEvent.isPopupTrigger(), srcEvent.getButton());
4250                    ((AWTEvent) srcEvent).copyPrivateDataInto(me);
4251                    // translate coordinates to this native container
4252                    final Point ptSrcOrigin = srcComponent
4253                            .getLocationOnScreen();
4254
4255                    if (AppContext.getAppContext() != nativeContainer.appContext) {
4256                        final MouseEvent mouseEvent = me;
4257                        Runnable r = new Runnable() {
4258                            public void run() {
4259                                if (!nativeContainer.isShowing()) {
4260                                    return;
4261                                }
4262
4263                                Point ptDstOrigin = nativeContainer
4264                                        .getLocationOnScreen();
4265                                mouseEvent.translatePoint(ptSrcOrigin.x
4266                                        - ptDstOrigin.x, ptSrcOrigin.y
4267                                        - ptDstOrigin.y);
4268                                Component targetOver = nativeContainer
4269                                        .getMouseEventTarget(mouseEvent.getX(),
4270                                                mouseEvent.getY(),
4271                                                Container.INCLUDE_SELF);
4272                                trackMouseEnterExit(targetOver, mouseEvent);
4273                            }
4274                        };
4275                        SunToolkit.executeOnEventHandlerThread(nativeContainer,
4276                                r);
4277                        return;
4278                    } else {
4279                        if (!nativeContainer.isShowing()) {
4280                            return;
4281                        }
4282
4283                        Point ptDstOrigin = nativeContainer
4284                                .getLocationOnScreen();
4285                        me.translatePoint(ptSrcOrigin.x - ptDstOrigin.x,
4286                                ptSrcOrigin.y - ptDstOrigin.y);
4287                    }
4288                }
4289                //System.out.println("Track event: " + me);
4290                // feed the 'dragged-over' event directly to the enter/exit
4291                // code (not a real event so don't pass it to dispatchEvent)
4292                Component targetOver = nativeContainer.getMouseEventTarget(me
4293                        .getX(), me.getY(), Container.INCLUDE_SELF);
4294                trackMouseEnterExit(targetOver, me);
4295            }
4296
4297            /**
4298             * Sends a mouse event to the current mouse event recipient using
4299             * the given event (sent to the windowed host) as a srcEvent.  If
4300             * the mouse event target is still in the component tree, the 
4301             * coordinates of the event are translated to those of the target.
4302             * If the target has been removed, we don't bother to send the
4303             * message.
4304             */
4305            void retargetMouseEvent(Component target, int id, MouseEvent e) {
4306                if (target == null) {
4307                    return; // mouse is over another hw component or target is disabled
4308                }
4309
4310                int x = e.getX(), y = e.getY();
4311                Component component;
4312
4313                for (component = target; component != null
4314                        && component != nativeContainer; component = component
4315                        .getParent()) {
4316                    x -= component.x;
4317                    y -= component.y;
4318                }
4319                MouseEvent retargeted;
4320                if (component != null) {
4321                    if (e instanceof  SunDropTargetEvent) {
4322                        retargeted = new SunDropTargetEvent(target, id, x, y,
4323                                ((SunDropTargetEvent) e).getDispatcher());
4324                    } else if (id == MouseEvent.MOUSE_WHEEL) {
4325                        retargeted = new MouseWheelEvent(target, id, e
4326                                .getWhen(), e.getModifiersEx()
4327                                | e.getModifiers(), x, y, e.getXOnScreen(), e
4328                                .getYOnScreen(), e.getClickCount(), e
4329                                .isPopupTrigger(), ((MouseWheelEvent) e)
4330                                .getScrollType(), ((MouseWheelEvent) e)
4331                                .getScrollAmount(), ((MouseWheelEvent) e)
4332                                .getWheelRotation());
4333                    } else {
4334                        retargeted = new MouseEvent(target, id, e.getWhen(), e
4335                                .getModifiersEx()
4336                                | e.getModifiers(), x, y, e.getXOnScreen(), e
4337                                .getYOnScreen(), e.getClickCount(), e
4338                                .isPopupTrigger(), e.getButton());
4339                    }
4340
4341                    ((AWTEvent) e).copyPrivateDataInto(retargeted);
4342
4343                    if (target == nativeContainer) {
4344                        // avoid recursively calling LightweightDispatcher...
4345                        ((Container) target).dispatchEventToSelf(retargeted);
4346                    } else {
4347                        assert AppContext.getAppContext() == target.appContext;
4348
4349                        if (nativeContainer.modalComp != null) {
4350                            if (((Container) nativeContainer.modalComp)
4351                                    .isAncestorOf(target)) {
4352                                target.dispatchEvent(retargeted);
4353                            } else {
4354                                e.consume();
4355                            }
4356                        } else {
4357                            target.dispatchEvent(retargeted);
4358                        }
4359                    }
4360                }
4361            }
4362
4363            // --- member variables -------------------------------
4364
4365            /**
4366             * The windowed container that might be hosting events for 
4367             * subcomponents.
4368             */
4369            private Container nativeContainer;
4370
4371            /**
4372             * This variable is not used, but kept for serialization compatibility
4373             */
4374            private Component focus;
4375
4376            /**
4377             * The current subcomponent being hosted by this windowed
4378             * component that has events being forwarded to it.  If this
4379             * is null, there are currently no events being forwarded to 
4380             * a subcomponent.
4381             */
4382            private transient Component mouseEventTarget;
4383
4384            /**
4385             * The last component entered
4386             */
4387            private transient Component targetLastEntered;
4388
4389            /**
4390             * Is the mouse over the native container
4391             */
4392            private transient boolean isMouseInNativeContainer = false;
4393
4394            /**
4395             * This variable is not used, but kept for serialization compatibility
4396             */
4397            private Cursor nativeCursor;
4398
4399            /**
4400             * The event mask for contained lightweight components.  Lightweight
4401             * components need a windowed container to host window-related 
4402             * events.  This separate mask indicates events that have been 
4403             * requested by contained lightweight components without effecting
4404             * the mask of the windowed component itself.
4405             */
4406            private long eventMask;
4407
4408            /**
4409             * The kind of events routed to lightweight components from windowed
4410             * hosts.
4411             */
4412            private static final long PROXY_EVENT_MASK = AWTEvent.FOCUS_EVENT_MASK
4413                    | AWTEvent.KEY_EVENT_MASK
4414                    | AWTEvent.MOUSE_EVENT_MASK
4415                    | AWTEvent.MOUSE_MOTION_EVENT_MASK
4416                    | AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4417
4418            private static final long MOUSE_MASK = AWTEvent.MOUSE_EVENT_MASK
4419                    | AWTEvent.MOUSE_MOTION_EVENT_MASK
4420                    | AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4421        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.