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 }
|