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

Print this page




 150  *    class MyApp implements java.io.Serializable
 151  *    {
 152  *         BigObjectThatShouldNotBeSerializedWithAButton bigOne;
 153  *         Button aButton = new Button();
 154  *
 155  *         static class MyActionListener implements ActionListener
 156  *         {
 157  *             public void actionPerformed(ActionEvent e)
 158  *             {
 159  *                 System.out.println("Hello There");
 160  *             }
 161  *         }
 162  *
 163  *         MyApp()
 164  *         {
 165  *             aButton.addActionListener(new MyActionListener());
 166  *         }
 167  *    }
 168  * </pre>
 169  * <p>
 170  * <b>Note</b>: For more information on the paint mechanisms utilitized
 171  * by AWT and Swing, including information on how to write the most
 172  * efficient painting code, see
 173  * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
 174  * <p>
 175  * For details on the focus subsystem, see
 176  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
 177  * How to Use the Focus Subsystem</a>,
 178  * a section in <em>The Java Tutorial</em>, and the
 179  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
 180  * for more information.
 181  *
 182  * @author      Arthur van Hoff
 183  * @author      Sami Shaio
 184  */
 185 public abstract class Component implements ImageObserver, MenuContainer,
 186                                            Serializable
 187 {
 188 
 189     private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component");
 190     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component");


 338      * visible is not drawn on the screen.
 339      *
 340      * @serial
 341      * @see #isVisible
 342      * @see #setVisible
 343      */
 344     boolean visible = true;
 345 
 346     /**
 347      * True when the object is enabled. An object that is not
 348      * enabled does not interact with the user.
 349      *
 350      * @serial
 351      * @see #isEnabled
 352      * @see #setEnabled
 353      */
 354     boolean enabled = true;
 355 
 356     /**
 357      * True when the object is valid. An invalid object needs to
 358      * be layed out. This flag is set to false when the object
 359      * size is changed.
 360      *
 361      * @serial
 362      * @see #isValid
 363      * @see #validate
 364      * @see #invalidate
 365      */
 366     private volatile boolean valid = false;
 367 
 368     /**
 369      * The <code>DropTarget</code> associated with this component.
 370      *
 371      * @since 1.2
 372      * @serial
 373      * @see #setDropTarget
 374      * @see #getDropTarget
 375      */
 376     DropTarget dropTarget;
 377 
 378     /**


 401      * @see #getName
 402      * @see #setName(String)
 403      */
 404     private boolean nameExplicitlySet = false;
 405 
 406     /**
 407      * Indicates whether this Component can be focused.
 408      *
 409      * @serial
 410      * @see #setFocusable
 411      * @see #isFocusable
 412      * @since 1.4
 413      */
 414     private boolean focusable = true;
 415 
 416     private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
 417     private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
 418     private static final int FOCUS_TRAVERSABLE_SET = 2;
 419 
 420     /**
 421      * Tracks whether this Component is relying on default focus travesability.
 422      *
 423      * @serial
 424      * @since 1.4
 425      */
 426     private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
 427 
 428     /**
 429      * The focus traversal keys. These keys will generate focus traversal
 430      * behavior for Components for which focus traversal keys are enabled. If a
 431      * value of null is specified for a traversal key, this Component inherits
 432      * that traversal key from its parent. If all ancestors of this Component
 433      * have null specified for that traversal key, then the current
 434      * KeyboardFocusManager's default traversal key is used.
 435      *
 436      * @serial
 437      * @see #setFocusTraversalKeys
 438      * @see #getFocusTraversalKeys
 439      * @since 1.4
 440      */
 441     Set<AWTKeyStroke>[] focusTraversalKeys;


 644      */
 645     private static final long serialVersionUID = -7644114512714619750L;
 646 
 647     /**
 648      * If any <code>PropertyChangeListeners</code> have been registered,
 649      * the <code>changeSupport</code> field describes them.
 650      *
 651      * @serial
 652      * @since 1.2
 653      * @see #addPropertyChangeListener
 654      * @see #removePropertyChangeListener
 655      * @see #firePropertyChange
 656      */
 657     private PropertyChangeSupport changeSupport;
 658 
 659     /*
 660      * In some cases using "this" as an object to synchronize by
 661      * can lead to a deadlock if client code also uses synchronization
 662      * by a component object. For every such situation revealed we should
 663      * consider possibility of replacing "this" with the package private
 664      * objectLock object introduced below. So far there're 3 issues known:
 665      * - CR 6708322 (the getName/setName methods);
 666      * - CR 6608764 (the PropertyChangeListener machinery);
 667      * - CR 7108598 (the Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods).
 668      *
 669      * Note: this field is considered final, though readObject() prohibits
 670      * initializing final fields.
 671      */
 672     private transient Object objectLock = new Object();
 673     Object getObjectLock() {
 674         return objectLock;
 675     }
 676 
 677     /*
 678      * Returns the acc this component was constructed with.
 679      */
 680     final AccessControlContext getAccessControlContext() {
 681         if (acc == null) {
 682             throw new SecurityException("Component is missing AccessControlContext");
 683         }
 684         return acc;


 766          *       baselineOffset--;
 767          *       padding = 1;
 768          *   }
 769          *   // The following calculates where the baseline lands for
 770          *   // the height z:
 771          *   int calculatedBaseline = (z + padding) / 2 + baselineOffset;
 772          * </pre>
 773          */
 774         CENTER_OFFSET,
 775 
 776         /**
 777          * Indicates the baseline resize behavior can not be expressed using
 778          * any of the other constants.  This may also indicate the baseline
 779          * varies with the width of the component.  This is also returned
 780          * by components that do not have a baseline.
 781          */
 782         OTHER
 783     }
 784 
 785     /*
 786      * The shape set with the applyCompoundShape() method. It uncludes the result

 787      * of the HW/LW mixing related shape computation. It may also include
 788      * the user-specified shape of the component.
 789      * The 'null' value means the component has normal shape (or has no shape at all)
 790      * and applyCompoundShape() will skip the following shape identical to normal.
 791      */
 792     private transient Region compoundShape = null;
 793 
 794     /*
 795      * Represents the shape of this lightweight component to be cut out from
 796      * heavyweight components should they intersect. Possible values:
 797      *    1. null - consider the shape rectangular
 798      *    2. EMPTY_REGION - nothing gets cut out (children still get cut out)
 799      *    3. non-empty - this shape gets cut out.
 800      */
 801     private transient Region mixingCutoutRegion = null;
 802 
 803     /*
 804      * Indicates whether addNotify() is complete
 805      * (i.e. the peer is created).
 806      */
 807     private transient boolean isAddNotifyComplete = false;
 808 
 809     /**
 810      * Should only be used in subclass getBounds to check that part of bounds
 811      * is actualy changing
 812      */
 813     int getBoundsOp() {
 814         assert Thread.holdsLock(getTreeLock());
 815         return boundsOp;
 816     }
 817 
 818     void setBoundsOp(int op) {
 819         assert Thread.holdsLock(getTreeLock());
 820         if (op == ComponentPeer.RESET_OPERATION) {
 821             boundsOp = ComponentPeer.DEFAULT_OPERATION;
 822         } else
 823             if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
 824                 boundsOp = op;
 825             }
 826     }
 827 
 828     // Whether this Component has had the background erase flag
 829     // specified via SunToolkit.disableBackgroundErase(). This is
 830     // needed in order to make this function work on X11 platforms,
 831     // where currently there is no chance to interpose on the creation


