< prev index next >

src/java.desktop/share/classes/java/awt/Container.java

Print this page




 166     // True if there is at least one thread that's printing this component
 167     private transient boolean printing = false;
 168 
 169     transient ContainerListener containerListener;
 170 
 171     /* HierarchyListener and HierarchyBoundsListener support */
 172     transient int listeningChildren;
 173     transient int listeningBoundsChildren;
 174     transient int descendantsCount;
 175 
 176     /* Non-opaque window support -- see Window.setLayersOpaque */
 177     transient Color preserveBackgroundColor = null;
 178 
 179     /**
 180      * JDK 1.1 serialVersionUID
 181      */
 182     private static final long serialVersionUID = 4613797578919906343L;
 183 
 184     /**
 185      * A constant which toggles one of the controllable behaviors
 186      * of <code>getMouseEventTarget</code>. It is used to specify whether
 187      * the method can return the Container on which it is originally called
 188      * in case if none of its children are the current mouse event targets.
 189      *
 190      * @see #getMouseEventTarget(int, int, boolean)
 191      */
 192     static final boolean INCLUDE_SELF = true;
 193 
 194     /**
 195      * A constant which toggles one of the controllable behaviors
 196      * of <code>getMouseEventTarget</code>. It is used to specify whether
 197      * the method should search only lightweight components.
 198      *
 199      * @see #getMouseEventTarget(int, int, boolean)
 200      */
 201     static final boolean SEARCH_HEAVYWEIGHTS = true;
 202 
 203     /*
 204      * Number of HW or LW components in this container (including
 205      * all descendant containers).
 206      */
 207     private transient int numOfHWComponents = 0;
 208     private transient int numOfLWComponents = 0;
 209 
 210     private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Container");
 211 
 212     /**
 213      * @serialField ncomponents                     int
 214      *       The number of components in this container.
 215      *       This value can be null.
 216      * @serialField component                       Component[]


 367     //       This functionality is implemented in a package-private method
 368     //       to insure that it cannot be overridden by client subclasses.
 369     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 370     final Component[] getComponents_NoClientCode() {
 371         return component.toArray(EMPTY_ARRAY);
 372     }
 373 
 374     /*
 375      * Wrapper for getComponents() method with a proper synchronization.
 376      */
 377     Component[] getComponentsSync() {
 378         synchronized (getTreeLock()) {
 379             return getComponents();
 380         }
 381     }
 382 
 383     /**
 384      * Determines the insets of this container, which indicate the size
 385      * of the container's border.
 386      * <p>
 387      * A <code>Frame</code> object, for example, has a top inset that
 388      * corresponds to the height of the frame's title bar.
 389      * @return    the insets of this container.
 390      * @see       Insets
 391      * @see       LayoutManager
 392      * @since     1.1
 393      */
 394     public Insets getInsets() {
 395         return insets();
 396     }
 397 
 398     /**
 399      * Returns the insets for this container.
 400      *
 401      * @deprecated As of JDK version 1.1,
 402      * replaced by <code>getInsets()</code>.
 403      * @return the insets for this container
 404      */
 405     @Deprecated
 406     public Insets insets() {
 407         ComponentPeer peer = this.peer;
 408         if (peer instanceof ContainerPeer) {
 409             ContainerPeer cpeer = (ContainerPeer)peer;
 410             return (Insets)cpeer.getInsets().clone();
 411         }
 412         return new Insets(0, 0, 0, 0);
 413     }
 414 
 415     /**
 416      * Appends the specified component to the end of this container.
 417      * This is a convenience method for {@link #addImpl}.
 418      * <p>
 419      * This method changes layout-related information, and therefore,
 420      * invalidates the component hierarchy. If the container has already been
 421      * displayed, the hierarchy must be validated thereafter in order to
 422      * display the added component.
 423      *
 424      * @param     comp   the component to be added
 425      * @exception NullPointerException if {@code comp} is {@code null}
 426      * @see #addImpl
 427      * @see #invalidate
 428      * @see #validate
 429      * @see javax.swing.JComponent#revalidate()
 430      * @return    the component argument
 431      */
 432     public Component add(Component comp) {
 433         addImpl(comp, null, -1);
 434         return comp;
 435     }
 436 
 437     /**
 438      * Adds the specified component to this container.
 439      * This is a convenience method for {@link #addImpl}.
 440      * <p>
 441      * This method is obsolete as of 1.1.  Please use the
 442      * method <code>add(Component, Object)</code> instead.
 443      * <p>
 444      * This method changes layout-related information, and therefore,
 445      * invalidates the component hierarchy. If the container has already been
 446      * displayed, the hierarchy must be validated thereafter in order to
 447      * display the added component.
 448      *
 449      * @param  name the name of the component to be added
 450      * @param  comp the component to be added
 451      * @return the component added
 452      * @exception NullPointerException if {@code comp} is {@code null}
 453      * @see #add(Component, Object)
 454      * @see #invalidate
 455      */
 456     public Component add(String name, Component comp) {
 457         addImpl(comp, name, -1);
 458         return comp;
 459     }
 460 
 461     /**
 462      * Adds the specified component to this container at the given
 463      * position.
 464      * This is a convenience method for {@link #addImpl}.
 465      * <p>
 466      * This method changes layout-related information, and therefore,
 467      * invalidates the component hierarchy. If the container has already been
 468      * displayed, the hierarchy must be validated thereafter in order to
 469      * display the added component.
 470      *
 471      *
 472      * @param     comp   the component to be added
 473      * @param     index    the position at which to insert the component,
 474      *                   or <code>-1</code> to append the component to the end
 475      * @exception NullPointerException if {@code comp} is {@code null}
 476      * @exception IllegalArgumentException if {@code index} is invalid (see
 477      *            {@link #addImpl} for details)
 478      * @return    the component <code>comp</code>
 479      * @see #addImpl
 480      * @see #remove
 481      * @see #invalidate
 482      * @see #validate
 483      * @see javax.swing.JComponent#revalidate()
 484      */
 485     public Component add(Component comp, int index) {
 486         addImpl(comp, null, index);
 487         return comp;
 488     }
 489 
 490     /**
 491      * Checks that the component
 492      * isn't supposed to be added into itself.
 493      */
 494     private void checkAddToSelf(Component comp){
 495         if (comp instanceof Container) {
 496             for (Container cn = this; cn != null; cn=cn.parent) {
 497                 if (cn == comp) {
 498                     throw new IllegalArgumentException("adding container's parent to itself");


 515      * Checks :  index in bounds of container's size,
 516      * comp is not one of this container's parents,
 517      * and comp is not a window.
 518      * Comp and container must be on the same GraphicsDevice.
 519      * if comp is container, all sub-components must be on
 520      * same GraphicsDevice.
 521      *
 522      * @since 1.5
 523      */
 524     private void checkAdding(Component comp, int index) {
 525         checkTreeLock();
 526 
 527         GraphicsConfiguration thisGC = getGraphicsConfiguration();
 528 
 529         if (index > component.size() || index < 0) {
 530             throw new IllegalArgumentException("illegal component position");
 531         }
 532         if (comp.parent == this) {
 533             if (index == component.size()) {
 534                 throw new IllegalArgumentException("illegal component position " +
 535                                                    index + " should be less then " + component.size());
 536             }
 537         }
 538         checkAddToSelf(comp);
 539         checkNotAWindow(comp);
 540 
 541         Window thisTopLevel = getContainingWindow();
 542         Window compTopLevel = comp.getContainingWindow();
 543         if (thisTopLevel != compTopLevel) {
 544             throw new IllegalArgumentException("component and container should be in the same top-level window");
 545         }
 546         if (thisGC != null) {
 547             comp.checkGD(thisGC.getDevice().getIDstring());
 548         }
 549     }
 550 
 551     /**
 552      * Removes component comp from this container without making unnecessary changes
 553      * and generating unnecessary events. This function intended to perform optimized
 554      * remove, for example, if newParent and current parent are the same it just changes
 555      * index without calling removeNotify.


 717             // is quite rare. If we ever need to save the peers, we'll have to slightly change the
 718             // addDelicately() method in order to handle such LW containers recursively, reparenting
 719             // each HW descendant independently.
 720             return !comp.peer.isReparentSupported();
 721         } else {
 722             return false;
 723         }
 724     }
 725 
 726     /**
 727      * Moves the specified component to the specified z-order index in
 728      * the container. The z-order determines the order that components
 729      * are painted; the component with the highest z-order paints first
 730      * and the component with the lowest z-order paints last.
 731      * Where components overlap, the component with the lower
 732      * z-order paints over the component with the higher z-order.
 733      * <p>
 734      * If the component is a child of some other container, it is
 735      * removed from that container before being added to this container.
 736      * The important difference between this method and
 737      * <code>java.awt.Container.add(Component, int)</code> is that this method
 738      * doesn't call <code>removeNotify</code> on the component while
 739      * removing it from its previous container unless necessary and when
 740      * allowed by the underlying native windowing system. This way, if the
 741      * component has the keyboard focus, it maintains the focus when
 742      * moved to the new position.
 743      * <p>
 744      * This property is guaranteed to apply only to lightweight
 745      * non-<code>Container</code> components.
 746      * <p>
 747      * This method changes layout-related information, and therefore,
 748      * invalidates the component hierarchy.
 749      * <p>
 750      * <b>Note</b>: Not all platforms support changing the z-order of
 751      * heavyweight components from one container into another without
 752      * the call to <code>removeNotify</code>. There is no way to detect
 753      * whether a platform supports this, so developers shouldn't make
 754      * any assumptions.
 755      *
 756      * @param     comp the component to be moved
 757      * @param     index the position in the container's list to
 758      *            insert the component, where <code>getComponentCount()</code>
 759      *            appends to the end
 760      * @exception NullPointerException if <code>comp</code> is
 761      *            <code>null</code>
 762      * @exception IllegalArgumentException if <code>comp</code> is one of the
 763      *            container's parents
 764      * @exception IllegalArgumentException if <code>index</code> is not in
 765      *            the range <code>[0, getComponentCount()]</code> for moving
 766      *            between containers, or not in the range
 767      *            <code>[0, getComponentCount()-1]</code> for moving inside
 768      *            a container
 769      * @exception IllegalArgumentException if adding a container to itself
 770      * @exception IllegalArgumentException if adding a <code>Window</code>
 771      *            to a container
 772      * @see #getComponentZOrder(java.awt.Component)
 773      * @see #invalidate
 774      * @since 1.5
 775      */
 776     public void setComponentZOrder(Component comp, int index) {
 777          synchronized (getTreeLock()) {
 778              // Store parent because remove will clear it
 779              Container curParent = comp.parent;
 780              int oldZindex = getComponentZOrder(comp);
 781 
 782              if (curParent == this && index == oldZindex) {
 783                  return;
 784              }
 785              checkAdding(comp, index);
 786 
 787              boolean peerRecreated = (curParent != null) ?
 788                  curParent.removeDelicately(comp, this, index) : false;
 789 
 790              addDelicately(comp, curParent, index);


 932             }
 933         } else {
 934             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
 935                                        this, HierarchyEvent.HIERARCHY_CHANGED,
 936                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 937         }
 938 
 939         if (peer != null && layoutMgr == null && isVisible()) {
 940             updateCursorImmediately();
 941         }
 942     }
 943 
 944     /**
 945      * Returns the z-order index of the component inside the container.
 946      * The higher a component is in the z-order hierarchy, the lower
 947      * its index.  The component with the lowest z-order index is
 948      * painted last, above all other child components.
 949      *
 950      * @param comp the component being queried
 951      * @return  the z-order index of the component; otherwise
 952      *          returns -1 if the component is <code>null</code>
 953      *          or doesn't belong to the container
 954      * @see #setComponentZOrder(java.awt.Component, int)
 955      * @since 1.5
 956      */
 957     public int getComponentZOrder(Component comp) {
 958         if (comp == null) {
 959             return -1;
 960         }
 961         synchronized(getTreeLock()) {
 962             // Quick check - container should be immediate parent of the component
 963             if (comp.parent != this) {
 964                 return -1;
 965             }
 966             return component.indexOf(comp);
 967         }
 968     }
 969 
 970     /**
 971      * Adds the specified component to the end of this container.
 972      * Also notifies the layout manager to add the component to


 993     public void add(Component comp, Object constraints) {
 994         addImpl(comp, constraints, -1);
 995     }
 996 
 997     /**
 998      * Adds the specified component to this container with the specified
 999      * constraints at the specified index.  Also notifies the layout
1000      * manager to add the component to the this container's layout using
1001      * the specified constraints object.
1002      * This is a convenience method for {@link #addImpl}.
1003      * <p>
1004      * This method changes layout-related information, and therefore,
1005      * invalidates the component hierarchy. If the container has already been
1006      * displayed, the hierarchy must be validated thereafter in order to
1007      * display the added component.
1008      *
1009      *
1010      * @param comp the component to be added
1011      * @param constraints an object expressing layout constraints for this
1012      * @param index the position in the container's list at which to insert
1013      * the component; <code>-1</code> means insert at the end
1014      * component
1015      * @exception NullPointerException if {@code comp} is {@code null}
1016      * @exception IllegalArgumentException if {@code index} is invalid (see
1017      *            {@link #addImpl} for details)
1018      * @see #addImpl
1019      * @see #invalidate
1020      * @see #validate
1021      * @see javax.swing.JComponent#revalidate()
1022      * @see #remove
1023      * @see LayoutManager
1024      */
1025     public void add(Component comp, Object constraints, int index) {
1026        addImpl(comp, constraints, index);
1027     }
1028 
1029     /**
1030      * Adds the specified component to this container at the specified
1031      * index. This method also notifies the layout manager to add
1032      * the component to this container's layout using the specified
1033      * constraints object via the <code>addLayoutComponent</code>
1034      * method.
1035      * <p>
1036      * The constraints are
1037      * defined by the particular layout manager being used.  For
1038      * example, the <code>BorderLayout</code> class defines five
1039      * constraints: <code>BorderLayout.NORTH</code>,
1040      * <code>BorderLayout.SOUTH</code>, <code>BorderLayout.EAST</code>,
1041      * <code>BorderLayout.WEST</code>, and <code>BorderLayout.CENTER</code>.
1042      * <p>
1043      * The <code>GridBagLayout</code> class requires a
1044      * <code>GridBagConstraints</code> object.  Failure to pass
1045      * the correct type of constraints object results in an
1046      * <code>IllegalArgumentException</code>.
1047      * <p>
1048      * If the current layout manager implements {@code LayoutManager2}, then
1049      * {@link LayoutManager2#addLayoutComponent(Component,Object)} is invoked on
1050      * it. If the current layout manager does not implement
1051      * {@code LayoutManager2}, and constraints is a {@code String}, then
1052      * {@link LayoutManager#addLayoutComponent(String,Component)} is invoked on it.
1053      * <p>
1054      * If the component is not an ancestor of this container and has a non-null
1055      * parent, it is removed from its current parent before it is added to this
1056      * container.
1057      * <p>
1058      * This is the method to override if a program needs to track
1059      * every add request to a container as all other add methods defer
1060      * to this one. An overriding method should
1061      * usually include a call to the superclass's version of the method:
1062      *
1063      * <blockquote>
1064      * <code>super.addImpl(comp, constraints, index)</code>
1065      * </blockquote>
1066      * <p>
1067      * This method changes layout-related information, and therefore,
1068      * invalidates the component hierarchy. If the container has already been
1069      * displayed, the hierarchy must be validated thereafter in order to
1070      * display the added component.
1071      *
1072      * @param     comp       the component to be added
1073      * @param     constraints an object expressing layout constraints
1074      *                 for this component
1075      * @param     index the position in the container's list at which to
1076      *                 insert the component, where <code>-1</code>
1077      *                 means append to the end
1078      * @exception IllegalArgumentException if {@code index} is invalid;
1079      *            if {@code comp} is a child of this container, the valid
1080      *            range is {@code [-1, getComponentCount()-1]}; if component is
1081      *            not a child of this container, the valid range is
1082      *            {@code [-1, getComponentCount()]}
1083      *
1084      * @exception IllegalArgumentException if {@code comp} is an ancestor of
1085      *                                     this container
1086      * @exception IllegalArgumentException if adding a window to a container
1087      * @exception NullPointerException if {@code comp} is {@code null}
1088      * @see       #add(Component)
1089      * @see       #add(Component, int)
1090      * @see       #add(Component, java.lang.Object)
1091      * @see #invalidate
1092      * @see       LayoutManager
1093      * @see       LayoutManager2
1094      * @since     1.1
1095      */
1096     protected void addImpl(Component comp, Object constraints, int index) {


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</code>,
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</code> 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);


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</code> 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</code> 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);


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</code> 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()</code>.
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>


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</code>.
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                 {


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</code> 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()</code>.
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</code> 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()</code>.
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</code> 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                }


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</code>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</code>.
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</code> 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</code> <code>c</code>
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</code>
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</code>
2210      *          doesn't specify a class or interface that implements
2211      *          <code>java.util.EventListener</code>
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</code>, it invokes the
2246      * <code>processContainerEvent</code> method, else it invokes
2247      * its superclass's <code>processEvent</code>.
2248      * <p>Note that if the event parameter is <code>null</code>
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</code>
2271      * <li>Container events are enabled via <code>enableEvents</code>
2272      * </ul>
2273      * <p>Note that if the event parameter is <code>null</code>
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 


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</code>.
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</code>, 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</code>.
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</code>, the method
2407      *        will bypass immediate lightweight children during the search.
2408      *        If <code>false</code>, the methods will bypass immediate
2409      *        heavyweight children during the search.
2410      * @param searchHeavyweightDescendants if <code>false</code>, the method
2411      *        will bypass heavyweight descendants which are not immediate
2412      *        children during the search. If <code>true</code>, 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.


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)</code>
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)</code>.
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</code> 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</code>'s
2607      * coordinate space if the <code>Container</code> is under the mouse pointer,
2608      * otherwise returns <code>null</code>.
2609      * This method is similar to {@link Component#getMousePosition()} with the exception
2610      * that it can take the <code>Container</code>'s children into account.
2611      * If <code>allowChildren</code> is <code>false</code>, this method will return
2612      * a non-null value only if the mouse pointer is above the <code>Container</code>
2613      * directly, not above the part obscured by children.
2614      * If <code>allowChildren</code> is <code>true</code>, this method returns
2615      * a non-null value if the mouse pointer is above <code>Container</code> 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</code>, 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         }


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</code> if it is an ancestor;
2852      *             <code>false</code> 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.


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</code>.
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</code>.
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</code>.  The children
3009      * of those children are printed at <code>indent+2</code>
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</code>.  The children
3036      * of those children are printed at <code>indent+2</code>
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 


