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

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
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:        }
w_w___w___._j__a__v__a_2__s_.co_m | Contact Us
Copyright 2003 - 08 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.