1674         if (b) {
1675             show();
1676         } else {
1677             hide();
1678         }
1679     }
1680 
1681     boolean containsFocus() {
1682         return isFocusOwner();
1683     }
1684 
1685     void clearMostRecentFocusOwnerOnHide() {
1686         KeyboardFocusManager.clearMostRecentFocusOwner(this);
1687     }
1688 
1689     void clearCurrentFocusCycleRootOnHide() {
1690         /* do nothing */
1691     }
1692 
1693     /*
1694      * Delete references from LightweithDispatcher of a heavyweight parent
1695      */
1696     void clearLightweightDispatcherOnRemove(Component removedComponent) {
1697         if (parent != null) {
1698             parent.clearLightweightDispatcherOnRemove(removedComponent);
1699         }
1700     }
1701 
1702     /**
1703      * @deprecated As of JDK version 1.1,
1704      * replaced by <code>setVisible(boolean)</code>.
1705      */
1706     @Deprecated
1707     public void hide() {
1708         isPacked = false;
1709 
1710         if (visible) {
1711             clearCurrentFocusCycleRootOnHide();
1712             clearMostRecentFocusOwnerOnHide();
1713             synchronized (getTreeLock()) {
1714                 visible = false;


2320                 boolean moved = (this.x != x) || (this.y != y);
2321                 if (!resized && !moved) {
2322                     return;
2323                 }
2324                 int oldX = this.x;
2325                 int oldY = this.y;
2326                 int oldWidth = this.width;
2327                 int oldHeight = this.height;
2328                 this.x = x;
2329                 this.y = y;
2330                 this.width = width;
2331                 this.height = height;
2332 
2333                 if (resized) {
2334                     isPacked = false;
2335                 }
2336 
2337                 boolean needNotify = true;
2338                 mixOnReshaping();
2339                 if (peer != null) {
2340                     // LightwightPeer is an empty stub so can skip peer.reshape
2341                     if (!(peer instanceof LightweightPeer)) {
2342                         reshapeNativePeer(x, y, width, height, getBoundsOp());
2343                         // Check peer actualy changed coordinates
2344                         resized = (oldWidth != this.width) || (oldHeight != this.height);
2345                         moved = (oldX != this.x) || (oldY != this.y);
2346                         // fix for 5025858: do not send ComponentEvents for toplevel
2347                         // windows here as it is done from peer or native code when
2348                         // the window is really resized or moved, otherwise some
2349                         // events may be sent twice
2350                         if (this instanceof Window) {
2351                             needNotify = false;
2352                         }
2353                     }
2354                     if (resized) {
2355                         invalidate();
2356                     }
2357                     if (parent != null) {
2358                         parent.invalidateIfValid();
2359                     }
2360                 }
2361                 if (needNotify) {
2362                     notifyNewBounds(resized, moved);
2363                 }


5089 
5090                 newMWE = new MouseWheelEvent(anc, // new source
5091                                              e.getID(),
5092                                              e.getWhen(),
5093                                              e.getModifiers(),
5094                                              newX, // x relative to new source
5095                                              newY, // y relative to new source
5096                                              e.getXOnScreen(),
5097                                              e.getYOnScreen(),
5098                                              e.getClickCount(),
5099                                              e.isPopupTrigger(),
5100                                              e.getScrollType(),
5101                                              e.getScrollAmount(),
5102                                              e.getWheelRotation(),
5103                                              e.getPreciseWheelRotation());
5104                 ((AWTEvent)e).copyPrivateDataInto(newMWE);
5105                 // When dispatching a wheel event to
5106                 // ancestor, there is no need trying to find descendant
5107                 // lightweights to dispatch event to.
5108                 // If we dispatch the event to toplevel ancestor,
5109                 // this could encolse the loop: 6480024.
5110                 anc.dispatchEventToSelf(newMWE);
5111                 if (newMWE.isConsumed()) {
5112                     e.consume();
5113                 }
5114                 return true;
5115             }
5116         }
5117         return false;
5118     }
5119 
5120     boolean areInputMethodsEnabled() {
5121         // in 1.2, we assume input method support is required for all
5122         // components that handle key events, but components can turn off
5123         // input methods by calling enableInputMethods(false).
5124         return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
5125             ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
5126     }
5127 
5128     // REMIND: remove when filtering is handled at lower level
5129     boolean eventEnabled(AWTEvent e) {


6186     transient sun.awt.EventQueueItem[] eventCache;
6187 
6188     /**
6189      * @see #isCoalescingEnabled
6190      * @see #checkCoalescing
6191      */
6192     transient private boolean coalescingEnabled = checkCoalescing();
6193 
6194     /**
6195      * Weak map of known coalesceEvent overriders.
6196      * Value indicates whether overriden.
6197      * Bootstrap classes are not included.
6198      */
6199     private static final Map<Class<?>, Boolean> coalesceMap =
6200         new java.util.WeakHashMap<Class<?>, Boolean>();
6201 
6202     /**
6203      * Indicates whether this class overrides coalesceEvents.
6204      * It is assumed that all classes that are loaded from the bootstrap
6205      *   do not.
6206      * The boostrap class loader is assumed to be represented by null.
6207      * We do not check that the method really overrides
6208      *   (it might be static, private or package private).
6209      */
6210      private boolean checkCoalescing() {
6211          if (getClass().getClassLoader()==null) {
6212              return false;
6213          }
6214          final Class<? extends Component> clazz = getClass();
6215          synchronized (coalesceMap) {
6216              // Check cache.
6217              Boolean value = coalesceMap.get(clazz);
6218              if (value != null) {
6219                  return value;
6220              }
6221 
6222              // Need to check non-bootstraps.
6223              Boolean enabled = java.security.AccessController.doPrivileged(
6224                  new java.security.PrivilegedAction<Boolean>() {
6225                      public Boolean run() {
6226                          return isCoalesceEventsOverriden(clazz);


6234 
6235     /**
6236      * Parameter types of coalesceEvents(AWTEvent,AWTEVent).
6237      */
6238     private static final Class<?>[] coalesceEventsParams = {
6239         AWTEvent.class, AWTEvent.class
6240     };
6241 
6242     /**
6243      * Indicates whether a class or its superclasses override coalesceEvents.
6244      * Must be called with lock on coalesceMap and privileged.
6245      * @see checkCoalsecing
6246      */
6247     private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
6248         assert Thread.holdsLock(coalesceMap);
6249 
6250         // First check superclass - we may not need to bother ourselves.
6251         Class<?> superclass = clazz.getSuperclass();
6252         if (superclass == null) {
6253             // Only occurs on implementations that
6254             //   do not use null to represent the bootsrap class loader.
6255             return false;
6256         }
6257         if (superclass.getClassLoader() != null) {
6258             Boolean value = coalesceMap.get(superclass);
6259             if (value == null) {
6260                 // Not done already - recurse.
6261                 if (isCoalesceEventsOverriden(superclass)) {
6262                     coalesceMap.put(superclass, true);
6263                     return true;
6264                 }
6265             } else if (value) {
6266                 return true;
6267             }
6268         }
6269 
6270         try {
6271             // Throws if not overriden.
6272             clazz.getDeclaredMethod(
6273                 "coalesceEvents", coalesceEventsParams
6274                 );


7744                 // of the toplevel. If, by any means, due to asynchronous nature of the event
7745                 // dispatching mechanism, the window happens to be natively inactive by the time
7746                 // this focus request is eventually handled, it should not re-activate the
7747                 // toplevel. Otherwise the result may not meet user expectations. See 6981400.
7748                 focusedWindowChangeAllowed = false;
7749             }
7750         }
7751         if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
7752             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7753                 focusLog.finest("requestFocus is not accepted");
7754             }
7755             return false;
7756         }
7757         // Update most-recent map
7758         KeyboardFocusManager.setMostRecentFocusOwner(this);
7759 
7760         Component window = this;
7761         while ( (window != null) && !(window instanceof Window)) {
7762             if (!window.isVisible()) {
7763                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7764                     focusLog.finest("component is recurively invisible");
7765                 }
7766                 return false;
7767             }
7768             window = window.parent;
7769         }
7770 
7771         ComponentPeer peer = this.peer;
7772         Component heavyweight = (peer instanceof LightweightPeer)
7773             ? getNativeContainer() : this;
7774         if (heavyweight == null || !heavyweight.isVisible()) {
7775             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7776                 focusLog.finest("Component is not a part of visible hierarchy");
7777             }
7778             return false;
7779         }
7780         peer = heavyweight.peer;
7781         if (peer == null) {
7782             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7783                 focusLog.finest("Peer is null");
7784             }


7848             if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7849                 focusOwner = null;
7850             }
7851         }
7852 
7853         if (focusOwner == this || focusOwner == null) {
7854             // Controller is supposed to verify focus transfers and for this it
7855             // should know both from and to components.  And it shouldn't verify
7856             // transfers from when these components are equal.
7857             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7858                 focusLog.finest("focus owner is null or this");
7859             }
7860             return true;
7861         }
7862 
7863         if (CausedFocusEvent.Cause.ACTIVATION == cause) {
7864             // we shouldn't call RequestFocusController in case we are
7865             // in activation.  We do request focus on component which
7866             // has got temporary focus lost and then on component which is
7867             // most recent focus owner.  But most recent focus owner can be
7868             // changed by requestFocsuXXX() call only, so this transfer has
7869             // been already approved.
7870             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7871                 focusLog.finest("cause is activation");
7872             }
7873             return true;
7874         }
7875 
7876         boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
7877                                                                           this,
7878                                                                           temporary,
7879                                                                           focusedWindowChangeAllowed,
7880                                                                           cause);
7881         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7882             focusLog.finest("RequestFocusController returns {0}", ret);
7883         }
7884 
7885         return ret;
7886     }
7887 
7888     private static RequestFocusController requestFocusController = new DummyRequestFocusController();