3132      *         operation for this Container
3133      * @since 1.4
3134      * @beaninfo
3135      *       bound: true
3136      */
3137     public void setFocusTraversalKeys(int id,
3138                                       Set<? extends AWTKeyStroke> keystrokes)
3139     {
3140         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3141             throw new IllegalArgumentException("invalid focus traversal key identifier");
3142         }
3143 
3144         // Don't call super.setFocusTraversalKey. The Component parameter check
3145         // does not allow DOWN_CYCLE_TRAVERSAL_KEYS, but we do.
3146         setFocusTraversalKeys_NoIDCheck(id, keystrokes);
3147     }
3148 
3149     /**
3150      * Returns the Set of focus traversal keys for a given traversal operation
3151      * for this Container. (See
3152      * <code>setFocusTraversalKeys</code> for a full description of each key.)
3153      * <p>
3154      * If a Set of traversal keys has not been explicitly defined for this
3155      * Container, then this Container's parent's Set is returned. If no Set
3156      * has been explicitly defined for any of this Container's ancestors, then
3157      * the current KeyboardFocusManager's default Set is returned.
3158      *
3159      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3160      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3161      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3162      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3163      * @return the Set of AWTKeyStrokes for the specified operation. The Set
3164      *         will be unmodifiable, and may be empty. null will never be
3165      *         returned.
3166      * @see #setFocusTraversalKeys
3167      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3168      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3169      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3170      * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
3171      * @throws IllegalArgumentException if id is not one of
3172      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3173      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3174      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3175      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3176      * @since 1.4
3177      */
3178     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
3179         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3180             throw new IllegalArgumentException("invalid focus traversal key identifier");
3181         }
3182 
3183         // Don't call super.getFocusTraversalKey. The Component parameter check
3184         // does not allow DOWN_CYCLE_TRAVERSAL_KEY, but we do.
3185         return getFocusTraversalKeys_NoIDCheck(id);
3186     }
3187 
3188     /**
3189      * Returns whether the Set of focus traversal keys for the given focus
3190      * traversal operation has been explicitly defined for this Container. If
3191      * this method returns <code>false</code>, this Container is inheriting the
3192      * Set from an ancestor, or from the current KeyboardFocusManager.
3193      *
3194      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3195      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3196      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3197      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3198      * @return <code>true</code> if the Set of focus traversal keys for the
3199      *         given focus traversal operation has been explicitly defined for
3200      *         this Component; <code>false</code> otherwise.
3201      * @throws IllegalArgumentException if id is not one of
3202      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3203      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3204      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3205      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3206      * @since 1.4
3207      */
3208     public boolean areFocusTraversalKeysSet(int id) {
3209         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3210             throw new IllegalArgumentException("invalid focus traversal key identifier");
3211         }
3212 
3213         return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
3214     }
3215 
3216     /**
3217      * Returns whether the specified Container is the focus cycle root of this
3218      * Container's focus traversal cycle. Each focus traversal cycle has only
3219      * a single focus cycle root and each Container which is not a focus cycle
3220      * root belongs to only a single focus traversal cycle. Containers which
3221      * are focus cycle roots belong to two cycles: one rooted at the Container
3222      * itself, and one rooted at the Container's nearest focus-cycle-root
3223      * ancestor. This method will return <code>true</code> for both such
3224      * Containers in this case.
3225      *
3226      * @param container the Container to be tested
3227      * @return <code>true</code> if the specified Container is a focus-cycle-
3228      *         root of this Container; <code>false</code> otherwise
3229      * @see #isFocusCycleRoot()
3230      * @since 1.4
3231      */
3232     public boolean isFocusCycleRoot(Container container) {
3233         if (isFocusCycleRoot() && container == this) {
3234             return true;
3235         } else {
3236             return super.isFocusCycleRoot(container);
3237         }
3238     }
3239 
3240     private Container findTraversalRoot() {
3241         // I potentially have two roots, myself and my root parent
3242         // If I am the current root, then use me
3243         // If none of my parents are roots, then use me
3244         // If my root parent is the current root, then use my root parent
3245         // If neither I nor my root parent is the current root, then
3246         // use my root parent (a guess)
3247 
3248         Container currentFocusCycleRoot = KeyboardFocusManager.


3377         if (!isFocusTraversalPolicyProvider() && !isFocusCycleRoot()) {
3378             return null;
3379         }
3380 
3381         FocusTraversalPolicy policy = this.focusTraversalPolicy;
3382         if (policy != null) {
3383             return policy;
3384         }
3385 
3386         Container rootAncestor = getFocusCycleRootAncestor();
3387         if (rootAncestor != null) {
3388             return rootAncestor.getFocusTraversalPolicy();
3389         } else {
3390             return KeyboardFocusManager.getCurrentKeyboardFocusManager().
3391                 getDefaultFocusTraversalPolicy();
3392         }
3393     }
3394 
3395     /**
3396      * Returns whether the focus traversal policy has been explicitly set for
3397      * this Container. If this method returns <code>false</code>, this
3398      * Container will inherit its focus traversal policy from an ancestor.
3399      *
3400      * @return <code>true</code> if the focus traversal policy has been
3401      *         explicitly set for this Container; <code>false</code> otherwise.
3402      * @since 1.4
3403      */
3404     public boolean isFocusTraversalPolicySet() {
3405         return (focusTraversalPolicy != null);
3406     }
3407 
3408     /**
3409      * Sets whether this Container is the root of a focus traversal cycle. Once
3410      * focus enters a traversal cycle, typically it cannot leave it via focus
3411      * traversal unless one of the up- or down-cycle keys is pressed. Normal
3412      * traversal is limited to this Container, and all of this Container's
3413      * descendants that are not descendants of inferior focus cycle roots. Note
3414      * that a FocusTraversalPolicy may bend these restrictions, however. For
3415      * example, ContainerOrderFocusTraversalPolicy supports implicit down-cycle
3416      * traversal.
3417      * <p>
3418      * The alternative way to specify the traversal order of this Container's
3419      * children is to make this Container a
3420      * <a href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy provider</a>.
3421      *


3447      * Normal traversal is limited to this Container, and all of this
3448      * Container's descendants that are not descendants of inferior focus
3449      * cycle roots. Note that a FocusTraversalPolicy may bend these
3450      * restrictions, however. For example, ContainerOrderFocusTraversalPolicy
3451      * supports implicit down-cycle traversal.
3452      *
3453      * @return whether this Container is the root of a focus traversal cycle
3454      * @see #setFocusCycleRoot
3455      * @see #setFocusTraversalPolicy
3456      * @see #getFocusTraversalPolicy
3457      * @see ContainerOrderFocusTraversalPolicy
3458      * @since 1.4
3459      */
3460     public boolean isFocusCycleRoot() {
3461         return focusCycleRoot;
3462     }
3463 
3464     /**
3465      * Sets whether this container will be used to provide focus
3466      * traversal policy. Container with this property as
3467      * <code>true</code> will be used to acquire focus traversal policy
3468      * instead of closest focus cycle root ancestor.
3469      * @param provider indicates whether this container will be used to
3470      *                provide focus traversal policy
3471      * @see #setFocusTraversalPolicy
3472      * @see #getFocusTraversalPolicy
3473      * @see #isFocusTraversalPolicyProvider
3474      * @since 1.5
3475      * @beaninfo
3476      *        bound: true
3477      */
3478     public final void setFocusTraversalPolicyProvider(boolean provider) {
3479         boolean oldProvider;
3480         synchronized(this) {
3481             oldProvider = focusTraversalPolicyProvider;
3482             focusTraversalPolicyProvider = provider;
3483         }
3484         firePropertyChange("focusTraversalPolicyProvider", oldProvider, provider);
3485     }
3486 
3487     /**
3488      * Returns whether this container provides focus traversal
3489      * policy. If this property is set to <code>true</code> then when
3490      * keyboard focus manager searches container hierarchy for focus
3491      * traversal policy and encounters this container before any other
3492      * container with this property as true or focus cycle roots then
3493      * its focus traversal policy will be used instead of focus cycle
3494      * root's policy.
3495      * @see #setFocusTraversalPolicy
3496      * @see #getFocusTraversalPolicy
3497      * @see #setFocusCycleRoot
3498      * @see #setFocusTraversalPolicyProvider
3499      * @return <code>true</code> if this container provides focus traversal
3500      *         policy, <code>false</code> otherwise
3501      * @since 1.5
3502      * @beaninfo
3503      *        bound: true
3504      */
3505     public final boolean isFocusTraversalPolicyProvider() {
3506         return focusTraversalPolicyProvider;
3507     }
3508 
3509     /**
3510      * Transfers the focus down one focus traversal cycle. If this Container is
3511      * a focus cycle root, then the focus owner is set to this Container's
3512      * default Component to focus, and the current focus cycle root is set to
3513      * this Container. If this Container is not a focus cycle root, then no
3514      * focus traversal operation occurs.
3515      *
3516      * @see       Component#requestFocus()
3517      * @see       #isFocusCycleRoot
3518      * @see       #setFocusCycleRoot
3519      * @since     1.4
3520      */


