1 /*
   2  * Copyright 1995-2009 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.dnd.DropTarget;
  28 
  29 import java.awt.event.*;
  30 
  31 import java.awt.peer.ContainerPeer;
  32 import java.awt.peer.ComponentPeer;
  33 import java.awt.peer.LightweightPeer;
  34 
  35 import java.beans.PropertyChangeListener;
  36 
  37 import java.io.IOException;
  38 import java.io.ObjectInputStream;
  39 import java.io.ObjectOutputStream;
  40 import java.io.ObjectStreamField;
  41 import java.io.PrintStream;
  42 import java.io.PrintWriter;
  43 
  44 import java.util.Arrays;
  45 import java.util.EventListener;
  46 import java.util.HashSet;
  47 import java.util.Set;
  48 
  49 import java.util.logging.*;
  50 
  51 import javax.accessibility.*;
  52 
  53 import sun.awt.AppContext;
  54 import sun.awt.CausedFocusEvent;
  55 import sun.awt.PeerEvent;
  56 import sun.awt.SunToolkit;
  57 
  58 import sun.awt.dnd.SunDropTargetEvent;
  59 
  60 import sun.java2d.pipe.Region;
  61 
  62 /**
  63  * A generic Abstract Window Toolkit(AWT) container object is a component
  64  * that can contain other AWT components.
  65  * <p>
  66  * Components added to a container are tracked in a list.  The order
  67  * of the list will define the components' front-to-back stacking order
  68  * within the container.  If no index is specified when adding a
  69  * component to a container, it will be added to the end of the list
  70  * (and hence to the bottom of the stacking order).
  71  * <p>
  72  * <b>Note</b>: For details on the focus subsystem, see
  73  * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
  74  * How to Use the Focus Subsystem</a>,
  75  * a section in <em>The Java Tutorial</em>, and the
  76  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  77  * for more information.
  78  *
  79  * @author      Arthur van Hoff
  80  * @author      Sami Shaio
  81  * @see       #add(java.awt.Component, int)
  82  * @see       #getComponent(int)
  83  * @see       LayoutManager
  84  * @since     JDK1.0
  85  */
  86 public class Container extends Component {
  87 
  88     private static final Logger log = Logger.getLogger("java.awt.Container");
  89     private static final Logger eventLog = Logger.getLogger("java.awt.event.Container");
  90 
  91     private static final Component[] EMPTY_ARRAY = new Component[0];
  92 
  93     /**
  94      * The components in this container.
  95      * @see #add
  96      * @see #getComponents
  97      */
  98     private java.util.List<Component> component = new java.util.ArrayList<Component>();
  99 
 100     /**
 101      * Layout manager for this container.
 102      * @see #doLayout
 103      * @see #setLayout
 104      * @see #getLayout
 105      */
 106     LayoutManager layoutMgr;
 107 
 108     /**
 109      * Event router for lightweight components.  If this container
 110      * is native, this dispatcher takes care of forwarding and
 111      * retargeting the events to lightweight components contained
 112      * (if any).
 113      */
 114     private LightweightDispatcher dispatcher;
 115 
 116     /**
 117      * The focus traversal policy that will manage keyboard traversal of this
 118      * Container's children, if this Container is a focus cycle root. If the
 119      * value is null, this Container inherits its policy from its focus-cycle-
 120      * root ancestor. If all such ancestors of this Container have null
 121      * policies, then the current KeyboardFocusManager's default policy is
 122      * used. If the value is non-null, this policy will be inherited by all
 123      * focus-cycle-root children that have no keyboard-traversal policy of
 124      * their own (as will, recursively, their focus-cycle-root children).
 125      * <p>
 126      * If this Container is not a focus cycle root, the value will be
 127      * remembered, but will not be used or inherited by this or any other
 128      * Containers until this Container is made a focus cycle root.
 129      *
 130      * @see #setFocusTraversalPolicy
 131      * @see #getFocusTraversalPolicy
 132      * @since 1.4
 133      */
 134     private transient FocusTraversalPolicy focusTraversalPolicy;
 135 
 136     /**
 137      * Indicates whether this Component is the root of a focus traversal cycle.
 138      * Once focus enters a traversal cycle, typically it cannot leave it via
 139      * focus traversal unless one of the up- or down-cycle keys is pressed.
 140      * Normal traversal is limited to this Container, and all of this
 141      * Container's descendants that are not descendants of inferior focus cycle
 142      * roots.
 143      *
 144      * @see #setFocusCycleRoot
 145      * @see #isFocusCycleRoot
 146      * @since 1.4
 147      */
 148     private boolean focusCycleRoot = false;
 149 
 150 
 151     /**
 152      * Stores the value of focusTraversalPolicyProvider property.
 153      * @since 1.5
 154      * @see #setFocusTraversalPolicyProvider
 155      */
 156     private boolean focusTraversalPolicyProvider;
 157 
 158     // keeps track of the threads that are printing this component
 159     private transient Set printingThreads;
 160     // True if there is at least one thread that's printing this component
 161     private transient boolean printing = false;
 162 
 163     transient ContainerListener containerListener;
 164 
 165     /* HierarchyListener and HierarchyBoundsListener support */
 166     transient int listeningChildren;
 167     transient int listeningBoundsChildren;
 168     transient int descendantsCount;
 169 
 170     /* Non-opaque window support -- see Window.setLayersOpaque */
 171     transient Color preserveBackgroundColor = null;
 172 
 173     /**
 174      * JDK 1.1 serialVersionUID
 175      */
 176     private static final long serialVersionUID = 4613797578919906343L;
 177 
 178     /**
 179      * A constant which toggles one of the controllable behaviors
 180      * of <code>getMouseEventTarget</code>. It is used to specify whether
 181      * the method can return the Container on which it is originally called
 182      * in case if none of its children are the current mouse event targets.
 183      *
 184      * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
 185      */
 186     static final boolean INCLUDE_SELF = true;
 187 
 188     /**
 189      * A constant which toggles one of the controllable behaviors
 190      * of <code>getMouseEventTarget</code>. It is used to specify whether
 191      * the method should search only lightweight components.
 192      *
 193      * @see #getMouseEventTarget(int, int, boolean, boolean, boolean)
 194      */
 195     static final boolean SEARCH_HEAVYWEIGHTS = true;
 196 
 197     /*
 198      * Number of HW or LW components in this container (including
 199      * all descendant containers).
 200      */
 201     private transient int numOfHWComponents = 0;
 202     private transient int numOfLWComponents = 0;
 203 
 204     private static final Logger mixingLog = Logger.getLogger("java.awt.mixing.Container");
 205 
 206     /**
 207      * @serialField ncomponents                     int
 208      *       The number of components in this container.
 209      *       This value can be null.
 210      * @serialField component                       Component[]
 211      *       The components in this container.
 212      * @serialField layoutMgr                       LayoutManager
 213      *       Layout manager for this container.
 214      * @serialField dispatcher                      LightweightDispatcher
 215      *       Event router for lightweight components.  If this container
 216      *       is native, this dispatcher takes care of forwarding and
 217      *       retargeting the events to lightweight components contained
 218      *       (if any).
 219      * @serialField maxSize                         Dimension
 220      *       Maximum size of this Container.
 221      * @serialField focusCycleRoot                  boolean
 222      *       Indicates whether this Component is the root of a focus traversal cycle.
 223      *       Once focus enters a traversal cycle, typically it cannot leave it via
 224      *       focus traversal unless one of the up- or down-cycle keys is pressed.
 225      *       Normal traversal is limited to this Container, and all of this
 226      *       Container's descendants that are not descendants of inferior focus cycle
 227      *       roots.
 228      * @serialField containerSerializedDataVersion  int
 229      *       Container Serial Data Version.
 230      * @serialField focusTraversalPolicyProvider    boolean
 231      *       Stores the value of focusTraversalPolicyProvider property.
 232      */
 233     private static final ObjectStreamField[] serialPersistentFields = {
 234         new ObjectStreamField("ncomponents", Integer.TYPE),
 235         new ObjectStreamField("component", Component[].class),
 236         new ObjectStreamField("layoutMgr", LayoutManager.class),
 237         new ObjectStreamField("dispatcher", LightweightDispatcher.class),
 238         new ObjectStreamField("maxSize", Dimension.class),
 239         new ObjectStreamField("focusCycleRoot", Boolean.TYPE),
 240         new ObjectStreamField("containerSerializedDataVersion", Integer.TYPE),
 241         new ObjectStreamField("focusTraversalPolicyProvider", Boolean.TYPE),
 242     };
 243 
 244     static {
 245         /* ensure that the necessary native libraries are loaded */
 246         Toolkit.loadLibraries();
 247         if (!GraphicsEnvironment.isHeadless()) {
 248             initIDs();
 249         }
 250     }
 251 
 252     /**
 253      * Initialize JNI field and method IDs for fields that may be
 254        called from C.
 255      */
 256     private static native void initIDs();
 257 
 258     /**
 259      * Constructs a new Container. Containers can be extended directly,
 260      * but are lightweight in this case and must be contained by a parent
 261      * somewhere higher up in the component tree that is native.
 262      * (such as Frame for example).
 263      */
 264     public Container() {
 265     }
 266 
 267     void initializeFocusTraversalKeys() {
 268         focusTraversalKeys = new Set[4];
 269     }
 270 
 271     /**
 272      * Gets the number of components in this panel.
 273      * <p>
 274      * Note: This method should be called under AWT tree lock.
 275      *
 276      * @return    the number of components in this panel.
 277      * @see       #getComponent
 278      * @since     JDK1.1
 279      * @see Component#getTreeLock()
 280      */
 281     public int getComponentCount() {
 282         return countComponents();
 283     }
 284 
 285     /**
 286      * @deprecated As of JDK version 1.1,
 287      * replaced by getComponentCount().
 288      */
 289     @Deprecated
 290     public int countComponents() {
 291         // This method is not synchronized under AWT tree lock.
 292         // Instead, the calling code is responsible for the
 293         // synchronization. See 6784816 for details.
 294         return component.size();
 295     }
 296 
 297     /**
 298      * Gets the nth component in this container.
 299      * <p>
 300      * Note: This method should be called under AWT tree lock.
 301      *
 302      * @param      n   the index of the component to get.
 303      * @return     the n<sup>th</sup> component in this container.
 304      * @exception  ArrayIndexOutOfBoundsException
 305      *                 if the n<sup>th</sup> value does not exist.
 306      * @see Component#getTreeLock()
 307      */
 308     public Component getComponent(int n) {
 309         // This method is not synchronized under AWT tree lock.
 310         // Instead, the calling code is responsible for the
 311         // synchronization. See 6784816 for details.
 312         try {
 313             return component.get(n);
 314         } catch (IndexOutOfBoundsException z) {
 315             throw new ArrayIndexOutOfBoundsException("No such child: " + n);
 316         }
 317     }
 318 
 319     /**
 320      * Gets all the components in this container.
 321      * <p>
 322      * Note: This method should be called under AWT tree lock.
 323      *
 324      * @return    an array of all the components in this container.
 325      * @see Component#getTreeLock()
 326      */
 327     public Component[] getComponents() {
 328         // This method is not synchronized under AWT tree lock.
 329         // Instead, the calling code is responsible for the
 330         // synchronization. See 6784816 for details.
 331         return getComponents_NoClientCode();
 332     }
 333 
 334     // NOTE: This method may be called by privileged threads.
 335     //       This functionality is implemented in a package-private method
 336     //       to insure that it cannot be overridden by client subclasses.
 337     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 338     final Component[] getComponents_NoClientCode() {
 339         return component.toArray(EMPTY_ARRAY);
 340     }
 341 
 342     /*
 343      * Wrapper for getComponents() method with a proper synchronization.
 344      */
 345     Component[] getComponentsSync() {
 346         synchronized (getTreeLock()) {
 347             return getComponents();
 348         }
 349     }
 350 
 351     /**
 352      * Determines the insets of this container, which indicate the size
 353      * of the container's border.
 354      * <p>
 355      * A <code>Frame</code> object, for example, has a top inset that
 356      * corresponds to the height of the frame's title bar.
 357      * @return    the insets of this container.
 358      * @see       Insets
 359      * @see       LayoutManager
 360      * @since     JDK1.1
 361      */
 362     public Insets getInsets() {
 363         return insets();
 364     }
 365 
 366     /**
 367      * @deprecated As of JDK version 1.1,
 368      * replaced by <code>getInsets()</code>.
 369      */
 370     @Deprecated
 371     public Insets insets() {
 372         ComponentPeer peer = this.peer;
 373         if (peer instanceof ContainerPeer) {
 374             ContainerPeer cpeer = (ContainerPeer)peer;
 375             return (Insets)cpeer.getInsets().clone();
 376         }
 377         return new Insets(0, 0, 0, 0);
 378     }
 379 
 380     /**
 381      * Appends the specified component to the end of this container.
 382      * This is a convenience method for {@link #addImpl}.
 383      * <p>
 384      * Note: If a component has been added to a container that
 385      * has been displayed, <code>validate</code> must be
 386      * called on that container to display the new component.
 387      * If multiple components are being added, you can improve
 388      * efficiency by calling <code>validate</code> only once,
 389      * after all the components have been added.
 390      *
 391      * @param     comp   the component to be added
 392      * @exception NullPointerException if {@code comp} is {@code null}
 393      * @see #addImpl
 394      * @see #validate
 395      * @see javax.swing.JComponent#revalidate()
 396      * @return    the component argument
 397      */
 398     public Component add(Component comp) {
 399         addImpl(comp, null, -1);
 400         return comp;
 401     }
 402 
 403     /**
 404      * Adds the specified component to this container.
 405      * This is a convenience method for {@link #addImpl}.
 406      * <p>
 407      * This method is obsolete as of 1.1.  Please use the
 408      * method <code>add(Component, Object)</code> instead.
 409      * @exception NullPointerException if {@code comp} is {@code null}
 410      * @see #add(Component, Object)
 411      */
 412     public Component add(String name, Component comp) {
 413         addImpl(comp, name, -1);
 414         return comp;
 415     }
 416 
 417     /**
 418      * Adds the specified component to this container at the given
 419      * position.
 420      * This is a convenience method for {@link #addImpl}.
 421      * <p>
 422      * Note: If a component has been added to a container that
 423      * has been displayed, <code>validate</code> must be
 424      * called on that container to display the new component.
 425      * If multiple components are being added, you can improve
 426      * efficiency by calling <code>validate</code> only once,
 427      * after all the components have been added.
 428      *
 429      * @param     comp   the component to be added
 430      * @param     index    the position at which to insert the component,
 431      *                   or <code>-1</code> to append the component to the end
 432      * @exception NullPointerException if {@code comp} is {@code null}
 433      * @exception IllegalArgumentException if {@code index} is invalid (see
 434      *            {@link #addImpl} for details)
 435      * @return    the component <code>comp</code>
 436      * @see #addImpl
 437      * @see #remove
 438      * @see #validate
 439      * @see javax.swing.JComponent#revalidate()
 440      */
 441     public Component add(Component comp, int index) {
 442         addImpl(comp, null, index);
 443         return comp;
 444     }
 445 
 446     /**
 447      * Checks that the component
 448      * isn't supposed to be added into itself.
 449      */
 450     private void checkAddToSelf(Component comp){
 451         if (comp instanceof Container) {
 452             for (Container cn = this; cn != null; cn=cn.parent) {
 453                 if (cn == comp) {
 454                     throw new IllegalArgumentException("adding container's parent to itself");
 455                 }
 456             }
 457         }
 458     }
 459 
 460     /**
 461      * Checks that the component is not a Window instance.
 462      */
 463     private void checkNotAWindow(Component comp){
 464         if (comp instanceof Window) {
 465             throw new IllegalArgumentException("adding a window to a container");
 466         }
 467     }
 468 
 469     /**
 470      * Checks that the component comp can be added to this container
 471      * Checks :  index in bounds of container's size,
 472      * comp is not one of this container's parents,
 473      * and comp is not a window.
 474      * Comp and container must be on the same GraphicsDevice.
 475      * if comp is container, all sub-components must be on
 476      * same GraphicsDevice.
 477      *
 478      * @since 1.5
 479      */
 480     private void checkAdding(Component comp, int index) {
 481         checkTreeLock();
 482 
 483         GraphicsConfiguration thisGC = getGraphicsConfiguration();
 484 
 485         if (index > component.size() || index < 0) {
 486             throw new IllegalArgumentException("illegal component position");
 487         }
 488         if (comp.parent == this) {
 489             if (index == component.size()) {
 490                 throw new IllegalArgumentException("illegal component position " +
 491                                                    index + " should be less then " + component.size());
 492             }
 493         }
 494         checkAddToSelf(comp);
 495         checkNotAWindow(comp);
 496 
 497         Window thisTopLevel = getContainingWindow();
 498         Window compTopLevel = comp.getContainingWindow();
 499         if (thisTopLevel != compTopLevel) {
 500             throw new IllegalArgumentException("component and container should be in the same top-level window");
 501         }
 502         if (thisGC != null) {
 503             comp.checkGD(thisGC.getDevice().getIDstring());
 504         }
 505     }
 506 
 507     /**
 508      * Removes component comp from this container without making unneccessary changes
 509      * and generating unneccessary events. This function intended to perform optimized
 510      * remove, for example, if newParent and current parent are the same it just changes
 511      * index without calling removeNotify.
 512      * Note: Should be called while holding treeLock
 513      * Returns whether removeNotify was invoked
 514      * @since: 1.5
 515      */
 516     private boolean removeDelicately(Component comp, Container newParent, int newIndex) {
 517         checkTreeLock();
 518 
 519         int index = getComponentZOrder(comp);
 520         boolean needRemoveNotify = isRemoveNotifyNeeded(comp, this, newParent);
 521         if (needRemoveNotify) {
 522             comp.removeNotify();
 523         }
 524         if (newParent != this) {
 525             if (layoutMgr != null) {
 526                 layoutMgr.removeLayoutComponent(comp);
 527             }
 528             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
 529                                     -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
 530             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
 531                                     -comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
 532             adjustDescendants(-(comp.countHierarchyMembers()));
 533 
 534             comp.parent = null;
 535             if (needRemoveNotify) {
 536                 comp.setGraphicsConfiguration(null);
 537             }
 538             component.remove(index);
 539 
 540             invalidateIfValid();
 541         } else {
 542             // We should remove component and then
 543             // add it by the newIndex without newIndex decrement if even we shift components to the left
 544             // after remove. Consult the rules below:
 545             // 2->4: 012345 -> 013425, 2->5: 012345 -> 013452
 546             // 4->2: 012345 -> 014235
 547             component.remove(index);
 548             component.add(newIndex, comp);
 549         }
 550         if (comp.parent == null) { // was actually removed
 551             if (containerListener != null ||
 552                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
 553                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
 554                 ContainerEvent e = new ContainerEvent(this,
 555                                                       ContainerEvent.COMPONENT_REMOVED,
 556                                                       comp);
 557                 dispatchEvent(e);
 558 
 559             }
 560             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
 561                                        this, HierarchyEvent.PARENT_CHANGED,
 562                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 563             if (peer != null && layoutMgr == null && isVisible()) {
 564                 updateCursorImmediately();
 565             }
 566         }
 567         return needRemoveNotify;
 568     }
 569 
 570     /**
 571      * Checks whether this container can contain component which is focus owner.
 572      * Verifies that container is enable and showing, and if it is focus cycle root
 573      * its FTP allows component to be focus owner
 574      * @since 1.5
 575      */
 576     boolean canContainFocusOwner(Component focusOwnerCandidate) {
 577         if (!(isEnabled() && isDisplayable()
 578               && isVisible() && isFocusable()))
 579         {
 580             return false;
 581         }
 582         if (isFocusCycleRoot()) {
 583             FocusTraversalPolicy policy = getFocusTraversalPolicy();
 584             if (policy instanceof DefaultFocusTraversalPolicy) {
 585                 if (!((DefaultFocusTraversalPolicy)policy).accept(focusOwnerCandidate)) {
 586                     return false;
 587                 }
 588             }
 589         }
 590         synchronized(getTreeLock()) {
 591             if (parent != null) {
 592                 return parent.canContainFocusOwner(focusOwnerCandidate);
 593             }
 594         }
 595         return true;
 596     }
 597 
 598     /**
 599      * Checks whether or not this container has heavyweight children.
 600      * Note: Should be called while holding tree lock
 601      * @return true if there is at least one heavyweight children in a container, false otherwise
 602      * @since 1.5
 603      */
 604     final boolean hasHeavyweightDescendants() {
 605         checkTreeLock();
 606         return numOfHWComponents > 0;
 607     }
 608 
 609     /**
 610      * Checks whether or not this container has lightweight children.
 611      * Note: Should be called while holding tree lock
 612      * @return true if there is at least one lightweight children in a container, false otherwise
 613      * @since 1.7
 614      */
 615     final boolean hasLightweightDescendants() {
 616         checkTreeLock();
 617         return numOfLWComponents > 0;
 618     }
 619 
 620     /**
 621      * Returns closest heavyweight component to this container. If this container is heavyweight
 622      * returns this.
 623      * @since 1.5
 624      */
 625     Container getHeavyweightContainer() {
 626         checkTreeLock();
 627         if (peer != null && !(peer instanceof LightweightPeer)) {
 628             return this;
 629         } else {
 630             return getNativeContainer();
 631         }
 632     }
 633 
 634     /**
 635      * Detects whether or not remove from current parent and adding to new parent requires call of
 636      * removeNotify on the component. Since removeNotify destroys native window this might (not)
 637      * be required. For example, if new container and old containers are the same we don't need to
 638      * destroy native window.
 639      * @since: 1.5
 640      */
 641     private static boolean isRemoveNotifyNeeded(Component comp, Container oldContainer, Container newContainer) {
 642         if (oldContainer == null) { // Component didn't have parent - no removeNotify
 643             return false;
 644         }
 645         if (comp.peer == null) { // Component didn't have peer - no removeNotify
 646             return false;
 647         }
 648         if (newContainer.peer == null) {
 649             // Component has peer but new Container doesn't - call removeNotify
 650             return true;
 651         }
 652 
 653         // If component is lightweight non-Container or lightweight Container with all but heavyweight
 654         // children there is no need to call remove notify
 655         if (comp.isLightweight()) {
 656             boolean isContainer = comp instanceof Container;
 657 
 658             if (!isContainer || (isContainer && !((Container)comp).hasHeavyweightDescendants())) {
 659                 return false;
 660             }
 661         }
 662 
 663         // If this point is reached, then the comp is either a HW or a LW container with HW descendants.
 664 
 665         // All three components have peers, check for peer change
 666         Container newNativeContainer = oldContainer.getHeavyweightContainer();
 667         Container oldNativeContainer = newContainer.getHeavyweightContainer();
 668         if (newNativeContainer != oldNativeContainer) {
 669             // Native containers change - check whether or not current platform supports
 670             // changing of widget hierarchy on native level without recreation.
 671             // The current implementation forbids reparenting of LW containers with HW descendants
 672             // into another native container w/o destroying the peers. Actually such an operation
 673             // is quite rare. If we ever need to save the peers, we'll have to slightly change the
 674             // addDelicately() method in order to handle such LW containers recursively, reparenting
 675             // each HW descendant independently.
 676             return !comp.peer.isReparentSupported();
 677         } else {
 678             return false;
 679         }
 680     }
 681 
 682     /**
 683      * Moves the specified component to the specified z-order index in
 684      * the container. The z-order determines the order that components
 685      * are painted; the component with the highest z-order paints first
 686      * and the component with the lowest z-order paints last.
 687      * Where components overlap, the component with the lower
 688      * z-order paints over the component with the higher z-order.
 689      * <p>
 690      * If the component is a child of some other container, it is
 691      * removed from that container before being added to this container.
 692      * The important difference between this method and
 693      * <code>java.awt.Container.add(Component, int)</code> is that this method
 694      * doesn't call <code>removeNotify</code> on the component while
 695      * removing it from its previous container unless necessary and when
 696      * allowed by the underlying native windowing system. This way, if the
 697      * component has the keyboard focus, it maintains the focus when
 698      * moved to the new position.
 699      * <p>
 700      * This property is guaranteed to apply only to lightweight
 701      * non-<code>Container</code> components.
 702      * <p>
 703      * <b>Note</b>: Not all platforms support changing the z-order of
 704      * heavyweight components from one container into another without
 705      * the call to <code>removeNotify</code>. There is no way to detect
 706      * whether a platform supports this, so developers shouldn't make
 707      * any assumptions.
 708      *
 709      * @param     comp the component to be moved
 710      * @param     index the position in the container's list to
 711      *            insert the component, where <code>getComponentCount()</code>
 712      *            appends to the end
 713      * @exception NullPointerException if <code>comp</code> is
 714      *            <code>null</code>
 715      * @exception IllegalArgumentException if <code>comp</code> is one of the
 716      *            container's parents
 717      * @exception IllegalArgumentException if <code>index</code> is not in
 718      *            the range <code>[0, getComponentCount()]</code> for moving
 719      *            between containers, or not in the range
 720      *            <code>[0, getComponentCount()-1]</code> for moving inside
 721      *            a container
 722      * @exception IllegalArgumentException if adding a container to itself
 723      * @exception IllegalArgumentException if adding a <code>Window</code>
 724      *            to a container
 725      * @see #getComponentZOrder(java.awt.Component)
 726      * @since 1.5
 727      */
 728     public void setComponentZOrder(Component comp, int index) {
 729          synchronized (getTreeLock()) {
 730              // Store parent because remove will clear it
 731              Container curParent = comp.parent;
 732              int oldZindex = getComponentZOrder(comp);
 733 
 734              if (curParent == this && index == oldZindex) {
 735                  return;
 736              }
 737              checkAdding(comp, index);
 738 
 739              boolean peerRecreated = (curParent != null) ?
 740                  curParent.removeDelicately(comp, this, index) : false;
 741 
 742              addDelicately(comp, curParent, index);
 743 
 744              // If the oldZindex == -1, the component gets inserted,
 745              // rather than it changes its z-order.
 746              if (!peerRecreated && oldZindex != -1) {
 747                  // The new 'index' cannot be == -1.
 748                  // It gets checked at the checkAdding() method.
 749                  // Therefore both oldZIndex and index denote
 750                  // some existing positions at this point and
 751                  // this is actually a Z-order changing.
 752                  comp.mixOnZOrderChanging(oldZindex, index);
 753              }
 754          }
 755     }
 756 
 757     /**
 758      * Traverses the tree of components and reparents children heavyweight component
 759      * to new heavyweight parent.
 760      * @since 1.5
 761      */
 762     private void reparentTraverse(ContainerPeer parentPeer, Container child) {
 763         checkTreeLock();
 764 
 765         for (int i = 0; i < child.getComponentCount(); i++) {
 766             Component comp = child.getComponent(i);
 767             if (comp.isLightweight()) {
 768                 // If components is lightweight check if it is container
 769                 // If it is container it might contain heavyweight children we need to reparent
 770                 if (comp instanceof Container) {
 771                     reparentTraverse(parentPeer, (Container)comp);
 772                 }
 773             } else {
 774                 // Q: Need to update NativeInLightFixer?
 775                 comp.getPeer().reparent(parentPeer);
 776             }
 777         }
 778     }
 779 
 780     /**
 781      * Reparents child component peer to this container peer.
 782      * Container must be heavyweight.
 783      * @since 1.5
 784      */
 785     private void reparentChild(Component comp) {
 786         checkTreeLock();
 787         if (comp == null) {
 788             return;
 789         }
 790         if (comp.isLightweight()) {
 791             // If component is lightweight container we need to reparent all its explicit  heavyweight children
 792             if (comp instanceof Container) {
 793                 // Traverse component's tree till depth-first until encountering heavyweight component
 794                 reparentTraverse((ContainerPeer)getPeer(), (Container)comp);
 795             }
 796         } else {
 797             comp.getPeer().reparent((ContainerPeer)getPeer());
 798         }
 799     }
 800 
 801     /**
 802      * Adds component to this container. Tries to minimize side effects of this adding -
 803      * doesn't call remove notify if it is not required.
 804      * @since 1.5
 805      */
 806     private void addDelicately(Component comp, Container curParent, int index) {
 807         checkTreeLock();
 808 
 809         // Check if moving between containers
 810         if (curParent != this) {
 811             //index == -1 means add to the end.
 812             if (index == -1) {
 813                 component.add(comp);
 814             } else {
 815                 component.add(index, comp);
 816             }
 817             comp.parent = this;
 818             comp.setGraphicsConfiguration(getGraphicsConfiguration());
 819 
 820             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
 821                                     comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
 822             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
 823                                     comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
 824             adjustDescendants(comp.countHierarchyMembers());
 825         } else {
 826             if (index < component.size()) {
 827                 component.set(index, comp);
 828             }
 829         }
 830 
 831         invalidateIfValid();
 832         if (peer != null) {
 833             if (comp.peer == null) { // Remove notify was called or it didn't have peer - create new one
 834                 comp.addNotify();
 835             } else { // Both container and child have peers, it means child peer should be reparented.
 836                 // In both cases we need to reparent native widgets.
 837                 Container newNativeContainer = getHeavyweightContainer();
 838                 Container oldNativeContainer = curParent.getHeavyweightContainer();
 839                 if (oldNativeContainer != newNativeContainer) {
 840                     // Native container changed - need to reparent native widgets
 841                     newNativeContainer.reparentChild(comp);
 842                 }
 843                 comp.updateZOrder();
 844 
 845                 if (!comp.isLightweight() && isLightweight()) {
 846                     // If component is heavyweight and one of the containers is lightweight
 847                     // the location of the component should be fixed.
 848                     comp.relocateComponent();
 849                 }
 850             }
 851         }
 852         if (curParent != this) {
 853             /* Notify the layout manager of the added component. */
 854             if (layoutMgr != null) {
 855                 if (layoutMgr instanceof LayoutManager2) {
 856                     ((LayoutManager2)layoutMgr).addLayoutComponent(comp, null);
 857                 } else {
 858                     layoutMgr.addLayoutComponent(null, comp);
 859                 }
 860             }
 861             if (containerListener != null ||
 862                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
 863                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
 864                 ContainerEvent e = new ContainerEvent(this,
 865                                                       ContainerEvent.COMPONENT_ADDED,
 866                                                       comp);
 867                 dispatchEvent(e);
 868             }
 869             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
 870                                        this, HierarchyEvent.PARENT_CHANGED,
 871                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 872 
 873             // If component is focus owner or parent container of focus owner check that after reparenting
 874             // focus owner moved out if new container prohibit this kind of focus owner.
 875             if (comp.isFocusOwner() && !comp.canBeFocusOwnerRecursively()) {
 876                 comp.transferFocus();
 877             } else if (comp instanceof Container) {
 878                 Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
 879                 if (focusOwner != null && isParentOf(focusOwner) && !focusOwner.canBeFocusOwnerRecursively()) {
 880                     focusOwner.transferFocus();
 881                 }
 882             }
 883         } else {
 884             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
 885                                        this, HierarchyEvent.HIERARCHY_CHANGED,
 886                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 887         }
 888 
 889         if (peer != null && layoutMgr == null && isVisible()) {
 890             updateCursorImmediately();
 891         }
 892     }
 893 
 894     /**
 895      * Returns the z-order index of the component inside the container.
 896      * The higher a component is in the z-order hierarchy, the lower
 897      * its index.  The component with the lowest z-order index is
 898      * painted last, above all other child components.
 899      *
 900      * @param comp the component being queried
 901      * @return  the z-order index of the component; otherwise
 902      *          returns -1 if the component is <code>null</code>
 903      *          or doesn't belong to the container
 904      * @see #setComponentZOrder(java.awt.Component, int)
 905      * @since 1.5
 906      */
 907     public int getComponentZOrder(Component comp) {
 908         if (comp == null) {
 909             return -1;
 910         }
 911         synchronized(getTreeLock()) {
 912             // Quick check - container should be immediate parent of the component
 913             if (comp.parent != this) {
 914                 return -1;
 915             }
 916             return component.indexOf(comp);
 917         }
 918     }
 919 
 920     /**
 921      * Adds the specified component to the end of this container.
 922      * Also notifies the layout manager to add the component to
 923      * this container's layout using the specified constraints object.
 924      * This is a convenience method for {@link #addImpl}.
 925      * <p>
 926      * Note: If a component has been added to a container that
 927      * has been displayed, <code>validate</code> must be
 928      * called on that container to display the new component.
 929      * If multiple components are being added, you can improve
 930      * efficiency by calling <code>validate</code> only once,
 931      * after all the components have been added.
 932      *
 933      * @param     comp the component to be added
 934      * @param     constraints an object expressing
 935      *                  layout contraints for this component
 936      * @exception NullPointerException if {@code comp} is {@code null}
 937      * @see #addImpl
 938      * @see #validate
 939      * @see javax.swing.JComponent#revalidate()
 940      * @see       LayoutManager
 941      * @since     JDK1.1
 942      */
 943     public void add(Component comp, Object constraints) {
 944         addImpl(comp, constraints, -1);
 945     }
 946 
 947     /**
 948      * Adds the specified component to this container with the specified
 949      * constraints at the specified index.  Also notifies the layout
 950      * manager to add the component to the this container's layout using
 951      * the specified constraints object.
 952      * This is a convenience method for {@link #addImpl}.
 953      * <p>
 954      * Note: If a component has been added to a container that
 955      * has been displayed, <code>validate</code> must be
 956      * called on that container to display the new component.
 957      * If multiple components are being added, you can improve
 958      * efficiency by calling <code>validate</code> only once,
 959      * after all the components have been added.
 960      *
 961      * @param comp the component to be added
 962      * @param constraints an object expressing layout contraints for this
 963      * @param index the position in the container's list at which to insert
 964      * the component; <code>-1</code> means insert at the end
 965      * component
 966      * @exception NullPointerException if {@code comp} is {@code null}
 967      * @exception IllegalArgumentException if {@code index} is invalid (see
 968      *            {@link #addImpl} for details)
 969      * @see #addImpl
 970      * @see #validate
 971      * @see javax.swing.JComponent#revalidate()
 972      * @see #remove
 973      * @see LayoutManager
 974      */
 975     public void add(Component comp, Object constraints, int index) {
 976        addImpl(comp, constraints, index);
 977     }
 978 
 979     /**
 980      * Adds the specified component to this container at the specified
 981      * index. This method also notifies the layout manager to add
 982      * the component to this container's layout using the specified
 983      * constraints object via the <code>addLayoutComponent</code>
 984      * method.
 985      * <p>
 986      * The constraints are
 987      * defined by the particular layout manager being used.  For
 988      * example, the <code>BorderLayout</code> class defines five
 989      * constraints: <code>BorderLayout.NORTH</code>,
 990      * <code>BorderLayout.SOUTH</code>, <code>BorderLayout.EAST</code>,
 991      * <code>BorderLayout.WEST</code>, and <code>BorderLayout.CENTER</code>.
 992      * <p>
 993      * The <code>GridBagLayout</code> class requires a
 994      * <code>GridBagConstraints</code> object.  Failure to pass
 995      * the correct type of constraints object results in an
 996      * <code>IllegalArgumentException</code>.
 997      * <p>
 998      * If the current layout manager implements {@code LayoutManager2}, then
 999      * {@link LayoutManager2#addLayoutComponent(Component,Object)} is invoked on
1000      * it. If the current layout manager does not implement
1001      * {@code LayoutManager2}, and constraints is a {@code String}, then
1002      * {@link LayoutManager#addLayoutComponent(String,Component)} is invoked on it.
1003      * <p>
1004      * If the component is not an ancestor of this container and has a non-null
1005      * parent, it is removed from its current parent before it is added to this
1006      * container.
1007      * <p>
1008      * This is the method to override if a program needs to track
1009      * every add request to a container as all other add methods defer
1010      * to this one. An overriding method should
1011      * usually include a call to the superclass's version of the method:
1012      * <p>
1013      * <blockquote>
1014      * <code>super.addImpl(comp, constraints, index)</code>
1015      * </blockquote>
1016      * <p>
1017      * @param     comp       the component to be added
1018      * @param     constraints an object expressing layout constraints
1019      *                 for this component
1020      * @param     index the position in the container's list at which to
1021      *                 insert the component, where <code>-1</code>
1022      *                 means append to the end
1023      * @exception IllegalArgumentException if {@code index} is invalid;
1024      *            if {@code comp} is a child of this container, the valid
1025      *            range is {@code [-1, getComponentCount()-1]}; if component is
1026      *            not a child of this container, the valid range is
1027      *            {@code [-1, getComponentCount()]}
1028      *
1029      * @exception IllegalArgumentException if {@code comp} is an ancestor of
1030      *                                     this container
1031      * @exception IllegalArgumentException if adding a window to a container
1032      * @exception NullPointerException if {@code comp} is {@code null}
1033      * @see       #add(Component)
1034      * @see       #add(Component, int)
1035      * @see       #add(Component, java.lang.Object)
1036      * @see       LayoutManager
1037      * @see       LayoutManager2
1038      * @since     JDK1.1
1039      */
1040     protected void addImpl(Component comp, Object constraints, int index) {
1041         synchronized (getTreeLock()) {
1042             /* Check for correct arguments:  index in bounds,
1043              * comp cannot be one of this container's parents,
1044              * and comp cannot be a window.
1045              * comp and container must be on the same GraphicsDevice.
1046              * if comp is container, all sub-components must be on
1047              * same GraphicsDevice.
1048              */
1049             GraphicsConfiguration thisGC = this.getGraphicsConfiguration();
1050 
1051             if (index > component.size() || (index < 0 && index != -1)) {
1052                 throw new IllegalArgumentException(
1053                           "illegal component position");
1054             }
1055             checkAddToSelf(comp);
1056             checkNotAWindow(comp);
1057             if (thisGC != null) {
1058                 comp.checkGD(thisGC.getDevice().getIDstring());
1059             }
1060 
1061             /* Reparent the component and tidy up the tree's state. */
1062             if (comp.parent != null) {
1063                 comp.parent.remove(comp);
1064                     if (index > component.size()) {
1065                         throw new IllegalArgumentException("illegal component position");
1066                     }
1067             }
1068 
1069             //index == -1 means add to the end.
1070             if (index == -1) {
1071                 component.add(comp);
1072             } else {
1073                 component.add(index, comp);
1074             }
1075             comp.parent = this;
1076             comp.setGraphicsConfiguration(thisGC);
1077 
1078             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1079                 comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1080             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1081                 comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1082             adjustDescendants(comp.countHierarchyMembers());
1083 
1084             invalidateIfValid();
1085             if (peer != null) {
1086                 comp.addNotify();
1087             }
1088 
1089             /* Notify the layout manager of the added component. */
1090             if (layoutMgr != null) {
1091                 if (layoutMgr instanceof LayoutManager2) {
1092                     ((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);
1093                 } else if (constraints instanceof String) {
1094                     layoutMgr.addLayoutComponent((String)constraints, comp);
1095                 }
1096             }
1097             if (containerListener != null ||
1098                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1099                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1100                 ContainerEvent e = new ContainerEvent(this,
1101                                      ContainerEvent.COMPONENT_ADDED,
1102                                      comp);
1103                 dispatchEvent(e);
1104             }
1105 
1106             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
1107                                        this, HierarchyEvent.PARENT_CHANGED,
1108                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1109             if (peer != null && layoutMgr == null && isVisible()) {
1110                 updateCursorImmediately();
1111             }
1112         }
1113     }
1114 
1115     @Override
1116     boolean updateGraphicsData(GraphicsConfiguration gc) {
1117         checkTreeLock();
1118 
1119         boolean ret = super.updateGraphicsData(gc);
1120 
1121         for (Component comp : component) {
1122             if (comp != null) {
1123                 ret |= comp.updateGraphicsData(gc);
1124             }
1125         }
1126         return ret;
1127     }
1128 
1129     /**
1130      * Checks that all Components that this Container contains are on
1131      * the same GraphicsDevice as this Container.  If not, throws an
1132      * IllegalArgumentException.
1133      */
1134     void checkGD(String stringID) {
1135         for (Component comp : component) {
1136             if (comp != null) {
1137                 comp.checkGD(stringID);
1138             }
1139         }
1140     }
1141 
1142     /**
1143      * Removes the component, specified by <code>index</code>,
1144      * from this container.
1145      * This method also notifies the layout manager to remove the
1146      * component from this container's layout via the
1147      * <code>removeLayoutComponent</code> method.
1148      *
1149      * <p>
1150      * Note: If a component has been removed from a container that
1151      * had been displayed, {@link #validate} must be
1152      * called on that container to reflect changes.
1153      * If multiple components are being removed, you can improve
1154      * efficiency by calling {@link #validate} only once,
1155      * after all the components have been removed.
1156      *
1157      * @param     index   the index of the component to be removed
1158      * @throws ArrayIndexOutOfBoundsException if {@code index} is not in
1159      *         range {@code [0, getComponentCount()-1]}
1160      * @see #add
1161      * @see #validate
1162      * @see #getComponentCount
1163      * @since JDK1.1
1164      */
1165     public void remove(int index) {
1166         synchronized (getTreeLock()) {
1167             if (index < 0  || index >= component.size()) {
1168                 throw new ArrayIndexOutOfBoundsException(index);
1169             }
1170             Component comp = component.get(index);
1171             if (peer != null) {
1172                 comp.removeNotify();
1173             }
1174             if (layoutMgr != null) {
1175                 layoutMgr.removeLayoutComponent(comp);
1176             }
1177 
1178             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1179                 -comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
1180             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1181                 -comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1182             adjustDescendants(-(comp.countHierarchyMembers()));
1183 
1184             comp.parent = null;
1185             component.remove(index);
1186             comp.setGraphicsConfiguration(null);
1187 
1188             invalidateIfValid();
1189             if (containerListener != null ||
1190                 (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1191                 Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1192                 ContainerEvent e = new ContainerEvent(this,
1193                                      ContainerEvent.COMPONENT_REMOVED,
1194                                      comp);
1195                 dispatchEvent(e);
1196             }
1197 
1198             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
1199                                        this, HierarchyEvent.PARENT_CHANGED,
1200                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1201             if (peer != null && layoutMgr == null && isVisible()) {
1202                 updateCursorImmediately();
1203             }
1204         }
1205     }
1206 
1207     /**
1208      * Removes the specified component from this container.
1209      * This method also notifies the layout manager to remove the
1210      * component from this container's layout via the
1211      * <code>removeLayoutComponent</code> method.
1212      *
1213      * <p>
1214      * Note: If a component has been removed from a container that
1215      * had been displayed, {@link #validate} must be
1216      * called on that container to reflect changes.
1217      * If multiple components are being removed, you can improve
1218      * efficiency by calling {@link #validate} only once,
1219      * after all the components have been removed.
1220      *
1221      * @param comp the component to be removed
1222      * @see #add
1223      * @see #validate
1224      * @see #remove(int)
1225      */
1226     public void remove(Component comp) {
1227         synchronized (getTreeLock()) {
1228             if (comp.parent == this)  {
1229                 int index = component.indexOf(comp);
1230                 if (index >= 0) {
1231                     remove(index);
1232                 }
1233             }
1234         }
1235     }
1236 
1237     /**
1238      * Removes all the components from this container.
1239      * This method also notifies the layout manager to remove the
1240      * components from this container's layout via the
1241      * <code>removeLayoutComponent</code> method.
1242      * @see #add
1243      * @see #remove
1244      */
1245     public void removeAll() {
1246         synchronized (getTreeLock()) {
1247             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
1248                                     -listeningChildren);
1249             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
1250                                     -listeningBoundsChildren);
1251             adjustDescendants(-descendantsCount);
1252 
1253             while (!component.isEmpty()) {
1254                 Component comp = component.remove(component.size()-1);
1255 
1256                 if (peer != null) {
1257                     comp.removeNotify();
1258                 }
1259                 if (layoutMgr != null) {
1260                     layoutMgr.removeLayoutComponent(comp);
1261                 }
1262                 comp.parent = null;
1263                 comp.setGraphicsConfiguration(null);
1264                 if (containerListener != null ||
1265                    (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
1266                     Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
1267                     ContainerEvent e = new ContainerEvent(this,
1268                                      ContainerEvent.COMPONENT_REMOVED,
1269                                      comp);
1270                     dispatchEvent(e);
1271                 }
1272 
1273                 comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1274                                            comp, this,
1275                                            HierarchyEvent.PARENT_CHANGED,
1276                                            Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1277             }
1278             if (peer != null && layoutMgr == null && isVisible()) {
1279                 updateCursorImmediately();
1280             }
1281             invalidateIfValid();
1282         }
1283     }
1284 
1285     // Should only be called while holding tree lock
1286     int numListening(long mask) {
1287         int superListening = super.numListening(mask);
1288 
1289         if (mask == AWTEvent.HIERARCHY_EVENT_MASK) {
1290             if (eventLog.isLoggable(Level.FINE)) {
1291                 // Verify listeningChildren is correct
1292                 int sum = 0;
1293                 for (Component comp : component) {
1294                     sum += comp.numListening(mask);
1295                 }
1296                 if (listeningChildren != sum) {
1297                     eventLog.log(Level.FINE, "Assertion (listeningChildren == sum) failed");
1298                 }
1299             }
1300             return listeningChildren + superListening;
1301         } else if (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
1302             if (eventLog.isLoggable(Level.FINE)) {
1303                 // Verify listeningBoundsChildren is correct
1304                 int sum = 0;
1305                 for (Component comp : component) {
1306                     sum += comp.numListening(mask);
1307                 }
1308                 if (listeningBoundsChildren != sum) {
1309                     eventLog.log(Level.FINE, "Assertion (listeningBoundsChildren == sum) failed");
1310                 }
1311             }
1312             return listeningBoundsChildren + superListening;
1313         } else {
1314             // assert false;
1315             if (eventLog.isLoggable(Level.FINE)) {
1316                 eventLog.log(Level.FINE, "This code must never be reached");
1317             }
1318             return superListening;
1319         }
1320     }
1321 
1322     // Should only be called while holding tree lock
1323     void adjustListeningChildren(long mask, int num) {
1324         if (eventLog.isLoggable(Level.FINE)) {
1325             boolean toAssert = (mask == AWTEvent.HIERARCHY_EVENT_MASK ||
1326                                 mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK ||
1327                                 mask == (AWTEvent.HIERARCHY_EVENT_MASK |
1328                                          AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
1329             if (!toAssert) {
1330                 eventLog.log(Level.FINE, "Assertion failed");
1331             }
1332         }
1333 
1334         if (num == 0)
1335             return;
1336 
1337         if ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
1338             listeningChildren += num;
1339         }
1340         if ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
1341             listeningBoundsChildren += num;
1342         }
1343 
1344         adjustListeningChildrenOnParent(mask, num);
1345     }
1346 
1347     // Should only be called while holding tree lock
1348     void adjustDescendants(int num) {
1349         if (num == 0)
1350             return;
1351 
1352         descendantsCount += num;
1353         adjustDecendantsOnParent(num);
1354     }
1355 
1356     // Should only be called while holding tree lock
1357     void adjustDecendantsOnParent(int num) {
1358         if (parent != null) {
1359             parent.adjustDescendants(num);
1360         }
1361     }
1362 
1363     // Should only be called while holding tree lock
1364     int countHierarchyMembers() {
1365         if (log.isLoggable(Level.FINE)) {
1366             // Verify descendantsCount is correct
1367             int sum = 0;
1368             for (Component comp : component) {
1369                 sum += comp.countHierarchyMembers();
1370             }
1371             if (descendantsCount != sum) {
1372                 log.log(Level.FINE, "Assertion (descendantsCount == sum) failed");
1373             }
1374         }
1375         return descendantsCount + 1;
1376     }
1377 
1378     private int getListenersCount(int id, boolean enabledOnToolkit) {
1379         checkTreeLock();
1380         if (enabledOnToolkit) {
1381             return descendantsCount;
1382         }
1383         switch (id) {
1384           case HierarchyEvent.HIERARCHY_CHANGED:
1385             return listeningChildren;
1386           case HierarchyEvent.ANCESTOR_MOVED:
1387           case HierarchyEvent.ANCESTOR_RESIZED:
1388             return listeningBoundsChildren;
1389           default:
1390             return 0;
1391         }
1392     }
1393 
1394     final int createHierarchyEvents(int id, Component changed,
1395         Container changedParent, long changeFlags, boolean enabledOnToolkit)
1396     {
1397         checkTreeLock();
1398         int listeners = getListenersCount(id, enabledOnToolkit);
1399 
1400         for (int count = listeners, i = 0; count > 0; i++) {
1401             count -= component.get(i).createHierarchyEvents(id, changed,
1402                 changedParent, changeFlags, enabledOnToolkit);
1403         }
1404         return listeners +
1405             super.createHierarchyEvents(id, changed, changedParent,
1406                                         changeFlags, enabledOnToolkit);
1407     }
1408 
1409     final void createChildHierarchyEvents(int id, long changeFlags,
1410         boolean enabledOnToolkit)
1411     {
1412         checkTreeLock();
1413         if (component.isEmpty()) {
1414             return;
1415         }
1416         int listeners = getListenersCount(id, enabledOnToolkit);
1417 
1418         for (int count = listeners, i = 0; count > 0; i++) {
1419             count -= component.get(i).createHierarchyEvents(id, this, parent,
1420                 changeFlags, enabledOnToolkit);
1421         }
1422     }
1423 
1424     /**
1425      * Gets the layout manager for this container.
1426      * @see #doLayout
1427      * @see #setLayout
1428      */
1429     public LayoutManager getLayout() {
1430         return layoutMgr;
1431     }
1432 
1433     /**
1434      * Sets the layout manager for this container.
1435      * @param mgr the specified layout manager
1436      * @see #doLayout
1437      * @see #getLayout
1438      */
1439     public void setLayout(LayoutManager mgr) {
1440         layoutMgr = mgr;
1441         invalidateIfValid();
1442     }
1443 
1444     /**
1445      * Causes this container to lay out its components.  Most programs
1446      * should not call this method directly, but should invoke
1447      * the <code>validate</code> method instead.
1448      * @see LayoutManager#layoutContainer
1449      * @see #setLayout
1450      * @see #validate
1451      * @since JDK1.1
1452      */
1453     public void doLayout() {
1454         layout();
1455     }
1456 
1457     /**
1458      * @deprecated As of JDK version 1.1,
1459      * replaced by <code>doLayout()</code>.
1460      */
1461     @Deprecated
1462     public void layout() {
1463         LayoutManager layoutMgr = this.layoutMgr;
1464         if (layoutMgr != null) {
1465             layoutMgr.layoutContainer(this);
1466         }
1467     }
1468 
1469     /**
1470      * Invalidates the container.  The container and all parents
1471      * above it are marked as needing to be laid out.  This method can
1472      * be called often, so it needs to execute quickly.
1473      *
1474      * <p> If the {@code LayoutManager} installed on this container is
1475      * an instance of {@code LayoutManager2}, then
1476      * {@link LayoutManager2#invalidateLayout(Container)} is invoked on
1477      * it supplying this {@code Container} as the argument.
1478      *
1479      * @see #validate
1480      * @see #layout
1481      * @see LayoutManager
1482      * @see LayoutManager2#invalidateLayout(Container)
1483      */
1484     public void invalidate() {
1485         LayoutManager layoutMgr = this.layoutMgr;
1486         if (layoutMgr instanceof LayoutManager2) {
1487             LayoutManager2 lm = (LayoutManager2) layoutMgr;
1488             lm.invalidateLayout(this);
1489         }
1490         super.invalidate();
1491     }
1492 
1493     /**
1494      * Validates this container and all of its subcomponents.
1495      * <p>
1496      * The <code>validate</code> method is used to cause a container
1497      * to lay out its subcomponents again. It should be invoked when
1498      * this container's subcomponents are modified (added to or
1499      * removed from the container, or layout-related information
1500      * changed) after the container has been displayed.
1501      *
1502      * <p>If this {@code Container} is not valid, this method invokes
1503      * the {@code validateTree} method and marks this {@code Container}
1504      * as valid. Otherwise, no action is performed.
1505      *
1506      * @see #add(java.awt.Component)
1507      * @see Component#invalidate
1508      * @see javax.swing.JComponent#revalidate()
1509      * @see #validateTree
1510      */
1511     public void validate() {
1512         /* Avoid grabbing lock unless really necessary. */
1513         if (!isValid()) {
1514             boolean updateCur = false;
1515             synchronized (getTreeLock()) {
1516                 if (!isValid() && peer != null) {
1517                     ContainerPeer p = null;
1518                     if (peer instanceof ContainerPeer) {
1519                         p = (ContainerPeer) peer;
1520                     }
1521                     if (p != null) {
1522                         p.beginValidate();
1523                     }
1524                     validateTree();
1525                     if (p != null) {
1526                         p.endValidate();
1527                         updateCur = isVisible();
1528                     }
1529                 }
1530             }
1531             if (updateCur) {
1532                 updateCursorImmediately();
1533             }
1534         }
1535     }
1536 
1537     /**
1538      * Recursively descends the container tree and recomputes the
1539      * layout for any subtrees marked as needing it (those marked as
1540      * invalid).  Synchronization should be provided by the method
1541      * that calls this one:  <code>validate</code>.
1542      *
1543      * @see #doLayout
1544      * @see #validate
1545      */
1546     protected void validateTree() {
1547         checkTreeLock();
1548         if (!isValid()) {
1549             if (peer instanceof ContainerPeer) {
1550                 ((ContainerPeer)peer).beginLayout();
1551             }
1552             doLayout();
1553             for (int i = 0; i < component.size(); i++) {
1554                 Component comp = component.get(i);
1555                 if (   (comp instanceof Container)
1556                        && !(comp instanceof Window)
1557                        && !comp.isValid()) {
1558                     ((Container)comp).validateTree();
1559                 } else {
1560                     comp.validate();
1561                 }
1562             }
1563             if (peer instanceof ContainerPeer) {
1564                 ((ContainerPeer)peer).endLayout();
1565             }
1566         }
1567         super.validate();
1568     }
1569 
1570     /**
1571      * Recursively descends the container tree and invalidates all
1572      * contained components.
1573      */
1574     void invalidateTree() {
1575         synchronized (getTreeLock()) {
1576             for (int i = 0; i < component.size(); i++) {
1577                 Component comp = component.get(i);
1578                 if (comp instanceof Container) {
1579                     ((Container)comp).invalidateTree();
1580                 }
1581                 else {
1582                     comp.invalidateIfValid();
1583                 }
1584             }
1585             invalidateIfValid();
1586         }
1587     }
1588 
1589     /**
1590      * Sets the font of this container.
1591      * @param f The font to become this container's font.
1592      * @see Component#getFont
1593      * @since JDK1.0
1594      */
1595     public void setFont(Font f) {
1596         boolean shouldinvalidate = false;
1597 
1598         Font oldfont = getFont();
1599         super.setFont(f);
1600         Font newfont = getFont();
1601         if (newfont != oldfont && (oldfont == null ||
1602                                    !oldfont.equals(newfont))) {
1603             invalidateTree();
1604         }
1605     }
1606 
1607     /**
1608      * Returns the preferred size of this container.  If the preferred size has
1609      * not been set explicitly by {@link Component#setPreferredSize(Dimension)}
1610      * and this {@code Container} has a {@code non-null} {@link LayoutManager},
1611      * then {@link LayoutManager#preferredLayoutSize(Container)}
1612      * is used to calculate the preferred size.
1613      *
1614      * <p>Note: some implementations may cache the value returned from the
1615      * {@code LayoutManager}.  Implementations that cache need not invoke
1616      * {@code preferredLayoutSize} on the {@code LayoutManager} every time
1617      * this method is invoked, rather the {@code LayoutManager} will only
1618      * be queried after the {@code Container} becomes invalid.
1619      *
1620      * @return    an instance of <code>Dimension</code> that represents
1621      *                the preferred size of this container.
1622      * @see       #getMinimumSize
1623      * @see       #getMaximumSize
1624      * @see       #getLayout
1625      * @see       LayoutManager#preferredLayoutSize(Container)
1626      * @see       Component#getPreferredSize
1627      */
1628     public Dimension getPreferredSize() {
1629         return preferredSize();
1630     }
1631 
1632     /**
1633      * @deprecated As of JDK version 1.1,
1634      * replaced by <code>getPreferredSize()</code>.
1635      */
1636     @Deprecated
1637     public Dimension preferredSize() {
1638         /* Avoid grabbing the lock if a reasonable cached size value
1639          * is available.
1640          */
1641         Dimension dim = prefSize;
1642         if (dim == null || !(isPreferredSizeSet() || isValid())) {
1643             synchronized (getTreeLock()) {
1644                 prefSize = (layoutMgr != null) ?
1645                     layoutMgr.preferredLayoutSize(this) :
1646                     super.preferredSize();
1647                 dim = prefSize;
1648             }
1649         }
1650         if (dim != null){
1651             return new Dimension(dim);
1652         }
1653         else{
1654             return dim;
1655         }
1656     }
1657 
1658     /**
1659      * Returns the minimum size of this container.  If the minimum size has
1660      * not been set explicitly by {@link Component#setMinimumSize(Dimension)}
1661      * and this {@code Container} has a {@code non-null} {@link LayoutManager},
1662      * then {@link LayoutManager#minimumLayoutSize(Container)}
1663      * is used to calculate the minimum size.
1664      *
1665      * <p>Note: some implementations may cache the value returned from the
1666      * {@code LayoutManager}.  Implementations that cache need not invoke
1667      * {@code minimumLayoutSize} on the {@code LayoutManager} every time
1668      * this method is invoked, rather the {@code LayoutManager} will only
1669      * be queried after the {@code Container} becomes invalid.
1670      *
1671      * @return    an instance of <code>Dimension</code> that represents
1672      *                the minimum size of this container.
1673      * @see       #getPreferredSize
1674      * @see       #getMaximumSize
1675      * @see       #getLayout
1676      * @see       LayoutManager#minimumLayoutSize(Container)
1677      * @see       Component#getMinimumSize
1678      * @since     JDK1.1
1679      */
1680     public Dimension getMinimumSize() {
1681         return minimumSize();
1682     }
1683 
1684     /**
1685      * @deprecated As of JDK version 1.1,
1686      * replaced by <code>getMinimumSize()</code>.
1687      */
1688     @Deprecated
1689     public Dimension minimumSize() {
1690         /* Avoid grabbing the lock if a reasonable cached size value
1691          * is available.
1692          */
1693         Dimension dim = minSize;
1694         if (dim == null || !(isMinimumSizeSet() || isValid())) {
1695             synchronized (getTreeLock()) {
1696                 minSize = (layoutMgr != null) ?
1697                     layoutMgr.minimumLayoutSize(this) :
1698                     super.minimumSize();
1699                 dim = minSize;
1700             }
1701         }
1702         if (dim != null){
1703             return new Dimension(dim);
1704         }
1705         else{
1706             return dim;
1707         }
1708     }
1709 
1710     /**
1711      * Returns the maximum size of this container.  If the maximum size has
1712      * not been set explicitly by {@link Component#setMaximumSize(Dimension)}
1713      * and the {@link LayoutManager} installed on this {@code Container}
1714      * is an instance of {@link LayoutManager2}, then
1715      * {@link LayoutManager2#maximumLayoutSize(Container)}
1716      * is used to calculate the maximum size.
1717      *
1718      * <p>Note: some implementations may cache the value returned from the
1719      * {@code LayoutManager2}.  Implementations that cache need not invoke
1720      * {@code maximumLayoutSize} on the {@code LayoutManager2} every time
1721      * this method is invoked, rather the {@code LayoutManager2} will only
1722      * be queried after the {@code Container} becomes invalid.
1723      *
1724      * @return    an instance of <code>Dimension</code> that represents
1725      *                the maximum size of this container.
1726      * @see       #getPreferredSize
1727      * @see       #getMinimumSize
1728      * @see       #getLayout
1729      * @see       LayoutManager2#maximumLayoutSize(Container)
1730      * @see       Component#getMaximumSize
1731      */
1732     public Dimension getMaximumSize() {
1733         /* Avoid grabbing the lock if a reasonable cached size value
1734          * is available.
1735          */
1736         Dimension dim = maxSize;
1737         if (dim == null || !(isMaximumSizeSet() || isValid())) {
1738             synchronized (getTreeLock()) {
1739                if (layoutMgr instanceof LayoutManager2) {
1740                     LayoutManager2 lm = (LayoutManager2) layoutMgr;
1741                     maxSize = lm.maximumLayoutSize(this);
1742                } else {
1743                     maxSize = super.getMaximumSize();
1744                }
1745                dim = maxSize;
1746             }
1747         }
1748         if (dim != null){
1749             return new Dimension(dim);
1750         }
1751         else{
1752             return dim;
1753         }
1754     }
1755 
1756     /**
1757      * Returns the alignment along the x axis.  This specifies how
1758      * the component would like to be aligned relative to other
1759      * components.  The value should be a number between 0 and 1
1760      * where 0 represents alignment along the origin, 1 is aligned
1761      * the furthest away from the origin, 0.5 is centered, etc.
1762      */
1763     public float getAlignmentX() {
1764         float xAlign;
1765         if (layoutMgr instanceof LayoutManager2) {
1766             synchronized (getTreeLock()) {
1767                 LayoutManager2 lm = (LayoutManager2) layoutMgr;
1768                 xAlign = lm.getLayoutAlignmentX(this);
1769             }
1770         } else {
1771             xAlign = super.getAlignmentX();
1772         }
1773         return xAlign;
1774     }
1775 
1776     /**
1777      * Returns the alignment along the y axis.  This specifies how
1778      * the component would like to be aligned relative to other
1779      * components.  The value should be a number between 0 and 1
1780      * where 0 represents alignment along the origin, 1 is aligned
1781      * the furthest away from the origin, 0.5 is centered, etc.
1782      */
1783     public float getAlignmentY() {
1784         float yAlign;
1785         if (layoutMgr instanceof LayoutManager2) {
1786             synchronized (getTreeLock()) {
1787                 LayoutManager2 lm = (LayoutManager2) layoutMgr;
1788                 yAlign = lm.getLayoutAlignmentY(this);
1789             }
1790         } else {
1791             yAlign = super.getAlignmentY();
1792         }
1793         return yAlign;
1794     }
1795 
1796     /**
1797      * Paints the container. This forwards the paint to any lightweight
1798      * components that are children of this container. If this method is
1799      * reimplemented, super.paint(g) should be called so that lightweight
1800      * components are properly rendered. If a child component is entirely
1801      * clipped by the current clipping setting in g, paint() will not be
1802      * forwarded to that child.
1803      *
1804      * @param g the specified Graphics window
1805      * @see   Component#update(Graphics)
1806      */
1807     public void paint(Graphics g) {
1808         if (isShowing()) {
1809             synchronized (this) {
1810                 if (printing) {
1811                     if (printingThreads.contains(Thread.currentThread())) {
1812                         return;
1813                     }
1814                 }
1815             }
1816 
1817             // The container is showing on screen and
1818             // this paint() is not called from print().
1819             // Paint self and forward the paint to lightweight subcomponents.
1820 
1821             // super.paint(); -- Don't bother, since it's a NOP.
1822 
1823             GraphicsCallback.PaintCallback.getInstance().
1824                 runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
1825         }
1826     }
1827 
1828     /**
1829      * Updates the container.  This forwards the update to any lightweight
1830      * components that are children of this container.  If this method is
1831      * reimplemented, super.update(g) should be called so that lightweight
1832      * components are properly rendered.  If a child component is entirely
1833      * clipped by the current clipping setting in g, update() will not be
1834      * forwarded to that child.
1835      *
1836      * @param g the specified Graphics window
1837      * @see   Component#update(Graphics)
1838      */
1839     public void update(Graphics g) {
1840         if (isShowing()) {
1841             if (! (peer instanceof LightweightPeer)) {
1842                 g.clearRect(0, 0, width, height);
1843             }
1844             paint(g);
1845         }
1846     }
1847 
1848     /**
1849      * Prints the container. This forwards the print to any lightweight
1850      * components that are children of this container. If this method is
1851      * reimplemented, super.print(g) should be called so that lightweight
1852      * components are properly rendered. If a child component is entirely
1853      * clipped by the current clipping setting in g, print() will not be
1854      * forwarded to that child.
1855      *
1856      * @param g the specified Graphics window
1857      * @see   Component#update(Graphics)
1858      */
1859     public void print(Graphics g) {
1860         if (isShowing()) {
1861             Thread t = Thread.currentThread();
1862             try {
1863                 synchronized (this) {
1864                     if (printingThreads == null) {
1865                         printingThreads = new HashSet();
1866                     }
1867                     printingThreads.add(t);
1868                     printing = true;
1869                 }
1870                 super.print(g);  // By default, Component.print() calls paint()
1871             } finally {
1872                 synchronized (this) {
1873                     printingThreads.remove(t);
1874                     printing = !printingThreads.isEmpty();
1875                 }
1876             }
1877 
1878             GraphicsCallback.PrintCallback.getInstance().
1879                 runComponents(getComponentsSync(), g, GraphicsCallback.LIGHTWEIGHTS);
1880         }
1881     }
1882 
1883     /**
1884      * Paints each of the components in this container.
1885      * @param     g   the graphics context.
1886      * @see       Component#paint
1887      * @see       Component#paintAll
1888      */
1889     public void paintComponents(Graphics g) {
1890         if (isShowing()) {
1891             GraphicsCallback.PaintAllCallback.getInstance().
1892                 runComponents(getComponentsSync(), g, GraphicsCallback.TWO_PASSES);
1893         }
1894     }
1895 
1896     /**
1897      * Simulates the peer callbacks into java.awt for printing of
1898      * lightweight Containers.
1899      * @param     g   the graphics context to use for printing.
1900      * @see       Component#printAll
1901      * @see       #printComponents
1902      */
1903     void lightweightPaint(Graphics g) {
1904         super.lightweightPaint(g);
1905         paintHeavyweightComponents(g);
1906     }
1907 
1908     /**
1909      * Prints all the heavyweight subcomponents.
1910      */
1911     void paintHeavyweightComponents(Graphics g) {
1912         if (isShowing()) {
1913             GraphicsCallback.PaintHeavyweightComponentsCallback.getInstance().
1914                 runComponents(getComponentsSync(), g,
1915                               GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
1916         }
1917     }
1918 
1919     /**
1920      * Prints each of the components in this container.
1921      * @param     g   the graphics context.
1922      * @see       Component#print
1923      * @see       Component#printAll
1924      */
1925     public void printComponents(Graphics g) {
1926         if (isShowing()) {
1927             GraphicsCallback.PrintAllCallback.getInstance().
1928                 runComponents(getComponentsSync(), g, GraphicsCallback.TWO_PASSES);
1929         }
1930     }
1931 
1932     /**
1933      * Simulates the peer callbacks into java.awt for printing of
1934      * lightweight Containers.
1935      * @param     g   the graphics context to use for printing.
1936      * @see       Component#printAll
1937      * @see       #printComponents
1938      */
1939     void lightweightPrint(Graphics g) {
1940         super.lightweightPrint(g);
1941         printHeavyweightComponents(g);
1942     }
1943 
1944     /**
1945      * Prints all the heavyweight subcomponents.
1946      */
1947     void printHeavyweightComponents(Graphics g) {
1948         if (isShowing()) {
1949             GraphicsCallback.PrintHeavyweightComponentsCallback.getInstance().
1950                 runComponents(getComponentsSync(), g,
1951                               GraphicsCallback.LIGHTWEIGHTS | GraphicsCallback.HEAVYWEIGHTS);
1952         }
1953     }
1954 
1955     /**
1956      * Adds the specified container listener to receive container events
1957      * from this container.
1958      * If l is null, no exception is thrown and no action is performed.
1959      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1960      * >AWT Threading Issues</a> for details on AWT's threading model.
1961      *
1962      * @param    l the container listener
1963      *
1964      * @see #removeContainerListener
1965      * @see #getContainerListeners
1966      */
1967     public synchronized void addContainerListener(ContainerListener l) {
1968         if (l == null) {
1969             return;
1970         }
1971         containerListener = AWTEventMulticaster.add(containerListener, l);
1972         newEventsOnly = true;
1973     }
1974 
1975     /**
1976      * Removes the specified container listener so it no longer receives
1977      * container events from this container.
1978      * If l is null, no exception is thrown and no action is performed.
1979      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1980      * >AWT Threading Issues</a> for details on AWT's threading model.
1981      *
1982      * @param   l the container listener
1983      *
1984      * @see #addContainerListener
1985      * @see #getContainerListeners
1986      */
1987     public synchronized void removeContainerListener(ContainerListener l) {
1988         if (l == null) {
1989             return;
1990         }
1991         containerListener = AWTEventMulticaster.remove(containerListener, l);
1992     }
1993 
1994     /**
1995      * Returns an array of all the container listeners
1996      * registered on this container.
1997      *
1998      * @return all of this container's <code>ContainerListener</code>s
1999      *         or an empty array if no container
2000      *         listeners are currently registered
2001      *
2002      * @see #addContainerListener
2003      * @see #removeContainerListener
2004      * @since 1.4
2005      */
2006     public synchronized ContainerListener[] getContainerListeners() {
2007         return (ContainerListener[]) (getListeners(ContainerListener.class));
2008     }
2009 
2010     /**
2011      * Returns an array of all the objects currently registered
2012      * as <code><em>Foo</em>Listener</code>s
2013      * upon this <code>Container</code>.
2014      * <code><em>Foo</em>Listener</code>s are registered using the
2015      * <code>add<em>Foo</em>Listener</code> method.
2016      *
2017      * <p>
2018      * You can specify the <code>listenerType</code> argument
2019      * with a class literal, such as
2020      * <code><em>Foo</em>Listener.class</code>.
2021      * For example, you can query a
2022      * <code>Container</code> <code>c</code>
2023      * for its container listeners with the following code:
2024      *
2025      * <pre>ContainerListener[] cls = (ContainerListener[])(c.getListeners(ContainerListener.class));</pre>
2026      *
2027      * If no such listeners exist, this method returns an empty array.
2028      *
2029      * @param listenerType the type of listeners requested; this parameter
2030      *          should specify an interface that descends from
2031      *          <code>java.util.EventListener</code>
2032      * @return an array of all objects registered as
2033      *          <code><em>Foo</em>Listener</code>s on this container,
2034      *          or an empty array if no such listeners have been added
2035      * @exception ClassCastException if <code>listenerType</code>
2036      *          doesn't specify a class or interface that implements
2037      *          <code>java.util.EventListener</code>
2038      *
2039      * @see #getContainerListeners
2040      *
2041      * @since 1.3
2042      */
2043     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
2044         EventListener l = null;
2045         if  (listenerType == ContainerListener.class) {
2046             l = containerListener;
2047         } else {
2048             return super.getListeners(listenerType);
2049         }
2050         return AWTEventMulticaster.getListeners(l, listenerType);
2051     }
2052 
2053     // REMIND: remove when filtering is done at lower level
2054     boolean eventEnabled(AWTEvent e) {
2055         int id = e.getID();
2056 
2057         if (id == ContainerEvent.COMPONENT_ADDED ||
2058             id == ContainerEvent.COMPONENT_REMOVED) {
2059             if ((eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
2060                 containerListener != null) {
2061                 return true;
2062             }
2063             return false;
2064         }
2065         return super.eventEnabled(e);
2066     }
2067 
2068     /**
2069      * Processes events on this container. If the event is a
2070      * <code>ContainerEvent</code>, it invokes the
2071      * <code>processContainerEvent</code> method, else it invokes
2072      * its superclass's <code>processEvent</code>.
2073      * <p>Note that if the event parameter is <code>null</code>
2074      * the behavior is unspecified and may result in an
2075      * exception.
2076      *
2077      * @param e the event
2078      */
2079     protected void processEvent(AWTEvent e) {
2080         if (e instanceof ContainerEvent) {
2081             processContainerEvent((ContainerEvent)e);
2082             return;
2083         }
2084         super.processEvent(e);
2085     }
2086 
2087     /**
2088      * Processes container events occurring on this container by
2089      * dispatching them to any registered ContainerListener objects.
2090      * NOTE: This method will not be called unless container events
2091      * are enabled for this component; this happens when one of the
2092      * following occurs:
2093      * <ul>
2094      * <li>A ContainerListener object is registered via
2095      *     <code>addContainerListener</code>
2096      * <li>Container events are enabled via <code>enableEvents</code>
2097      * </ul>
2098      * <p>Note that if the event parameter is <code>null</code>
2099      * the behavior is unspecified and may result in an
2100      * exception.
2101      *
2102      * @param e the container event
2103      * @see Component#enableEvents
2104      */
2105     protected void processContainerEvent(ContainerEvent e) {
2106         ContainerListener listener = containerListener;
2107         if (listener != null) {
2108             switch(e.getID()) {
2109               case ContainerEvent.COMPONENT_ADDED:
2110                 listener.componentAdded(e);
2111                 break;
2112               case ContainerEvent.COMPONENT_REMOVED:
2113                 listener.componentRemoved(e);
2114                 break;
2115             }
2116         }
2117     }
2118 
2119     /*
2120      * Dispatches an event to this component or one of its sub components.
2121      * Create ANCESTOR_RESIZED and ANCESTOR_MOVED events in response to
2122      * COMPONENT_RESIZED and COMPONENT_MOVED events. We have to do this
2123      * here instead of in processComponentEvent because ComponentEvents
2124      * may not be enabled for this Container.
2125      * @param e the event
2126      */
2127     void dispatchEventImpl(AWTEvent e) {
2128         if ((dispatcher != null) && dispatcher.dispatchEvent(e)) {
2129             // event was sent to a lightweight component.  The
2130             // native-produced event sent to the native container
2131             // must be properly disposed of by the peer, so it
2132             // gets forwarded.  If the native host has been removed
2133             // as a result of the sending the lightweight event,
2134             // the peer reference will be null.
2135             e.consume();
2136             if (peer != null) {
2137                 peer.handleEvent(e);
2138             }
2139             return;
2140         }
2141 
2142         super.dispatchEventImpl(e);
2143 
2144         synchronized (getTreeLock()) {
2145             switch (e.getID()) {
2146               case ComponentEvent.COMPONENT_RESIZED:
2147                 createChildHierarchyEvents(HierarchyEvent.ANCESTOR_RESIZED, 0,
2148                                            Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2149                 break;
2150               case ComponentEvent.COMPONENT_MOVED:
2151                 createChildHierarchyEvents(HierarchyEvent.ANCESTOR_MOVED, 0,
2152                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
2153                 break;
2154               default:
2155                 break;
2156             }
2157         }
2158     }
2159 
2160     /*
2161      * Dispatches an event to this component, without trying to forward
2162      * it to any subcomponents
2163      * @param e the event
2164      */
2165     void dispatchEventToSelf(AWTEvent e) {
2166         super.dispatchEventImpl(e);
2167     }
2168 
2169     /**
2170      * Fetchs the top-most (deepest) lightweight component that is interested
2171      * in receiving mouse events.
2172      */
2173     Component getMouseEventTarget(int x, int y, boolean includeSelf) {
2174         return getMouseEventTarget(x, y, includeSelf,
2175                                    MouseEventTargetFilter.FILTER,
2176                                    !SEARCH_HEAVYWEIGHTS);
2177     }
2178 
2179     /**
2180      * Fetches the top-most (deepest) component to receive SunDropTargetEvents.
2181      */
2182     Component getDropTargetEventTarget(int x, int y, boolean includeSelf) {
2183         return getMouseEventTarget(x, y, includeSelf,
2184                                    DropTargetEventTargetFilter.FILTER,
2185                                    SEARCH_HEAVYWEIGHTS);
2186     }
2187 
2188     /**
2189      * A private version of getMouseEventTarget which has two additional
2190      * controllable behaviors. This method searches for the top-most
2191      * descendant of this container that contains the given coordinates
2192      * and is accepted by the given filter. The search will be constrained to
2193      * lightweight descendants if the last argument is <code>false</code>.
2194      *
2195      * @param filter EventTargetFilter instance to determine whether the
2196      *        given component is a valid target for this event.
2197      * @param searchHeavyweights if <code>false</code>, the method
2198      *        will bypass heavyweight components during the search.
2199      */
2200     private Component getMouseEventTarget(int x, int y, boolean includeSelf,
2201                                           EventTargetFilter filter,
2202                                           boolean searchHeavyweights) {
2203         Component comp = null;
2204         if (searchHeavyweights) {
2205             comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2206                                            SEARCH_HEAVYWEIGHTS,
2207                                            searchHeavyweights);
2208         }
2209 
2210         if (comp == null || comp == this) {
2211             comp = getMouseEventTargetImpl(x, y, includeSelf, filter,
2212                                            !SEARCH_HEAVYWEIGHTS,
2213                                            searchHeavyweights);
2214         }
2215 
2216         return comp;
2217     }
2218 
2219     /**
2220      * A private version of getMouseEventTarget which has three additional
2221      * controllable behaviors. This method searches for the top-most
2222      * descendant of this container that contains the given coordinates
2223      * and is accepted by the given filter. The search will be constrained to
2224      * descendants of only lightweight children or only heavyweight children
2225      * of this container depending on searchHeavyweightChildren. The search will
2226      * be constrained to only lightweight descendants of the searched children
2227      * of this container if searchHeavyweightDescendants is <code>false</code>.
2228      *
2229      * @param filter EventTargetFilter instance to determine whether the
2230      *        selected component is a valid target for this event.
2231      * @param searchHeavyweightChildren if <code>true</code>, the method
2232      *        will bypass immediate lightweight children during the search.
2233      *        If <code>false</code>, the methods will bypass immediate
2234      *        heavyweight children during the search.
2235      * @param searchHeavyweightDescendants if <code>false</code>, the method
2236      *        will bypass heavyweight descendants which are not immediate
2237      *        children during the search. If <code>true</code>, the method
2238      *        will traverse both lightweight and heavyweight descendants during
2239      *        the search.
2240      */
2241     private Component getMouseEventTargetImpl(int x, int y, boolean includeSelf,
2242                                          EventTargetFilter filter,
2243                                          boolean searchHeavyweightChildren,
2244                                          boolean searchHeavyweightDescendants) {
2245         synchronized (getTreeLock()) {
2246 
2247             for (int i = 0; i < component.size(); i++) {
2248                 Component comp = component.get(i);
2249                 if (comp != null && comp.visible &&
2250                     ((!searchHeavyweightChildren &&
2251                       comp.peer instanceof LightweightPeer) ||
2252                      (searchHeavyweightChildren &&
2253                       !(comp.peer instanceof LightweightPeer))) &&
2254                     comp.contains(x - comp.x, y - comp.y)) {
2255 
2256                     // found a component that intersects the point, see if there
2257                     // is a deeper possibility.
2258                     if (comp instanceof Container) {
2259                         Container child = (Container) comp;
2260                         Component deeper = child.getMouseEventTarget(
2261                                 x - child.x,
2262                                 y - child.y,
2263                                 includeSelf,
2264                                 filter,
2265                                 searchHeavyweightDescendants);
2266                         if (deeper != null) {
2267                             return deeper;
2268                         }
2269                     } else {
2270                         if (filter.accept(comp)) {
2271                             // there isn't a deeper target, but this component
2272                             // is a target
2273                             return comp;
2274                         }
2275                     }
2276                 }
2277             }
2278 
2279             boolean isPeerOK;
2280             boolean isMouseOverMe;
2281 
2282             isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
2283             isMouseOverMe = contains(x,y);
2284 
2285             // didn't find a child target, return this component if it's
2286             // a possible target
2287             if (isMouseOverMe && isPeerOK && filter.accept(this)) {
2288                 return this;
2289             }
2290             // no possible target
2291             return null;
2292         }
2293     }
2294 
2295     static interface EventTargetFilter {
2296         boolean accept(final Component comp);
2297     }
2298 
2299     static class MouseEventTargetFilter implements EventTargetFilter {
2300         static final EventTargetFilter FILTER = new MouseEventTargetFilter();
2301 
2302         private MouseEventTargetFilter() {}
2303 
2304         public boolean accept(final Component comp) {
2305             return (comp.eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
2306                 || (comp.eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
2307                 || (comp.eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0
2308                 || comp.mouseListener != null
2309                 || comp.mouseMotionListener != null
2310                 || comp.mouseWheelListener != null;
2311         }
2312     }
2313 
2314     static class DropTargetEventTargetFilter implements EventTargetFilter {
2315         static final EventTargetFilter FILTER = new DropTargetEventTargetFilter();
2316 
2317         private DropTargetEventTargetFilter() {}
2318 
2319         public boolean accept(final Component comp) {
2320             DropTarget dt = comp.getDropTarget();
2321             return dt != null && dt.isActive();
2322         }
2323     }
2324 
2325     /**
2326      * This is called by lightweight components that want the containing
2327      * windowed parent to enable some kind of events on their behalf.
2328      * This is needed for events that are normally only dispatched to
2329      * windows to be accepted so that they can be forwarded downward to
2330      * the lightweight component that has enabled them.
2331      */
2332     void proxyEnableEvents(long events) {
2333         if (peer instanceof LightweightPeer) {
2334             // this container is lightweight.... continue sending it
2335             // upward.
2336             if (parent != null) {
2337                 parent.proxyEnableEvents(events);
2338             }
2339         } else {
2340             // This is a native container, so it needs to host
2341             // one of it's children.  If this function is called before
2342             // a peer has been created we don't yet have a dispatcher
2343             // because it has not yet been determined if this instance
2344             // is lightweight.
2345             if (dispatcher != null) {
2346                 dispatcher.enableEvents(events);
2347             }
2348         }
2349     }
2350 
2351     /**
2352      * @deprecated As of JDK version 1.1,
2353      * replaced by <code>dispatchEvent(AWTEvent e)</code>
2354      */
2355     @Deprecated
2356     public void deliverEvent(Event e) {
2357         Component comp = getComponentAt(e.x, e.y);
2358         if ((comp != null) && (comp != this)) {
2359             e.translate(-comp.x, -comp.y);
2360             comp.deliverEvent(e);
2361         } else {
2362             postEvent(e);
2363         }
2364     }
2365 
2366     /**
2367      * Locates the component that contains the x,y position.  The
2368      * top-most child component is returned in the case where there
2369      * is overlap in the components.  This is determined by finding
2370      * the component closest to the index 0 that claims to contain
2371      * the given point via Component.contains(), except that Components
2372      * which have native peers take precedence over those which do not
2373      * (i.e., lightweight Components).
2374      *
2375      * @param x the <i>x</i> coordinate
2376      * @param y the <i>y</i> coordinate
2377      * @return null if the component does not contain the position.
2378      * If there is no child component at the requested point and the
2379      * point is within the bounds of the container the container itself
2380      * is returned; otherwise the top-most child is returned.
2381      * @see Component#contains
2382      * @since JDK1.1
2383      */
2384     public Component getComponentAt(int x, int y) {
2385         return locate(x, y);
2386     }
2387 
2388     /**
2389      * @deprecated As of JDK version 1.1,
2390      * replaced by <code>getComponentAt(int, int)</code>.
2391      */
2392     @Deprecated
2393     public Component locate(int x, int y) {
2394         if (!contains(x, y)) {
2395             return null;
2396         }
2397         synchronized (getTreeLock()) {
2398             // Two passes: see comment in sun.awt.SunGraphicsCallback
2399             for (int i = 0; i < component.size(); i++) {
2400                 Component comp = component.get(i);
2401                 if (comp != null &&
2402                     !(comp.peer instanceof LightweightPeer)) {
2403                     if (comp.contains(x - comp.x, y - comp.y)) {
2404                         return comp;
2405                     }
2406                 }
2407             }
2408             for (int i = 0; i < component.size(); i++) {
2409                 Component comp = component.get(i);
2410                 if (comp != null &&
2411                     comp.peer instanceof LightweightPeer) {
2412                     if (comp.contains(x - comp.x, y - comp.y)) {
2413                         return comp;
2414                     }
2415                 }
2416             }
2417         }
2418         return this;
2419     }
2420 
2421     /**
2422      * Gets the component that contains the specified point.
2423      * @param      p   the point.
2424      * @return     returns the component that contains the point,
2425      *                 or <code>null</code> if the component does
2426      *                 not contain the point.
2427      * @see        Component#contains
2428      * @since      JDK1.1
2429      */
2430     public Component getComponentAt(Point p) {
2431         return getComponentAt(p.x, p.y);
2432     }
2433 
2434     /**
2435      * Returns the position of the mouse pointer in this <code>Container</code>'s
2436      * coordinate space if the <code>Container</code> is under the mouse pointer,
2437      * otherwise returns <code>null</code>.
2438      * This method is similar to {@link Component#getMousePosition()} with the exception
2439      * that it can take the <code>Container</code>'s children into account.
2440      * If <code>allowChildren</code> is <code>false</code>, this method will return
2441      * a non-null value only if the mouse pointer is above the <code>Container</code>
2442      * directly, not above the part obscured by children.
2443      * If <code>allowChildren</code> is <code>true</code>, this method returns
2444      * a non-null value if the mouse pointer is above <code>Container</code> or any
2445      * of its descendants.
2446      *
2447      * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2448      * @param     allowChildren true if children should be taken into account
2449      * @see       Component#getMousePosition
2450      * @return    mouse coordinates relative to this <code>Component</code>, or null
2451      * @since     1.5
2452      */
2453     public Point getMousePosition(boolean allowChildren) throws HeadlessException {
2454         if (GraphicsEnvironment.isHeadless()) {
2455             throw new HeadlessException();
2456         }
2457         PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged(
2458             new java.security.PrivilegedAction() {
2459                 public Object run() {
2460                     return MouseInfo.getPointerInfo();
2461                 }
2462             }
2463         );
2464         synchronized (getTreeLock()) {
2465             Component inTheSameWindow = findUnderMouseInWindow(pi);
2466             if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) {
2467                 return  pointRelativeToComponent(pi.getLocation());
2468             }
2469             return null;
2470         }
2471     }
2472 
2473     boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
2474         return this == comp || (allowChildren && isParentOf(comp));
2475     }
2476 
2477     /**
2478      * Locates the visible child component that contains the specified
2479      * position.  The top-most child component is returned in the case
2480      * where there is overlap in the components.  If the containing child
2481      * component is a Container, this method will continue searching for
2482      * the deepest nested child component.  Components which are not
2483      * visible are ignored during the search.<p>
2484      *
2485      * The findComponentAt method is different from getComponentAt in
2486      * that getComponentAt only searches the Container's immediate
2487      * children; if the containing component is a Container,
2488      * findComponentAt will search that child to find a nested component.
2489      *
2490      * @param x the <i>x</i> coordinate
2491      * @param y the <i>y</i> coordinate
2492      * @return null if the component does not contain the position.
2493      * If there is no child component at the requested point and the
2494      * point is within the bounds of the container the container itself
2495      * is returned.
2496      * @see Component#contains
2497      * @see #getComponentAt
2498      * @since 1.2
2499      */
2500     public Component findComponentAt(int x, int y) {
2501         return findComponentAt(x, y, true);
2502     }
2503 
2504     /**
2505      * Private version of findComponentAt which has a controllable
2506      * behavior. Setting 'ignoreEnabled' to 'false' bypasses disabled
2507      * Components during the search. This behavior is used by the
2508      * lightweight cursor support in sun.awt.GlobalCursorManager.
2509      * The cursor code calls this function directly via native code.
2510      *
2511      * The addition of this feature is temporary, pending the
2512      * adoption of new, public API which exports this feature.
2513      */
2514     final Component findComponentAt(int x, int y, boolean ignoreEnabled) {
2515         synchronized (getTreeLock()) {
2516             if (isRecursivelyVisible()){
2517                 return findComponentAtImpl(x, y, ignoreEnabled);
2518             }
2519         }
2520         return null;
2521     }
2522 
2523     final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
2524         checkTreeLock();
2525 
2526         if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
2527             return null;
2528         }
2529 
2530         // Two passes: see comment in sun.awt.SunGraphicsCallback
2531         for (int i = 0; i < component.size(); i++) {
2532             Component comp = component.get(i);
2533             if (comp != null &&
2534                 !(comp.peer instanceof LightweightPeer)) {
2535                 if (comp instanceof Container) {
2536                     comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2537                                                                  y - comp.y,
2538                                                                  ignoreEnabled);
2539                 } else {
2540                     comp = comp.locate(x - comp.x, y - comp.y);
2541                 }
2542                 if (comp != null && comp.visible &&
2543                     (ignoreEnabled || comp.enabled))
2544                 {
2545                     return comp;
2546                 }
2547             }
2548         }
2549         for (int i = 0; i < component.size(); i++) {
2550             Component comp = component.get(i);
2551             if (comp != null &&
2552                 comp.peer instanceof LightweightPeer) {
2553                 if (comp instanceof Container) {
2554                     comp = ((Container)comp).findComponentAtImpl(x - comp.x,
2555                                                                  y - comp.y,
2556                                                                  ignoreEnabled);
2557                 } else {
2558                     comp = comp.locate(x - comp.x, y - comp.y);
2559                 }
2560                 if (comp != null && comp.visible &&
2561                     (ignoreEnabled || comp.enabled))
2562                 {
2563                     return comp;
2564                 }
2565             }
2566         }
2567 
2568         return this;
2569     }
2570 
2571     /**
2572      * Locates the visible child component that contains the specified
2573      * point.  The top-most child component is returned in the case
2574      * where there is overlap in the components.  If the containing child
2575      * component is a Container, this method will continue searching for
2576      * the deepest nested child component.  Components which are not
2577      * visible are ignored during the search.<p>
2578      *
2579      * The findComponentAt method is different from getComponentAt in
2580      * that getComponentAt only searches the Container's immediate
2581      * children; if the containing component is a Container,
2582      * findComponentAt will search that child to find a nested component.
2583      *
2584      * @param      p   the point.
2585      * @return null if the component does not contain the position.
2586      * If there is no child component at the requested point and the
2587      * point is within the bounds of the container the container itself
2588      * is returned.
2589      * @see Component#contains
2590      * @see #getComponentAt
2591      * @since 1.2
2592      */
2593     public Component findComponentAt(Point p) {
2594         return findComponentAt(p.x, p.y);
2595     }
2596 
2597     /**
2598      * Makes this Container displayable by connecting it to
2599      * a native screen resource.  Making a container displayable will
2600      * cause all of its children to be made displayable.
2601      * This method is called internally by the toolkit and should
2602      * not be called directly by programs.
2603      * @see Component#isDisplayable
2604      * @see #removeNotify
2605      */
2606     public void addNotify() {
2607         synchronized (getTreeLock()) {
2608             // addNotify() on the children may cause proxy event enabling
2609             // on this instance, so we first call super.addNotify() and
2610             // possibly create an lightweight event dispatcher before calling
2611             // addNotify() on the children which may be lightweight.
2612             super.addNotify();
2613             if (! (peer instanceof LightweightPeer)) {
2614                 dispatcher = new LightweightDispatcher(this);
2615             }
2616 
2617             // We shouldn't use iterator because of the Swing menu
2618             // implementation specifics:
2619             // the menu is being assigned as a child to JLayeredPane
2620             // instead of particular component so always affect
2621             // collection of component if menu is becoming shown or hidden.
2622             for (int i = 0; i < component.size(); i++) {
2623                 component.get(i).addNotify();
2624             }
2625         }
2626     }
2627 
2628     /**
2629      * Makes this Container undisplayable by removing its connection
2630      * to its native screen resource.  Making a container undisplayable
2631      * will cause all of its children to be made undisplayable.
2632      * This method is called by the toolkit internally and should
2633      * not be called directly by programs.
2634      * @see Component#isDisplayable
2635      * @see #addNotify
2636      */
2637     public void removeNotify() {
2638         synchronized (getTreeLock()) {
2639             // We shouldn't use iterator because of the Swing menu
2640             // implementation specifics:
2641             // the menu is being assigned as a child to JLayeredPane
2642             // instead of particular component so always affect
2643             // collection of component if menu is becoming shown or hidden.
2644             for (int i = component.size()-1 ; i >= 0 ; i--) {
2645                 Component comp = component.get(i);
2646                 if (comp != null) {
2647                     // Fix for 6607170.
2648                     // We want to suppress focus change on disposal
2649                     // of the focused component. But because of focus
2650                     // is asynchronous, we should suppress focus change
2651                     // on every component in case it receives native focus
2652                     // in the process of disposal.
2653                     comp.setAutoFocusTransferOnDisposal(false);
2654                     comp.removeNotify();
2655                     comp.setAutoFocusTransferOnDisposal(true);
2656                  }
2657              }
2658             // If some of the children had focus before disposal then it still has.
2659             // Auto-transfer focus to the next (or previous) component if auto-transfer
2660             // is enabled.
2661             if (containsFocus() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
2662                 if (!transferFocus(false)) {
2663                     transferFocusBackward(true);
2664                 }
2665             }
2666             if ( dispatcher != null ) {
2667                 dispatcher.dispose();
2668                 dispatcher = null;
2669             }
2670             super.removeNotify();
2671         }
2672     }
2673 
2674     /**
2675      * Checks if the component is contained in the component hierarchy of
2676      * this container.
2677      * @param c the component
2678      * @return     <code>true</code> if it is an ancestor;
2679      *             <code>false</code> otherwise.
2680      * @since      JDK1.1
2681      */
2682     public boolean isAncestorOf(Component c) {
2683         Container p;
2684         if (c == null || ((p = c.getParent()) == null)) {
2685             return false;
2686         }
2687         while (p != null) {
2688             if (p == this) {
2689                 return true;
2690             }
2691             p = p.getParent();
2692         }
2693         return false;
2694     }
2695 
2696     /*
2697      * The following code was added to support modal JInternalFrames
2698      * Unfortunately this code has to be added here so that we can get access to
2699      * some private AWT classes like SequencedEvent.
2700      *
2701      * The native container of the LW component has this field set
2702      * to tell it that it should block Mouse events for all LW
2703      * children except for the modal component.
2704      *
2705      * In the case of nested Modal components, we store the previous
2706      * modal component in the new modal components value of modalComp;
2707      */
2708 
2709     transient Component modalComp;
2710     transient AppContext modalAppContext;
2711 
2712     private void startLWModal() {
2713         // Store the app context on which this component is being shown.
2714         // Event dispatch thread of this app context will be sleeping until
2715         // we wake it by any event from hideAndDisposeHandler().
2716         modalAppContext = AppContext.getAppContext();
2717 
2718         // keep the KeyEvents from being dispatched
2719         // until the focus has been transfered
2720         long time = Toolkit.getEventQueue().getMostRecentEventTime();
2721         Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null;
2722         if (predictedFocusOwner != null) {
2723             KeyboardFocusManager.getCurrentKeyboardFocusManager().
2724                 enqueueKeyEvents(time, predictedFocusOwner);
2725         }
2726         // We have two mechanisms for blocking: 1. If we're on the
2727         // EventDispatchThread, start a new event pump. 2. If we're
2728         // on any other thread, call wait() on the treelock.
2729         final Container nativeContainer;
2730         synchronized (getTreeLock()) {
2731             nativeContainer = getHeavyweightContainer();
2732             if (nativeContainer.modalComp != null) {
2733                 this.modalComp =  nativeContainer.modalComp;
2734                 nativeContainer.modalComp = this;
2735                 return;
2736             }
2737             else {
2738                 nativeContainer.modalComp = this;
2739             }
2740         }
2741 
2742         Runnable pumpEventsForHierarchy = new Runnable() {
2743             public void run() {
2744                 EventDispatchThread dispatchThread =
2745                     (EventDispatchThread)Thread.currentThread();
2746                 dispatchThread.pumpEventsForHierarchy(
2747                         new Conditional() {
2748                         public boolean evaluate() {
2749                         return ((windowClosingException == null) && (nativeContainer.modalComp != null)) ;
2750                         }
2751                         }, Container.this);
2752             }
2753         };
2754 
2755         if (EventQueue.isDispatchThread()) {
2756             SequencedEvent currentSequencedEvent =
2757                 KeyboardFocusManager.getCurrentKeyboardFocusManager().
2758                 getCurrentSequencedEvent();
2759             if (currentSequencedEvent != null) {
2760                 currentSequencedEvent.dispose();
2761             }
2762 
2763             pumpEventsForHierarchy.run();
2764         } else {
2765             synchronized (getTreeLock()) {
2766                 Toolkit.getEventQueue().
2767                     postEvent(new PeerEvent(this,
2768                                 pumpEventsForHierarchy,
2769                                 PeerEvent.PRIORITY_EVENT));
2770                 while ((windowClosingException == null) &&
2771                        (nativeContainer.modalComp != null))
2772                 {
2773                     try {
2774                         getTreeLock().wait();
2775                     } catch (InterruptedException e) {
2776                         break;
2777                     }
2778                 }
2779             }
2780         }
2781         if (windowClosingException != null) {
2782             windowClosingException.fillInStackTrace();
2783             throw windowClosingException;
2784         }
2785         if (predictedFocusOwner != null) {
2786             KeyboardFocusManager.getCurrentKeyboardFocusManager().
2787                 dequeueKeyEvents(time, predictedFocusOwner);
2788         }
2789     }
2790 
2791     private void stopLWModal() {
2792         synchronized (getTreeLock()) {
2793             if (modalAppContext != null) {
2794                 Container nativeContainer = getHeavyweightContainer();
2795                 if(nativeContainer != null) {
2796                     if (this.modalComp !=  null) {
2797                         nativeContainer.modalComp = this.modalComp;
2798                         this.modalComp = null;
2799                         return;
2800                     }
2801                     else {
2802                         nativeContainer.modalComp = null;
2803                     }
2804                 }
2805                 // Wake up event dispatch thread on which the dialog was
2806                 // initially shown
2807                 SunToolkit.postEvent(modalAppContext,
2808                         new PeerEvent(this,
2809                                 new WakingRunnable(),
2810                                 PeerEvent.PRIORITY_EVENT));
2811             }
2812             EventQueue.invokeLater(new WakingRunnable());
2813             getTreeLock().notifyAll();
2814         }
2815     }
2816 
2817     final static class WakingRunnable implements Runnable {
2818         public void run() {
2819         }
2820     }
2821 
2822     /* End of JOptionPane support code */
2823 
2824     /**
2825      * Returns a string representing the state of this <code>Container</code>.
2826      * This method is intended to be used only for debugging purposes, and the
2827      * content and format of the returned string may vary between
2828      * implementations. The returned string may be empty but may not be
2829      * <code>null</code>.
2830      *
2831      * @return    the parameter string of this container
2832      */
2833     protected String paramString() {
2834         String str = super.paramString();
2835         LayoutManager layoutMgr = this.layoutMgr;
2836         if (layoutMgr != null) {
2837             str += ",layout=" + layoutMgr.getClass().getName();
2838         }
2839         return str;
2840     }
2841 
2842     /**
2843      * Prints a listing of this container to the specified output
2844      * stream. The listing starts at the specified indentation.
2845      * <p>
2846      * The immediate children of the container are printed with
2847      * an indentation of <code>indent+1</code>.  The children
2848      * of those children are printed at <code>indent+2</code>
2849      * and so on.
2850      *
2851      * @param    out      a print stream
2852      * @param    indent   the number of spaces to indent
2853      * @see      Component#list(java.io.PrintStream, int)
2854      * @since    JDK1.0
2855      */
2856     public void list(PrintStream out, int indent) {
2857         super.list(out, indent);
2858         synchronized(getTreeLock()) {
2859             for (int i = 0; i < component.size(); i++) {
2860                 Component comp = component.get(i);
2861                 if (comp != null) {
2862                     comp.list(out, indent+1);
2863                 }
2864             }
2865         }
2866     }
2867 
2868     /**
2869      * Prints out a list, starting at the specified indentation,
2870      * to the specified print writer.
2871      * <p>
2872      * The immediate children of the container are printed with
2873      * an indentation of <code>indent+1</code>.  The children
2874      * of those children are printed at <code>indent+2</code>
2875      * and so on.
2876      *
2877      * @param    out      a print writer
2878      * @param    indent   the number of spaces to indent
2879      * @see      Component#list(java.io.PrintWriter, int)
2880      * @since    JDK1.1
2881      */
2882     public void list(PrintWriter out, int indent) {
2883         super.list(out, indent);
2884         synchronized(getTreeLock()) {
2885             for (int i = 0; i < component.size(); i++) {
2886                 Component comp = component.get(i);
2887                 if (comp != null) {
2888                     comp.list(out, indent+1);
2889                 }
2890             }
2891         }
2892     }
2893 
2894     /**
2895      * Sets the focus traversal keys for a given traversal operation for this
2896      * Container.
2897      * <p>
2898      * The default values for a Container's focus traversal keys are
2899      * implementation-dependent. Sun recommends that all implementations for a
2900      * particular native platform use the same default values. The
2901      * recommendations for Windows and Unix are listed below. These
2902      * recommendations are used in the Sun AWT implementations.
2903      *
2904      * <table border=1 summary="Recommended default values for a Container's focus traversal keys">
2905      * <tr>
2906      *    <th>Identifier</th>
2907      *    <th>Meaning</th>
2908      *    <th>Default</th>
2909      * </tr>
2910      * <tr>
2911      *    <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
2912      *    <td>Normal forward keyboard traversal</td>
2913      *    <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
2914      * </tr>
2915      * <tr>
2916      *    <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
2917      *    <td>Normal reverse keyboard traversal</td>
2918      *    <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
2919      * </tr>
2920      * <tr>
2921      *    <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
2922      *    <td>Go up one focus traversal cycle</td>
2923      *    <td>none</td>
2924      * </tr>
2925      * <tr>
2926      *    <td>KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS<td>
2927      *    <td>Go down one focus traversal cycle</td>
2928      *    <td>none</td>
2929      * </tr>
2930      * </table>
2931      *
2932      * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
2933      * recommended.
2934      * <p>
2935      * Using the AWTKeyStroke API, client code can specify on which of two
2936      * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
2937      * operation will occur. Regardless of which KeyEvent is specified,
2938      * however, all KeyEvents related to the focus traversal key, including the
2939      * associated KEY_TYPED event, will be consumed, and will not be dispatched
2940      * to any Container. It is a runtime error to specify a KEY_TYPED event as
2941      * mapping to a focus traversal operation, or to map the same event to
2942      * multiple default focus traversal operations.
2943      * <p>
2944      * If a value of null is specified for the Set, this Container inherits the
2945      * Set from its parent. If all ancestors of this Container have null
2946      * specified for the Set, then the current KeyboardFocusManager's default
2947      * Set is used.
2948      *
2949      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2950      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2951      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2952      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2953      * @param keystrokes the Set of AWTKeyStroke for the specified operation
2954      * @see #getFocusTraversalKeys
2955      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2956      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2957      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2958      * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2959      * @throws IllegalArgumentException if id is not one of
2960      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2961      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2962      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2963      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, or if keystrokes
2964      *         contains null, or if any Object in keystrokes is not an
2965      *         AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
2966      *         or if any keystroke already maps to another focus traversal
2967      *         operation for this Container
2968      * @since 1.4
2969      * @beaninfo
2970      *       bound: true
2971      */
2972     public void setFocusTraversalKeys(int id,
2973                                       Set<? extends AWTKeyStroke> keystrokes)
2974     {
2975         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2976             throw new IllegalArgumentException("invalid focus traversal key identifier");
2977         }
2978 
2979         // Don't call super.setFocusTraversalKey. The Component parameter check
2980         // does not allow DOWN_CYCLE_TRAVERSAL_KEYS, but we do.
2981         setFocusTraversalKeys_NoIDCheck(id, keystrokes);
2982     }
2983 
2984     /**
2985      * Returns the Set of focus traversal keys for a given traversal operation
2986      * for this Container. (See
2987      * <code>setFocusTraversalKeys</code> for a full description of each key.)
2988      * <p>
2989      * If a Set of traversal keys has not been explicitly defined for this
2990      * Container, then this Container's parent's Set is returned. If no Set
2991      * has been explicitly defined for any of this Container's ancestors, then
2992      * the current KeyboardFocusManager's default Set is returned.
2993      *
2994      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2995      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2996      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2997      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2998      * @return the Set of AWTKeyStrokes for the specified operation. The Set
2999      *         will be unmodifiable, and may be empty. null will never be
3000      *         returned.
3001      * @see #setFocusTraversalKeys
3002      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3003      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3004      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3005      * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
3006      * @throws IllegalArgumentException if id is not one of
3007      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3008      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3009      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3010      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3011      * @since 1.4
3012      */
3013     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
3014         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3015             throw new IllegalArgumentException("invalid focus traversal key identifier");
3016         }
3017 
3018         // Don't call super.getFocusTraversalKey. The Component parameter check
3019         // does not allow DOWN_CYCLE_TRAVERSAL_KEY, but we do.
3020         return getFocusTraversalKeys_NoIDCheck(id);
3021     }
3022 
3023     /**
3024      * Returns whether the Set of focus traversal keys for the given focus
3025      * traversal operation has been explicitly defined for this Container. If
3026      * this method returns <code>false</code>, this Container is inheriting the
3027      * Set from an ancestor, or from the current KeyboardFocusManager.
3028      *
3029      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3030      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3031      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3032      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3033      * @return <code>true</code> if the the Set of focus traversal keys for the
3034      *         given focus traversal operation has been explicitly defined for
3035      *         this Component; <code>false</code> otherwise.
3036      * @throws IllegalArgumentException if id is not one of
3037      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3038      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3039      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3040      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3041      * @since 1.4
3042      */
3043     public boolean areFocusTraversalKeysSet(int id) {
3044         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3045             throw new IllegalArgumentException("invalid focus traversal key identifier");
3046         }
3047 
3048         return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
3049     }
3050 
3051     /**
3052      * Returns whether the specified Container is the focus cycle root of this
3053      * Container's focus traversal cycle. Each focus traversal cycle has only
3054      * a single focus cycle root and each Container which is not a focus cycle
3055      * root belongs to only a single focus traversal cycle. Containers which
3056      * are focus cycle roots belong to two cycles: one rooted at the Container
3057      * itself, and one rooted at the Container's nearest focus-cycle-root
3058      * ancestor. This method will return <code>true</code> for both such
3059      * Containers in this case.
3060      *
3061      * @param container the Container to be tested
3062      * @return <code>true</code> if the specified Container is a focus-cycle-
3063      *         root of this Container; <code>false</code> otherwise
3064      * @see #isFocusCycleRoot()
3065      * @since 1.4
3066      */
3067     public boolean isFocusCycleRoot(Container container) {
3068         if (isFocusCycleRoot() && container == this) {
3069             return true;
3070         } else {
3071             return super.isFocusCycleRoot(container);
3072         }
3073     }
3074 
3075     private Container findTraversalRoot() {
3076         // I potentially have two roots, myself and my root parent
3077         // If I am the current root, then use me
3078         // If none of my parents are roots, then use me
3079         // If my root parent is the current root, then use my root parent
3080         // If neither I nor my root parent is the current root, then
3081         // use my root parent (a guess)
3082 
3083         Container currentFocusCycleRoot = KeyboardFocusManager.
3084             getCurrentKeyboardFocusManager().getCurrentFocusCycleRoot();
3085         Container root;
3086 
3087         if (currentFocusCycleRoot == this) {
3088             root = this;
3089         } else {
3090             root = getFocusCycleRootAncestor();
3091             if (root == null) {
3092                 root = this;
3093             }
3094         }
3095 
3096         if (root != currentFocusCycleRoot) {
3097             KeyboardFocusManager.getCurrentKeyboardFocusManager().
3098                 setGlobalCurrentFocusCycleRoot(root);
3099         }
3100         return root;
3101     }
3102 
3103     final boolean containsFocus() {
3104         final Component focusOwner = KeyboardFocusManager.
3105             getCurrentKeyboardFocusManager().getFocusOwner();
3106         return isParentOf(focusOwner);
3107     }
3108 
3109     /**
3110      * Check if this component is the child of this container or its children.
3111      * Note: this function acquires treeLock
3112      * Note: this function traverses children tree only in one Window.
3113      * @param comp a component in test, must not be null
3114      */
3115     private boolean isParentOf(Component comp) {
3116         synchronized(getTreeLock()) {
3117             while (comp != null && comp != this && !(comp instanceof Window)) {
3118                 comp = comp.getParent();
3119             }
3120             return (comp == this);
3121         }
3122     }
3123 
3124     void clearMostRecentFocusOwnerOnHide() {
3125         boolean reset = false;
3126         Window window = null;
3127 
3128         synchronized (getTreeLock()) {
3129             window = getContainingWindow();
3130             if (window != null) {
3131                 Component comp = KeyboardFocusManager.getMostRecentFocusOwner(window);
3132                 reset = ((comp == this) || isParentOf(comp));
3133                 // This synchronized should always be the second in a pair
3134                 // (tree lock, KeyboardFocusManager.class)
3135                 synchronized(KeyboardFocusManager.class) {
3136                     Component storedComp = window.getTemporaryLostComponent();
3137                     if (isParentOf(storedComp) || storedComp == this) {
3138                         window.setTemporaryLostComponent(null);
3139                     }
3140                 }
3141             }
3142         }
3143 
3144         if (reset) {
3145             KeyboardFocusManager.setMostRecentFocusOwner(window, null);
3146         }
3147     }
3148 
3149     void clearCurrentFocusCycleRootOnHide() {
3150         KeyboardFocusManager kfm =
3151             KeyboardFocusManager.getCurrentKeyboardFocusManager();
3152         Container cont = kfm.getCurrentFocusCycleRoot();
3153 
3154         if (cont == this || isParentOf(cont)) {
3155             kfm.setGlobalCurrentFocusCycleRoot(null);
3156         }
3157     }
3158 
3159     final Container getTraversalRoot() {
3160         if (isFocusCycleRoot()) {
3161             return findTraversalRoot();
3162         }
3163 
3164         return super.getTraversalRoot();
3165     }
3166 
3167     /**
3168      * Sets the focus traversal policy that will manage keyboard traversal of
3169      * this Container's children, if this Container is a focus cycle root. If
3170      * the argument is null, this Container inherits its policy from its focus-
3171      * cycle-root ancestor. If the argument is non-null, this policy will be
3172      * inherited by all focus-cycle-root children that have no keyboard-
3173      * traversal policy of their own (as will, recursively, their focus-cycle-
3174      * root children).
3175      * <p>
3176      * If this Container is not a focus cycle root, the policy will be
3177      * remembered, but will not be used or inherited by this or any other
3178      * Containers until this Container is made a focus cycle root.
3179      *
3180      * @param policy the new focus traversal policy for this Container
3181      * @see #getFocusTraversalPolicy
3182      * @see #setFocusCycleRoot
3183      * @see #isFocusCycleRoot
3184      * @since 1.4
3185      * @beaninfo
3186      *       bound: true
3187      */
3188     public void setFocusTraversalPolicy(FocusTraversalPolicy policy) {
3189         FocusTraversalPolicy oldPolicy;
3190         synchronized (this) {
3191             oldPolicy = this.focusTraversalPolicy;
3192             this.focusTraversalPolicy = policy;
3193         }
3194         firePropertyChange("focusTraversalPolicy", oldPolicy, policy);
3195     }
3196 
3197     /**
3198      * Returns the focus traversal policy that will manage keyboard traversal
3199      * of this Container's children, or null if this Container is not a focus
3200      * cycle root. If no traversal policy has been explicitly set for this
3201      * Container, then this Container's focus-cycle-root ancestor's policy is
3202      * returned.
3203      *
3204      * @return this Container's focus traversal policy, or null if this
3205      *         Container is not a focus cycle root.
3206      * @see #setFocusTraversalPolicy
3207      * @see #setFocusCycleRoot
3208      * @see #isFocusCycleRoot
3209      * @since 1.4
3210      */
3211     public FocusTraversalPolicy getFocusTraversalPolicy() {
3212         if (!isFocusTraversalPolicyProvider() && !isFocusCycleRoot()) {
3213             return null;
3214         }
3215 
3216         FocusTraversalPolicy policy = this.focusTraversalPolicy;
3217         if (policy != null) {
3218             return policy;
3219         }
3220 
3221         Container rootAncestor = getFocusCycleRootAncestor();
3222         if (rootAncestor != null) {
3223             return rootAncestor.getFocusTraversalPolicy();
3224         } else {
3225             return KeyboardFocusManager.getCurrentKeyboardFocusManager().
3226                 getDefaultFocusTraversalPolicy();
3227         }
3228     }
3229 
3230     /**
3231      * Returns whether the focus traversal policy has been explicitly set for
3232      * this Container. If this method returns <code>false</code>, this
3233      * Container will inherit its focus traversal policy from an ancestor.
3234      *
3235      * @return <code>true</code> if the focus traversal policy has been
3236      *         explicitly set for this Container; <code>false</code> otherwise.
3237      * @since 1.4
3238      */
3239     public boolean isFocusTraversalPolicySet() {
3240         return (focusTraversalPolicy != null);
3241     }
3242 
3243     /**
3244      * Sets whether this Container is the root of a focus traversal cycle. Once
3245      * focus enters a traversal cycle, typically it cannot leave it via focus
3246      * traversal unless one of the up- or down-cycle keys is pressed. Normal
3247      * traversal is limited to this Container, and all of this Container's
3248      * descendants that are not descendants of inferior focus cycle roots. Note
3249      * that a FocusTraversalPolicy may bend these restrictions, however. For
3250      * example, ContainerOrderFocusTraversalPolicy supports implicit down-cycle
3251      * traversal.
3252      * <p>
3253      * The alternative way to specify the traversal order of this Container's
3254      * children is to make this Container a
3255      * <a href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy provider</a>.
3256      *
3257      * @param focusCycleRoot indicates whether this Container is the root of a
3258      *        focus traversal cycle
3259      * @see #isFocusCycleRoot()
3260      * @see #setFocusTraversalPolicy
3261      * @see #getFocusTraversalPolicy
3262      * @see ContainerOrderFocusTraversalPolicy
3263      * @see #setFocusTraversalPolicyProvider
3264      * @since 1.4
3265      * @beaninfo
3266      *       bound: true
3267      */
3268     public void setFocusCycleRoot(boolean focusCycleRoot) {
3269         boolean oldFocusCycleRoot;
3270         synchronized (this) {
3271             oldFocusCycleRoot = this.focusCycleRoot;
3272             this.focusCycleRoot = focusCycleRoot;
3273         }
3274         firePropertyChange("focusCycleRoot", oldFocusCycleRoot,
3275                            focusCycleRoot);
3276     }
3277 
3278     /**
3279      * Returns whether this Container is the root of a focus traversal cycle.
3280      * Once focus enters a traversal cycle, typically it cannot leave it via
3281      * focus traversal unless one of the up- or down-cycle keys is pressed.
3282      * Normal traversal is limited to this Container, and all of this
3283      * Container's descendants that are not descendants of inferior focus
3284      * cycle roots. Note that a FocusTraversalPolicy may bend these
3285      * restrictions, however. For example, ContainerOrderFocusTraversalPolicy
3286      * supports implicit down-cycle traversal.
3287      *
3288      * @return whether this Container is the root of a focus traversal cycle
3289      * @see #setFocusCycleRoot
3290      * @see #setFocusTraversalPolicy
3291      * @see #getFocusTraversalPolicy
3292      * @see ContainerOrderFocusTraversalPolicy
3293      * @since 1.4
3294      */
3295     public boolean isFocusCycleRoot() {
3296         return focusCycleRoot;
3297     }
3298 
3299     /**
3300      * Sets whether this container will be used to provide focus
3301      * traversal policy. Container with this property as
3302      * <code>true</code> will be used to acquire focus traversal policy
3303      * instead of closest focus cycle root ancestor.
3304      * @param provider indicates whether this container will be used to
3305      *                provide focus traversal policy
3306      * @see #setFocusTraversalPolicy
3307      * @see #getFocusTraversalPolicy
3308      * @see #isFocusTraversalPolicyProvider
3309      * @since 1.5
3310      * @beaninfo
3311      *        bound: true
3312      */
3313     public final void setFocusTraversalPolicyProvider(boolean provider) {
3314         boolean oldProvider;
3315         synchronized(this) {
3316             oldProvider = focusTraversalPolicyProvider;
3317             focusTraversalPolicyProvider = provider;
3318         }
3319         firePropertyChange("focusTraversalPolicyProvider", oldProvider, provider);
3320     }
3321 
3322     /**
3323      * Returns whether this container provides focus traversal
3324      * policy. If this property is set to <code>true</code> then when
3325      * keyboard focus manager searches container hierarchy for focus
3326      * traversal policy and encounters this container before any other
3327      * container with this property as true or focus cycle roots then
3328      * its focus traversal policy will be used instead of focus cycle
3329      * root's policy.
3330      * @see #setFocusTraversalPolicy
3331      * @see #getFocusTraversalPolicy
3332      * @see #setFocusCycleRoot
3333      * @see #setFocusTraversalPolicyProvider
3334      * @return <code>true</code> if this container provides focus traversal
3335      *         policy, <code>false</code> otherwise
3336      * @since 1.5
3337      * @beaninfo
3338      *        bound: true
3339      */
3340     public final boolean isFocusTraversalPolicyProvider() {
3341         return focusTraversalPolicyProvider;
3342     }
3343 
3344     /**
3345      * Transfers the focus down one focus traversal cycle. If this Container is
3346      * a focus cycle root, then the focus owner is set to this Container's
3347      * default Component to focus, and the current focus cycle root is set to
3348      * this Container. If this Container is not a focus cycle root, then no
3349      * focus traversal operation occurs.
3350      *
3351      * @see       Component#requestFocus()
3352      * @see       #isFocusCycleRoot
3353      * @see       #setFocusCycleRoot
3354      * @since     1.4
3355      */
3356     public void transferFocusDownCycle() {
3357         if (isFocusCycleRoot()) {
3358             KeyboardFocusManager.getCurrentKeyboardFocusManager().
3359                 setGlobalCurrentFocusCycleRoot(this);
3360             Component toFocus = getFocusTraversalPolicy().
3361                 getDefaultComponent(this);
3362             if (toFocus != null) {
3363                 toFocus.requestFocus(CausedFocusEvent.Cause.TRAVERSAL_DOWN);
3364             }
3365         }
3366     }
3367 
3368     void preProcessKeyEvent(KeyEvent e) {
3369         Container parent = this.parent;
3370         if (parent != null) {
3371             parent.preProcessKeyEvent(e);
3372         }
3373     }
3374 
3375     void postProcessKeyEvent(KeyEvent e) {
3376         Container parent = this.parent;
3377         if (parent != null) {
3378             parent.postProcessKeyEvent(e);
3379         }
3380     }
3381 
3382     boolean postsOldMouseEvents() {
3383         return true;
3384     }
3385 
3386     /**
3387      * Sets the <code>ComponentOrientation</code> property of this container
3388      * and all components contained within it.
3389      *
3390      * @param o the new component orientation of this container and
3391      *        the components contained within it.
3392      * @exception NullPointerException if <code>orientation</code> is null.
3393      * @see Component#setComponentOrientation
3394      * @see Component#getComponentOrientation
3395      * @since 1.4
3396      */
3397     public void applyComponentOrientation(ComponentOrientation o) {
3398         super.applyComponentOrientation(o);
3399         synchronized (getTreeLock()) {
3400             for (int i = 0; i < component.size(); i++) {
3401                 Component comp = component.get(i);
3402                 comp.applyComponentOrientation(o);
3403             }
3404         }
3405     }
3406 
3407     /**
3408      * Adds a PropertyChangeListener to the listener list. The listener is
3409      * registered for all bound properties of this class, including the
3410      * following:
3411      * <ul>
3412      *    <li>this Container's font ("font")</li>
3413      *    <li>this Container's background color ("background")</li>
3414      *    <li>this Container's foreground color ("foreground")</li>
3415      *    <li>this Container's focusability ("focusable")</li>
3416      *    <li>this Container's focus traversal keys enabled state
3417      *        ("focusTraversalKeysEnabled")</li>
3418      *    <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3419      *        ("forwardFocusTraversalKeys")</li>
3420      *    <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3421      *        ("backwardFocusTraversalKeys")</li>
3422      *    <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3423      *        ("upCycleFocusTraversalKeys")</li>
3424      *    <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3425      *        ("downCycleFocusTraversalKeys")</li>
3426      *    <li>this Container's focus traversal policy ("focusTraversalPolicy")
3427      *        </li>
3428      *    <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3429      * </ul>
3430      * Note that if this Container is inheriting a bound property, then no
3431      * event will be fired in response to a change in the inherited property.
3432      * <p>
3433      * If listener is null, no exception is thrown and no action is performed.
3434      *
3435      * @param    listener  the PropertyChangeListener to be added
3436      *
3437      * @see Component#removePropertyChangeListener
3438      * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
3439      */
3440     public void addPropertyChangeListener(PropertyChangeListener listener) {
3441         super.addPropertyChangeListener(listener);
3442     }
3443 
3444     /**
3445      * Adds a PropertyChangeListener to the listener list for a specific
3446      * property. The specified property may be user-defined, or one of the
3447      * following defaults:
3448      * <ul>
3449      *    <li>this Container's font ("font")</li>
3450      *    <li>this Container's background color ("background")</li>
3451      *    <li>this Container's foreground color ("foreground")</li>
3452      *    <li>this Container's focusability ("focusable")</li>
3453      *    <li>this Container's focus traversal keys enabled state
3454      *        ("focusTraversalKeysEnabled")</li>
3455      *    <li>this Container's Set of FORWARD_TRAVERSAL_KEYS
3456      *        ("forwardFocusTraversalKeys")</li>
3457      *    <li>this Container's Set of BACKWARD_TRAVERSAL_KEYS
3458      *        ("backwardFocusTraversalKeys")</li>
3459      *    <li>this Container's Set of UP_CYCLE_TRAVERSAL_KEYS
3460      *        ("upCycleFocusTraversalKeys")</li>
3461      *    <li>this Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
3462      *        ("downCycleFocusTraversalKeys")</li>
3463      *    <li>this Container's focus traversal policy ("focusTraversalPolicy")
3464      *        </li>
3465      *    <li>this Container's focus-cycle-root state ("focusCycleRoot")</li>
3466      *    <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3467      *    <li>this Container's focus-traversal-policy-provider state("focusTraversalPolicyProvider")</li>
3468      * </ul>
3469      * Note that if this Container is inheriting a bound property, then no
3470      * event will be fired in response to a change in the inherited property.
3471      * <p>
3472      * If listener is null, no exception is thrown and no action is performed.
3473      *
3474      * @param propertyName one of the property names listed above
3475      * @param listener the PropertyChangeListener to be added
3476      *
3477      * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
3478      * @see Component#removePropertyChangeListener
3479      */
3480     public void addPropertyChangeListener(String propertyName,
3481                                           PropertyChangeListener listener) {
3482         super.addPropertyChangeListener(propertyName, listener);
3483     }
3484 
3485     // Serialization support. A Container is responsible for restoring the
3486     // parent fields of its component children.
3487 
3488     /**
3489      * Container Serial Data Version.
3490      */
3491     private int containerSerializedDataVersion = 1;
3492 
3493     /**
3494      * Serializes this <code>Container</code> to the specified
3495      * <code>ObjectOutputStream</code>.
3496      * <ul>
3497      *    <li>Writes default serializable fields to the stream.</li>
3498      *    <li>Writes a list of serializable ContainerListener(s) as optional
3499      *        data. The non-serializable ContainerListner(s) are detected and
3500      *        no attempt is made to serialize them.</li>
3501      *    <li>Write this Container's FocusTraversalPolicy if and only if it
3502      *        is Serializable; otherwise, <code>null</code> is written.</li>
3503      * </ul>
3504      *
3505      * @param s the <code>ObjectOutputStream</code> to write
3506      * @serialData <code>null</code> terminated sequence of 0 or more pairs;
3507      *   the pair consists of a <code>String</code> and <code>Object</code>;
3508      *   the <code>String</code> indicates the type of object and
3509      *   is one of the following:
3510      *   <code>containerListenerK</code> indicating an
3511      *     <code>ContainerListener</code> object;
3512      *   the <code>Container</code>'s <code>FocusTraversalPolicy</code>,
3513      *     or <code>null</code>
3514      *
3515      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
3516      * @see Container#containerListenerK
3517      * @see #readObject(ObjectInputStream)
3518      */
3519     private void writeObject(ObjectOutputStream s) throws IOException {
3520         ObjectOutputStream.PutField f = s.putFields();
3521         f.put("ncomponents", component.size());
3522         f.put("component", getComponentsSync());
3523         f.put("layoutMgr", layoutMgr);
3524         f.put("dispatcher", dispatcher);
3525         f.put("maxSize", maxSize);
3526         f.put("focusCycleRoot", focusCycleRoot);
3527         f.put("containerSerializedDataVersion", containerSerializedDataVersion);
3528         f.put("focusTraversalPolicyProvider", focusTraversalPolicyProvider);
3529         s.writeFields();
3530 
3531         AWTEventMulticaster.save(s, containerListenerK, containerListener);
3532         s.writeObject(null);
3533 
3534         if (focusTraversalPolicy instanceof java.io.Serializable) {
3535             s.writeObject(focusTraversalPolicy);
3536         } else {
3537             s.writeObject(null);
3538         }
3539     }
3540 
3541     /**
3542      * Deserializes this <code>Container</code> from the specified
3543      * <code>ObjectInputStream</code>.
3544      * <ul>
3545      *    <li>Reads default serializable fields from the stream.</li>
3546      *    <li>Reads a list of serializable ContainerListener(s) as optional
3547      *        data. If the list is null, no Listeners are installed.</li>
3548      *    <li>Reads this Container's FocusTraversalPolicy, which may be null,
3549      *        as optional data.</li>
3550      * </ul>
3551      *
3552      * @param s the <code>ObjectInputStream</code> to read
3553      * @serial
3554      * @see #addContainerListener
3555      * @see #writeObject(ObjectOutputStream)
3556      */
3557     private void readObject(ObjectInputStream s)
3558         throws ClassNotFoundException, IOException
3559     {
3560         ObjectInputStream.GetField f = s.readFields();
3561         Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY);
3562         int ncomponents = (Integer) f.get("ncomponents", 0);
3563         component = new java.util.ArrayList<Component>(ncomponents);
3564         for (int i = 0; i < ncomponents; ++i) {
3565             component.add(tmpComponent[i]);
3566         }
3567         layoutMgr = (LayoutManager)f.get("layoutMgr", null);
3568         dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
3569         // Old stream. Doesn't contain maxSize among Component's fields.
3570         if (maxSize == null) {
3571             maxSize = (Dimension)f.get("maxSize", null);
3572         }
3573         focusCycleRoot = f.get("focusCycleRoot", false);
3574         containerSerializedDataVersion = f.get("containerSerializedDataVersion", 1);
3575         focusTraversalPolicyProvider = f.get("focusTraversalPolicyProvider", false);
3576         java.util.List<Component> component = this.component;
3577         for(Component comp : component) {
3578             comp.parent = this;
3579             adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
3580                                     comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
3581             adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3582                                     comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
3583             adjustDescendants(comp.countHierarchyMembers());
3584         }
3585 
3586         Object keyOrNull;
3587         while(null != (keyOrNull = s.readObject())) {
3588             String key = ((String)keyOrNull).intern();
3589 
3590             if (containerListenerK == key) {
3591                 addContainerListener((ContainerListener)(s.readObject()));
3592             } else {
3593                 // skip value for unrecognized key
3594                 s.readObject();
3595             }
3596         }
3597 
3598         try {
3599             Object policy = s.readObject();
3600             if (policy instanceof FocusTraversalPolicy) {
3601                 focusTraversalPolicy = (FocusTraversalPolicy)policy;
3602             }
3603         } catch (java.io.OptionalDataException e) {
3604             // JDK 1.1/1.2/1.3 instances will not have this optional data.
3605             // e.eof will be true to indicate that there is no more data
3606             // available for this object. If e.eof is not true, throw the
3607             // exception as it might have been caused by reasons unrelated to
3608             // focusTraversalPolicy.
3609 
3610             if (!e.eof) {
3611                 throw e;
3612             }
3613         }
3614     }
3615 
3616     /*
3617      * --- Accessibility Support ---
3618      */
3619 
3620     /**
3621      * Inner class of Container used to provide default support for
3622      * accessibility.  This class is not meant to be used directly by
3623      * application developers, but is instead meant only to be
3624      * subclassed by container developers.
3625      * <p>
3626      * The class used to obtain the accessible role for this object,
3627      * as well as implementing many of the methods in the
3628      * AccessibleContainer interface.
3629      * @since 1.3
3630      */
3631     protected class AccessibleAWTContainer extends AccessibleAWTComponent {
3632 
3633         /**
3634          * JDK1.3 serialVersionUID
3635          */
3636         private static final long serialVersionUID = 5081320404842566097L;
3637 
3638         /**
3639          * Returns the number of accessible children in the object.  If all
3640          * of the children of this object implement <code>Accessible</code>,
3641          * then this method should return the number of children of this object.
3642          *
3643          * @return the number of accessible children in the object
3644          */
3645         public int getAccessibleChildrenCount() {
3646             return Container.this.getAccessibleChildrenCount();
3647         }
3648 
3649         /**
3650          * Returns the nth <code>Accessible</code> child of the object.
3651          *
3652          * @param i zero-based index of child
3653          * @return the nth <code>Accessible</code> child of the object
3654          */
3655         public Accessible getAccessibleChild(int i) {
3656             return Container.this.getAccessibleChild(i);
3657         }
3658 
3659         /**
3660          * Returns the <code>Accessible</code> child, if one exists,
3661          * contained at the local coordinate <code>Point</code>.
3662          *
3663          * @param p the point defining the top-left corner of the
3664          *    <code>Accessible</code>, given in the coordinate space
3665          *    of the object's parent
3666          * @return the <code>Accessible</code>, if it exists,
3667          *    at the specified location; else <code>null</code>
3668          */
3669         public Accessible getAccessibleAt(Point p) {
3670             return Container.this.getAccessibleAt(p);
3671         }
3672 
3673         protected ContainerListener accessibleContainerHandler = null;
3674 
3675         /**
3676          * Fire <code>PropertyChange</code> listener, if one is registered,
3677          * when children are added or removed.
3678          * @since 1.3
3679          */
3680         protected class AccessibleContainerHandler
3681             implements ContainerListener {
3682             public void componentAdded(ContainerEvent e) {
3683                 Component c = e.getChild();
3684                 if (c != null && c instanceof Accessible) {
3685                     AccessibleAWTContainer.this.firePropertyChange(
3686                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3687                         null, ((Accessible) c).getAccessibleContext());
3688                 }
3689             }
3690             public void componentRemoved(ContainerEvent e) {
3691                 Component c = e.getChild();
3692                 if (c != null && c instanceof Accessible) {
3693                     AccessibleAWTContainer.this.firePropertyChange(
3694                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3695                         ((Accessible) c).getAccessibleContext(), null);
3696                 }
3697             }
3698         }
3699 
3700         /**
3701          * Adds a PropertyChangeListener to the listener list.
3702          *
3703          * @param listener  the PropertyChangeListener to be added
3704          */
3705         public void addPropertyChangeListener(PropertyChangeListener listener) {
3706             if (accessibleContainerHandler == null) {
3707                 accessibleContainerHandler = new AccessibleContainerHandler();
3708                 Container.this.addContainerListener(accessibleContainerHandler);
3709             }
3710             super.addPropertyChangeListener(listener);
3711         }
3712 
3713     } // inner class AccessibleAWTContainer
3714 
3715     /**
3716      * Returns the <code>Accessible</code> child contained at the local
3717      * coordinate <code>Point</code>, if one exists.  Otherwise
3718      * returns <code>null</code>.
3719      *
3720      * @param p the point defining the top-left corner of the
3721      *    <code>Accessible</code>, given in the coordinate space
3722      *    of the object's parent
3723      * @return the <code>Accessible</code> at the specified location,
3724      *    if it exists; otherwise <code>null</code>
3725      */
3726     Accessible getAccessibleAt(Point p) {
3727         synchronized (getTreeLock()) {
3728             if (this instanceof Accessible) {
3729                 Accessible a = (Accessible)this;
3730                 AccessibleContext ac = a.getAccessibleContext();
3731                 if (ac != null) {
3732                     AccessibleComponent acmp;
3733                     Point location;
3734                     int nchildren = ac.getAccessibleChildrenCount();
3735                     for (int i=0; i < nchildren; i++) {
3736                         a = ac.getAccessibleChild(i);
3737                         if ((a != null)) {
3738                             ac = a.getAccessibleContext();
3739                             if (ac != null) {
3740                                 acmp = ac.getAccessibleComponent();
3741                                 if ((acmp != null) && (acmp.isShowing())) {
3742                                     location = acmp.getLocation();
3743                                     Point np = new Point(p.x-location.x,
3744                                                          p.y-location.y);
3745                                     if (acmp.contains(np)){
3746                                         return a;
3747                                     }
3748                                 }
3749                             }
3750                         }
3751                     }
3752                 }
3753                 return (Accessible)this;
3754             } else {
3755                 Component ret = this;
3756                 if (!this.contains(p.x,p.y)) {
3757                     ret = null;
3758                 } else {
3759                     int ncomponents = this.getComponentCount();
3760                     for (int i=0; i < ncomponents; i++) {
3761                         Component comp = this.getComponent(i);
3762                         if ((comp != null) && comp.isShowing()) {
3763                             Point location = comp.getLocation();
3764                             if (comp.contains(p.x-location.x,p.y-location.y)) {
3765                                 ret = comp;
3766                             }
3767                         }
3768                     }
3769                 }
3770                 if (ret instanceof Accessible) {
3771                     return (Accessible) ret;
3772                 }
3773             }
3774             return null;
3775         }
3776     }
3777 
3778     /**
3779      * Returns the number of accessible children in the object.  If all
3780      * of the children of this object implement <code>Accessible</code>,
3781      * then this method should return the number of children of this object.
3782      *
3783      * @return the number of accessible children in the object
3784      */
3785     int getAccessibleChildrenCount() {
3786         synchronized (getTreeLock()) {
3787             int count = 0;
3788             Component[] children = this.getComponents();
3789             for (int i = 0; i < children.length; i++) {
3790                 if (children[i] instanceof Accessible) {
3791                     count++;
3792                 }
3793             }
3794             return count;
3795         }
3796     }
3797 
3798     /**
3799      * Returns the nth <code>Accessible</code> child of the object.
3800      *
3801      * @param i zero-based index of child
3802      * @return the nth <code>Accessible</code> child of the object
3803      */
3804     Accessible getAccessibleChild(int i) {
3805         synchronized (getTreeLock()) {
3806             Component[] children = this.getComponents();
3807             int count = 0;
3808             for (int j = 0; j < children.length; j++) {
3809                 if (children[j] instanceof Accessible) {
3810                     if (count == i) {
3811                         return (Accessible) children[j];
3812                     } else {
3813                         count++;
3814                     }
3815                 }
3816             }
3817             return null;
3818         }
3819     }
3820 
3821     // ************************** MIXING CODE *******************************
3822 
3823     final void increaseComponentCount(Component c) {
3824         synchronized (getTreeLock()) {
3825             if (!c.isDisplayable()) {
3826                 throw new IllegalStateException(
3827                     "Peer does not exist while invoking the increaseComponentCount() method"
3828                 );
3829             }
3830 
3831             int addHW = 0;
3832             int addLW = 0;
3833 
3834             if (c instanceof Container) {
3835                 addLW = ((Container)c).numOfLWComponents;
3836                 addHW = ((Container)c).numOfHWComponents;
3837             }
3838             if (c.isLightweight()) {
3839                 addLW++;
3840             } else {
3841                 addHW++;
3842             }
3843 
3844             for (Container cont = this; cont != null; cont = cont.getContainer()) {
3845                 cont.numOfLWComponents += addLW;
3846                 cont.numOfHWComponents += addHW;
3847             }
3848         }
3849     }
3850 
3851     final void decreaseComponentCount(Component c) {
3852         synchronized (getTreeLock()) {
3853             if (!c.isDisplayable()) {
3854                 throw new IllegalStateException(
3855                     "Peer does not exist while invoking the decreaseComponentCount() method"
3856                 );
3857             }
3858 
3859             int subHW = 0;
3860             int subLW = 0;
3861 
3862             if (c instanceof Container) {
3863                 subLW = ((Container)c).numOfLWComponents;
3864                 subHW = ((Container)c).numOfHWComponents;
3865             }
3866             if (c.isLightweight()) {
3867                 subLW++;
3868             } else {
3869                 subHW++;
3870             }
3871 
3872             for (Container cont = this; cont != null; cont = cont.getContainer()) {
3873                 cont.numOfLWComponents -= subLW;
3874                 cont.numOfHWComponents -= subHW;
3875             }
3876         }
3877     }
3878 
3879     private int getTopmostComponentIndex() {
3880         checkTreeLock();
3881         if (getComponentCount() > 0) {
3882             return 0;
3883         }
3884         return -1;
3885     }
3886 
3887     private int getBottommostComponentIndex() {
3888         checkTreeLock();
3889         if (getComponentCount() > 0) {
3890             return getComponentCount() - 1;
3891         }
3892         return -1;
3893     }
3894 
3895     /*
3896      * This method is overriden to handle opaque children in non-opaque
3897      * containers.
3898      */
3899     @Override
3900     final Region getOpaqueShape() {
3901         checkTreeLock();
3902         if (isLightweight() && isNonOpaqueForMixing()
3903                 && hasLightweightDescendants())
3904         {
3905             Region s = Region.EMPTY_REGION;
3906             for (int index = 0; index < getComponentCount(); index++) {
3907                 Component c = getComponent(index);
3908                 if (c.isLightweight() && c.isShowing()) {
3909                     s = s.getUnion(c.getOpaqueShape());
3910                 }
3911             }
3912             return s.getIntersection(getNormalShape());
3913         }
3914         return super.getOpaqueShape();
3915     }
3916 
3917     final void recursiveSubtractAndApplyShape(Region shape) {
3918         recursiveSubtractAndApplyShape(shape, getTopmostComponentIndex(), getBottommostComponentIndex());
3919     }
3920 
3921     final void recursiveSubtractAndApplyShape(Region shape, int fromZorder) {
3922         recursiveSubtractAndApplyShape(shape, fromZorder, getBottommostComponentIndex());
3923     }
3924 
3925     final void recursiveSubtractAndApplyShape(Region shape, int fromZorder, int toZorder) {
3926         checkTreeLock();
3927         if (mixingLog.isLoggable(Level.FINE)) {
3928             mixingLog.fine("this = " + this +
3929                 "; shape=" + shape + "; fromZ=" + fromZorder + "; toZ=" + toZorder);
3930         }
3931         if (fromZorder == -1) {
3932             return;
3933         }
3934         if (shape.isEmpty()) {
3935             return;
3936         }
3937         // An invalid container with not-null layout should be ignored
3938         // by the mixing code, the container will be validated later
3939         // and the mixing code will be executed later.
3940         if (getLayout() != null && !isValid()) {
3941             return;
3942         }
3943         for (int index = fromZorder; index <= toZorder; index++) {
3944             Component comp = getComponent(index);
3945             if (!comp.isLightweight()) {
3946                 comp.subtractAndApplyShape(shape);
3947             } else if (comp instanceof Container &&
3948                     ((Container)comp).hasHeavyweightDescendants() && comp.isShowing()) {
3949                 ((Container)comp).recursiveSubtractAndApplyShape(shape);
3950             }
3951         }
3952     }
3953 
3954     final void recursiveApplyCurrentShape() {
3955         recursiveApplyCurrentShape(getTopmostComponentIndex(), getBottommostComponentIndex());
3956     }
3957 
3958     final void recursiveApplyCurrentShape(int fromZorder) {
3959         recursiveApplyCurrentShape(fromZorder, getBottommostComponentIndex());
3960     }
3961 
3962     final void recursiveApplyCurrentShape(int fromZorder, int toZorder) {
3963         checkTreeLock();
3964         if (mixingLog.isLoggable(Level.FINE)) {
3965             mixingLog.fine("this = " + this +
3966                 "; fromZ=" + fromZorder + "; toZ=" + toZorder);
3967         }
3968         if (fromZorder == -1) {
3969             return;
3970         }
3971         // An invalid container with not-null layout should be ignored
3972         // by the mixing code, the container will be validated later
3973         // and the mixing code will be executed later.
3974         if (getLayout() != null && !isValid()) {
3975             return;
3976         }
3977         for (int index = fromZorder; index <= toZorder; index++) {
3978             Component comp = getComponent(index);
3979             if (!comp.isLightweight()) {
3980                 comp.applyCurrentShape();
3981             }
3982             if (comp instanceof Container &&
3983                     ((Container)comp).hasHeavyweightDescendants()) {
3984                 ((Container)comp).recursiveApplyCurrentShape();
3985             }
3986         }
3987     }
3988 
3989     private void recursiveShowHeavyweightChildren() {
3990         if (!hasHeavyweightDescendants() || !isVisible()) {
3991             return;
3992         }
3993         for (int index = 0; index < getComponentCount(); index++) {
3994             Component comp = getComponent(index);
3995             if (comp.isLightweight()) {
3996                 if  (comp instanceof Container) {
3997                     ((Container)comp).recursiveShowHeavyweightChildren();
3998                 }
3999             } else {
4000                 if (comp.isVisible()) {
4001                     ComponentPeer peer = comp.getPeer();
4002                     if (peer != null) {
4003                         peer.setVisible(true);
4004                     }
4005                 }
4006             }
4007         }
4008     }
4009 
4010     private void recursiveHideHeavyweightChildren() {
4011         if (!hasHeavyweightDescendants()) {
4012             return;
4013         }
4014         for (int index = 0; index < getComponentCount(); index++) {
4015             Component comp = getComponent(index);
4016             if (comp.isLightweight()) {
4017                 if  (comp instanceof Container) {
4018                     ((Container)comp).recursiveHideHeavyweightChildren();
4019                 }
4020             } else {
4021                 if (comp.isVisible()) {
4022                     ComponentPeer peer = comp.getPeer();
4023                     if (peer != null) {
4024                         peer.setVisible(false);
4025                     }
4026                 }
4027             }
4028         }
4029     }
4030 
4031     private void recursiveRelocateHeavyweightChildren(Point origin) {
4032         for (int index = 0; index < getComponentCount(); index++) {
4033             Component comp = getComponent(index);
4034             if (comp.isLightweight()) {
4035                 if  (comp instanceof Container &&
4036                         ((Container)comp).hasHeavyweightDescendants())
4037                 {
4038                     final Point newOrigin = new Point(origin);
4039                     newOrigin.translate(comp.getX(), comp.getY());
4040                     ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
4041                 }
4042             } else {
4043                 ComponentPeer peer = comp.getPeer();
4044                 if (peer != null) {
4045                     peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
4046                             comp.getWidth(), comp.getHeight(),
4047                             ComponentPeer.SET_LOCATION);
4048                 }
4049             }
4050         }
4051     }
4052 
4053     /*
4054      * Consider the heavyweight container hides or shows the HW descendants
4055      * automatically. Therefore we care of LW containers' visibility only.
4056      */
4057     private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
4058         if (!isLightweight()) {
4059             return true;
4060         }
4061         return isVisible() && (getContainer() == null ||
4062              getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
4063     }
4064 
4065     @Override
4066     void mixOnShowing() {
4067         synchronized (getTreeLock()) {
4068             if (mixingLog.isLoggable(Level.FINE)) {
4069                 mixingLog.fine("this = " + this);
4070             }
4071 
4072             if (!isMixingNeeded()) {
4073                 return;
4074             }
4075 
4076             boolean isLightweight = isLightweight();
4077 
4078             if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
4079                 recursiveShowHeavyweightChildren();
4080             }
4081 
4082             if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
4083                 recursiveApplyCurrentShape();
4084             }
4085 
4086             super.mixOnShowing();
4087         }
4088     }
4089 
4090     @Override
4091     void mixOnHiding(boolean isLightweight) {
4092         synchronized (getTreeLock()) {
4093             if (mixingLog.isLoggable(Level.FINE)) {
4094                 mixingLog.fine("this = " + this +
4095                         "; isLightweight=" + isLightweight);
4096             }
4097             if (isLightweight) {
4098                 recursiveHideHeavyweightChildren();
4099             }
4100             super.mixOnHiding(isLightweight);
4101         }
4102     }
4103 
4104     @Override
4105     void mixOnReshaping() {
4106         synchronized (getTreeLock()) {
4107             if (mixingLog.isLoggable(Level.FINE)) {
4108                 mixingLog.fine("this = " + this);
4109             }
4110 
4111             boolean isMixingNeeded = isMixingNeeded();
4112 
4113             if (isLightweight() && hasHeavyweightDescendants()) {
4114                 final Point origin = new Point(getX(), getY());
4115                 for (Container cont = getContainer();
4116                         cont != null && cont.isLightweight();
4117                         cont = cont.getContainer())
4118                 {
4119                     origin.translate(cont.getX(), cont.getY());
4120                 }
4121 
4122                 recursiveRelocateHeavyweightChildren(origin);
4123 
4124                 if (!isMixingNeeded) {
4125                     return;
4126                 }
4127 
4128                 recursiveApplyCurrentShape();
4129             }
4130 
4131             if (!isMixingNeeded) {
4132                 return;
4133             }
4134 
4135             super.mixOnReshaping();
4136         }
4137     }
4138 
4139     @Override
4140     void mixOnZOrderChanging(int oldZorder, int newZorder) {
4141         synchronized (getTreeLock()) {
4142             if (mixingLog.isLoggable(Level.FINE)) {
4143                 mixingLog.fine("this = " + this +
4144                     "; oldZ=" + oldZorder + "; newZ=" + newZorder);
4145             }
4146 
4147             if (!isMixingNeeded()) {
4148                 return;
4149             }
4150 
4151             boolean becameHigher = newZorder < oldZorder;
4152 
4153             if (becameHigher && isLightweight() && hasHeavyweightDescendants()) {
4154                 recursiveApplyCurrentShape();
4155             }
4156             super.mixOnZOrderChanging(oldZorder, newZorder);
4157         }
4158     }
4159 
4160     @Override
4161     void mixOnValidating() {
4162         synchronized (getTreeLock()) {
4163             if (mixingLog.isLoggable(Level.FINE)) {
4164                 mixingLog.fine("this = " + this);
4165             }
4166 
4167             if (!isMixingNeeded()) {
4168                 return;
4169             }
4170 
4171             if (hasHeavyweightDescendants()) {
4172                 recursiveApplyCurrentShape();
4173             }
4174 
4175             if (isLightweight() && isNonOpaqueForMixing()) {
4176                 subtractAndApplyShapeBelowMe();
4177             }
4178 
4179             super.mixOnValidating();
4180         }
4181     }
4182 
4183     // ****************** END OF MIXING CODE ********************************
4184 }
4185 
4186 
4187 /**
4188  * Class to manage the dispatching of MouseEvents to the lightweight descendants
4189  * and SunDropTargetEvents to both lightweight and heavyweight descendants
4190  * contained by a native container.
4191  *
4192  * NOTE: the class name is not appropriate anymore, but we cannot change it
4193  * because we must keep serialization compatibility.
4194  *
4195  * @author Timothy Prinzing
4196  */
4197 class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
4198 
4199     /*
4200      * JDK 1.1 serialVersionUID
4201      */
4202     private static final long serialVersionUID = 5184291520170872969L;
4203     /*
4204      * Our own mouse event for when we're dragged over from another hw
4205      * container
4206      */
4207     private static final int  LWD_MOUSE_DRAGGED_OVER = 1500;
4208 
4209     private static final Logger eventLog = Logger.getLogger("java.awt.event.LightweightDispatcher");
4210 
4211     LightweightDispatcher(Container nativeContainer) {
4212         this.nativeContainer = nativeContainer;
4213         mouseEventTarget = null;
4214         eventMask = 0;
4215     }
4216 
4217     /*
4218      * Clean up any resources allocated when dispatcher was created;
4219      * should be called from Container.removeNotify
4220      */
4221     void dispose() {
4222         //System.out.println("Disposing lw dispatcher");
4223         stopListeningForOtherDrags();
4224         mouseEventTarget = null;
4225     }
4226 
4227     /**
4228      * Enables events to subcomponents.
4229      */
4230     void enableEvents(long events) {
4231         eventMask |= events;
4232     }
4233 
4234     /**
4235      * Dispatches an event to a sub-component if necessary, and
4236      * returns whether or not the event was forwarded to a
4237      * sub-component.
4238      *
4239      * @param e the event
4240      */
4241     boolean dispatchEvent(AWTEvent e) {
4242         boolean ret = false;
4243 
4244         /*
4245          * Fix for BugTraq Id 4389284.
4246          * Dispatch SunDropTargetEvents regardless of eventMask value.
4247          * Do not update cursor on dispatching SunDropTargetEvents.
4248          */
4249         if (e instanceof SunDropTargetEvent) {
4250 
4251             SunDropTargetEvent sdde = (SunDropTargetEvent) e;
4252             ret = processDropTargetEvent(sdde);
4253 
4254         } else {
4255             if (e instanceof MouseEvent && (eventMask & MOUSE_MASK) != 0) {
4256                 MouseEvent me = (MouseEvent) e;
4257                 ret = processMouseEvent(me);
4258             }
4259 
4260             if (e.getID() == MouseEvent.MOUSE_MOVED) {
4261                 nativeContainer.updateCursorImmediately();
4262             }
4263         }
4264 
4265         return ret;
4266     }
4267 
4268     /* This method effectively returns whether or not a mouse button was down
4269      * just BEFORE the event happened.  A better method name might be
4270      * wasAMouseButtonDownBeforeThisEvent().
4271      */
4272     private boolean isMouseGrab(MouseEvent e) {
4273         int modifiers = e.getModifiersEx();
4274 
4275         if(e.getID() == MouseEvent.MOUSE_PRESSED
4276             || e.getID() == MouseEvent.MOUSE_RELEASED)
4277         {
4278             switch (e.getButton()) {
4279             case MouseEvent.BUTTON1:
4280                 modifiers ^= InputEvent.BUTTON1_DOWN_MASK;
4281                 break;
4282             case MouseEvent.BUTTON2:
4283                 modifiers ^= InputEvent.BUTTON2_DOWN_MASK;
4284                 break;
4285             case MouseEvent.BUTTON3:
4286                 modifiers ^= InputEvent.BUTTON3_DOWN_MASK;
4287                 break;
4288             }
4289         }
4290         /* modifiers now as just before event */
4291         return ((modifiers & (InputEvent.BUTTON1_DOWN_MASK
4292                               | InputEvent.BUTTON2_DOWN_MASK
4293                               | InputEvent.BUTTON3_DOWN_MASK)) != 0);
4294     }
4295 
4296     /**
4297      * This method attempts to distribute a mouse event to a lightweight
4298      * component.  It tries to avoid doing any unnecessary probes down
4299      * into the component tree to minimize the overhead of determining
4300      * where to route the event, since mouse movement events tend to
4301      * come in large and frequent amounts.
4302      */
4303     private boolean processMouseEvent(MouseEvent e) {
4304         int id = e.getID();
4305         Component mouseOver =   // sensitive to mouse events
4306             nativeContainer.getMouseEventTarget(e.getX(), e.getY(),
4307                                                 Container.INCLUDE_SELF);
4308 
4309         trackMouseEnterExit(mouseOver, e);
4310 
4311     // 4508327 : MOUSE_CLICKED should only go to the recipient of
4312     // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
4313     // MOUSE_CLICKED.
4314     if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
4315             mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
4316         }
4317 
4318         if (mouseEventTarget != null) {
4319             switch (id) {
4320             case MouseEvent.MOUSE_ENTERED:
4321             case MouseEvent.MOUSE_EXITED:
4322                 break;
4323             case MouseEvent.MOUSE_PRESSED:
4324                 retargetMouseEvent(mouseEventTarget, id, e);
4325                 break;
4326         case MouseEvent.MOUSE_RELEASED:
4327             retargetMouseEvent(mouseEventTarget, id, e);
4328         break;
4329         case MouseEvent.MOUSE_CLICKED:
4330         // 4508327: MOUSE_CLICKED should never be dispatched to a Component
4331         // other than that which received the MOUSE_PRESSED event.  If the
4332         // mouse is now over a different Component, don't dispatch the event.
4333         // The previous fix for a similar problem was associated with bug
4334         // 4155217.
4335         if (mouseOver == mouseEventTarget) {
4336             retargetMouseEvent(mouseOver, id, e);
4337         }
4338         break;
4339             case MouseEvent.MOUSE_MOVED:
4340                 retargetMouseEvent(mouseEventTarget, id, e);
4341                 break;
4342         case MouseEvent.MOUSE_DRAGGED:
4343             if (isMouseGrab(e)) {
4344                 retargetMouseEvent(mouseEventTarget, id, e);
4345             }
4346                 break;
4347         case MouseEvent.MOUSE_WHEEL:
4348             // This may send it somewhere that doesn't have MouseWheelEvents
4349             // enabled.  In this case, Component.dispatchEventImpl() will
4350             // retarget the event to a parent that DOES have the events enabled.
4351             if (eventLog.isLoggable(Level.FINEST) && (mouseOver != null)) {
4352                 eventLog.log(Level.FINEST, "retargeting mouse wheel to " +
4353                              mouseOver.getName() + ", " +
4354                              mouseOver.getClass());
4355             }
4356             retargetMouseEvent(mouseOver, id, e);
4357         break;
4358             }
4359             e.consume();
4360     }
4361     return e.isConsumed();
4362     }
4363 
4364     private boolean processDropTargetEvent(SunDropTargetEvent e) {
4365         int id = e.getID();
4366         int x = e.getX();
4367         int y = e.getY();
4368 
4369         /*
4370          * Fix for BugTraq ID 4395290.
4371          * It is possible that SunDropTargetEvent's Point is outside of the
4372          * native container bounds. In this case we truncate coordinates.
4373          */
4374         if (!nativeContainer.contains(x, y)) {
4375             final Dimension d = nativeContainer.getSize();
4376             if (d.width <= x) {
4377                 x = d.width - 1;
4378             } else if (x < 0) {
4379                 x = 0;
4380             }
4381             if (d.height <= y) {
4382                 y = d.height - 1;
4383             } else if (y < 0) {
4384                 y = 0;
4385             }
4386         }
4387         Component mouseOver =   // not necessarily sensitive to mouse events
4388             nativeContainer.getDropTargetEventTarget(x, y,
4389                                                      Container.INCLUDE_SELF);
4390         trackMouseEnterExit(mouseOver, e);
4391 
4392         if (mouseOver != nativeContainer && mouseOver != null) {
4393             switch (id) {
4394             case SunDropTargetEvent.MOUSE_ENTERED:
4395             case SunDropTargetEvent.MOUSE_EXITED:
4396                 break;
4397             default:
4398                 retargetMouseEvent(mouseOver, id, e);
4399                 e.consume();
4400                 break;
4401             }
4402         }
4403         return e.isConsumed();
4404     }
4405 
4406     /*
4407      * Generates enter/exit events as mouse moves over lw components
4408      * @param targetOver        Target mouse is over (including native container)
4409      * @param e                 Mouse event in native container
4410      */
4411     private void trackMouseEnterExit(Component targetOver, MouseEvent e) {
4412         Component       targetEnter = null;
4413         int             id = e.getID();
4414 
4415         if (e instanceof SunDropTargetEvent &&
4416             id == MouseEvent.MOUSE_ENTERED &&
4417             isMouseInNativeContainer == true) {
4418             // This can happen if a lightweight component which initiated the
4419             // drag has an associated drop target. MOUSE_ENTERED comes when the
4420             // mouse is in the native container already. To propagate this event
4421             // properly we should null out targetLastEntered.
4422             targetLastEntered = null;
4423         } else if ( id != MouseEvent.MOUSE_EXITED &&
4424              id != MouseEvent.MOUSE_DRAGGED &&
4425              id != LWD_MOUSE_DRAGGED_OVER &&
4426              isMouseInNativeContainer == false ) {
4427             // any event but an exit or drag means we're in the native container
4428             isMouseInNativeContainer = true;
4429             startListeningForOtherDrags();
4430         } else if ( id == MouseEvent.MOUSE_EXITED ) {
4431             isMouseInNativeContainer = false;
4432             stopListeningForOtherDrags();
4433         }
4434 
4435         if (isMouseInNativeContainer) {
4436             targetEnter = targetOver;
4437         }
4438 
4439         if (targetLastEntered == targetEnter) {
4440                 return;
4441         }
4442 
4443         if (targetLastEntered != null) {
4444             retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED, e);
4445         }
4446         if (id == MouseEvent.MOUSE_EXITED) {
4447             // consume native exit event if we generate one
4448             e.consume();
4449         }
4450 
4451         if (targetEnter != null) {
4452             retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
4453         }
4454         if (id == MouseEvent.MOUSE_ENTERED) {
4455             // consume native enter event if we generate one
4456             e.consume();
4457         }
4458 
4459         targetLastEntered = targetEnter;
4460     }
4461 
4462     /*
4463      * Listens to global mouse drag events so even drags originating
4464      * from other heavyweight containers will generate enter/exit
4465      * events in this container
4466      */
4467     private void startListeningForOtherDrags() {
4468         //System.out.println("Adding AWTEventListener");
4469         java.security.AccessController.doPrivileged(
4470             new java.security.PrivilegedAction() {
4471                 public Object run() {
4472                     nativeContainer.getToolkit().addAWTEventListener(
4473                         LightweightDispatcher.this,
4474                         AWTEvent.MOUSE_EVENT_MASK |
4475                         AWTEvent.MOUSE_MOTION_EVENT_MASK);
4476                     return null;
4477                 }
4478             }
4479         );
4480     }
4481 
4482     private void stopListeningForOtherDrags() {
4483         //System.out.println("Removing AWTEventListener");
4484         java.security.AccessController.doPrivileged(
4485             new java.security.PrivilegedAction() {
4486                 public Object run() {
4487                     nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this);
4488                     return null;
4489                 }
4490             }
4491         );
4492     }
4493 
4494     /*
4495      * (Implementation of AWTEventListener)
4496      * Listen for drag events posted in other hw components so we can
4497      * track enter/exit regardless of where a drag originated
4498      */
4499     public void eventDispatched(AWTEvent e) {
4500         boolean isForeignDrag = (e instanceof MouseEvent) &&
4501                                 !(e instanceof SunDropTargetEvent) &&
4502                                 (e.id == MouseEvent.MOUSE_DRAGGED) &&
4503                                 (e.getSource() != nativeContainer);
4504 
4505         if (!isForeignDrag) {
4506             // only interested in drags from other hw components
4507             return;
4508         }
4509 
4510         MouseEvent      srcEvent = (MouseEvent)e;
4511         MouseEvent      me;
4512 
4513         synchronized (nativeContainer.getTreeLock()) {
4514             Component srcComponent = srcEvent.getComponent();
4515 
4516             // component may have disappeared since drag event posted
4517             // (i.e. Swing hierarchical menus)
4518             if ( !srcComponent.isShowing() ) {
4519                 return;
4520             }
4521 
4522             // see 5083555
4523             // check if srcComponent is in any modal blocked window
4524             Component c = nativeContainer;
4525             while ((c != null) && !(c instanceof Window)) {
4526                 c = c.getParent_NoClientCode();
4527             }
4528             if ((c == null) || ((Window)c).isModalBlocked()) {
4529                 return;
4530             }
4531 
4532             //
4533             // create an internal 'dragged-over' event indicating
4534             // we are being dragged over from another hw component
4535             //
4536             me = new MouseEvent(nativeContainer,
4537                                LWD_MOUSE_DRAGGED_OVER,
4538                                srcEvent.getWhen(),
4539                                srcEvent.getModifiersEx() | srcEvent.getModifiers(),
4540                                srcEvent.getX(),
4541                                srcEvent.getY(),
4542                                srcEvent.getXOnScreen(),
4543                                srcEvent.getYOnScreen(),
4544                                srcEvent.getClickCount(),
4545                                srcEvent.isPopupTrigger(),
4546                                srcEvent.getButton());
4547             ((AWTEvent)srcEvent).copyPrivateDataInto(me);
4548             // translate coordinates to this native container
4549             final Point ptSrcOrigin = srcComponent.getLocationOnScreen();
4550 
4551             if (AppContext.getAppContext() != nativeContainer.appContext) {
4552                 final MouseEvent mouseEvent = me;
4553                 Runnable r = new Runnable() {
4554                         public void run() {
4555                             if (!nativeContainer.isShowing() ) {
4556                                 return;
4557                             }
4558 
4559                             Point       ptDstOrigin = nativeContainer.getLocationOnScreen();
4560                             mouseEvent.translatePoint(ptSrcOrigin.x - ptDstOrigin.x,
4561                                               ptSrcOrigin.y - ptDstOrigin.y );
4562                             Component targetOver =
4563                                 nativeContainer.getMouseEventTarget(mouseEvent.getX(),
4564                                                                     mouseEvent.getY(),
4565                                                                     Container.INCLUDE_SELF);
4566                             trackMouseEnterExit(targetOver, mouseEvent);
4567                         }
4568                     };
4569                 SunToolkit.executeOnEventHandlerThread(nativeContainer, r);
4570                 return;
4571             } else {
4572                 if (!nativeContainer.isShowing() ) {
4573                     return;
4574                 }
4575 
4576                 Point   ptDstOrigin = nativeContainer.getLocationOnScreen();
4577                 me.translatePoint( ptSrcOrigin.x - ptDstOrigin.x, ptSrcOrigin.y - ptDstOrigin.y );
4578             }
4579         }
4580         //System.out.println("Track event: " + me);
4581         // feed the 'dragged-over' event directly to the enter/exit
4582         // code (not a real event so don't pass it to dispatchEvent)
4583         Component targetOver =
4584             nativeContainer.getMouseEventTarget(me.getX(), me.getY(),
4585                                                 Container.INCLUDE_SELF);
4586         trackMouseEnterExit(targetOver, me);
4587     }
4588 
4589     /**
4590      * Sends a mouse event to the current mouse event recipient using
4591      * the given event (sent to the windowed host) as a srcEvent.  If
4592      * the mouse event target is still in the component tree, the
4593      * coordinates of the event are translated to those of the target.
4594      * If the target has been removed, we don't bother to send the
4595      * message.
4596      */
4597     void retargetMouseEvent(Component target, int id, MouseEvent e) {
4598         if (target == null) {
4599             return; // mouse is over another hw component or target is disabled
4600         }
4601 
4602         int x = e.getX(), y = e.getY();
4603         Component component;
4604 
4605         for(component = target;
4606             component != null && component != nativeContainer;
4607             component = component.getParent()) {
4608             x -= component.x;
4609             y -= component.y;
4610         }
4611         MouseEvent retargeted;
4612         if (component != null) {
4613             if (e instanceof SunDropTargetEvent) {
4614                 retargeted = new SunDropTargetEvent(target,
4615                                                     id,
4616                                                     x,
4617                                                     y,
4618                                                     ((SunDropTargetEvent)e).getDispatcher());
4619             } else if (id == MouseEvent.MOUSE_WHEEL) {
4620                 retargeted = new MouseWheelEvent(target,
4621                                       id,
4622                                        e.getWhen(),
4623                                        e.getModifiersEx() | e.getModifiers(),
4624                                        x,
4625                                        y,
4626                                        e.getXOnScreen(),
4627                                        e.getYOnScreen(),
4628                                        e.getClickCount(),
4629                                        e.isPopupTrigger(),
4630                                        ((MouseWheelEvent)e).getScrollType(),
4631                                        ((MouseWheelEvent)e).getScrollAmount(),
4632                                        ((MouseWheelEvent)e).getWheelRotation(),
4633                                        ((MouseWheelEvent)e).getPreciseWheelRotation());
4634             }
4635             else {
4636                 retargeted = new MouseEvent(target,
4637                                             id,
4638                                             e.getWhen(),
4639                                             e.getModifiersEx() | e.getModifiers(),
4640                                             x,
4641                                             y,
4642                                             e.getXOnScreen(),
4643                                             e.getYOnScreen(),
4644                                             e.getClickCount(),
4645                                             e.isPopupTrigger(),
4646                                             e.getButton());
4647             }
4648 
4649             ((AWTEvent)e).copyPrivateDataInto(retargeted);
4650 
4651             if (target == nativeContainer) {
4652                 // avoid recursively calling LightweightDispatcher...
4653                 ((Container)target).dispatchEventToSelf(retargeted);
4654             } else {
4655                 assert AppContext.getAppContext() == target.appContext;
4656 
4657                 if (nativeContainer.modalComp != null) {
4658                     if (((Container)nativeContainer.modalComp).isAncestorOf(target)) {
4659                         target.dispatchEvent(retargeted);
4660                     } else {
4661                         e.consume();
4662                     }
4663                 } else {
4664                     target.dispatchEvent(retargeted);
4665                 }
4666             }
4667         }
4668     }
4669 
4670     // --- member variables -------------------------------
4671 
4672     /**
4673      * The windowed container that might be hosting events for
4674      * subcomponents.
4675      */
4676     private Container nativeContainer;
4677 
4678     /**
4679      * This variable is not used, but kept for serialization compatibility
4680      */
4681     private Component focus;
4682 
4683     /**
4684      * The current subcomponent being hosted by this windowed
4685      * component that has events being forwarded to it.  If this
4686      * is null, there are currently no events being forwarded to
4687      * a subcomponent.
4688      */
4689     private transient Component mouseEventTarget;
4690 
4691     /**
4692      * The last component entered
4693      */
4694     private transient Component targetLastEntered;
4695 
4696     /**
4697      * Is the mouse over the native container
4698      */
4699     private transient boolean isMouseInNativeContainer = false;
4700 
4701     /**
4702      * This variable is not used, but kept for serialization compatibility
4703      */
4704     private Cursor nativeCursor;
4705 
4706     /**
4707      * The event mask for contained lightweight components.  Lightweight
4708      * components need a windowed container to host window-related
4709      * events.  This separate mask indicates events that have been
4710      * requested by contained lightweight components without effecting
4711      * the mask of the windowed component itself.
4712      */
4713     private long eventMask;
4714 
4715     /**
4716      * The kind of events routed to lightweight components from windowed
4717      * hosts.
4718      */
4719     private static final long PROXY_EVENT_MASK =
4720         AWTEvent.FOCUS_EVENT_MASK |
4721         AWTEvent.KEY_EVENT_MASK |
4722         AWTEvent.MOUSE_EVENT_MASK |
4723         AWTEvent.MOUSE_MOTION_EVENT_MASK |
4724         AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4725 
4726     private static final long MOUSE_MASK =
4727         AWTEvent.MOUSE_EVENT_MASK |
4728         AWTEvent.MOUSE_MOTION_EVENT_MASK |
4729         AWTEvent.MOUSE_WHEEL_EVENT_MASK;
4730 }