8675     }
8676 
8677 
8678     // Serialization support.
8679 
8680     /**
8681      * Component Serialized Data Version.
8682      *
8683      * @serial
8684      */
8685     private int componentSerializedDataVersion = 4;
8686 
8687     /**
8688      * This hack is for Swing serialization. It will invoke
8689      * the Swing package private method <code>compWriteObjectNotify</code>.
8690      */
8691     private void doSwingSerialization() {
8692         Package swingPackage = Package.getPackage("javax.swing");
8693         // For Swing serialization to correctly work Swing needs to
8694         // be notified before Component does it's serialization.  This
8695         // hack accomodates this.
8696         //
8697         // Swing classes MUST be loaded by the bootstrap class loader,
8698         // otherwise we don't consider them.
8699         for (Class<?> klass = Component.this.getClass(); klass != null;
8700                    klass = klass.getSuperclass()) {
8701             if (klass.getPackage() == swingPackage &&
8702                       klass.getClassLoader() == null) {
8703                 final Class<?> swingClass = klass;
8704                 // Find the first override of the compWriteObjectNotify method
8705                 Method[] methods = AccessController.doPrivileged(
8706                                                                  new PrivilegedAction<Method[]>() {
8707                                                                      public Method[] run() {
8708                                                                          return swingClass.getDeclaredMethods();
8709                                                                      }
8710                                                                  });
8711                 for (int counter = methods.length - 1; counter >= 0;
8712                      counter--) {
8713                     final Method method = methods[counter];
8714                     if (method.getName().equals("compWriteObjectNotify")){
8715                         // We found it, use doPrivileged to make it accessible


9023      * @see #getComponentOrientation
9024      * @see #invalidate
9025      * @since 1.4
9026      */
9027     public void applyComponentOrientation(ComponentOrientation orientation) {
9028         if (orientation == null) {
9029             throw new NullPointerException();
9030         }
9031         setComponentOrientation(orientation);
9032     }
9033 
9034     final boolean canBeFocusOwner() {
9035         // It is enabled, visible, focusable.
9036         if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
9037             return true;
9038         }
9039         return false;
9040     }
9041 
9042     /**
9043      * Checks that this component meets the prerequesites to be focus owner:
9044      * - it is enabled, visible, focusable
9045      * - it's parents are all enabled and showing
9046      * - top-level window is focusable
9047      * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
9048      * this component as focus owner
9049      * @since 1.5
9050      */
9051     final boolean canBeFocusOwnerRecursively() {
9052         // - it is enabled, visible, focusable
9053         if (!canBeFocusOwner()) {
9054             return false;
9055         }
9056 
9057         // - it's parents are all enabled and showing
9058         synchronized(getTreeLock()) {
9059             if (parent != null) {
9060                 return parent.canContainFocusOwner(this);
9061             }
9062         }
9063         return true;


9632          */
9633         public Rectangle getBounds() {
9634             return Component.this.getBounds();
9635         }
9636 
9637         /**
9638          * Sets the bounds of this object in the form of a
9639          * <code>Rectangle</code> object.
9640          * The bounds specify this object's width, height, and location
9641          * relative to its parent.
9642          *
9643          * @param r a rectangle indicating this component's bounds
9644          */
9645         public void setBounds(Rectangle r) {
9646             Component.this.setBounds(r);
9647         }
9648 
9649         /**
9650          * Returns the size of this object in the form of a
9651          * <code>Dimension</code> object. The height field of the
9652          * <code>Dimension</code> object contains this objects's
9653          * height, and the width field of the <code>Dimension</code>
9654          * object contains this object's width.
9655          *
9656          * @return a <code>Dimension</code> object that indicates
9657          *     the size of this component; <code>null</code> if
9658          *     this object is not on the screen
9659          */
9660         public Dimension getSize() {
9661             return Component.this.getSize();
9662         }
9663 
9664         /**
9665          * Resizes this object so that it has width and height.
9666          *
9667          * @param d - the dimension specifying the new size of the object
9668          */
9669         public void setSize(Dimension d) {
9670             Component.this.setSize(d);
9671         }
9672 


9816     static boolean isInstanceOf(Object obj, String className) {
9817         if (obj == null) return false;
9818         if (className == null) return false;
9819 
9820         Class<?> cls = obj.getClass();
9821         while (cls != null) {
9822             if (cls.getName().equals(className)) {
9823                 return true;
9824             }
9825             cls = cls.getSuperclass();
9826         }
9827         return false;
9828     }
9829 
9830 
9831     // ************************** MIXING CODE *******************************
9832 
9833     /**
9834      * Check whether we can trust the current bounds of the component.
9835      * The return value of false indicates that the container of the
9836      * component is invalid, and therefore needs to be layed out, which would
9837      * probably mean changing the bounds of its children.
9838      * Null-layout of the container or absence of the container mean
9839      * the bounds of the component are final and can be trusted.
9840      */
9841     final boolean areBoundsValid() {
9842         Container cont = getContainer();
9843         return cont == null || cont.isValid() || cont.getLayout() == null;
9844     }
9845 
9846     /**
9847      * Applies the shape to the component
9848      * @param shape Shape to be applied to the component
9849      */
9850     void applyCompoundShape(Region shape) {
9851         checkTreeLock();
9852 
9853         if (!areBoundsValid()) {
9854             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
9855                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9856             }




 150  *    class MyApp implements java.io.Serializable
 151  *    {
 152  *         BigObjectThatShouldNotBeSerializedWithAButton bigOne;
 153  *         Button aButton = new Button();
 154  *
 155  *         static class MyActionListener implements ActionListener
 156  *         {
 157  *             public void actionPerformed(ActionEvent e)
 158  *             {
 159  *                 System.out.println("Hello There");
 160  *             }
 161  *         }
 162  *
 163  *         MyApp()
 164  *         {
 165  *             aButton.addActionListener(new MyActionListener());
 166  *         }
 167  *    }
 168  * </pre>
 169  * <p>
 170  * <b>Note</b>: For more information on the paint mechanisms utilized
 171  * by AWT and Swing, including information on how to write the most
 172  * efficient painting code, see
 173  * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.
 174  * <p>
 175  * For details on the focus subsystem, see
 176  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
 177  * How to Use the Focus Subsystem</a>,
 178  * a section in <em>The Java Tutorial</em>, and the
 179  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
 180  * for more information.
 181  *
 182  * @author      Arthur van Hoff
 183  * @author      Sami Shaio
 184  */
 185 public abstract class Component implements ImageObserver, MenuContainer,
 186                                            Serializable
 187 {
 188 
 189     private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component");
 190     private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component");


 338      * visible is not drawn on the screen.
 339      *
 340      * @serial
 341      * @see #isVisible
 342      * @see #setVisible
 343      */
 344     boolean visible = true;
 345 
 346     /**
 347      * True when the object is enabled. An object that is not
 348      * enabled does not interact with the user.
 349      *
 350      * @serial
 351      * @see #isEnabled
 352      * @see #setEnabled
 353      */
 354     boolean enabled = true;
 355 
 356     /**
 357      * True when the object is valid. An invalid object needs to
 358      * be laid out. This flag is set to false when the object
 359      * size is changed.
 360      *
 361      * @serial
 362      * @see #isValid
 363      * @see #validate
 364      * @see #invalidate
 365      */
 366     private volatile boolean valid = false;
 367 
 368     /**
 369      * The <code>DropTarget</code> associated with this component.
 370      *
 371      * @since 1.2
 372      * @serial
 373      * @see #setDropTarget
 374      * @see #getDropTarget
 375      */
 376     DropTarget dropTarget;
 377 
 378     /**


 401      * @see #getName
 402      * @see #setName(String)
 403      */
 404     private boolean nameExplicitlySet = false;
 405 
 406     /**
 407      * Indicates whether this Component can be focused.
 408      *
 409      * @serial
 410      * @see #setFocusable
 411      * @see #isFocusable
 412      * @since 1.4
 413      */
 414     private boolean focusable = true;
 415 
 416     private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
 417     private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
 418     private static final int FOCUS_TRAVERSABLE_SET = 2;
 419 
 420     /**
 421      * Tracks whether this Component is relying on default focus traversability.
 422      *
 423      * @serial
 424      * @since 1.4
 425      */
 426     private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
 427 
 428     /**
 429      * The focus traversal keys. These keys will generate focus traversal
 430      * behavior for Components for which focus traversal keys are enabled. If a
 431      * value of null is specified for a traversal key, this Component inherits
 432      * that traversal key from its parent. If all ancestors of this Component
 433      * have null specified for that traversal key, then the current
 434      * KeyboardFocusManager's default traversal key is used.
 435      *
 436      * @serial
 437      * @see #setFocusTraversalKeys
 438      * @see #getFocusTraversalKeys
 439      * @since 1.4
 440      */
 441     Set<AWTKeyStroke>[] focusTraversalKeys;


 644      */
 645     private static final long serialVersionUID = -7644114512714619750L;
 646 
 647     /**
 648      * If any <code>PropertyChangeListeners</code> have been registered,
 649      * the <code>changeSupport</code> field describes them.
 650      *
 651      * @serial
 652      * @since 1.2
 653      * @see #addPropertyChangeListener
 654      * @see #removePropertyChangeListener
 655      * @see #firePropertyChange
 656      */
 657     private PropertyChangeSupport changeSupport;
 658 
 659     /*
 660      * In some cases using "this" as an object to synchronize by
 661      * can lead to a deadlock if client code also uses synchronization
 662      * by a component object. For every such situation revealed we should
 663      * consider possibility of replacing "this" with the package private
 664      * objectLock object introduced below. So far there are 3 issues known:
 665      * - CR 6708322 (the getName/setName methods);
 666      * - CR 6608764 (the PropertyChangeListener machinery);
 667      * - CR 7108598 (the Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods).
 668      *
 669      * Note: this field is considered final, though readObject() prohibits
 670      * initializing final fields.
 671      */
 672     private transient Object objectLock = new Object();
 673     Object getObjectLock() {
 674         return objectLock;
 675     }
 676 
 677     /*
 678      * Returns the acc this component was constructed with.
 679      */
 680     final AccessControlContext getAccessControlContext() {
 681         if (acc == null) {
 682             throw new SecurityException("Component is missing AccessControlContext");
 683         }
 684         return acc;


 766          *       baselineOffset--;
 767          *       padding = 1;
 768          *   }
 769          *   // The following calculates where the baseline lands for
 770          *   // the height z:
 771          *   int calculatedBaseline = (z + padding) / 2 + baselineOffset;
 772          * </pre>
 773          */
 774         CENTER_OFFSET,
 775 
 776         /**
 777          * Indicates the baseline resize behavior can not be expressed using
 778          * any of the other constants.  This may also indicate the baseline
 779          * varies with the width of the component.  This is also returned
 780          * by components that do not have a baseline.
 781          */
 782         OTHER
 783     }
 784 
 785     /*
 786      * The shape set with the applyCompoundShape() method. It includes the
 787      * result
 788      * of the HW/LW mixing related shape computation. It may also include
 789      * the user-specified shape of the component.
 790      * The 'null' value means the component has normal shape (or has no shape at all)
 791      * and applyCompoundShape() will skip the following shape identical to normal.
 792      */
 793     private transient Region compoundShape = null;
 794 
 795     /*
 796      * Represents the shape of this lightweight component to be cut out from
 797      * heavyweight components should they intersect. Possible values:
 798      *    1. null - consider the shape rectangular
 799      *    2. EMPTY_REGION - nothing gets cut out (children still get cut out)
 800      *    3. non-empty - this shape gets cut out.
 801      */
 802     private transient Region mixingCutoutRegion = null;
 803 
 804     /*
 805      * Indicates whether addNotify() is complete
 806      * (i.e. the peer is created).
 807      */
 808     private transient boolean isAddNotifyComplete = false;
 809 
 810     /**
 811      * Should only be used in subclass getBounds to check that part of bounds
 812      * is actually changing
 813      */
 814     int getBoundsOp() {
 815         assert Thread.holdsLock(getTreeLock());
 816         return boundsOp;
 817     }
 818 
 819     void setBoundsOp(int op) {
 820         assert Thread.holdsLock(getTreeLock());
 821         if (op == ComponentPeer.RESET_OPERATION) {
 822             boundsOp = ComponentPeer.DEFAULT_OPERATION;
 823         } else
 824             if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
 825                 boundsOp = op;
 826             }
 827     }
 828 
 829     // Whether this Component has had the background erase flag
 830     // specified via SunToolkit.disableBackgroundErase(). This is
 831     // needed in order to make this function work on X11 platforms,
 832     // where currently there is no chance to interpose on the creation


1675         if (b) {
1676             show();
1677         } else {
1678             hide();
1679         }
1680     }
1681 
1682     boolean containsFocus() {
1683         return isFocusOwner();
1684     }
1685 
1686     void clearMostRecentFocusOwnerOnHide() {
1687         KeyboardFocusManager.clearMostRecentFocusOwner(this);
1688     }
1689 
1690     void clearCurrentFocusCycleRootOnHide() {
1691         /* do nothing */
1692     }
1693 
1694     /*
1695      * Delete references from LightweightDispatcher of a heavyweight parent
1696      */
1697     void clearLightweightDispatcherOnRemove(Component removedComponent) {
1698         if (parent != null) {
1699             parent.clearLightweightDispatcherOnRemove(removedComponent);
1700         }
1701     }
1702 
1703     /**
1704      * @deprecated As of JDK version 1.1,
1705      * replaced by <code>setVisible(boolean)</code>.
1706      */
1707     @Deprecated
1708     public void hide() {
1709         isPacked = false;
1710 
1711         if (visible) {
1712             clearCurrentFocusCycleRootOnHide();
1713             clearMostRecentFocusOwnerOnHide();
1714             synchronized (getTreeLock()) {
1715                 visible = false;


2321                 boolean moved = (this.x != x) || (this.y != y);
2322                 if (!resized && !moved) {
2323                     return;
2324                 }
2325                 int oldX = this.x;
2326                 int oldY = this.y;
2327                 int oldWidth = this.width;
2328                 int oldHeight = this.height;
2329                 this.x = x;
2330                 this.y = y;
2331                 this.width = width;
2332                 this.height = height;
2333 
2334                 if (resized) {
2335                     isPacked = false;
2336                 }
2337 
2338                 boolean needNotify = true;
2339                 mixOnReshaping();
2340                 if (peer != null) {
2341                     // LightweightPeer is an empty stub so can skip peer.reshape
2342                     if (!(peer instanceof LightweightPeer)) {
2343                         reshapeNativePeer(x, y, width, height, getBoundsOp());
2344                         // Check peer actually changed coordinates
2345                         resized = (oldWidth != this.width) || (oldHeight != this.height);
2346                         moved = (oldX != this.x) || (oldY != this.y);
2347                         // fix for 5025858: do not send ComponentEvents for toplevel
2348                         // windows here as it is done from peer or native code when
2349                         // the window is really resized or moved, otherwise some
2350                         // events may be sent twice
2351                         if (this instanceof Window) {
2352                             needNotify = false;
2353                         }
2354                     }
2355                     if (resized) {
2356                         invalidate();
2357                     }
2358                     if (parent != null) {
2359                         parent.invalidateIfValid();
2360                     }
2361                 }
2362                 if (needNotify) {
2363                     notifyNewBounds(resized, moved);
2364                 }


5090 
5091                 newMWE = new MouseWheelEvent(anc, // new source
5092                                              e.getID(),
5093                                              e.getWhen(),
5094                                              e.getModifiers(),
5095                                              newX, // x relative to new source
5096                                              newY, // y relative to new source
5097                                              e.getXOnScreen(),
5098                                              e.getYOnScreen(),
5099                                              e.getClickCount(),
5100                                              e.isPopupTrigger(),
5101                                              e.getScrollType(),
5102                                              e.getScrollAmount(),
5103                                              e.getWheelRotation(),
5104                                              e.getPreciseWheelRotation());
5105                 ((AWTEvent)e).copyPrivateDataInto(newMWE);
5106                 // When dispatching a wheel event to
5107                 // ancestor, there is no need trying to find descendant
5108                 // lightweights to dispatch event to.
5109                 // If we dispatch the event to toplevel ancestor,
5110                 // this could enclose the loop: 6480024.
5111                 anc.dispatchEventToSelf(newMWE);
5112                 if (newMWE.isConsumed()) {
5113                     e.consume();
5114                 }
5115                 return true;
5116             }
5117         }
5118         return false;
5119     }
5120 
5121     boolean areInputMethodsEnabled() {
5122         // in 1.2, we assume input method support is required for all
5123         // components that handle key events, but components can turn off
5124         // input methods by calling enableInputMethods(false).
5125         return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
5126             ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
5127     }
5128 
5129     // REMIND: remove when filtering is handled at lower level
5130     boolean eventEnabled(AWTEvent e) {


6187     transient sun.awt.EventQueueItem[] eventCache;
6188 
6189     /**
6190      * @see #isCoalescingEnabled
6191      * @see #checkCoalescing
6192      */
6193     transient private boolean coalescingEnabled = checkCoalescing();
6194 
6195     /**
6196      * Weak map of known coalesceEvent overriders.
6197      * Value indicates whether overriden.
6198      * Bootstrap classes are not included.
6199      */
6200     private static final Map<Class<?>, Boolean> coalesceMap =
6201         new java.util.WeakHashMap<Class<?>, Boolean>();
6202 
6203     /**
6204      * Indicates whether this class overrides coalesceEvents.
6205      * It is assumed that all classes that are loaded from the bootstrap
6206      *   do not.
6207      * The bootstrap class loader is assumed to be represented by null.
6208      * We do not check that the method really overrides
6209      *   (it might be static, private or package private).
6210      */
6211      private boolean checkCoalescing() {
6212          if (getClass().getClassLoader()==null) {
6213              return false;
6214          }
6215          final Class<? extends Component> clazz = getClass();
6216          synchronized (coalesceMap) {
6217              // Check cache.
6218              Boolean value = coalesceMap.get(clazz);
6219              if (value != null) {
6220                  return value;
6221              }
6222 
6223              // Need to check non-bootstraps.
6224              Boolean enabled = java.security.AccessController.doPrivileged(
6225                  new java.security.PrivilegedAction<Boolean>() {
6226                      public Boolean run() {
6227                          return isCoalesceEventsOverriden(clazz);


6235 
6236     /**
6237      * Parameter types of coalesceEvents(AWTEvent,AWTEVent).
6238      */
6239     private static final Class<?>[] coalesceEventsParams = {
6240         AWTEvent.class, AWTEvent.class
6241     };
6242 
6243     /**
6244      * Indicates whether a class or its superclasses override coalesceEvents.
6245      * Must be called with lock on coalesceMap and privileged.
6246      * @see checkCoalsecing
6247      */
6248     private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
6249         assert Thread.holdsLock(coalesceMap);
6250 
6251         // First check superclass - we may not need to bother ourselves.
6252         Class<?> superclass = clazz.getSuperclass();
6253         if (superclass == null) {
6254             // Only occurs on implementations that
6255             //   do not use null to represent the bootstrap class loader.
6256             return false;
6257         }
6258         if (superclass.getClassLoader() != null) {
6259             Boolean value = coalesceMap.get(superclass);
6260             if (value == null) {
6261                 // Not done already - recurse.
6262                 if (isCoalesceEventsOverriden(superclass)) {
6263                     coalesceMap.put(superclass, true);
6264                     return true;
6265                 }
6266             } else if (value) {
6267                 return true;
6268             }
6269         }
6270 
6271         try {
6272             // Throws if not overriden.
6273             clazz.getDeclaredMethod(
6274                 "coalesceEvents", coalesceEventsParams
6275                 );


7745                 // of the toplevel. If, by any means, due to asynchronous nature of the event
7746                 // dispatching mechanism, the window happens to be natively inactive by the time
7747                 // this focus request is eventually handled, it should not re-activate the
7748                 // toplevel. Otherwise the result may not meet user expectations. See 6981400.
7749                 focusedWindowChangeAllowed = false;
7750             }
7751         }
7752         if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
7753             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7754                 focusLog.finest("requestFocus is not accepted");
7755             }
7756             return false;
7757         }
7758         // Update most-recent map
7759         KeyboardFocusManager.setMostRecentFocusOwner(this);
7760 
7761         Component window = this;
7762         while ( (window != null) && !(window instanceof Window)) {
7763             if (!window.isVisible()) {
7764                 if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7765                     focusLog.finest("component is recursively invisible");
7766                 }
7767                 return false;
7768             }
7769             window = window.parent;
7770         }
7771 
7772         ComponentPeer peer = this.peer;
7773         Component heavyweight = (peer instanceof LightweightPeer)
7774             ? getNativeContainer() : this;
7775         if (heavyweight == null || !heavyweight.isVisible()) {
7776             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7777                 focusLog.finest("Component is not a part of visible hierarchy");
7778             }
7779             return false;
7780         }
7781         peer = heavyweight.peer;
7782         if (peer == null) {
7783             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7784                 focusLog.finest("Peer is null");
7785             }


7849             if (focusOwner != null && focusOwner.getContainingWindow() != window) {
7850                 focusOwner = null;
7851             }
7852         }
7853 
7854         if (focusOwner == this || focusOwner == null) {
7855             // Controller is supposed to verify focus transfers and for this it
7856             // should know both from and to components.  And it shouldn't verify
7857             // transfers from when these components are equal.
7858             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7859                 focusLog.finest("focus owner is null or this");
7860             }
7861             return true;
7862         }
7863 
7864         if (CausedFocusEvent.Cause.ACTIVATION == cause) {
7865             // we shouldn't call RequestFocusController in case we are
7866             // in activation.  We do request focus on component which
7867             // has got temporary focus lost and then on component which is
7868             // most recent focus owner.  But most recent focus owner can be
7869             // changed by requestFocusXXX() call only, so this transfer has
7870             // been already approved.
7871             if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7872                 focusLog.finest("cause is activation");
7873             }
7874             return true;
7875         }
7876 
7877         boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,
7878                                                                           this,
7879                                                                           temporary,
7880                                                                           focusedWindowChangeAllowed,
7881                                                                           cause);
7882         if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
7883             focusLog.finest("RequestFocusController returns {0}", ret);
7884         }
7885 
7886         return ret;
7887     }
7888 
7889     private static RequestFocusController requestFocusController = new DummyRequestFocusController();