3532 
3533     void preProcessKeyEvent(KeyEvent e) {
3534         Container parent = this.parent;
3535         if (parent != null) {
3536             parent.preProcessKeyEvent(e);
3537         }
3538     }
3539 
3540     void postProcessKeyEvent(KeyEvent e) {
3541         Container parent = this.parent;
3542         if (parent != null) {
3543             parent.postProcessKeyEvent(e);
3544         }
3545     }
3546 
3547     boolean postsOldMouseEvents() {
3548         return true;
3549     }
3550 
3551     /**
3552      * Sets the <code>ComponentOrientation</code> property of this container
3553      * and all components contained within it.
3554      * <p>
3555      * This method changes layout-related information, and therefore,
3556      * invalidates the component hierarchy.
3557      *
3558      * @param o the new component orientation of this container and
3559      *        the components contained within it.
3560      * @exception NullPointerException if <code>orientation</code> is null.
3561      * @see Component#setComponentOrientation
3562      * @see Component#getComponentOrientation
3563      * @see #invalidate
3564      * @since 1.4
3565      */
3566     public void applyComponentOrientation(ComponentOrientation o) {
3567         super.applyComponentOrientation(o);
3568         synchronized (getTreeLock()) {
3569             for (int i = 0; i < component.size(); i++) {
3570                 Component comp = component.get(i);
3571                 comp.applyComponentOrientation(o);
3572             }
3573         }
3574     }
3575 
3576     /**
3577      * Adds a PropertyChangeListener to the listener list. The listener is
3578      * registered for all bound properties of this class, including the
3579      * following:
3580      * <ul>


3643      * @param propertyName one of the property names listed above
3644      * @param listener the PropertyChangeListener to be added
3645      *
3646      * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
3647      * @see Component#removePropertyChangeListener
3648      */
3649     public void addPropertyChangeListener(String propertyName,
3650                                           PropertyChangeListener listener) {
3651         super.addPropertyChangeListener(propertyName, listener);
3652     }
3653 
3654     // Serialization support. A Container is responsible for restoring the
3655     // parent fields of its component children.
3656 
3657     /**
3658      * Container Serial Data Version.
3659      */
3660     private int containerSerializedDataVersion = 1;
3661 
3662     /**
3663      * Serializes this <code>Container</code> to the specified
3664      * <code>ObjectOutputStream</code>.
3665      * <ul>
3666      *    <li>Writes default serializable fields to the stream.</li>
3667      *    <li>Writes a list of serializable ContainerListener(s) as optional
3668      *        data. The non-serializable ContainerListener(s) are detected and
3669      *        no attempt is made to serialize them.</li>
3670      *    <li>Write this Container's FocusTraversalPolicy if and only if it
3671      *        is Serializable; otherwise, <code>null</code> is written.</li>
3672      * </ul>
3673      *
3674      * @param s the <code>ObjectOutputStream</code> to write
3675      * @serialData <code>null</code> terminated sequence of 0 or more pairs;
3676      *   the pair consists of a <code>String</code> and <code>Object</code>;
3677      *   the <code>String</code> indicates the type of object and
3678      *   is one of the following:
3679      *   <code>containerListenerK</code> indicating an
3680      *     <code>ContainerListener</code> object;
3681      *   the <code>Container</code>'s <code>FocusTraversalPolicy</code>,
3682      *     or <code>null</code>
3683      *
3684      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
3685      * @see Container#containerListenerK
3686      * @see #readObject(ObjectInputStream)
3687      */
3688     private void writeObject(ObjectOutputStream s) throws IOException {
3689         ObjectOutputStream.PutField f = s.putFields();
3690         f.put("ncomponents", component.size());
3691         f.put("component", component.toArray(EMPTY_ARRAY));
3692         f.put("layoutMgr", layoutMgr);
3693         f.put("dispatcher", dispatcher);
3694         f.put("maxSize", maxSize);
3695         f.put("focusCycleRoot", focusCycleRoot);
3696         f.put("containerSerializedDataVersion", containerSerializedDataVersion);
3697         f.put("focusTraversalPolicyProvider", focusTraversalPolicyProvider);
3698         s.writeFields();
3699 
3700         AWTEventMulticaster.save(s, containerListenerK, containerListener);
3701         s.writeObject(null);
3702 
3703         if (focusTraversalPolicy instanceof java.io.Serializable) {
3704             s.writeObject(focusTraversalPolicy);
3705         } else {
3706             s.writeObject(null);
3707         }
3708     }
3709 
3710     /**
3711      * Deserializes this <code>Container</code> from the specified
3712      * <code>ObjectInputStream</code>.
3713      * <ul>
3714      *    <li>Reads default serializable fields from the stream.</li>
3715      *    <li>Reads a list of serializable ContainerListener(s) as optional
3716      *        data. If the list is null, no Listeners are installed.</li>
3717      *    <li>Reads this Container's FocusTraversalPolicy, which may be null,
3718      *        as optional data.</li>
3719      * </ul>
3720      *
3721      * @param s the <code>ObjectInputStream</code> to read
3722      * @serial
3723      * @see #addContainerListener
3724      * @see #writeObject(ObjectOutputStream)
3725      */
3726     private void readObject(ObjectInputStream s)
3727         throws ClassNotFoundException, IOException
3728     {
3729         ObjectInputStream.GetField f = s.readFields();
3730         Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY);
3731         int ncomponents = (Integer) f.get("ncomponents", 0);
3732         component = new java.util.ArrayList<Component>(ncomponents);
3733         for (int i = 0; i < ncomponents; ++i) {
3734             component.add(tmpComponent[i]);
3735         }
3736         layoutMgr = (LayoutManager)f.get("layoutMgr", null);
3737         dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
3738         // Old stream. Doesn't contain maxSize among Component's fields.
3739         if (maxSize == null) {
3740             maxSize = (Dimension)f.get("maxSize", null);
3741         }


