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