8676     }
8677 
8678 
8679     // Serialization support.
8680 
8681     /**
8682      * Component Serialized Data Version.
8683      *
8684      * @serial
8685      */
8686     private int componentSerializedDataVersion = 4;
8687 
8688     /**
8689      * This hack is for Swing serialization. It will invoke
8690      * the Swing package private method <code>compWriteObjectNotify</code>.
8691      */
8692     private void doSwingSerialization() {
8693         Package swingPackage = Package.getPackage("javax.swing");
8694         // For Swing serialization to correctly work Swing needs to
8695         // be notified before Component does it's serialization.  This
8696         // hack accommodates this.
8697         //
8698         // Swing classes MUST be loaded by the bootstrap class loader,
8699         // otherwise we don't consider them.
8700         for (Class<?> klass = Component.this.getClass(); klass != null;
8701                    klass = klass.getSuperclass()) {
8702             if (klass.getPackage() == swingPackage &&
8703                       klass.getClassLoader() == null) {
8704                 final Class<?> swingClass = klass;
8705                 // Find the first override of the compWriteObjectNotify method
8706                 Method[] methods = AccessController.doPrivileged(
8707                                                                  new PrivilegedAction<Method[]>() {
8708                                                                      public Method[] run() {
8709                                                                          return swingClass.getDeclaredMethods();
8710                                                                      }
8711                                                                  });
8712                 for (int counter = methods.length - 1; counter >= 0;
8713                      counter--) {
8714                     final Method method = methods[counter];
8715                     if (method.getName().equals("compWriteObjectNotify")){
8716                         // We found it, use doPrivileged to make it accessible


9024      * @see #getComponentOrientation
9025      * @see #invalidate
9026      * @since 1.4
9027      */
9028     public void applyComponentOrientation(ComponentOrientation orientation) {
9029         if (orientation == null) {
9030             throw new NullPointerException();
9031         }
9032         setComponentOrientation(orientation);
9033     }
9034 
9035     final boolean canBeFocusOwner() {
9036         // It is enabled, visible, focusable.
9037         if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
9038             return true;
9039         }
9040         return false;
9041     }
9042 
9043     /**
9044      * Checks that this component meets the prerequisites to be focus owner:
9045      * - it is enabled, visible, focusable
9046      * - it's parents are all enabled and showing
9047      * - top-level window is focusable
9048      * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
9049      * this component as focus owner
9050      * @since 1.5
9051      */
9052     final boolean canBeFocusOwnerRecursively() {
9053         // - it is enabled, visible, focusable
9054         if (!canBeFocusOwner()) {
9055             return false;
9056         }
9057 
9058         // - it's parents are all enabled and showing
9059         synchronized(getTreeLock()) {
9060             if (parent != null) {
9061                 return parent.canContainFocusOwner(this);
9062             }
9063         }
9064         return true;


9633          */
9634         public Rectangle getBounds() {
9635             return Component.this.getBounds();
9636         }
9637 
9638         /**
9639          * Sets the bounds of this object in the form of a
9640          * <code>Rectangle</code> object.
9641          * The bounds specify this object's width, height, and location
9642          * relative to its parent.
9643          *
9644          * @param r a rectangle indicating this component's bounds
9645          */
9646         public void setBounds(Rectangle r) {
9647             Component.this.setBounds(r);
9648         }
9649 
9650         /**
9651          * Returns the size of this object in the form of a
9652          * <code>Dimension</code> object. The height field of the
9653          * <code>Dimension</code> object contains this object's
9654          * height, and the width field of the <code>Dimension</code>
9655          * object contains this object's width.
9656          *
9657          * @return a <code>Dimension</code> object that indicates
9658          *     the size of this component; <code>null</code> if
9659          *     this object is not on the screen
9660          */
9661         public Dimension getSize() {
9662             return Component.this.getSize();
9663         }
9664 
9665         /**
9666          * Resizes this object so that it has width and height.
9667          *
9668          * @param d - the dimension specifying the new size of the object
9669          */
9670         public void setSize(Dimension d) {
9671             Component.this.setSize(d);
9672         }
9673 


9817     static boolean isInstanceOf(Object obj, String className) {
9818         if (obj == null) return false;
9819         if (className == null) return false;
9820 
9821         Class<?> cls = obj.getClass();
9822         while (cls != null) {
9823             if (cls.getName().equals(className)) {
9824                 return true;
9825             }
9826             cls = cls.getSuperclass();
9827         }
9828         return false;
9829     }
9830 
9831 
9832     // ************************** MIXING CODE *******************************
9833 
9834     /**
9835      * Check whether we can trust the current bounds of the component.
9836      * The return value of false indicates that the container of the
9837      * component is invalid, and therefore needs to be laid out, which would
9838      * probably mean changing the bounds of its children.
9839      * Null-layout of the container or absence of the container mean
9840      * the bounds of the component are final and can be trusted.
9841      */
9842     final boolean areBoundsValid() {
9843         Container cont = getContainer();
9844         return cont == null || cont.isValid() || cont.getLayout() == null;
9845     }
9846 
9847     /**
9848      * Applies the shape to the component
9849      * @param shape Shape to be applied to the component
9850      */
9851     void applyCompoundShape(Region shape) {
9852         checkTreeLock();
9853 
9854         if (!areBoundsValid()) {
9855             if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {
9856                 mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());
9857             }