3789     /**
3790      * Inner class of Container used to provide default support for
3791      * accessibility.  This class is not meant to be used directly by
3792      * application developers, but is instead meant only to be
3793      * subclassed by container developers.
3794      * <p>
3795      * The class used to obtain the accessible role for this object,
3796      * as well as implementing many of the methods in the
3797      * AccessibleContainer interface.
3798      * @since 1.3
3799      */
3800     protected class AccessibleAWTContainer extends AccessibleAWTComponent {
3801 
3802         /**
3803          * JDK1.3 serialVersionUID
3804          */
3805         private static final long serialVersionUID = 5081320404842566097L;
3806 
3807         /**
3808          * Returns the number of accessible children in the object.  If all
3809          * of the children of this object implement <code>Accessible</code>,
3810          * then this method should return the number of children of this object.
3811          *
3812          * @return the number of accessible children in the object
3813          */
3814         public int getAccessibleChildrenCount() {
3815             return Container.this.getAccessibleChildrenCount();
3816         }
3817 
3818         /**
3819          * Returns the nth <code>Accessible</code> child of the object.
3820          *
3821          * @param i zero-based index of child
3822          * @return the nth <code>Accessible</code> child of the object
3823          */
3824         public Accessible getAccessibleChild(int i) {
3825             return Container.this.getAccessibleChild(i);
3826         }
3827 
3828         /**
3829          * Returns the <code>Accessible</code> child, if one exists,
3830          * contained at the local coordinate <code>Point</code>.
3831          *
3832          * @param p the point defining the top-left corner of the
3833          *    <code>Accessible</code>, given in the coordinate space
3834          *    of the object's parent
3835          * @return the <code>Accessible</code>, if it exists,
3836          *    at the specified location; else <code>null</code>
3837          */
3838         public Accessible getAccessibleAt(Point p) {
3839             return Container.this.getAccessibleAt(p);
3840         }
3841 
3842         /**
3843          * Number of PropertyChangeListener objects registered. It's used
3844          * to add/remove ContainerListener to track target Container's state.
3845          */
3846         private transient volatile int propertyListenersCount = 0;
3847 
3848         /**
3849          * The handler to fire {@code PropertyChange}
3850          * when children are added or removed
3851          */
3852         protected ContainerListener accessibleContainerHandler = null;
3853 
3854         /**
3855          * Fire <code>PropertyChange</code> listener, if one is registered,
3856          * when children are added or removed.
3857          * @since 1.3
3858          */
3859         protected class AccessibleContainerHandler
3860             implements ContainerListener {
3861             public void componentAdded(ContainerEvent e) {
3862                 Component c = e.getChild();
3863                 if (c != null && c instanceof Accessible) {
3864                     AccessibleAWTContainer.this.firePropertyChange(
3865                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3866                         null, ((Accessible) c).getAccessibleContext());
3867                 }
3868             }
3869             public void componentRemoved(ContainerEvent e) {
3870                 Component c = e.getChild();
3871                 if (c != null && c instanceof Accessible) {
3872                     AccessibleAWTContainer.this.firePropertyChange(
3873                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3874                         ((Accessible) c).getAccessibleContext(), null);
3875                 }


3891             super.addPropertyChangeListener(listener);
3892         }
3893 
3894         /**
3895          * Remove a PropertyChangeListener from the listener list.
3896          * This removes a PropertyChangeListener that was registered
3897          * for all properties.
3898          *
3899          * @param listener the PropertyChangeListener to be removed
3900          */
3901         public void removePropertyChangeListener(PropertyChangeListener listener) {
3902             if (--propertyListenersCount == 0) {
3903                 Container.this.removeContainerListener(accessibleContainerHandler);
3904             }
3905             super.removePropertyChangeListener(listener);
3906         }
3907 
3908     } // inner class AccessibleAWTContainer
3909 
3910     /**
3911      * Returns the <code>Accessible</code> child contained at the local
3912      * coordinate <code>Point</code>, if one exists.  Otherwise
3913      * returns <code>null</code>.
3914      *
3915      * @param p the point defining the top-left corner of the
3916      *    <code>Accessible</code>, given in the coordinate space
3917      *    of the object's parent
3918      * @return the <code>Accessible</code> at the specified location,
3919      *    if it exists; otherwise <code>null</code>
3920      */
3921     Accessible getAccessibleAt(Point p) {
3922         synchronized (getTreeLock()) {
3923             if (this instanceof Accessible) {
3924                 Accessible a = (Accessible)this;
3925                 AccessibleContext ac = a.getAccessibleContext();
3926                 if (ac != null) {
3927                     AccessibleComponent acmp;
3928                     Point location;
3929                     int nchildren = ac.getAccessibleChildrenCount();
3930                     for (int i=0; i < nchildren; i++) {
3931                         a = ac.getAccessibleChild(i);
3932                         if ((a != null)) {
3933                             ac = a.getAccessibleContext();
3934                             if (ac != null) {
3935                                 acmp = ac.getAccessibleComponent();
3936                                 if ((acmp != null) && (acmp.isShowing())) {
3937                                     location = acmp.getLocation();
3938                                     Point np = new Point(p.x-location.x,
3939                                                          p.y-location.y);


3955                     for (int i=0; i < ncomponents; i++) {
3956                         Component comp = this.getComponent(i);
3957                         if ((comp != null) && comp.isShowing()) {
3958                             Point location = comp.getLocation();
3959                             if (comp.contains(p.x-location.x,p.y-location.y)) {
3960                                 ret = comp;
3961                             }
3962                         }
3963                     }
3964                 }
3965                 if (ret instanceof Accessible) {
3966                     return (Accessible) ret;
3967                 }
3968             }
3969             return null;
3970         }
3971     }
3972 
3973     /**
3974      * Returns the number of accessible children in the object.  If all
3975      * of the children of this object implement <code>Accessible</code>,
3976      * then this method should return the number of children of this object.
3977      *
3978      * @return the number of accessible children in the object
3979      */
3980     int getAccessibleChildrenCount() {
3981         synchronized (getTreeLock()) {
3982             int count = 0;
3983             Component[] children = this.getComponents();
3984             for (int i = 0; i < children.length; i++) {
3985                 if (children[i] instanceof Accessible) {
3986                     count++;
3987                 }
3988             }
3989             return count;
3990         }
3991     }
3992 
3993     /**
3994      * Returns the nth <code>Accessible</code> child of the object.
3995      *
3996      * @param i zero-based index of child
3997      * @return the nth <code>Accessible</code> child of the object
3998      */
3999     Accessible getAccessibleChild(int i) {
4000         synchronized (getTreeLock()) {
4001             Component[] children = this.getComponents();
4002             int count = 0;
4003             for (int j = 0; j < children.length; j++) {
4004                 if (children[j] instanceof Accessible) {
4005                     if (count == i) {
4006                         return (Accessible) children[j];
4007                     } else {
4008                         count++;
4009                     }
4010                 }
4011             }
4012             return null;
4013         }
4014     }
4015 
4016     // ************************** MIXING CODE *******************************
4017 




 166     // True if there is at least one thread that's printing this component
 167     private transient boolean printing = false;
 168 
 169     transient ContainerListener containerListener;
 170 
 171     /* HierarchyListener and HierarchyBoundsListener support */
 172     transient int listeningChildren;
 173     transient int listeningBoundsChildren;
 174     transient int descendantsCount;
 175 
 176     /* Non-opaque window support -- see Window.setLayersOpaque */
 177     transient Color preserveBackgroundColor = null;
 178 
 179     /**
 180      * JDK 1.1 serialVersionUID
 181      */
 182     private static final long serialVersionUID = 4613797578919906343L;
 183 
 184     /**
 185      * A constant which toggles one of the controllable behaviors
 186      * of {@code getMouseEventTarget}. It is used to specify whether
 187      * the method can return the Container on which it is originally called
 188      * in case if none of its children are the current mouse event targets.
 189      *
 190      * @see #getMouseEventTarget(int, int, boolean)
 191      */
 192     static final boolean INCLUDE_SELF = true;
 193 
 194     /**
 195      * A constant which toggles one of the controllable behaviors
 196      * of {@code getMouseEventTarget}. It is used to specify whether
 197      * the method should search only lightweight components.
 198      *
 199      * @see #getMouseEventTarget(int, int, boolean)
 200      */
 201     static final boolean SEARCH_HEAVYWEIGHTS = true;
 202 
 203     /*
 204      * Number of HW or LW components in this container (including
 205      * all descendant containers).
 206      */
 207     private transient int numOfHWComponents = 0;
 208     private transient int numOfLWComponents = 0;
 209 
 210     private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Container");
 211 
 212     /**
 213      * @serialField ncomponents                     int
 214      *       The number of components in this container.
 215      *       This value can be null.
 216      * @serialField component                       Component[]


 367     //       This functionality is implemented in a package-private method
 368     //       to insure that it cannot be overridden by client subclasses.
 369     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
 370     final Component[] getComponents_NoClientCode() {
 371         return component.toArray(EMPTY_ARRAY);
 372     }
 373 
 374     /*
 375      * Wrapper for getComponents() method with a proper synchronization.
 376      */
 377     Component[] getComponentsSync() {
 378         synchronized (getTreeLock()) {
 379             return getComponents();
 380         }
 381     }
 382 
 383     /**
 384      * Determines the insets of this container, which indicate the size
 385      * of the container's border.
 386      * <p>
 387      * A {@code Frame} object, for example, has a top inset that
 388      * corresponds to the height of the frame's title bar.
 389      * @return    the insets of this container.
 390      * @see       Insets
 391      * @see       LayoutManager
 392      * @since     1.1
 393      */
 394     public Insets getInsets() {
 395         return insets();
 396     }
 397 
 398     /**
 399      * Returns the insets for this container.
 400      *
 401      * @deprecated As of JDK version 1.1,
 402      * replaced by {@code getInsets()}.
 403      * @return the insets for this container
 404      */
 405     @Deprecated
 406     public Insets insets() {
 407         ComponentPeer peer = this.peer;
 408         if (peer instanceof ContainerPeer) {
 409             ContainerPeer cpeer = (ContainerPeer)peer;
 410             return (Insets)cpeer.getInsets().clone();
 411         }
 412         return new Insets(0, 0, 0, 0);
 413     }
 414 
 415     /**
 416      * Appends the specified component to the end of this container.
 417      * This is a convenience method for {@link #addImpl}.
 418      * <p>
 419      * This method changes layout-related information, and therefore,
 420      * invalidates the component hierarchy. If the container has already been
 421      * displayed, the hierarchy must be validated thereafter in order to
 422      * display the added component.
 423      *
 424      * @param     comp   the component to be added
 425      * @exception NullPointerException if {@code comp} is {@code null}
 426      * @see #addImpl
 427      * @see #invalidate
 428      * @see #validate
 429      * @see javax.swing.JComponent#revalidate()
 430      * @return    the component argument
 431      */
 432     public Component add(Component comp) {
 433         addImpl(comp, null, -1);
 434         return comp;
 435     }
 436 
 437     /**
 438      * Adds the specified component to this container.
 439      * This is a convenience method for {@link #addImpl}.
 440      * <p>
 441      * This method is obsolete as of 1.1.  Please use the
 442      * method {@code add(Component, Object)} instead.
 443      * <p>
 444      * This method changes layout-related information, and therefore,
 445      * invalidates the component hierarchy. If the container has already been
 446      * displayed, the hierarchy must be validated thereafter in order to
 447      * display the added component.
 448      *
 449      * @param  name the name of the component to be added
 450      * @param  comp the component to be added
 451      * @return the component added
 452      * @exception NullPointerException if {@code comp} is {@code null}
 453      * @see #add(Component, Object)
 454      * @see #invalidate
 455      */
 456     public Component add(String name, Component comp) {
 457         addImpl(comp, name, -1);
 458         return comp;
 459     }
 460 
 461     /**
 462      * Adds the specified component to this container at the given
 463      * position.
 464      * This is a convenience method for {@link #addImpl}.
 465      * <p>
 466      * This method changes layout-related information, and therefore,
 467      * invalidates the component hierarchy. If the container has already been
 468      * displayed, the hierarchy must be validated thereafter in order to
 469      * display the added component.
 470      *
 471      *
 472      * @param     comp   the component to be added
 473      * @param     index    the position at which to insert the component,
 474      *                   or {@code -1} to append the component to the end
 475      * @exception NullPointerException if {@code comp} is {@code null}
 476      * @exception IllegalArgumentException if {@code index} is invalid (see
 477      *            {@link #addImpl} for details)
 478      * @return    the component {@code comp}
 479      * @see #addImpl
 480      * @see #remove
 481      * @see #invalidate
 482      * @see #validate
 483      * @see javax.swing.JComponent#revalidate()
 484      */
 485     public Component add(Component comp, int index) {
 486         addImpl(comp, null, index);
 487         return comp;
 488     }
 489 
 490     /**
 491      * Checks that the component
 492      * isn't supposed to be added into itself.
 493      */
 494     private void checkAddToSelf(Component comp){
 495         if (comp instanceof Container) {
 496             for (Container cn = this; cn != null; cn=cn.parent) {
 497                 if (cn == comp) {
 498                     throw new IllegalArgumentException("adding container's parent to itself");


 515      * Checks :  index in bounds of container's size,
 516      * comp is not one of this container's parents,
 517      * and comp is not a window.
 518      * Comp and container must be on the same GraphicsDevice.
 519      * if comp is container, all sub-components must be on
 520      * same GraphicsDevice.
 521      *
 522      * @since 1.5
 523      */
 524     private void checkAdding(Component comp, int index) {
 525         checkTreeLock();
 526 
 527         GraphicsConfiguration thisGC = getGraphicsConfiguration();
 528 
 529         if (index > component.size() || index < 0) {
 530             throw new IllegalArgumentException("illegal component position");
 531         }
 532         if (comp.parent == this) {
 533             if (index == component.size()) {
 534                 throw new IllegalArgumentException("illegal component position " +
 535                                                    index + " should be less than " + component.size());
 536             }
 537         }
 538         checkAddToSelf(comp);
 539         checkNotAWindow(comp);
 540 
 541         Window thisTopLevel = getContainingWindow();
 542         Window compTopLevel = comp.getContainingWindow();
 543         if (thisTopLevel != compTopLevel) {
 544             throw new IllegalArgumentException("component and container should be in the same top-level window");
 545         }
 546         if (thisGC != null) {
 547             comp.checkGD(thisGC.getDevice().getIDstring());
 548         }
 549     }
 550 
 551     /**
 552      * Removes component comp from this container without making unnecessary changes
 553      * and generating unnecessary events. This function intended to perform optimized
 554      * remove, for example, if newParent and current parent are the same it just changes
 555      * index without calling removeNotify.


 717             // is quite rare. If we ever need to save the peers, we'll have to slightly change the
 718             // addDelicately() method in order to handle such LW containers recursively, reparenting
 719             // each HW descendant independently.
 720             return !comp.peer.isReparentSupported();
 721         } else {
 722             return false;
 723         }
 724     }
 725 
 726     /**
 727      * Moves the specified component to the specified z-order index in
 728      * the container. The z-order determines the order that components
 729      * are painted; the component with the highest z-order paints first
 730      * and the component with the lowest z-order paints last.
 731      * Where components overlap, the component with the lower
 732      * z-order paints over the component with the higher z-order.
 733      * <p>
 734      * If the component is a child of some other container, it is
 735      * removed from that container before being added to this container.
 736      * The important difference between this method and
 737      * {@code java.awt.Container.add(Component, int)} is that this method
 738      * doesn't call {@code removeNotify} on the component while
 739      * removing it from its previous container unless necessary and when
 740      * allowed by the underlying native windowing system. This way, if the
 741      * component has the keyboard focus, it maintains the focus when
 742      * moved to the new position.
 743      * <p>
 744      * This property is guaranteed to apply only to lightweight
 745      * non-{@code Container} components.
 746      * <p>
 747      * This method changes layout-related information, and therefore,
 748      * invalidates the component hierarchy.
 749      * <p>
 750      * <b>Note</b>: Not all platforms support changing the z-order of
 751      * heavyweight components from one container into another without
 752      * the call to {@code removeNotify}. There is no way to detect
 753      * whether a platform supports this, so developers shouldn't make
 754      * any assumptions.
 755      *
 756      * @param     comp the component to be moved
 757      * @param     index the position in the container's list to
 758      *            insert the component, where {@code getComponentCount()}
 759      *            appends to the end
 760      * @exception NullPointerException if {@code comp} is
 761      *            {@code null}
 762      * @exception IllegalArgumentException if {@code comp} is one of the
 763      *            container's parents
 764      * @exception IllegalArgumentException if {@code index} is not in
 765      *            the range {@code [0, getComponentCount()]} for moving
 766      *            between containers, or not in the range
 767      *            {@code [0, getComponentCount()-1]} for moving inside
 768      *            a container
 769      * @exception IllegalArgumentException if adding a container to itself
 770      * @exception IllegalArgumentException if adding a {@code Window}
 771      *            to a container
 772      * @see #getComponentZOrder(java.awt.Component)
 773      * @see #invalidate
 774      * @since 1.5
 775      */
 776     public void setComponentZOrder(Component comp, int index) {
 777          synchronized (getTreeLock()) {
 778              // Store parent because remove will clear it
 779              Container curParent = comp.parent;
 780              int oldZindex = getComponentZOrder(comp);
 781 
 782              if (curParent == this && index == oldZindex) {
 783                  return;
 784              }
 785              checkAdding(comp, index);
 786 
 787              boolean peerRecreated = (curParent != null) ?
 788                  curParent.removeDelicately(comp, this, index) : false;
 789 
 790              addDelicately(comp, curParent, index);


 932             }
 933         } else {
 934             comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
 935                                        this, HierarchyEvent.HIERARCHY_CHANGED,
 936                                        Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
 937         }
 938 
 939         if (peer != null && layoutMgr == null && isVisible()) {
 940             updateCursorImmediately();
 941         }
 942     }
 943 
 944     /**
 945      * Returns the z-order index of the component inside the container.
 946      * The higher a component is in the z-order hierarchy, the lower
 947      * its index.  The component with the lowest z-order index is
 948      * painted last, above all other child components.
 949      *
 950      * @param comp the component being queried
 951      * @return  the z-order index of the component; otherwise
 952      *          returns -1 if the component is {@code null}
 953      *          or doesn't belong to the container
 954      * @see #setComponentZOrder(java.awt.Component, int)
 955      * @since 1.5
 956      */
 957     public int getComponentZOrder(Component comp) {
 958         if (comp == null) {
 959             return -1;
 960         }
 961         synchronized(getTreeLock()) {
 962             // Quick check - container should be immediate parent of the component
 963             if (comp.parent != this) {
 964                 return -1;
 965             }
 966             return component.indexOf(comp);
 967         }
 968     }
 969 
 970     /**
 971      * Adds the specified component to the end of this container.
 972      * Also notifies the layout manager to add the component to


 993     public void add(Component comp, Object constraints) {
 994         addImpl(comp, constraints, -1);
 995     }
 996 
 997     /**
 998      * Adds the specified component to this container with the specified
 999      * constraints at the specified index.  Also notifies the layout
1000      * manager to add the component to the this container's layout using
1001      * the specified constraints object.
1002      * This is a convenience method for {@link #addImpl}.
1003      * <p>
1004      * This method changes layout-related information, and therefore,
1005      * invalidates the component hierarchy. If the container has already been
1006      * displayed, the hierarchy must be validated thereafter in order to
1007      * display the added component.
1008      *
1009      *
1010      * @param comp the component to be added
1011      * @param constraints an object expressing layout constraints for this
1012      * @param index the position in the container's list at which to insert
1013      * the component; {@code -1} means insert at the end
1014      * component
1015      * @exception NullPointerException if {@code comp} is {@code null}
1016      * @exception IllegalArgumentException if {@code index} is invalid (see
1017      *            {@link #addImpl} for details)
1018      * @see #addImpl
1019      * @see #invalidate
1020      * @see #validate
1021      * @see javax.swing.JComponent#revalidate()
1022      * @see #remove
1023      * @see LayoutManager
1024      */
1025     public void add(Component comp, Object constraints, int index) {
1026        addImpl(comp, constraints, index);
1027     }
1028 
1029     /**
1030      * Adds the specified component to this container at the specified
1031      * index. This method also notifies the layout manager to add
1032      * the component to this container's layout using the specified
1033      * constraints object via the {@code addLayoutComponent}
1034      * method.
1035      * <p>
1036      * The constraints are
1037      * defined by the particular layout manager being used.  For
1038      * example, the {@code BorderLayout} class defines five
1039      * constraints: {@code BorderLayout.NORTH},
1040      * {@code BorderLayout.SOUTH}, {@code BorderLayout.EAST},
1041      * {@code BorderLayout.WEST}, and {@code BorderLayout.CENTER}.
1042      * <p>
1043      * The {@code GridBagLayout} class requires a
1044      * {@code GridBagConstraints} object.  Failure to pass
1045      * the correct type of constraints object results in an
1046      * {@code IllegalArgumentException}.
1047      * <p>
1048      * If the current layout manager implements {@code LayoutManager2}, then
1049      * {@link LayoutManager2#addLayoutComponent(Component,Object)} is invoked on
1050      * it. If the current layout manager does not implement
1051      * {@code LayoutManager2}, and constraints is a {@code String}, then
1052      * {@link LayoutManager#addLayoutComponent(String,Component)} is invoked on it.
1053      * <p>
1054      * If the component is not an ancestor of this container and has a non-null
1055      * parent, it is removed from its current parent before it is added to this
1056      * container.
1057      * <p>
1058      * This is the method to override if a program needs to track
1059      * every add request to a container as all other add methods defer
1060      * to this one. An overriding method should
1061      * usually include a call to the superclass's version of the method:
1062      *
1063      * <blockquote>
1064      * {@code super.addImpl(comp, constraints, index)}
1065      * </blockquote>
1066      * <p>
1067      * This method changes layout-related information, and therefore,
1068      * invalidates the component hierarchy. If the container has already been
1069      * displayed, the hierarchy must be validated thereafter in order to
1070      * display the added component.
1071      *
1072      * @param     comp       the component to be added
1073      * @param     constraints an object expressing layout constraints
1074      *                 for this component
1075      * @param     index the position in the container's list at which to
1076      *                 insert the component, where {@code -1}
1077      *                 means append to the end
1078      * @exception IllegalArgumentException if {@code index} is invalid;
1079      *            if {@code comp} is a child of this container, the valid
1080      *            range is {@code [-1, getComponentCount()-1]}; if component is
1081      *            not a child of this container, the valid range is
1082      *            {@code [-1, getComponentCount()]}
1083      *
1084      * @exception IllegalArgumentException if {@code comp} is an ancestor of
1085      *                                     this container
1086      * @exception IllegalArgumentException if adding a window to a container
1087      * @exception NullPointerException if {@code comp} is {@code null}
1088      * @see       #add(Component)
1089      * @see       #add(Component, int)
1090      * @see       #add(Component, java.lang.Object)
1091      * @see #invalidate
1092      * @see       LayoutManager
1093      * @see       LayoutManager2
1094      * @since     1.1
1095      */
1096     protected void addImpl(Component comp, Object constraints, int index) {


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);


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);


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>


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                 {


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                }


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 


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.


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         }


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.


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 


3132      *         operation for this Container
3133      * @since 1.4
3134      * @beaninfo
3135      *       bound: true
3136      */
3137     public void setFocusTraversalKeys(int id,
3138                                       Set<? extends AWTKeyStroke> keystrokes)
3139     {
3140         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3141             throw new IllegalArgumentException("invalid focus traversal key identifier");
3142         }
3143 
3144         // Don't call super.setFocusTraversalKey. The Component parameter check
3145         // does not allow DOWN_CYCLE_TRAVERSAL_KEYS, but we do.
3146         setFocusTraversalKeys_NoIDCheck(id, keystrokes);
3147     }
3148 
3149     /**
3150      * Returns the Set of focus traversal keys for a given traversal operation
3151      * for this Container. (See
3152      * {@code setFocusTraversalKeys} for a full description of each key.)
3153      * <p>
3154      * If a Set of traversal keys has not been explicitly defined for this
3155      * Container, then this Container's parent's Set is returned. If no Set
3156      * has been explicitly defined for any of this Container's ancestors, then
3157      * the current KeyboardFocusManager's default Set is returned.
3158      *
3159      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3160      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3161      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3162      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3163      * @return the Set of AWTKeyStrokes for the specified operation. The Set
3164      *         will be unmodifiable, and may be empty. null will never be
3165      *         returned.
3166      * @see #setFocusTraversalKeys
3167      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3168      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3169      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3170      * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
3171      * @throws IllegalArgumentException if id is not one of
3172      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3173      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3174      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3175      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3176      * @since 1.4
3177      */
3178     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
3179         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3180             throw new IllegalArgumentException("invalid focus traversal key identifier");
3181         }
3182 
3183         // Don't call super.getFocusTraversalKey. The Component parameter check
3184         // does not allow DOWN_CYCLE_TRAVERSAL_KEY, but we do.
3185         return getFocusTraversalKeys_NoIDCheck(id);
3186     }
3187 
3188     /**
3189      * Returns whether the Set of focus traversal keys for the given focus
3190      * traversal operation has been explicitly defined for this Container. If
3191      * this method returns {@code false}, this Container is inheriting the
3192      * Set from an ancestor, or from the current KeyboardFocusManager.
3193      *
3194      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3195      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3196      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3197      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3198      * @return {@code true} if the Set of focus traversal keys for the
3199      *         given focus traversal operation has been explicitly defined for
3200      *         this Component; {@code false} otherwise.
3201      * @throws IllegalArgumentException if id is not one of
3202      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3203      *        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
3204      *        KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
3205      *        KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
3206      * @since 1.4
3207      */
3208     public boolean areFocusTraversalKeysSet(int id) {
3209         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
3210             throw new IllegalArgumentException("invalid focus traversal key identifier");
3211         }
3212 
3213         return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
3214     }
3215 
3216     /**
3217      * Returns whether the specified Container is the focus cycle root of this
3218      * Container's focus traversal cycle. Each focus traversal cycle has only
3219      * a single focus cycle root and each Container which is not a focus cycle
3220      * root belongs to only a single focus traversal cycle. Containers which
3221      * are focus cycle roots belong to two cycles: one rooted at the Container
3222      * itself, and one rooted at the Container's nearest focus-cycle-root
3223      * ancestor. This method will return {@code true} for both such
3224      * Containers in this case.
3225      *
3226      * @param container the Container to be tested
3227      * @return {@code true} if the specified Container is a focus-cycle-
3228      *         root of this Container; {@code false} otherwise
3229      * @see #isFocusCycleRoot()
3230      * @since 1.4
3231      */
3232     public boolean isFocusCycleRoot(Container container) {
3233         if (isFocusCycleRoot() && container == this) {
3234             return true;
3235         } else {
3236             return super.isFocusCycleRoot(container);
3237         }
3238     }
3239 
3240     private Container findTraversalRoot() {
3241         // I potentially have two roots, myself and my root parent
3242         // If I am the current root, then use me
3243         // If none of my parents are roots, then use me
3244         // If my root parent is the current root, then use my root parent
3245         // If neither I nor my root parent is the current root, then
3246         // use my root parent (a guess)
3247 
3248         Container currentFocusCycleRoot = KeyboardFocusManager.


3377         if (!isFocusTraversalPolicyProvider() && !isFocusCycleRoot()) {
3378             return null;
3379         }
3380 
3381         FocusTraversalPolicy policy = this.focusTraversalPolicy;
3382         if (policy != null) {
3383             return policy;
3384         }
3385 
3386         Container rootAncestor = getFocusCycleRootAncestor();
3387         if (rootAncestor != null) {
3388             return rootAncestor.getFocusTraversalPolicy();
3389         } else {
3390             return KeyboardFocusManager.getCurrentKeyboardFocusManager().
3391                 getDefaultFocusTraversalPolicy();
3392         }
3393     }
3394 
3395     /**
3396      * Returns whether the focus traversal policy has been explicitly set for
3397      * this Container. If this method returns {@code false}, this
3398      * Container will inherit its focus traversal policy from an ancestor.
3399      *
3400      * @return {@code true} if the focus traversal policy has been
3401      *         explicitly set for this Container; {@code false} otherwise.
3402      * @since 1.4
3403      */
3404     public boolean isFocusTraversalPolicySet() {
3405         return (focusTraversalPolicy != null);
3406     }
3407 
3408     /**
3409      * Sets whether this Container is the root of a focus traversal cycle. Once
3410      * focus enters a traversal cycle, typically it cannot leave it via focus
3411      * traversal unless one of the up- or down-cycle keys is pressed. Normal
3412      * traversal is limited to this Container, and all of this Container's
3413      * descendants that are not descendants of inferior focus cycle roots. Note
3414      * that a FocusTraversalPolicy may bend these restrictions, however. For
3415      * example, ContainerOrderFocusTraversalPolicy supports implicit down-cycle
3416      * traversal.
3417      * <p>
3418      * The alternative way to specify the traversal order of this Container's
3419      * children is to make this Container a
3420      * <a href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal policy provider</a>.
3421      *


3447      * Normal traversal is limited to this Container, and all of this
3448      * Container's descendants that are not descendants of inferior focus
3449      * cycle roots. Note that a FocusTraversalPolicy may bend these
3450      * restrictions, however. For example, ContainerOrderFocusTraversalPolicy
3451      * supports implicit down-cycle traversal.
3452      *
3453      * @return whether this Container is the root of a focus traversal cycle
3454      * @see #setFocusCycleRoot
3455      * @see #setFocusTraversalPolicy
3456      * @see #getFocusTraversalPolicy
3457      * @see ContainerOrderFocusTraversalPolicy
3458      * @since 1.4
3459      */
3460     public boolean isFocusCycleRoot() {
3461         return focusCycleRoot;
3462     }
3463 
3464     /**
3465      * Sets whether this container will be used to provide focus
3466      * traversal policy. Container with this property as
3467      * {@code true} will be used to acquire focus traversal policy
3468      * instead of closest focus cycle root ancestor.
3469      * @param provider indicates whether this container will be used to
3470      *                provide focus traversal policy
3471      * @see #setFocusTraversalPolicy
3472      * @see #getFocusTraversalPolicy
3473      * @see #isFocusTraversalPolicyProvider
3474      * @since 1.5
3475      * @beaninfo
3476      *        bound: true
3477      */
3478     public final void setFocusTraversalPolicyProvider(boolean provider) {
3479         boolean oldProvider;
3480         synchronized(this) {
3481             oldProvider = focusTraversalPolicyProvider;
3482             focusTraversalPolicyProvider = provider;
3483         }
3484         firePropertyChange("focusTraversalPolicyProvider", oldProvider, provider);
3485     }
3486 
3487     /**
3488      * Returns whether this container provides focus traversal
3489      * policy. If this property is set to {@code true} then when
3490      * keyboard focus manager searches container hierarchy for focus
3491      * traversal policy and encounters this container before any other
3492      * container with this property as true or focus cycle roots then
3493      * its focus traversal policy will be used instead of focus cycle
3494      * root's policy.
3495      * @see #setFocusTraversalPolicy
3496      * @see #getFocusTraversalPolicy
3497      * @see #setFocusCycleRoot
3498      * @see #setFocusTraversalPolicyProvider
3499      * @return {@code true} if this container provides focus traversal
3500      *         policy, {@code false} otherwise
3501      * @since 1.5
3502      * @beaninfo
3503      *        bound: true
3504      */
3505     public final boolean isFocusTraversalPolicyProvider() {
3506         return focusTraversalPolicyProvider;
3507     }
3508 
3509     /**
3510      * Transfers the focus down one focus traversal cycle. If this Container is
3511      * a focus cycle root, then the focus owner is set to this Container's
3512      * default Component to focus, and the current focus cycle root is set to
3513      * this Container. If this Container is not a focus cycle root, then no
3514      * focus traversal operation occurs.
3515      *
3516      * @see       Component#requestFocus()
3517      * @see       #isFocusCycleRoot
3518      * @see       #setFocusCycleRoot
3519      * @since     1.4
3520      */


3532 
3533     void preProcessKeyEvent(KeyEvent e) {
3534         Container parent = this.parent;
3535         if (parent != null) {
3536             parent.preProcessKeyEvent(e);
3537         }
3538     }
3539 
3540     void postProcessKeyEvent(KeyEvent e) {
3541         Container parent = this.parent;
3542         if (parent != null) {
3543             parent.postProcessKeyEvent(e);
3544         }
3545     }
3546 
3547     boolean postsOldMouseEvents() {
3548         return true;
3549     }
3550 
3551     /**
3552      * Sets the {@code ComponentOrientation} property of this container
3553      * and all components contained within it.
3554      * <p>
3555      * This method changes layout-related information, and therefore,
3556      * invalidates the component hierarchy.
3557      *
3558      * @param o the new component orientation of this container and
3559      *        the components contained within it.
3560      * @exception NullPointerException if {@code orientation} is null.
3561      * @see Component#setComponentOrientation
3562      * @see Component#getComponentOrientation
3563      * @see #invalidate
3564      * @since 1.4
3565      */
3566     public void applyComponentOrientation(ComponentOrientation o) {
3567         super.applyComponentOrientation(o);
3568         synchronized (getTreeLock()) {
3569             for (int i = 0; i < component.size(); i++) {
3570                 Component comp = component.get(i);
3571                 comp.applyComponentOrientation(o);
3572             }
3573         }
3574     }
3575 
3576     /**
3577      * Adds a PropertyChangeListener to the listener list. The listener is
3578      * registered for all bound properties of this class, including the
3579      * following:
3580      * <ul>


3643      * @param propertyName one of the property names listed above
3644      * @param listener the PropertyChangeListener to be added
3645      *
3646      * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
3647      * @see Component#removePropertyChangeListener
3648      */
3649     public void addPropertyChangeListener(String propertyName,
3650                                           PropertyChangeListener listener) {
3651         super.addPropertyChangeListener(propertyName, listener);
3652     }
3653 
3654     // Serialization support. A Container is responsible for restoring the
3655     // parent fields of its component children.
3656 
3657     /**
3658      * Container Serial Data Version.
3659      */
3660     private int containerSerializedDataVersion = 1;
3661 
3662     /**
3663      * Serializes this {@code Container} to the specified
3664      * {@code ObjectOutputStream}.
3665      * <ul>
3666      *    <li>Writes default serializable fields to the stream.</li>
3667      *    <li>Writes a list of serializable ContainerListener(s) as optional
3668      *        data. The non-serializable ContainerListener(s) are detected and
3669      *        no attempt is made to serialize them.</li>
3670      *    <li>Write this Container's FocusTraversalPolicy if and only if it
3671      *        is Serializable; otherwise, {@code null} is written.</li>
3672      * </ul>
3673      *
3674      * @param s the {@code ObjectOutputStream} to write
3675      * @serialData {@code null} terminated sequence of 0 or more pairs;
3676      *   the pair consists of a {@code String} and {@code Object};
3677      *   the {@code String} indicates the type of object and
3678      *   is one of the following:
3679      *   {@code containerListenerK} indicating an
3680      *     {@code ContainerListener} object;
3681      *   the {@code Container}'s {@code FocusTraversalPolicy},
3682      *     or {@code null}
3683      *
3684      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
3685      * @see Container#containerListenerK
3686      * @see #readObject(ObjectInputStream)
3687      */
3688     private void writeObject(ObjectOutputStream s) throws IOException {
3689         ObjectOutputStream.PutField f = s.putFields();
3690         f.put("ncomponents", component.size());
3691         f.put("component", component.toArray(EMPTY_ARRAY));
3692         f.put("layoutMgr", layoutMgr);
3693         f.put("dispatcher", dispatcher);
3694         f.put("maxSize", maxSize);
3695         f.put("focusCycleRoot", focusCycleRoot);
3696         f.put("containerSerializedDataVersion", containerSerializedDataVersion);
3697         f.put("focusTraversalPolicyProvider", focusTraversalPolicyProvider);
3698         s.writeFields();
3699 
3700         AWTEventMulticaster.save(s, containerListenerK, containerListener);
3701         s.writeObject(null);
3702 
3703         if (focusTraversalPolicy instanceof java.io.Serializable) {
3704             s.writeObject(focusTraversalPolicy);
3705         } else {
3706             s.writeObject(null);
3707         }
3708     }
3709 
3710     /**
3711      * Deserializes this {@code Container} from the specified
3712      * {@code ObjectInputStream}.
3713      * <ul>
3714      *    <li>Reads default serializable fields from the stream.</li>
3715      *    <li>Reads a list of serializable ContainerListener(s) as optional
3716      *        data. If the list is null, no Listeners are installed.</li>
3717      *    <li>Reads this Container's FocusTraversalPolicy, which may be null,
3718      *        as optional data.</li>
3719      * </ul>
3720      *
3721      * @param s the {@code ObjectInputStream} to read
3722      * @serial
3723      * @see #addContainerListener
3724      * @see #writeObject(ObjectOutputStream)
3725      */
3726     private void readObject(ObjectInputStream s)
3727         throws ClassNotFoundException, IOException
3728     {
3729         ObjectInputStream.GetField f = s.readFields();
3730         Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY);
3731         int ncomponents = (Integer) f.get("ncomponents", 0);
3732         component = new java.util.ArrayList<Component>(ncomponents);
3733         for (int i = 0; i < ncomponents; ++i) {
3734             component.add(tmpComponent[i]);
3735         }
3736         layoutMgr = (LayoutManager)f.get("layoutMgr", null);
3737         dispatcher = (LightweightDispatcher)f.get("dispatcher", null);
3738         // Old stream. Doesn't contain maxSize among Component's fields.
3739         if (maxSize == null) {
3740             maxSize = (Dimension)f.get("maxSize", null);
3741         }


3789     /**
3790      * Inner class of Container used to provide default support for
3791      * accessibility.  This class is not meant to be used directly by
3792      * application developers, but is instead meant only to be
3793      * subclassed by container developers.
3794      * <p>
3795      * The class used to obtain the accessible role for this object,
3796      * as well as implementing many of the methods in the
3797      * AccessibleContainer interface.
3798      * @since 1.3
3799      */
3800     protected class AccessibleAWTContainer extends AccessibleAWTComponent {
3801 
3802         /**
3803          * JDK1.3 serialVersionUID
3804          */
3805         private static final long serialVersionUID = 5081320404842566097L;
3806 
3807         /**
3808          * Returns the number of accessible children in the object.  If all
3809          * of the children of this object implement {@code Accessible},
3810          * then this method should return the number of children of this object.
3811          *
3812          * @return the number of accessible children in the object
3813          */
3814         public int getAccessibleChildrenCount() {
3815             return Container.this.getAccessibleChildrenCount();
3816         }
3817 
3818         /**
3819          * Returns the nth {@code Accessible} child of the object.
3820          *
3821          * @param i zero-based index of child
3822          * @return the nth {@code Accessible} child of the object
3823          */
3824         public Accessible getAccessibleChild(int i) {
3825             return Container.this.getAccessibleChild(i);
3826         }
3827 
3828         /**
3829          * Returns the {@code Accessible} child, if one exists,
3830          * contained at the local coordinate {@code Point}.
3831          *
3832          * @param p the point defining the top-left corner of the
3833          *    {@code Accessible}, given in the coordinate space
3834          *    of the object's parent
3835          * @return the {@code Accessible}, if it exists,
3836          *    at the specified location; else {@code null}
3837          */
3838         public Accessible getAccessibleAt(Point p) {
3839             return Container.this.getAccessibleAt(p);
3840         }
3841 
3842         /**
3843          * Number of PropertyChangeListener objects registered. It's used
3844          * to add/remove ContainerListener to track target Container's state.
3845          */
3846         private transient volatile int propertyListenersCount = 0;
3847 
3848         /**
3849          * The handler to fire {@code PropertyChange}
3850          * when children are added or removed
3851          */
3852         protected ContainerListener accessibleContainerHandler = null;
3853 
3854         /**
3855          * Fire {@code PropertyChange} listener, if one is registered,
3856          * when children are added or removed.
3857          * @since 1.3
3858          */
3859         protected class AccessibleContainerHandler
3860             implements ContainerListener {
3861             public void componentAdded(ContainerEvent e) {
3862                 Component c = e.getChild();
3863                 if (c != null && c instanceof Accessible) {
3864                     AccessibleAWTContainer.this.firePropertyChange(
3865                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3866                         null, ((Accessible) c).getAccessibleContext());
3867                 }
3868             }
3869             public void componentRemoved(ContainerEvent e) {
3870                 Component c = e.getChild();
3871                 if (c != null && c instanceof Accessible) {
3872                     AccessibleAWTContainer.this.firePropertyChange(
3873                         AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3874                         ((Accessible) c).getAccessibleContext(), null);
3875                 }


3891             super.addPropertyChangeListener(listener);
3892         }
3893 
3894         /**
3895          * Remove a PropertyChangeListener from the listener list.
3896          * This removes a PropertyChangeListener that was registered
3897          * for all properties.
3898          *
3899          * @param listener the PropertyChangeListener to be removed
3900          */
3901         public void removePropertyChangeListener(PropertyChangeListener listener) {
3902             if (--propertyListenersCount == 0) {
3903                 Container.this.removeContainerListener(accessibleContainerHandler);
3904             }
3905             super.removePropertyChangeListener(listener);
3906         }
3907 
3908     } // inner class AccessibleAWTContainer
3909 
3910     /**
3911      * Returns the {@code Accessible} child contained at the local
3912      * coordinate {@code Point}, if one exists.  Otherwise
3913      * returns {@code null}.
3914      *
3915      * @param p the point defining the top-left corner of the
3916      *    {@code Accessible}, given in the coordinate space
3917      *    of the object's parent
3918      * @return the {@code Accessible} at the specified location,
3919      *    if it exists; otherwise {@code null}
3920      */
3921     Accessible getAccessibleAt(Point p) {
3922         synchronized (getTreeLock()) {
3923             if (this instanceof Accessible) {
3924                 Accessible a = (Accessible)this;
3925                 AccessibleContext ac = a.getAccessibleContext();
3926                 if (ac != null) {
3927                     AccessibleComponent acmp;
3928                     Point location;
3929                     int nchildren = ac.getAccessibleChildrenCount();
3930                     for (int i=0; i < nchildren; i++) {
3931                         a = ac.getAccessibleChild(i);
3932                         if ((a != null)) {
3933                             ac = a.getAccessibleContext();
3934                             if (ac != null) {
3935                                 acmp = ac.getAccessibleComponent();
3936                                 if ((acmp != null) && (acmp.isShowing())) {
3937                                     location = acmp.getLocation();
3938                                     Point np = new Point(p.x-location.x,
3939                                                          p.y-location.y);


3955                     for (int i=0; i < ncomponents; i++) {
3956                         Component comp = this.getComponent(i);
3957                         if ((comp != null) && comp.isShowing()) {
3958                             Point location = comp.getLocation();
3959                             if (comp.contains(p.x-location.x,p.y-location.y)) {
3960                                 ret = comp;
3961                             }
3962                         }
3963                     }
3964                 }
3965                 if (ret instanceof Accessible) {
3966                     return (Accessible) ret;
3967                 }
3968             }
3969             return null;
3970         }
3971     }
3972 
3973     /**
3974      * Returns the number of accessible children in the object.  If all
3975      * of the children of this object implement {@code Accessible},
3976      * then this method should return the number of children of this object.
3977      *
3978      * @return the number of accessible children in the object
3979      */
3980     int getAccessibleChildrenCount() {
3981         synchronized (getTreeLock()) {
3982             int count = 0;
3983             Component[] children = this.getComponents();
3984             for (int i = 0; i < children.length; i++) {
3985                 if (children[i] instanceof Accessible) {
3986                     count++;
3987                 }
3988             }
3989             return count;
3990         }
3991     }
3992 
3993     /**
3994      * Returns the nth {@code Accessible} child of the object.
3995      *
3996      * @param i zero-based index of child
3997      * @return the nth {@code Accessible} child of the object
3998      */
3999     Accessible getAccessibleChild(int i) {
4000         synchronized (getTreeLock()) {
4001             Component[] children = this.getComponents();
4002             int count = 0;
4003             for (int j = 0; j < children.length; j++) {
4004                 if (children[j] instanceof Accessible) {
4005                     if (count == i) {
4006                         return (Accessible) children[j];
4007                     } else {
4008                         count++;
4009                     }
4010                 }
4011             }
4012             return null;
4013         }
4014     }
4015 
4016     // ************************** MIXING CODE *******************************
4017 


< prev index next >