0001 /*
0002 * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025 package java.awt;
0026
0027 import java.io.PrintStream;
0028 import java.io.PrintWriter;
0029 import java.util.Vector;
0030 import java.util.Locale;
0031 import java.util.EventListener;
0032 import java.util.Iterator;
0033 import java.util.HashSet;
0034 import java.util.Map;
0035 import java.util.Set;
0036 import java.util.Collections;
0037 import java.awt.peer.ComponentPeer;
0038 import java.awt.peer.ContainerPeer;
0039 import java.awt.peer.LightweightPeer;
0040 import java.awt.image.BufferStrategy;
0041 import java.awt.image.ImageObserver;
0042 import java.awt.image.ImageProducer;
0043 import java.awt.image.ColorModel;
0044 import java.awt.image.VolatileImage;
0045 import java.awt.event.*;
0046 import java.io.Serializable;
0047 import java.io.ObjectOutputStream;
0048 import java.io.ObjectInputStream;
0049 import java.io.IOException;
0050 import java.beans.PropertyChangeListener;
0051 import java.beans.PropertyChangeSupport;
0052 import java.awt.event.InputMethodListener;
0053 import java.awt.event.InputMethodEvent;
0054 import java.awt.im.InputContext;
0055 import java.awt.im.InputMethodRequests;
0056 import java.awt.dnd.DropTarget;
0057 import java.lang.reflect.InvocationTargetException;
0058 import java.lang.reflect.Method;
0059 import java.security.AccessController;
0060 import java.security.PrivilegedAction;
0061 import javax.accessibility.*;
0062 import java.util.logging.*;
0063 import java.applet.Applet;
0064
0065 import sun.security.action.GetPropertyAction;
0066 import sun.awt.AppContext;
0067 import sun.awt.ConstrainableGraphics;
0068 import sun.awt.DebugHelper;
0069 import sun.awt.SubRegionShowable;
0070 import sun.awt.WindowClosingListener;
0071 import sun.awt.CausedFocusEvent;
0072 import sun.awt.EmbeddedFrame;
0073 import sun.awt.dnd.SunDropTargetEvent;
0074 import sun.awt.im.CompositionArea;
0075 import sun.java2d.SunGraphics2D;
0076 import sun.awt.RequestFocusController;
0077
0078 /**
0079 * A <em>component</em> is an object having a graphical representation
0080 * that can be displayed on the screen and that can interact with the
0081 * user. Examples of components are the buttons, checkboxes, and scrollbars
0082 * of a typical graphical user interface. <p>
0083 * The <code>Component</code> class is the abstract superclass of
0084 * the nonmenu-related Abstract Window Toolkit components. Class
0085 * <code>Component</code> can also be extended directly to create a
0086 * lightweight component. A lightweight component is a component that is
0087 * not associated with a native opaque window.
0088 * <p>
0089 * <h3>Serialization</h3>
0090 * It is important to note that only AWT listeners which conform
0091 * to the <code>Serializable</code> protocol will be saved when
0092 * the object is stored. If an AWT object has listeners that
0093 * aren't marked serializable, they will be dropped at
0094 * <code>writeObject</code> time. Developers will need, as always,
0095 * to consider the implications of making an object serializable.
0096 * One situation to watch out for is this:
0097 * <pre>
0098 * import java.awt.*;
0099 * import java.awt.event.*;
0100 * import java.io.Serializable;
0101 *
0102 * class MyApp implements ActionListener, Serializable
0103 * {
0104 * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
0105 * Button aButton = new Button();
0106 *
0107 * MyApp()
0108 * {
0109 * // Oops, now aButton has a listener with a reference
0110 * // to bigOne!
0111 * aButton.addActionListener(this);
0112 * }
0113 *
0114 * public void actionPerformed(ActionEvent e)
0115 * {
0116 * System.out.println("Hello There");
0117 * }
0118 * }
0119 * </pre>
0120 * In this example, serializing <code>aButton</code> by itself
0121 * will cause <code>MyApp</code> and everything it refers to
0122 * to be serialized as well. The problem is that the listener
0123 * is serializable by coincidence, not by design. To separate
0124 * the decisions about <code>MyApp</code> and the
0125 * <code>ActionListener</code> being serializable one can use a
0126 * nested class, as in the following example:
0127 * <pre>
0128 * import java.awt.*;
0129 * import java.awt.event.*;
0130 * import java.io.Serializable;
0131 *
0132 * class MyApp java.io.Serializable
0133 * {
0134 * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
0135 * Button aButton = new Button();
0136 *
0137 * static class MyActionListener implements ActionListener
0138 * {
0139 * public void actionPerformed(ActionEvent e)
0140 * {
0141 * System.out.println("Hello There");
0142 * }
0143 * }
0144 *
0145 * MyApp()
0146 * {
0147 * aButton.addActionListener(new MyActionListener());
0148 * }
0149 * }
0150 * </pre>
0151 * <p>
0152 * <b>Note</b>: For more information on the paint mechanisms utilitized
0153 * by AWT and Swing, including information on how to write the most
0154 * efficient painting code, see
0155 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
0156 * <p>
0157 * For details on the focus subsystem, see
0158 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
0159 * How to Use the Focus Subsystem</a>,
0160 * a section in <em>The Java Tutorial</em>, and the
0161 * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
0162 * for more information.
0163 *
0164 * @version 1.442, 06/25/07
0165 * @author Arthur van Hoff
0166 * @author Sami Shaio
0167 */
0168 public abstract class Component implements ImageObserver,
0169 MenuContainer, Serializable {
0170
0171 private static final Logger focusLog = Logger
0172 .getLogger("java.awt.focus.Component");
0173 private static final Logger log = Logger
0174 .getLogger("java.awt.Component");
0175 /**
0176 * The peer of the component. The peer implements the component's
0177 * behavior. The peer is set when the <code>Component</code> is
0178 * added to a container that also is a peer.
0179 * @see #addNotify
0180 * @see #removeNotify
0181 */
0182 transient ComponentPeer peer;
0183
0184 /**
0185 * The parent of the object. It may be <code>null</code>
0186 * for top-level components.
0187 * @see #getParent
0188 */
0189 transient Container parent;
0190
0191 /**
0192 * The <code>AppContext</code> of the component. Applets/Plugin may
0193 * change the AppContext.
0194 */
0195 transient AppContext appContext;
0196
0197 /**
0198 * The x position of the component in the parent's coordinate system.
0199 *
0200 * @serial
0201 * @see #getLocation
0202 */
0203 int x;
0204
0205 /**
0206 * The y position of the component in the parent's coordinate system.
0207 *
0208 * @serial
0209 * @see #getLocation
0210 */
0211 int y;
0212
0213 /**
0214 * The width of the component.
0215 *
0216 * @serial
0217 * @see #getSize
0218 */
0219 int width;
0220
0221 /**
0222 * The height of the component.
0223 *
0224 * @serial
0225 * @see #getSize
0226 */
0227 int height;
0228
0229 /**
0230 * The foreground color for this component.
0231 * <code>foreground</code> can be <code>null</code>.
0232 *
0233 * @serial
0234 * @see #getForeground
0235 * @see #setForeground
0236 */
0237 Color foreground;
0238
0239 /**
0240 * The background color for this component.
0241 * <code>background</code> can be <code>null</code>.
0242 *
0243 * @serial
0244 * @see #getBackground
0245 * @see #setBackground
0246 */
0247 Color background;
0248
0249 /**
0250 * The font used by this component.
0251 * The <code>font</code> can be <code>null</code>.
0252 *
0253 * @serial
0254 * @see #getFont
0255 * @see #setFont
0256 */
0257 Font font;
0258
0259 /**
0260 * The font which the peer is currently using.
0261 * (<code>null</code> if no peer exists.)
0262 */
0263 Font peerFont;
0264
0265 /**
0266 * The cursor displayed when pointer is over this component.
0267 * This value can be <code>null</code>.
0268 *
0269 * @serial
0270 * @see #getCursor
0271 * @see #setCursor
0272 */
0273 Cursor cursor;
0274
0275 /**
0276 * The locale for the component.
0277 *
0278 * @serial
0279 * @see #getLocale
0280 * @see #setLocale
0281 */
0282 Locale locale;
0283
0284 /**
0285 * A reference to a <code>GraphicsConfiguration</code> object
0286 * used to describe the characteristics of a graphics
0287 * destination.
0288 * This value can be <code>null</code>.
0289 *
0290 * @since 1.3
0291 * @serial
0292 * @see GraphicsConfiguration
0293 * @see #getGraphicsConfiguration
0294 */
0295 transient GraphicsConfiguration graphicsConfig = null;
0296
0297 /**
0298 * A reference to a <code>BufferStrategy</code> object
0299 * used to manipulate the buffers on this component.
0300 *
0301 * @since 1.4
0302 * @see java.awt.image.BufferStrategy
0303 * @see #getBufferStrategy()
0304 */
0305 transient BufferStrategy bufferStrategy = null;
0306
0307 /**
0308 * True when the object should ignore all repaint events.
0309 *
0310 * @since 1.4
0311 * @serial
0312 * @see #setIgnoreRepaint
0313 * @see #getIgnoreRepaint
0314 */
0315 boolean ignoreRepaint = false;
0316
0317 /**
0318 * True when the object is visible. An object that is not
0319 * visible is not drawn on the screen.
0320 *
0321 * @serial
0322 * @see #isVisible
0323 * @see #setVisible
0324 */
0325 boolean visible = true;
0326
0327 /**
0328 * True when the object is enabled. An object that is not
0329 * enabled does not interact with the user.
0330 *
0331 * @serial
0332 * @see #isEnabled
0333 * @see #setEnabled
0334 */
0335 boolean enabled = true;
0336
0337 /**
0338 * True when the object is valid. An invalid object needs to
0339 * be layed out. This flag is set to false when the object
0340 * size is changed.
0341 *
0342 * @serial
0343 * @see #isValid
0344 * @see #validate
0345 * @see #invalidate
0346 */
0347 volatile boolean valid = false;
0348
0349 /**
0350 * The <code>DropTarget</code> associated with this component.
0351 *
0352 * @since 1.2
0353 * @serial
0354 * @see #setDropTarget
0355 * @see #getDropTarget
0356 */
0357 DropTarget dropTarget;
0358
0359 /**
0360 * @serial
0361 * @see #add
0362 */
0363 Vector popups;
0364
0365 /**
0366 * A component's name.
0367 * This field can be <code>null</code>.
0368 *
0369 * @serial
0370 * @see #getName
0371 * @see #setName(String)
0372 */
0373 private String name;
0374
0375 /**
0376 * A bool to determine whether the name has
0377 * been set explicitly. <code>nameExplicitlySet</code> will
0378 * be false if the name has not been set and
0379 * true if it has.
0380 *
0381 * @serial
0382 * @see #getName
0383 * @see #setName(String)
0384 */
0385 private boolean nameExplicitlySet = false;
0386
0387 /**
0388 * Indicates whether this Component can be focused.
0389 *
0390 * @serial
0391 * @see #setFocusable
0392 * @see #isFocusable
0393 * @since 1.4
0394 */
0395 private boolean focusable = true;
0396
0397 private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
0398 private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
0399 private static final int FOCUS_TRAVERSABLE_SET = 2;
0400
0401 /**
0402 * Tracks whether this Component is relying on default focus travesability.
0403 *
0404 * @serial
0405 * @since 1.4
0406 */
0407 private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
0408
0409 /**
0410 * The focus traversal keys. These keys will generate focus traversal
0411 * behavior for Components for which focus traversal keys are enabled. If a
0412 * value of null is specified for a traversal key, this Component inherits
0413 * that traversal key from its parent. If all ancestors of this Component
0414 * have null specified for that traversal key, then the current
0415 * KeyboardFocusManager's default traversal key is used.
0416 *
0417 * @serial
0418 * @see #setFocusTraversalKeys
0419 * @see #getFocusTraversalKeys
0420 * @since 1.4
0421 */
0422 Set[] focusTraversalKeys;
0423
0424 private static final String[] focusTraversalKeyPropertyNames = {
0425 "forwardFocusTraversalKeys", "backwardFocusTraversalKeys",
0426 "upCycleFocusTraversalKeys", "downCycleFocusTraversalKeys" };
0427
0428 /**
0429 * Indicates whether focus traversal keys are enabled for this Component.
0430 * Components for which focus traversal keys are disabled receive key
0431 * events for focus traversal keys. Components for which focus traversal
0432 * keys are enabled do not see these events; instead, the events are
0433 * automatically converted to traversal operations.
0434 *
0435 * @serial
0436 * @see #setFocusTraversalKeysEnabled
0437 * @see #getFocusTraversalKeysEnabled
0438 * @since 1.4
0439 */
0440 private boolean focusTraversalKeysEnabled = true;
0441
0442 /**
0443 * The locking object for AWT component-tree and layout operations.
0444 *
0445 * @see #getTreeLock
0446 */
0447 static final Object LOCK = new AWTTreeLock();
0448
0449 static class AWTTreeLock {
0450 }
0451
0452 /**
0453 * Minimum size.
0454 * (This field perhaps should have been transient).
0455 *
0456 * @serial
0457 */
0458 Dimension minSize;
0459
0460 /**
0461 * Whether or not setMinimumSize has been invoked with a non-null value.
0462 */
0463 boolean minSizeSet;
0464
0465 /**
0466 * Preferred size.
0467 * (This field perhaps should have been transient).
0468 *
0469 * @serial
0470 */
0471 Dimension prefSize;
0472
0473 /**
0474 * Whether or not setPreferredSize has been invoked with a non-null value.
0475 */
0476 boolean prefSizeSet;
0477
0478 /**
0479 * Maximum size
0480 *
0481 * @serial
0482 */
0483 Dimension maxSize;
0484
0485 /**
0486 * Whether or not setMaximumSize has been invoked with a non-null value.
0487 */
0488 boolean maxSizeSet;
0489
0490 /**
0491 * The orientation for this component.
0492 * @see #getComponentOrientation
0493 * @see #setComponentOrientation
0494 */
0495 transient ComponentOrientation componentOrientation = ComponentOrientation.UNKNOWN;
0496
0497 /**
0498 * <code>newEventsOnly</code> will be true if the event is
0499 * one of the event types enabled for the component.
0500 * It will then allow for normal processing to
0501 * continue. If it is false the event is passed
0502 * to the component's parent and up the ancestor
0503 * tree until the event has been consumed.
0504 *
0505 * @serial
0506 * @see #dispatchEvent
0507 */
0508 boolean newEventsOnly = false;
0509 transient ComponentListener componentListener;
0510 transient FocusListener focusListener;
0511 transient HierarchyListener hierarchyListener;
0512 transient HierarchyBoundsListener hierarchyBoundsListener;
0513 transient KeyListener keyListener;
0514 transient MouseListener mouseListener;
0515 transient MouseMotionListener mouseMotionListener;
0516 transient MouseWheelListener mouseWheelListener;
0517 transient InputMethodListener inputMethodListener;
0518
0519 transient RuntimeException windowClosingException = null;
0520
0521 /** Internal, constants for serialization */
0522 final static String actionListenerK = "actionL";
0523 final static String adjustmentListenerK = "adjustmentL";
0524 final static String componentListenerK = "componentL";
0525 final static String containerListenerK = "containerL";
0526 final static String focusListenerK = "focusL";
0527 final static String itemListenerK = "itemL";
0528 final static String keyListenerK = "keyL";
0529 final static String mouseListenerK = "mouseL";
0530 final static String mouseMotionListenerK = "mouseMotionL";
0531 final static String mouseWheelListenerK = "mouseWheelL";
0532 final static String textListenerK = "textL";
0533 final static String ownedWindowK = "ownedL";
0534 final static String windowListenerK = "windowL";
0535 final static String inputMethodListenerK = "inputMethodL";
0536 final static String hierarchyListenerK = "hierarchyL";
0537 final static String hierarchyBoundsListenerK = "hierarchyBoundsL";
0538 final static String windowStateListenerK = "windowStateL";
0539 final static String windowFocusListenerK = "windowFocusL";
0540
0541 /**
0542 * The <code>eventMask</code> is ONLY set by subclasses via
0543 * <code>enableEvents</code>.
0544 * The mask should NOT be set when listeners are registered
0545 * so that we can distinguish the difference between when
0546 * listeners request events and subclasses request them.
0547 * One bit is used to indicate whether input methods are
0548 * enabled; this bit is set by <code>enableInputMethods</code> and is
0549 * on by default.
0550 *
0551 * @serial
0552 * @see #enableInputMethods
0553 * @see AWTEvent
0554 */
0555 long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK;
0556
0557 private static final DebugHelper dbg = DebugHelper
0558 .create(Component.class);
0559
0560 /**
0561 * Static properties for incremental drawing.
0562 * @see #imageUpdate
0563 */
0564 static boolean isInc;
0565 static int incRate;
0566 static {
0567 /* ensure that the necessary native libraries are loaded */
0568 Toolkit.loadLibraries();
0569 /* initialize JNI field and method ids */
0570 if (!GraphicsEnvironment.isHeadless()) {
0571 initIDs();
0572 }
0573
0574 String s = (String) java.security.AccessController
0575 .doPrivileged(new GetPropertyAction(
0576 "awt.image.incrementaldraw"));
0577 isInc = (s == null || s.equals("true"));
0578
0579 s = (String) java.security.AccessController
0580 .doPrivileged(new GetPropertyAction(
0581 "awt.image.redrawrate"));
0582 incRate = (s != null) ? Integer.parseInt(s) : 100;
0583 }
0584
0585 /**
0586 * Ease-of-use constant for <code>getAlignmentY()</code>.
0587 * Specifies an alignment to the top of the component.
0588 * @see #getAlignmentY
0589 */
0590 public static final float TOP_ALIGNMENT = 0.0f;
0591
0592 /**
0593 * Ease-of-use constant for <code>getAlignmentY</code> and
0594 * <code>getAlignmentX</code>. Specifies an alignment to
0595 * the center of the component
0596 * @see #getAlignmentX
0597 * @see #getAlignmentY
0598 */
0599 public static final float CENTER_ALIGNMENT = 0.5f;
0600
0601 /**
0602 * Ease-of-use constant for <code>getAlignmentY</code>.
0603 * Specifies an alignment to the bottom of the component.
0604 * @see #getAlignmentY
0605 */
0606 public static final float BOTTOM_ALIGNMENT = 1.0f;
0607
0608 /**
0609 * Ease-of-use constant for <code>getAlignmentX</code>.
0610 * Specifies an alignment to the left side of the component.
0611 * @see #getAlignmentX
0612 */
0613 public static final float LEFT_ALIGNMENT = 0.0f;
0614
0615 /**
0616 * Ease-of-use constant for <code>getAlignmentX</code>.
0617 * Specifies an alignment to the right side of the component.
0618 * @see #getAlignmentX
0619 */
0620 public static final float RIGHT_ALIGNMENT = 1.0f;
0621
0622 /*
0623 * JDK 1.1 serialVersionUID
0624 */
0625 private static final long serialVersionUID = -7644114512714619750L;
0626
0627 /**
0628 * If any <code>PropertyChangeListeners</code> have been registered,
0629 * the <code>changeSupport</code> field describes them.
0630 *
0631 * @serial
0632 * @since 1.2
0633 * @see #addPropertyChangeListener
0634 * @see #removePropertyChangeListener
0635 * @see #firePropertyChange
0636 */
0637 private PropertyChangeSupport changeSupport;
0638
0639 boolean isPacked = false;
0640
0641 /**
0642 * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize
0643 * to signal setBounds what's changing. Should be used under TreeLock.
0644 * This is only needed due to the inability to change the cross-calling
0645 * order of public and deprecated methods.
0646 */
0647 private int boundsOp = ComponentPeer.DEFAULT_OPERATION;
0648
0649 /**
0650 * Enumeration of the common ways the baseline of a component can
0651 * change as the size changes. The baseline resize behavior is
0652 * primarily for layout managers that need to know how the
0653 * position of the baseline changes as the component size changes.
0654 * In general the baseline resize behavior will be valid for sizes
0655 * greater than or equal to the minimum size (the actual minimum
0656 * size; not a developer specified minimum size). For sizes
0657 * smaller than the minimum size the baseline may change in a way
0658 * other than the baseline resize behavior indicates. Similarly,
0659 * as the size approaches <code>Integer.MAX_VALUE</code> and/or
0660 * <code>Short.MAX_VALUE</code> the baseline may change in a way
0661 * other than the baseline resize behavior indicates.
0662 *
0663 * @see #getBaselineResizeBehavior
0664 * @see #getBaseline(int,int)
0665 * @since 1.6
0666 */
0667 public enum BaselineResizeBehavior {
0668 /**
0669 * Indicates the baseline remains fixed relative to the
0670 * y-origin. That is, <code>getBaseline</code> returns
0671 * the same value regardless of the height or width. For example, a
0672 * <code>JLabel</code> containing non-empty text with a
0673 * vertical alignment of <code>TOP</code> should have a
0674 * baseline type of <code>CONSTANT_ASCENT</code>.
0675 */
0676 CONSTANT_ASCENT,
0677
0678 /**
0679 * Indicates the baseline remains fixed relative to the height
0680 * and does not change as the width is varied. That is, for
0681 * any height H the difference between H and
0682 * <code>getBaseline(w, H)</code> is the same. For example, a
0683 * <code>JLabel</code> containing non-empty text with a
0684 * vertical alignment of <code>BOTTOM</code> should have a
0685 * baseline type of <code>CONSTANT_DESCENT</code>.
0686 */
0687 CONSTANT_DESCENT,
0688
0689 /**
0690 * Indicates the baseline remains a fixed distance from
0691 * the center of the component. That is, for any height H the
0692 * difference between <code>getBaseline(w, H)</code> and
0693 * <code>H / 2</code> is the same (plus or minus one depending upon
0694 * rounding error).
0695 * <p>
0696 * Because of possible rounding errors it is recommended
0697 * you ask for the baseline with two consecutive heights and use
0698 * the return value to determine if you need to pad calculations
0699 * by 1. The following shows how to calculate the baseline for
0700 * any height:
0701 * <pre>
0702 * Dimension preferredSize = component.getPreferredSize();
0703 * int baseline = getBaseline(preferredSize.width,
0704 * preferredSize.height);
0705 * int nextBaseline = getBaseline(preferredSize.width,
0706 * preferredSize.height + 1);
0707 * // Amount to add to height when calculating where baseline
0708 * // lands for a particular height:
0709 * int padding = 0;
0710 * // Where the baseline is relative to the mid point
0711 * int baselineOffset = baseline - height / 2;
0712 * if (preferredSize.height % 2 == 0 &&
0713 * baseline != nextBaseline) {
0714 * padding = 1;
0715 * }
0716 * else if (preferredSize.height % 2 == 1 &&
0717 * baseline == nextBaseline) {
0718 * baselineOffset--;
0719 * padding = 1;
0720 * }
0721 * // The following calculates where the baseline lands for
0722 * // the height z:
0723 * int calculatedBaseline = (z + padding) / 2 + baselineOffset;
0724 * </pre>
0725 */
0726 CENTER_OFFSET,
0727
0728 /**
0729 * Indicates the baseline resize behavior can not be expressed using
0730 * any of the other constants. This may also indicate the baseline
0731 * varies with the width of the component. This is also returned
0732 * by components that do not have a baseline.
0733 */
0734 OTHER
0735 }
0736
0737 /**
0738 * Should only be used in subclass getBounds to check that part of bounds
0739 * is actualy changing
0740 */
0741 int getBoundsOp() {
0742 assert Thread.holdsLock(getTreeLock());
0743 return boundsOp;
0744 }
0745
0746 void setBoundsOp(int op) {
0747 assert Thread.holdsLock(getTreeLock());
0748 if (op == ComponentPeer.RESET_OPERATION) {
0749 boundsOp = ComponentPeer.DEFAULT_OPERATION;
0750 } else if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
0751 boundsOp = op;
0752 }
0753 }
0754
0755 /**
0756 * Constructs a new component. Class <code>Component</code> can be
0757 * extended directly to create a lightweight component that does not
0758 * utilize an opaque native window. A lightweight component must be
0759 * hosted by a native container somewhere higher up in the component
0760 * tree (for example, by a <code>Frame</code> object).
0761 */
0762 protected Component() {
0763 appContext = AppContext.getAppContext();
0764 }
0765
0766 void initializeFocusTraversalKeys() {
0767 focusTraversalKeys = new Set[3];
0768 }
0769
0770 /**
0771 * Constructs a name for this component. Called by <code>getName</code>
0772 * when the name is <code>null</code>.
0773 */
0774 String constructComponentName() {
0775 return null; // For strict compliance with prior platform versions, a Component
0776 // that doesn't set its name should return null from
0777 // getName()
0778 }
0779
0780 /**
0781 * Gets the name of the component.
0782 * @return this component's name
0783 * @see #setName
0784 * @since JDK1.1
0785 */
0786 public String getName() {
0787 if (name == null && !nameExplicitlySet) {
0788 synchronized (this ) {
0789 if (name == null && !nameExplicitlySet)
0790 name = constructComponentName();
0791 }
0792 }
0793 return name;
0794 }
0795
0796 /**
0797 * Sets the name of the component to the specified string.
0798 * @param name the string that is to be this
0799 * component's name
0800 * @see #getName
0801 * @since JDK1.1
0802 */
0803 public void setName(String name) {
0804 String oldName;
0805 synchronized (this ) {
0806 oldName = this .name;
0807 this .name = name;
0808 nameExplicitlySet = true;
0809 }
0810 firePropertyChange("name", oldName, name);
0811 }
0812
0813 /**
0814 * Gets the parent of this component.
0815 * @return the parent container of this component
0816 * @since JDK1.0
0817 */
0818 public Container getParent() {
0819 return getParent_NoClientCode();
0820 }
0821
0822 // NOTE: This method may be called by privileged threads.
0823 // This functionality is implemented in a package-private method
0824 // to insure that it cannot be overridden by client subclasses.
0825 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
0826 final Container getParent_NoClientCode() {
0827 return parent;
0828 }
0829
0830 /**
0831 * @deprecated As of JDK version 1.1,
0832 * programs should not directly manipulate peers;
0833 * replaced by <code>boolean isDisplayable()</code>.
0834 */
0835 @Deprecated
0836 public ComponentPeer getPeer() {
0837 return peer;
0838 }
0839
0840 /**
0841 * Associate a <code>DropTarget</code> with this component.
0842 * The <code>Component</code> will receive drops only if it
0843 * is enabled.
0844 *
0845 * @see #isEnabled
0846 * @param dt The DropTarget
0847 */
0848
0849 public synchronized void setDropTarget(DropTarget dt) {
0850 if (dt == dropTarget
0851 || (dropTarget != null && dropTarget.equals(dt)))
0852 return;
0853
0854 DropTarget old;
0855
0856 if ((old = dropTarget) != null) {
0857 if (peer != null)
0858 dropTarget.removeNotify(peer);
0859
0860 DropTarget t = dropTarget;
0861
0862 dropTarget = null;
0863
0864 try {
0865 t.setComponent(null);
0866 } catch (IllegalArgumentException iae) {
0867 // ignore it.
0868 }
0869 }
0870
0871 // if we have a new one, and we have a peer, add it!
0872
0873 if ((dropTarget = dt) != null) {
0874 try {
0875 dropTarget.setComponent(this );
0876 if (peer != null)
0877 dropTarget.addNotify(peer);
0878 } catch (IllegalArgumentException iae) {
0879 if (old != null) {
0880 try {
0881 old.setComponent(this );
0882 if (peer != null)
0883 dropTarget.addNotify(peer);
0884 } catch (IllegalArgumentException iae1) {
0885 // ignore it!
0886 }
0887 }
0888 }
0889 }
0890 }
0891
0892 /**
0893 * Gets the <code>DropTarget</code> associated with this
0894 * <code>Component</code>.
0895 */
0896
0897 public synchronized DropTarget getDropTarget() {
0898 return dropTarget;
0899 }
0900
0901 /**
0902 * Gets the <code>GraphicsConfiguration</code> associated with this
0903 * <code>Component</code>.
0904 * If the <code>Component</code> has not been assigned a specific
0905 * <code>GraphicsConfiguration</code>,
0906 * the <code>GraphicsConfiguration</code> of the
0907 * <code>Component</code> object's top-level container is
0908 * returned.
0909 * If the <code>Component</code> has been created, but not yet added
0910 * to a <code>Container</code>, this method returns <code>null</code>.
0911 *
0912 * @return the <code>GraphicsConfiguration</code> used by this
0913 * <code>Component</code> or <code>null</code>
0914 * @since 1.3
0915 */
0916 public GraphicsConfiguration getGraphicsConfiguration() {
0917 synchronized (getTreeLock()) {
0918 GraphicsConfiguration gc = graphicsConfig;
0919 Component parent = getParent();
0920 while ((gc == null) && (parent != null)) {
0921 gc = parent.getGraphicsConfiguration();
0922 parent = parent.getParent();
0923 }
0924 return gc;
0925 }
0926 }
0927
0928 final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
0929 GraphicsConfiguration gc = this .graphicsConfig;
0930 Component par = this .parent;
0931 while ((gc == null) && (par != null)) {
0932 gc = par.getGraphicsConfiguration_NoClientCode();
0933 par = par.parent;
0934 }
0935 return gc;
0936 }
0937
0938 /**
0939 * Resets this <code>Component</code>'s
0940 * <code>GraphicsConfiguration</code> back to a default
0941 * value. For most componenets, this is <code>null</code>.
0942 * Called from the Toolkit thread, so NO CLIENT CODE.
0943 */
0944 void resetGC() {
0945 synchronized (getTreeLock()) {
0946 graphicsConfig = null;
0947 }
0948 }
0949
0950 /*
0951 * Not called on Component, but needed for Canvas and Window
0952 */
0953 void setGCFromPeer() {
0954 synchronized (getTreeLock()) {
0955 if (peer != null) { // can't imagine how this will be false,
0956 // but just in case
0957 graphicsConfig = peer.getGraphicsConfiguration();
0958 } else {
0959 graphicsConfig = null;
0960 }
0961 }
0962 }
0963
0964 /**
0965 * Checks that this component's <code>GraphicsDevice</code>
0966 * <code>idString</code> matches the string argument.
0967 */
0968 void checkGD(String stringID) {
0969 if (graphicsConfig != null) {
0970 if (!graphicsConfig.getDevice().getIDstring().equals(
0971 stringID)) {
0972 throw new IllegalArgumentException(
0973 "adding a container to a container on a different GraphicsDevice");
0974 }
0975 }
0976 }
0977
0978 /**
0979 * Gets this component's locking object (the object that owns the thread
0980 * sychronization monitor) for AWT component-tree and layout
0981 * operations.
0982 * @return this component's locking object
0983 */
0984 public final Object getTreeLock() {
0985 return LOCK;
0986 }
0987
0988 /**
0989 * Gets the toolkit of this component. Note that
0990 * the frame that contains a component controls which
0991 * toolkit is used by that component. Therefore if the component
0992 * is moved from one frame to another, the toolkit it uses may change.
0993 * @return the toolkit of this component
0994 * @since JDK1.0
0995 */
0996 public Toolkit getToolkit() {
0997 return getToolkitImpl();
0998 }
0999
1000 /*
1001 * This is called by the native code, so client code can't
1002 * be called on the toolkit thread.
1003 */
1004 final Toolkit getToolkitImpl() {
1005 ComponentPeer peer = this .peer;
1006 if ((peer != null) && !(peer instanceof LightweightPeer)) {
1007 return peer.getToolkit();
1008 }
1009 Container parent = this .parent;
1010 if (parent != null) {
1011 return parent.getToolkitImpl();
1012 }
1013 return Toolkit.getDefaultToolkit();
1014 }
1015
1016 /**
1017 * Determines whether this component is valid. A component is valid
1018 * when it is correctly sized and positioned within its parent
1019 * container and all its children are also valid.
1020 * In order to account for peers' size requirements, components are invalidated
1021 * before they are first shown on the screen. By the time the parent container
1022 * is fully realized, all its components will be valid.
1023 * @return <code>true</code> if the component is valid, <code>false</code>
1024 * otherwise
1025 * @see #validate
1026 * @see #invalidate
1027 * @since JDK1.0
1028 */
1029 public boolean isValid() {
1030 return (peer != null) && valid;
1031 }
1032
1033 /**
1034 * Determines whether this component is displayable. A component is
1035 * displayable when it is connected to a native screen resource.
1036 * <p>
1037 * A component is made displayable either when it is added to
1038 * a displayable containment hierarchy or when its containment
1039 * hierarchy is made displayable.
1040 * A containment hierarchy is made displayable when its ancestor
1041 * window is either packed or made visible.
1042 * <p>
1043 * A component is made undisplayable either when it is removed from
1044 * a displayable containment hierarchy or when its containment hierarchy
1045 * is made undisplayable. A containment hierarchy is made
1046 * undisplayable when its ancestor window is disposed.
1047 *
1048 * @return <code>true</code> if the component is displayable,
1049 * <code>false</code> otherwise
1050 * @see Container#add(Component)
1051 * @see Window#pack
1052 * @see Window#show
1053 * @see Container#remove(Component)
1054 * @see Window#dispose
1055 * @since 1.2
1056 */
1057 public boolean isDisplayable() {
1058 return getPeer() != null;
1059 }
1060
1061 /**
1062 * Determines whether this component should be visible when its
1063 * parent is visible. Components are
1064 * initially visible, with the exception of top level components such
1065 * as <code>Frame</code> objects.
1066 * @return <code>true</code> if the component is visible,
1067 * <code>false</code> otherwise
1068 * @see #setVisible
1069 * @since JDK1.0
1070 */
1071 public boolean isVisible() {
1072 return isVisible_NoClientCode();
1073 }
1074
1075 final boolean isVisible_NoClientCode() {
1076 return visible;
1077 }
1078
1079 /**
1080 * Determines whether this component will be displayed on the screen.
1081 * @return <code>true</code> if the component and all of its ancestors
1082 * until a toplevel window or null parent are visible,
1083 * <code>false</code> otherwise
1084 */
1085 boolean isRecursivelyVisible() {
1086 return visible
1087 && (parent == null || parent.isRecursivelyVisible());
1088 }
1089
1090 /**
1091 * Translates absolute coordinates into coordinates in the coordinate
1092 * space of this component.
1093 */
1094 Point pointRelativeToComponent(Point absolute) {
1095 Point compCoords = getLocationOnScreen();
1096 return new Point(absolute.x - compCoords.x, absolute.y
1097 - compCoords.y);
1098 }
1099
1100 /**
1101 * Assuming that mouse location is stored in PointerInfo passed
1102 * to this method, it finds a Component that is in the same
1103 * Window as this Component and is located under the mouse pointer.
1104 * If no such Component exists, null is returned.
1105 * NOTE: this method should be called under the protection of
1106 * tree lock, as it is done in Component.getMousePosition() and
1107 * Container.getMousePosition(boolean).
1108 */
1109 Component findUnderMouseInWindow(PointerInfo pi) {
1110 if (!isShowing()) {
1111 return null;
1112 }
1113 Window win = getContainingWindow();
1114 if (!Toolkit.getDefaultToolkit().getMouseInfoPeer()
1115 .isWindowUnderMouse(win)) {
1116 return null;
1117 }
1118 final boolean INCLUDE_DISABLED = true;
1119 Point relativeToWindow = win.pointRelativeToComponent(pi
1120 .getLocation());
1121 Component inTheSameWindow = win.findComponentAt(
1122 relativeToWindow.x, relativeToWindow.y,
1123 INCLUDE_DISABLED);
1124 return inTheSameWindow;
1125 }
1126
1127 /**
1128 * Returns the position of the mouse pointer in this <code>Component</code>'s
1129 * coordinate space if the <code>Component</code> is directly under the mouse
1130 * pointer, otherwise returns <code>null</code>.
1131 * If the <code>Component</code> is not showing on the screen, this method
1132 * returns <code>null</code> even if the mouse pointer is above the area
1133 * where the <code>Component</code> would be displayed.
1134 * If the <code>Component</code> is partially or fully obscured by other
1135 * <code>Component</code>s or native windows, this method returns a non-null
1136 * value only if the mouse pointer is located above the unobscured part of the
1137 * <code>Component</code>.
1138 * <p>
1139 * For <code>Container</code>s it returns a non-null value if the mouse is
1140 * above the <code>Container</code> itself or above any of its descendants.
1141 * Use {@link Container#getMousePosition(boolean)} if you need to exclude children.
1142 * <p>
1143 * Sometimes the exact mouse coordinates are not important, and the only thing
1144 * that matters is whether a specific <code>Component</code> is under the mouse
1145 * pointer. If the return value of this method is <code>null</code>, mouse
1146 * pointer is not directly above the <code>Component</code>.
1147 *
1148 * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
1149 * @see #isShowing
1150 * @see Container#getMousePosition
1151 * @return mouse coordinates relative to this <code>Component</code>, or null
1152 * @since 1.5
1153 */
1154 public Point getMousePosition() throws HeadlessException {
1155 if (GraphicsEnvironment.isHeadless()) {
1156 throw new HeadlessException();
1157 }
1158
1159 PointerInfo pi = (PointerInfo) java.security.AccessController
1160 .doPrivileged(new java.security.PrivilegedAction() {
1161 public Object run() {
1162 return MouseInfo.getPointerInfo();
1163 }
1164 });
1165
1166 synchronized (getTreeLock()) {
1167 Component inTheSameWindow = findUnderMouseInWindow(pi);
1168 if (!isSameOrAncestorOf(inTheSameWindow, true)) {
1169 return null;
1170 }
1171 return pointRelativeToComponent(pi.getLocation());
1172 }
1173 }
1174
1175 /**
1176 * Overridden in Container. Must be called under TreeLock.
1177 */
1178 boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
1179 return comp == this ;
1180 }
1181
1182 /**
1183 * Determines whether this component is showing on screen. This means
1184 * that the component must be visible, and it must be in a container
1185 * that is visible and showing.
1186 * <p>
1187 * <strong>Note:</strong> sometimes there is no way to detect whether the
1188 * {@code Component} is actually visible to the user. This can happen when:
1189 * <ul>
1190 * <li>the component has been added to a visible {@code ScrollPane} but
1191 * the {@code Component} is not currently in the scroll pane's view port.
1192 * <li>the {@code Component} is obscured by another {@code Component} or
1193 * {@code Container}.
1194 * </ul>
1195 * @return <code>true</code> if the component is showing,
1196 * <code>false</code> otherwise
1197 * @see #setVisible
1198 * @since JDK1.0
1199 */
1200 public boolean isShowing() {
1201 if (visible && (peer != null)) {
1202 Container parent = this .parent;
1203 return (parent == null) || parent.isShowing();
1204 }
1205 return false;
1206 }
1207
1208 /**
1209 * Determines whether this component is enabled. An enabled component
1210 * can respond to user input and generate events. Components are
1211 * enabled initially by default. A component may be enabled or disabled by
1212 * calling its <code>setEnabled</code> method.
1213 * @return <code>true</code> if the component is enabled,
1214 * <code>false</code> otherwise
1215 * @see #setEnabled
1216 * @since JDK1.0
1217 */
1218 public boolean isEnabled() {
1219 return isEnabledImpl();
1220 }
1221
1222 /*
1223 * This is called by the native code, so client code can't
1224 * be called on the toolkit thread.
1225 */
1226 final boolean isEnabledImpl() {
1227 return enabled;
1228 }
1229
1230 /**
1231 * Enables or disables this component, depending on the value of the
1232 * parameter <code>b</code>. An enabled component can respond to user
1233 * input and generate events. Components are enabled initially by default.
1234 *
1235 * <p>Note: Disabling a lightweight component does not prevent it from
1236 * receiving MouseEvents.
1237 * <p>Note: Disabling a heavyweight container prevents all components
1238 * in this container from receiving any input events. But disabling a
1239 * lightweight container affects only this container.
1240 *
1241 * @param b If <code>true</code>, this component is
1242 * enabled; otherwise this component is disabled
1243 * @see #isEnabled
1244 * @see #isLightweight
1245 * @since JDK1.1
1246 */
1247 public void setEnabled(boolean b) {
1248 enable(b);
1249 }
1250
1251 /**
1252 * @deprecated As of JDK version 1.1,
1253 * replaced by <code>setEnabled(boolean)</code>.
1254 */
1255 @Deprecated
1256 public void enable() {
1257 if (!enabled) {
1258 synchronized (getTreeLock()) {
1259 enabled = true;
1260 ComponentPeer peer = this .peer;
1261 if (peer != null) {
1262 peer.enable();
1263 if (visible) {
1264 updateCursorImmediately();
1265 }
1266 }
1267 }
1268 if (accessibleContext != null) {
1269 accessibleContext.firePropertyChange(
1270 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1271 null, AccessibleState.ENABLED);
1272 }
1273 }
1274 }
1275
1276 /**
1277 * @deprecated As of JDK version 1.1,
1278 * replaced by <code>setEnabled(boolean)</code>.
1279 */
1280 @Deprecated
1281 public void enable(boolean b) {
1282 if (b) {
1283 enable();
1284 } else {
1285 disable();
1286 }
1287 }
1288
1289 /**
1290 * @deprecated As of JDK version 1.1,
1291 * replaced by <code>setEnabled(boolean)</code>.
1292 */
1293 @Deprecated
1294 public void disable() {
1295 if (enabled) {
1296 KeyboardFocusManager.clearMostRecentFocusOwner(this );
1297 synchronized (getTreeLock()) {
1298 enabled = false;
1299 if (isFocusOwner()) {
1300 // Don't clear the global focus owner. If transferFocus
1301 // fails, we want the focus to stay on the disabled
1302 // Component so that keyboard traversal, et. al. still
1303 // makes sense to the user.
1304 autoTransferFocus(false);
1305 }
1306 ComponentPeer peer = this .peer;
1307 if (peer != null) {
1308 peer.disable();
1309 if (visible) {
1310 updateCursorImmediately();
1311 }
1312 }
1313 }
1314 if (accessibleContext != null) {
1315 accessibleContext.firePropertyChange(
1316 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1317 null, AccessibleState.ENABLED);
1318 }
1319 }
1320 }
1321
1322 /**
1323 * Returns true if this component is painted to an offscreen image
1324 * ("buffer") that's copied to the screen later. Component
1325 * subclasses that support double buffering should override this
1326 * method to return true if double buffering is enabled.
1327 *
1328 * @return false by default
1329 */
1330 public boolean isDoubleBuffered() {
1331 return false;
1332 }
1333
1334 /**
1335 * Enables or disables input method support for this component. If input
1336 * method support is enabled and the component also processes key events,
1337 * incoming events are offered to
1338 * the current input method and will only be processed by the component or
1339 * dispatched to its listeners if the input method does not consume them.
1340 * By default, input method support is enabled.
1341 *
1342 * @param enable true to enable, false to disable
1343 * @see #processKeyEvent
1344 * @since 1.2
1345 */
1346 public void enableInputMethods(boolean enable) {
1347 if (enable) {
1348 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)
1349 return;
1350
1351 // If this component already has focus, then activate the
1352 // input method by dispatching a synthesized focus gained
1353 // event.
1354 if (isFocusOwner()) {
1355 InputContext inputContext = getInputContext();
1356 if (inputContext != null) {
1357 FocusEvent focusGainedEvent = new FocusEvent(this ,
1358 FocusEvent.FOCUS_GAINED);
1359 inputContext.dispatchEvent(focusGainedEvent);
1360 }
1361 }
1362
1363 eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK;
1364 } else {
1365 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
1366 InputContext inputContext = getInputContext();
1367 if (inputContext != null) {
1368 inputContext.endComposition();
1369 inputContext.removeNotify(this );
1370 }
1371 }
1372 eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK;
1373 }
1374 }
1375
1376 /**
1377 * Shows or hides this component depending on the value of parameter
1378 * <code>b</code>.
1379 * @param b if <code>true</code>, shows this component;
1380 * otherwise, hides this component
1381 * @see #isVisible
1382 * @since JDK1.1
1383 */
1384 public void setVisible(boolean b) {
1385 show(b);
1386 }
1387
1388 /**
1389 * @deprecated As of JDK version 1.1,
1390 * replaced by <code>setVisible(boolean)</code>.
1391 */
1392 @Deprecated
1393 public void show() {
1394 if (!visible) {
1395 synchronized (getTreeLock()) {
1396 visible = true;
1397 ComponentPeer peer = this .peer;
1398 if (peer != null) {
1399 peer.show();
1400 createHierarchyEvents(
1401 HierarchyEvent.HIERARCHY_CHANGED,
1402 this ,
1403 parent,
1404 HierarchyEvent.SHOWING_CHANGED,
1405 Toolkit
1406 .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1407 if (peer instanceof LightweightPeer) {
1408 repaint();
1409 }
1410 updateCursorImmediately();
1411 }
1412
1413 if (componentListener != null
1414 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
1415 || Toolkit
1416 .enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1417 ComponentEvent e = new ComponentEvent(this ,
1418 ComponentEvent.COMPONENT_SHOWN);
1419 Toolkit.getEventQueue().postEvent(e);
1420 }
1421 }
1422 Container parent = this .parent;
1423 if (parent != null) {
1424 parent.invalidate();
1425 }
1426 }
1427 }
1428
1429 /**
1430 * @deprecated As of JDK version 1.1,
1431 * replaced by <code>setVisible(boolean)</code>.
1432 */
1433 @Deprecated
1434 public void show(boolean b) {
1435 if (b) {
1436 show();
1437 } else {
1438 hide();
1439 }
1440 }
1441
1442 boolean containsFocus() {
1443 return isFocusOwner();
1444 }
1445
1446 void clearMostRecentFocusOwnerOnHide() {
1447 KeyboardFocusManager.clearMostRecentFocusOwner(this );
1448 }
1449
1450 void clearCurrentFocusCycleRootOnHide() {
1451 /* do nothing */
1452 }
1453
1454 /**
1455 * @deprecated As of JDK version 1.1,
1456 * replaced by <code>setVisible(boolean)</code>.
1457 */
1458 @Deprecated
1459 public void hide() {
1460 isPacked = false;
1461
1462 if (visible) {
1463 clearCurrentFocusCycleRootOnHide();
1464 clearMostRecentFocusOwnerOnHide();
1465 synchronized (getTreeLock()) {
1466 visible = false;
1467 if (containsFocus()) {
1468 autoTransferFocus(true);
1469 }
1470 ComponentPeer peer = this .peer;
1471 if (peer != null) {
1472 peer.hide();
1473 createHierarchyEvents(
1474 HierarchyEvent.HIERARCHY_CHANGED,
1475 this ,
1476 parent,
1477 HierarchyEvent.SHOWING_CHANGED,
1478 Toolkit
1479 .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1480 if (peer instanceof LightweightPeer) {
1481 repaint();
1482 }
1483 updateCursorImmediately();
1484 }
1485 if (componentListener != null
1486 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
1487 || Toolkit
1488 .enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1489 ComponentEvent e = new ComponentEvent(this ,
1490 ComponentEvent.COMPONENT_HIDDEN);
1491 Toolkit.getEventQueue().postEvent(e);
1492 }
1493 }
1494 Container parent = this .parent;
1495 if (parent != null) {
1496 parent.invalidate();
1497 }
1498 }
1499 }
1500
1501 /**
1502 * Gets the foreground color of this component.
1503 * @return this component's foreground color; if this component does
1504 * not have a foreground color, the foreground color of its parent
1505 * is returned
1506 * @see #setForeground
1507 * @since JDK1.0
1508 * @beaninfo
1509 * bound: true
1510 */
1511 public Color getForeground() {
1512 Color foreground = this .foreground;
1513 if (foreground != null) {
1514 return foreground;
1515 }
1516 Container parent = this .parent;
1517 return (parent != null) ? parent.getForeground() : null;
1518 }
1519
1520 /**
1521 * Sets the foreground color of this component.
1522 * @param c the color to become this component's
1523 * foreground color; if this parameter is <code>null</code>
1524 * then this component will inherit
1525 * the foreground color of its parent
1526 * @see #getForeground
1527 * @since JDK1.0
1528 */
1529 public void setForeground(Color c) {
1530 Color oldColor = foreground;
1531 ComponentPeer peer = this .peer;
1532 foreground = c;
1533 if (peer != null) {
1534 c = getForeground();
1535 if (c != null) {
1536 peer.setForeground(c);
1537 }
1538 }
1539 // This is a bound property, so report the change to
1540 // any registered listeners. (Cheap if there are none.)
1541 firePropertyChange("foreground", oldColor, c);
1542 }
1543
1544 /**
1545 * Returns whether the foreground color has been explicitly set for this
1546 * Component. If this method returns <code>false</code>, this Component is
1547 * inheriting its foreground color from an ancestor.
1548 *
1549 * @return <code>true</code> if the foreground color has been explicitly
1550 * set for this Component; <code>false</code> otherwise.
1551 * @since 1.4
1552 */
1553 public boolean isForegroundSet() {
1554 return (foreground != null);
1555 }
1556
1557 /**
1558 * Gets the background color of this component.
1559 * @return this component's background color; if this component does
1560 * not have a background color,
1561 * the background color of its parent is returned
1562 * @see #setBackground
1563 * @since JDK1.0
1564 */
1565 public Color getBackground() {
1566 Color background = this .background;
1567 if (background != null) {
1568 return background;
1569 }
1570 Container parent = this .parent;
1571 return (parent != null) ? parent.getBackground() : null;
1572 }
1573
1574 /**
1575 * Sets the background color of this component.
1576 * <p>
1577 * The background color affects each component differently and the
1578 * parts of the component that are affected by the background color
1579 * may differ between operating systems.
1580 *
1581 * @param c the color to become this component's color;
1582 * if this parameter is <code>null</code>, then this
1583 * component will inherit the background color of its parent
1584 * @see #getBackground
1585 * @since JDK1.0
1586 * @beaninfo
1587 * bound: true
1588 */
1589 public void setBackground(Color c) {
1590 Color oldColor = background;
1591 ComponentPeer peer = this .peer;
1592 background = c;
1593 if (peer != null) {
1594 c = getBackground();
1595 if (c != null) {
1596 peer.setBackground(c);
1597 }
1598 }
1599 // This is a bound property, so report the change to
1600 // any registered listeners. (Cheap if there are none.)
1601 firePropertyChange("background", oldColor, c);
1602 }
1603
1604 /**
1605 * Returns whether the background color has been explicitly set for this
1606 * Component. If this method returns <code>false</code>, this Component is
1607 * inheriting its background color from an ancestor.
1608 *
1609 * @return <code>true</code> if the background color has been explicitly
1610 * set for this Component; <code>false</code> otherwise.
1611 * @since 1.4
1612 */
1613 public boolean isBackgroundSet() {
1614 return (background != null);
1615 }
1616
1617 /**
1618 * Gets the font of this component.
1619 * @return this component's font; if a font has not been set
1620 * for this component, the font of its parent is returned
1621 * @see #setFont
1622 * @since JDK1.0
1623 */
1624 public Font getFont() {
1625 return getFont_NoClientCode();
1626 }
1627
1628 // NOTE: This method may be called by privileged threads.
1629 // This functionality is implemented in a package-private method
1630 // to insure that it cannot be overridden by client subclasses.
1631 // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1632 final Font getFont_NoClientCode() {
1633 Font font = this .font;
1634 if (font != null) {
1635 return font;
1636 }
1637 Container parent = this .parent;
1638 return (parent != null) ? parent.getFont_NoClientCode() : null;
1639 }
1640
1641 /**
1642 * Sets the font of this component.
1643 * @param f the font to become this component's font;
1644 * if this parameter is <code>null</code> then this
1645 * component will inherit the font of its parent
1646 * @see #getFont
1647 * @since JDK1.0
1648 * @beaninfo
1649 * bound: true
1650 */
1651 public void setFont(Font f) {
1652 Font oldFont, newFont;
1653 synchronized (getTreeLock()) {
1654 synchronized (this ) {
1655 oldFont = font;
1656 newFont = font = f;
1657 }
1658 ComponentPeer peer = this .peer;
1659 if (peer != null) {
1660 f = getFont();
1661 if (f != null) {
1662 peer.setFont(f);
1663 peerFont = f;
1664 }
1665 }
1666 }
1667 // This is a bound property, so report the change to
1668 // any registered listeners. (Cheap if there are none.)
1669 firePropertyChange("font", oldFont, newFont);
1670
1671 // This could change the preferred size of the Component.
1672 // Fix for 6213660. Should compare old and new fonts and do not
1673 // call invalidate() if they are equal.
1674 if (valid && f != oldFont
1675 && (oldFont == null || !oldFont.equals(f))) {
1676 invalidate();
1677 }
1678 }
1679
1680 /**
1681 * Returns whether the font has been explicitly set for this Component. If
1682 * this method returns <code>false</code>, this Component is inheriting its
1683 * font from an ancestor.
1684 *
1685 * @return <code>true</code> if the font has been explicitly set for this
1686 * Component; <code>false</code> otherwise.
1687 * @since 1.4
1688 */
1689 public boolean isFontSet() {
1690 return (font != null);
1691 }
1692
1693 /**
1694 * Gets the locale of this component.
1695 * @return this component's locale; if this component does not
1696 * have a locale, the locale of its parent is returned
1697 * @see #setLocale
1698 * @exception IllegalComponentStateException if the <code>Component</code>
1699 * does not have its own locale and has not yet been added to
1700 * a containment hierarchy such that the locale can be determined
1701 * from the containing parent
1702 * @since JDK1.1
1703 */
1704 public Locale getLocale() {
1705 Locale locale = this .locale;
1706 if (locale != null) {
1707 return locale;
1708 }
1709 Container parent = this .parent;
1710
1711 if (parent == null) {
1712 throw new IllegalComponentStateException(
1713 "This component must have a parent in order to determine its locale");
1714 } else {
1715 return parent.getLocale();
1716 }
1717 }
1718
1719 /**
1720 * Sets the locale of this component. This is a bound property.
1721 * @param l the locale to become this component's locale
1722 * @see #getLocale
1723 * @since JDK1.1
1724 */
1725 public void setLocale(Locale l) {
1726 Locale oldValue = locale;
1727 locale = l;
1728
1729 // This is a bound property, so report the change to
1730 // any registered listeners. (Cheap if there are none.)
1731 firePropertyChange("locale", oldValue, l);
1732
1733 // This could change the preferred size of the Component.
1734 if (valid) {
1735 invalidate();
1736 }
1737 }
1738
1739 /**
1740 * Gets the instance of <code>ColorModel</code> used to display
1741 * the component on the output device.
1742 * @return the color model used by this component
1743 * @see java.awt.image.ColorModel
1744 * @see java.awt.peer.ComponentPeer#getColorModel()
1745 * @see Toolkit#getColorModel()
1746 * @since JDK1.0
1747 */
1748 public ColorModel getColorModel() {
1749 ComponentPeer peer = this .peer;
1750 if ((peer != null) && !(peer instanceof LightweightPeer)) {
1751 return peer.getColorModel();
1752 } else if (GraphicsEnvironment.isHeadless()) {
1753 return ColorModel.getRGBdefault();
1754 } // else
1755 return getToolkit().getColorModel();
1756 }
1757
1758 /**
1759 * Gets the location of this component in the form of a
1760 * point specifying the component's top-left corner.
1761 * The location will be relative to the parent's coordinate space.
1762 * <p>
1763 * Due to the asynchronous nature of native event handling, this
1764 * method can return outdated values (for instance, after several calls
1765 * of <code>setLocation()</code> in rapid succession). For this
1766 * reason, the recommended method of obtaining a component's position is
1767 * within <code>java.awt.event.ComponentListener.componentMoved()</code>,
1768 * which is called after the operating system has finished moving the
1769 * component.
1770 * </p>
1771 * @return an instance of <code>Point</code> representing
1772 * the top-left corner of the component's bounds in
1773 * the coordinate space of the component's parent
1774 * @see #setLocation
1775 * @see #getLocationOnScreen
1776 * @since JDK1.1
1777 */
1778 public Point getLocation() {
1779 return location();
1780 }
1781
1782 /**
1783 * Gets the location of this component in the form of a point
1784 * specifying the component's top-left corner in the screen's
1785 * coordinate space.
1786 * @return an instance of <code>Point</code> representing
1787 * the top-left corner of the component's bounds in the
1788 * coordinate space of the screen
1789 * @throws <code>IllegalComponentStateException</code> if the
1790 * component is not showing on the screen
1791 * @see #setLocation
1792 * @see #getLocation
1793 */
1794 public Point getLocationOnScreen() {
1795 synchronized (getTreeLock()) {
1796 return getLocationOnScreen_NoTreeLock();
1797 }
1798 }
1799
1800 /*
1801 * a package private version of getLocationOnScreen
1802 * used by GlobalCursormanager to update cursor
1803 */
1804 final Point getLocationOnScreen_NoTreeLock() {
1805
1806 if (peer != null && isShowing()) {
1807 if (peer instanceof LightweightPeer) {
1808 // lightweight component location needs to be translated
1809 // relative to a native component.
1810 Container host = getNativeContainer();
1811 Point pt = host.peer.getLocationOnScreen();
1812 for (Component c = this ; c != host; c = c.getParent()) {
1813 pt.x += c.x;
1814 pt.y += c.y;
1815 }
1816 return pt;
1817 } else {
1818 Point pt = peer.getLocationOnScreen();
1819 return pt;
1820 }
1821 } else {
1822 throw new IllegalComponentStateException(
1823 "component must be showing on the screen to determine its location");
1824 }
1825 }
1826
1827 /**
1828 * @deprecated As of JDK version 1.1,
1829 * replaced by <code>getLocation()</code>.
1830 */
1831 @Deprecated
1832 public Point location() {
1833 return location_NoClientCode();
1834 }
1835
1836 private Point location_NoClientCode() {
1837 return new Point(x, y);
1838 }
1839
1840 /**
1841 * Moves this component to a new location. The top-left corner of
1842 * the new location is specified by the <code>x</code> and <code>y</code>
1843 * parameters in the coordinate space of this component's parent.
1844 * @param x the <i>x</i>-coordinate of the new location's
1845 * top-left corner in the parent's coordinate space
1846 * @param y the <i>y</i>-coordinate of the new location's
1847 * top-left corner in the parent's coordinate space
1848 * @see #getLocation
1849 * @see #setBounds
1850 * @since JDK1.1
1851 */
1852 public void setLocation(int x, int y) {
1853 move(x, y);
1854 }
1855
1856 /**
1857 * @deprecated As of JDK version 1.1,
1858 * replaced by <code>setLocation(int, int)</code>.
1859 */
1860 @Deprecated
1861 public void move(int x, int y) {
1862 synchronized (getTreeLock()) {
1863 setBoundsOp(ComponentPeer.SET_LOCATION);
1864 setBounds(x, y, width, height);
1865 }
1866 }
1867
1868 /**
1869 * Moves this component to a new location. The top-left corner of
1870 * the new location is specified by point <code>p</code>. Point
1871 * <code>p</code> is given in the parent's coordinate space.
1872 * @param p the point defining the top-left corner
1873 * of the new location, given in the coordinate space of this
1874 * component's parent
1875 * @see #getLocation
1876 * @see #setBounds
1877 * @since JDK1.1
1878 */
1879 public void setLocation(Point p) {
1880 setLocation(p.x, p.y);
1881 }
1882
1883 /**
1884 * Returns the size of this component in the form of a
1885 * <code>Dimension</code> object. The <code>height</code>
1886 * field of the <code>Dimension</code> object contains
1887 * this component's height, and the <code>width</code>
1888 * field of the <code>Dimension</code> object contains
1889 * this component's width.
1890 * @return a <code>Dimension</code> object that indicates the
1891 * size of this component
1892 * @see #setSize
1893 * @since JDK1.1
1894 */
1895 public Dimension getSize() {
1896 return size();
1897 }
1898
1899 /**
1900 * @deprecated As of JDK version 1.1,
1901 * replaced by <code>getSize()</code>.
1902 */
1903 @Deprecated
1904 public Dimension size() {
1905 return new Dimension(width, height);
1906 }
1907
1908 /**
1909 * Resizes this component so that it has width <code>width</code>
1910 * and height <code>height</code>.
1911 * @param width the new width of this component in pixels
1912 * @param height the new height of this component in pixels
1913 * @see #getSize
1914 * @see #setBounds
1915 * @since JDK1.1
1916 */
1917 public void setSize(int width, int height) {
1918 resize(width, height);
1919 }
1920
1921 /**
1922 * @deprecated As of JDK version 1.1,
1923 * replaced by <code>setSize(int, int)</code>.
1924 */
1925 @Deprecated
1926 public void resize(int width, int height) {
1927 synchronized (getTreeLock()) {
1928 setBoundsOp(ComponentPeer.SET_SIZE);
1929 setBounds(x, y, width, height);
1930 }
1931 }
1932
1933 /**
1934 * Resizes this component so that it has width <code>d.width</code>
1935 * and height <code>d.height</code>.
1936 * @param d the dimension specifying the new size
1937 * of this component
1938 * @see #setSize
1939 * @see #setBounds
1940 * @since JDK1.1
1941 */
1942 public void setSize(Dimension d) {
1943 resize(d);
1944 }
1945
1946 /**
1947 * @deprecated As of JDK version 1.1,
1948 * replaced by <code>setSize(Dimension)</code>.
1949 */
1950 @Deprecated
1951 public void resize(Dimension d) {
1952 setSize(d.width, d.height);
1953 }
1954
1955 /**
1956 * Gets the bounds of this component in the form of a
1957 * <code>Rectangle</code> object. The bounds specify this
1958 * component's width, height, and location relative to
1959 * its parent.
1960 * @return a rectangle indicating this component's bounds
1961 * @see #setBounds
1962 * @see #getLocation
1963 * @see #getSize
1964 */
1965 public Rectangle getBounds() {
1966 return bounds();
1967 }
1968
1969 /**
1970 * @deprecated As of JDK version 1.1,
1971 * replaced by <code>getBounds()</code>.
1972 */
1973 @Deprecated
1974 public Rectangle bounds() {
1975 return new Rectangle(x, y, width, height);
1976 }
1977
1978 /**
1979 * Moves and resizes this component. The new location of the top-left
1980 * corner is specified by <code>x</code> and <code>y</code>, and the
1981 * new size is specified by <code>width</code> and <code>height</code>.
1982 * @param x the new <i>x</i>-coordinate of this component
1983 * @param y the new <i>y</i>-coordinate of this component
1984 * @param width the new <code>width</code> of this component
1985 * @param height the new <code>height</code> of this
1986 * component
1987 * @see #getBounds
1988 * @see #setLocation(int, int)
1989 * @see #setLocation(Point)
1990 * @see #setSize(int, int)
1991 * @see #setSize(Dimension)
1992 * @since JDK1.1
1993 */
1994 public void setBounds(int x, int y, int width, int height) {
1995 reshape(x, y, width, height);
1996 }
1997
1998 /**
1999 * @deprecated As of JDK version 1.1,
2000 * replaced by <code>setBounds(int, int, int, int)</code>.
2001 */
2002 @Deprecated
2003 public void reshape(int x, int y, int width, int height) {
2004 synchronized (getTreeLock()) {
2005 try {
2006 setBoundsOp(ComponentPeer.SET_BOUNDS);
2007 boolean resized = (this .width != width)
2008 || (this .height != height);
2009 boolean moved = (this .x != x) || (this .y != y);
2010 if (!resized && !moved) {
2011 return;
2012 }
2013 int oldX = this .x;
2014 int oldY = this .y;
2015 int oldWidth = this .width;
2016 int oldHeight = this .height;
2017 this .x = x;
2018 this .y = y;
2019 this .width = width;
2020 this .height = height;
2021
2022 if (resized) {
2023 isPacked = false;
2024 }
2025
2026 boolean needNotify = true;
2027 if (peer != null) {
2028 // LightwightPeer is an empty stub so can skip peer.reshape
2029 if (!(peer instanceof LightweightPeer)) {
2030 reshapeNativePeer(x, y, width, height,
2031 getBoundsOp());
2032 // Check peer actualy changed coordinates
2033 resized = (oldWidth != this .width)
2034 || (oldHeight != this .height);
2035 moved = (oldX != this .x) || (oldY != this .y);
2036 // fix for 5025858: do not send ComponentEvents for toplevel
2037 // windows here as it is done from peer or native code when
2038 // the window is really resized or moved, otherwise some
2039 // events may be sent twice
2040 if (this instanceof Window) {
2041 needNotify = false;
2042 }
2043 }
2044 if (resized) {
2045 invalidate();
2046 }
2047 if (parent != null && parent.valid) {
2048 parent.invalidate();
2049 }
2050 }
2051 if (needNotify) {
2052 notifyNewBounds(resized, moved);
2053 }
2054 repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight);
2055 } finally {
2056 setBoundsOp(ComponentPeer.RESET_OPERATION);
2057 }
2058 }
2059 }
2060
2061 private void repaintParentIfNeeded(int oldX, int oldY,
2062 int oldWidth, int oldHeight) {
2063 if (parent != null && peer instanceof LightweightPeer
2064 && isShowing()) {
2065 // Have the parent redraw the area this component occupied.
2066 parent.repaint(oldX, oldY, oldWidth, oldHeight);
2067 // Have the parent redraw the area this component *now* occupies.
2068 repaint();
2069 }
2070 }
2071
2072 private void reshapeNativePeer(int x, int y, int width, int height,
2073 int op) {
2074 // native peer might be offset by more than direct
2075 // parent since parent might be lightweight.
2076 int nativeX = x;
2077 int nativeY = y;
2078 for (Component c = parent; (c != null)
2079 && (c.peer instanceof LightweightPeer); c = c.parent) {
2080 nativeX += c.x;
2081 nativeY += c.y;
2082 }
2083 peer.setBounds(nativeX, nativeY, width, height, op);
2084 }
2085
2086 private void notifyNewBounds(boolean resized, boolean moved) {
2087 if (componentListener != null
2088 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
2089 || Toolkit
2090 .enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
2091 if (resized) {
2092 ComponentEvent e = new ComponentEvent(this ,
2093 ComponentEvent.COMPONENT_RESIZED);
2094 Toolkit.getEventQueue().postEvent(e);
2095 }
2096 if (moved) {
2097 ComponentEvent e = new ComponentEvent(this ,
2098 ComponentEvent.COMPONENT_MOVED);
2099 Toolkit.getEventQueue().postEvent(e);
2100 }
2101 } else {
2102 if (this instanceof Container
2103 && ((Container) this ).ncomponents > 0) {
2104 boolean enabledOnToolkit = Toolkit
2105 .enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2106 if (resized) {
2107
2108 ((Container) this ).createChildHierarchyEvents(
2109 HierarchyEvent.ANCESTOR_RESIZED, 0,
2110 enabledOnToolkit);
2111 }
2112 if (moved) {
2113 ((Container) this ).createChildHierarchyEvents(
2114 HierarchyEvent.ANCESTOR_MOVED, 0,
2115 enabledOnToolkit);
2116 }
2117 }
2118 }
2119 }
2120
2121 /**
2122 * Moves and resizes this component to conform to the new
2123 * bounding rectangle <code>r</code>. This component's new
2124 * position is specified by <code>r.x</code> and <code>r.y</code>,
2125 * and its new size is specified by <code>r.width</code> and
2126 * <code>r.height</code>
2127 * @param r the new bounding rectangle for this component
2128 * @see #getBounds
2129 * @see #setLocation(int, int)
2130 * @see #setLocation(Point)
2131 * @see #setSize(int, int)
2132 * @see #setSize(Dimension)
2133 * @since JDK1.1
2134 */
2135 public void setBounds(Rectangle r) {
2136 setBounds(r.x, r.y, r.width, r.height);
2137 }
2138
2139 /**
2140 * Returns the current x coordinate of the components origin.
2141 * This method is preferable to writing
2142 * <code>component.getBounds().x</code>,
2143 * or <code>component.getLocation().x</code> because it doesn't
2144 * cause any heap allocations.
2145 *
2146 * @return the current x coordinate of the components origin
2147 * @since 1.2
2148 */
2149 public int getX() {
2150 return x;
2151 }
2152
2153 /**
2154 * Returns the current y coordinate of the components origin.
2155 * This method is preferable to writing
2156 * <code>component.getBounds().y</code>,
2157 * or <code>component.getLocation().y</code> because it
2158 * doesn't cause any heap allocations.
2159 *
2160 * @return the current y coordinate of the components origin
2161 * @since 1.2
2162 */
2163 public int getY() {
2164 return y;
2165 }
2166
2167 /**
2168 * Returns the current width of this component.
2169 * This method is preferable to writing
2170 * <code>component.getBounds().width</code>,
2171 * or <code>component.getSize().width</code> because it
2172 * doesn't cause any heap allocations.
2173 *
2174 * @return the current width of this component
2175 * @since 1.2
2176 */
2177 public int getWidth() {
2178 return width;
2179 }
2180
2181 /**
2182 * Returns the current height of this component.
2183 * This method is preferable to writing
2184 * <code>component.getBounds().height</code>,
2185 * or <code>component.getSize().height</code> because it
2186 * doesn't cause any heap allocations.
2187 *
2188 * @return the current height of this component
2189 * @since 1.2
2190 */
2191 public int getHeight() {
2192 return height;
2193 }
2194
2195 /**
2196 * Stores the bounds of this component into "return value" <b>rv</b> and
2197 * return <b>rv</b>. If rv is <code>null</code> a new
2198 * <code>Rectangle</code> is allocated.
2199 * This version of <code>getBounds</code> is useful if the caller
2200 * wants to avoid allocating a new <code>Rectangle</code> object
2201 * on the heap.
2202 *
2203 * @param rv the return value, modified to the components bounds
2204 * @return rv
2205 */
2206 public Rectangle getBounds(Rectangle rv) {
2207 if (rv == null) {
2208 return new Rectangle(getX(), getY(), getWidth(),
2209 getHeight());
2210 } else {
2211 rv.setBounds(getX(), getY(), getWidth(), getHeight());
2212 return rv;
2213 }
2214 }
2215
2216 /**
2217 * Stores the width/height of this component into "return value" <b>rv</b>
2218 * and return <b>rv</b>. If rv is <code>null</code> a new
2219 * <code>Dimension</code> object is allocated. This version of
2220 * <code>getSize</code> is useful if the caller wants to avoid
2221 * allocating a new <code>Dimension</code> object on the heap.
2222 *
2223 * @param rv the return value, modified to the components size
2224 * @return rv
2225 */
2226 public Dimension getSize(Dimension rv) {
2227 if (rv == null) {
2228 return new Dimension(getWidth(), getHeight());
2229 } else {
2230 rv.setSize(getWidth(), getHeight());
2231 return rv;
2232 }
2233 }
2234
2235 /**
2236 * Stores the x,y origin of this component into "return value" <b>rv</b>
2237 * and return <b>rv</b>. If rv is <code>null</code> a new
2238 * <code>Point</code> is allocated.
2239 * This version of <code>getLocation</code> is useful if the
2240 * caller wants to avoid allocating a new <code>Point</code>
2241 * object on the heap.
2242 *
2243 * @param rv the return value, modified to the components location
2244 * @return rv
2245 */
2246 public Point getLocation(Point rv) {
2247 if (rv == null) {
2248 return new Point(getX(), getY());
2249 } else {
2250 rv.setLocation(getX(), getY());
2251 return rv;
2252 }
2253 }
2254
2255 /**
2256 * Returns true if this component is completely opaque, returns
2257 * false by default.
2258 * <p>
2259 * An opaque component paints every pixel within its
2260 * rectangular region. A non-opaque component paints only some of
2261 * its pixels, allowing the pixels underneath it to "show through".
2262 * A component that does not fully paint its pixels therefore
2263 * provides a degree of transparency. Only lightweight
2264 * components can be transparent.
2265 * <p>
2266 * Subclasses that guarantee to always completely paint their
2267 * contents should override this method and return true. All
2268 * of the "heavyweight" AWT components are opaque.
2269 *
2270 * @return true if this component is completely opaque
2271 * @see #isLightweight
2272 * @since 1.2
2273 */
2274 public boolean isOpaque() {
2275 if (getPeer() == null) {
2276 return false;
2277 } else {
2278 return !isLightweight();
2279 }
2280 }
2281
2282 /**
2283 * A lightweight component doesn't have a native toolkit peer.
2284 * Subclasses of <code>Component</code> and <code>Container</code>,
2285 * other than the ones defined in this package like <code>Button</code>
2286 * or <code>Scrollbar</code>, are lightweight.
2287 * All of the Swing components are lightweights.
2288 * <p>
2289 * This method will always return <code>false</code> if this component
2290 * is not displayable because it is impossible to determine the
2291 * weight of an undisplayable component.
2292 *
2293 * @return true if this component has a lightweight peer; false if
2294 * it has a native peer or no peer
2295 * @see #isDisplayable
2296 * @since 1.2
2297 */
2298 public boolean isLightweight() {
2299 return getPeer() instanceof LightweightPeer;
2300 }
2301
2302 /**
2303 * Sets the preferred size of this component to a constant
2304 * value. Subsequent calls to <code>getPreferredSize</code> will always
2305 * return this value. Setting the preferred size to <code>null</code>
2306 * restores the default behavior.
2307 *
2308 * @param preferredSize The new preferred size, or null
2309 * @see #getPreferredSize
2310 * @see #isPreferredSizeSet
2311 * @since 1.5
2312 */
2313 public void setPreferredSize(Dimension preferredSize) {
2314 Dimension old;
2315 // If the preferred size was set, use it as the old value, otherwise
2316 // use null to indicate we didn't previously have a set preferred
2317 // size.
2318 if (prefSizeSet) {
2319 old = this .prefSize;
2320 } else {
2321 old = null;
2322 }
2323 this .prefSize = preferredSize;
2324 prefSizeSet = (preferredSize != null);
2325 firePropertyChange("preferredSize", old, preferredSize);
2326 }
2327
2328 /**
2329 * Returns true if the preferred size has been set to a
2330 * non-<code>null</code> value otherwise returns false.
2331 *
2332 * @return true if <code>setPreferredSize</code> has been invoked
2333 * with a non-null value.
2334 * @since 1.5
2335 */
2336 public boolean isPreferredSizeSet() {
2337 return prefSizeSet;
2338 }
2339
2340 /**
2341 * Gets the preferred size of this component.
2342 * @return a dimension object indicating this component's preferred size
2343 * @see #getMinimumSize
2344 * @see LayoutManager
2345 */
2346 public Dimension getPreferredSize() {
2347 return preferredSize();
2348 }
2349
2350 /**
2351 * @deprecated As of JDK version 1.1,
2352 * replaced by <code>getPreferredSize()</code>.
2353 */
2354 @Deprecated
2355 public Dimension preferredSize() {
2356 /* Avoid grabbing the lock if a reasonable cached size value
2357 * is available.
2358 */
2359 Dimension dim = prefSize;
2360 if (dim == null || !(isPreferredSizeSet() || isValid())) {
2361 synchronized (getTreeLock()) {
2362 prefSize = (peer != null) ? peer.preferredSize()
2363 : getMinimumSize();
2364 dim = prefSize;
2365 }
2366 }
2367 return new Dimension(dim);
2368 }
2369
2370 /**
2371 * Sets the minimum size of this component to a constant
2372 * value. Subsequent calls to <code>getMinimumSize</code> will always
2373 * return this value. Setting the minimum size to <code>null</code>
2374 * restores the default behavior.
2375 *
2376 * @param minimumSize the new minimum size of this component
2377 * @see #getMinimumSize
2378 * @see #isMinimumSizeSet
2379 * @since 1.5
2380 */
2381 public void setMinimumSize(Dimension minimumSize) {
2382 Dimension old;
2383 // If the minimum size was set, use it as the old value, otherwise
2384 // use null to indicate we didn't previously have a set minimum
2385 // size.
2386 if (minSizeSet) {
2387 old = this .minSize;
2388 } else {
2389 old = null;
2390 }
2391 this .minSize = minimumSize;
2392 minSizeSet = (minimumSize != null);
2393 firePropertyChange("minimumSize", old, minimumSize);
2394 }
2395
2396 /**
2397 * Returns whether or not <code>setMinimumSize</code> has been
2398 * invoked with a non-null value.
2399 *
2400 * @return true if <code>setMinimumSize</code> has been invoked with a
2401 * non-null value.
2402 * @since 1.5
2403 */
2404 public boolean isMinimumSizeSet() {
2405 return minSizeSet;
2406 }
2407
2408 /**
2409 * Gets the mininimum size of this component.
2410 * @return a dimension object indicating this component's minimum size
2411 * @see #getPreferredSize
2412 * @see LayoutManager
2413 */
2414 public Dimension getMinimumSize() {
2415 return minimumSize();
2416 }
2417
2418 /**
2419 * @deprecated As of JDK version 1.1,
2420 * replaced by <code>getMinimumSize()</code>.
2421 */
2422 @Deprecated
2423 public Dimension minimumSize() {
2424 /* Avoid grabbing the lock if a reasonable cached size value
2425 * is available.
2426 */
2427 Dimension dim = minSize;
2428 if (dim == null || !(isMinimumSizeSet() || isValid())) {
2429 synchronized (getTreeLock()) {
2430 minSize = (peer != null) ? peer.minimumSize() : size();
2431 dim = minSize;
2432 }
2433 }
2434 return new Dimension(dim);
2435 }
2436
2437 /**
2438 * Sets the maximum size of this component to a constant
2439 * value. Subsequent calls to <code>getMaximumSize</code> will always
2440 * return this value. Setting the maximum size to <code>null</code>
2441 * restores the default behavior.
2442 *
2443 * @param maximumSize a <code>Dimension</code> containing the
2444 * desired maximum allowable size
2445 * @see #getMaximumSize
2446 * @see #isMaximumSizeSet
2447 * @since 1.5
2448 */
2449 public void setMaximumSize(Dimension maximumSize) {
2450 // If the maximum size was set, use it as the old value, otherwise
2451 // use null to indicate we didn't previously have a set maximum
2452 // size.
2453 Dimension old;
2454 if (maxSizeSet) {
2455 old = this .maxSize;
2456 } else {
2457 old = null;
2458 }
2459 this .maxSize = maximumSize;
2460 maxSizeSet = (maximumSize != null);
2461 firePropertyChange("maximumSize", old, maximumSize);
2462 }
2463
2464 /**
2465 * Returns true if the maximum size has been set to a non-<code>null</code>
2466 * value otherwise returns false.
2467 *
2468 * @return true if <code>maximumSize</code> is non-<code>null</code>,
2469 * false otherwise
2470 * @since 1.5
2471 */
2472 public boolean isMaximumSizeSet() {
2473 return maxSizeSet;
2474 }
2475
2476 /**
2477 * Gets the maximum size of this component.
2478 * @return a dimension object indicating this component's maximum size
2479 * @see #getMinimumSize
2480 * @see #getPreferredSize
2481 * @see LayoutManager
2482 */
2483 public Dimension getMaximumSize() {
2484 if (isMaximumSizeSet()) {
2485 return new Dimension(maxSize);
2486 }
2487 return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
2488 }
2489
2490 /**
2491 * Returns the alignment along the x axis. This specifies how
2492 * the component would like to be aligned relative to other
2493 * components. The value should be a number between 0 and 1
2494 * where 0 represents alignment along the origin, 1 is aligned
2495 * the furthest away from the origin, 0.5 is centered, etc.
2496 */
2497 public float getAlignmentX() {
2498 return CENTER_ALIGNMENT;
2499 }
2500
2501 /**
2502 * Returns the alignment along the y axis. This specifies how
2503 * the component would like to be aligned relative to other
2504 * components. The value should be a number between 0 and 1
2505 * where 0 represents alignment along the origin, 1 is aligned
2506 * the furthest away from the origin, 0.5 is centered, etc.
2507 */
2508 public float getAlignmentY() {
2509 return CENTER_ALIGNMENT;
2510 }
2511
2512 /**
2513 * Returns the baseline. The baseline is measured from the top of
2514 * the component. This method is primarily meant for
2515 * <code>LayoutManager</code>s to align components along their
2516 * baseline. A return value less than 0 indicates this component
2517 * does not have a reasonable baseline and that
2518 * <code>LayoutManager</code>s should not align this component on
2519 * its baseline.
2520 * <p>
2521 * The default implementation returns -1. Subclasses that support
2522 * baseline should override appropriately. If a value >= 0 is
2523 * returned, then the component has a valid baseline for any
2524 * size >= the minimum size and <code>getBaselineResizeBehavior</code>
2525 * can be used to determine how the baseline changes with size.
2526 *
2527 * @param width the width to get the baseline for
2528 * @param height the height to get the baseline for
2529 * @return the baseline or < 0 indicating there is no reasonable
2530 * baseline
2531 * @throws IllegalArgumentException if width or height is < 0
2532 * @see #getBaselineResizeBehavior
2533 * @see java.awt.FontMetrics
2534 * @since 1.6
2535 */
2536 public int getBaseline(int width, int height) {
2537 if (width < 0 || height < 0) {
2538 throw new IllegalArgumentException(
2539 "Width and height must be >= 0");
2540 }
2541 return -1;
2542 }
2543
2544 /**
2545 * Returns an enum indicating how the baseline of the component
2546 * changes as the size changes. This method is primarily meant for
2547 * layout managers and GUI builders.
2548 * <p>
2549 * The default implementation returns
2550 * <code>BaselineResizeBehavior.OTHER</code>. Subclasses that have a
2551 * baseline should override appropriately. Subclasses should
2552 * never return <code>null</code>; if the baseline can not be
2553 * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers
2554 * should first ask for the baseline using
2555 * <code>getBaseline</code> and if a value >= 0 is returned use
2556 * this method. It is acceptable for this method to return a
2557 * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2558 * <code>getBaseline</code> returns a value less than 0.
2559 *
2560 * @return an enum indicating how the baseline changes as the component
2561 * size changes
2562 * @see #getBaseline(int, int)
2563 * @since 1.6
2564 */
2565 public BaselineResizeBehavior getBaselineResizeBehavior() {
2566 return BaselineResizeBehavior.OTHER;
2567 }
2568
2569 /**
2570 * Prompts the layout manager to lay out this component. This is
2571 * usually called when the component (more specifically, container)
2572 * is validated.
2573 * @see #validate
2574 * @see LayoutManager
2575 */
2576 public void doLayout() {
2577 layout();
2578 }
2579
2580 /**
2581 * @deprecated As of JDK version 1.1,
2582 * replaced by <code>doLayout()</code>.
2583 */
2584 @Deprecated
2585 public void layout() {
2586 }
2587
2588 /**
2589 * Ensures that this component has a valid layout. This method is
2590 * primarily intended to operate on instances of <code>Container</code>.
2591 * @see #invalidate
2592 * @see #doLayout()
2593 * @see LayoutManager
2594 * @see Container#validate
2595 * @since JDK1.0
2596 */
2597 public void validate() {
2598 synchronized (getTreeLock()) {
2599 ComponentPeer peer = this .peer;
2600 if (!valid && peer != null) {
2601 Font newfont = getFont();
2602 Font oldfont = peerFont;
2603 if (newfont != oldfont
2604 && (oldfont == null || !oldfont.equals(newfont))) {
2605 peer.setFont(newfont);
2606 peerFont = newfont;
2607 }
2608 peer.layout();
2609 }
2610 valid = true;
2611 }
2612 }
2613
2614 /**
2615 * Invalidates this component. This component and all parents
2616 * above it are marked as needing to be laid out. This method can
2617 * be called often, so it needs to execute quickly.
2618 * @see #validate
2619 * @see #doLayout
2620 * @see LayoutManager
2621 * @since JDK1.0
2622 */
2623 public void invalidate() {
2624 synchronized (getTreeLock()) {
2625 /* Nullify cached layout and size information.
2626 * For efficiency, propagate invalidate() upwards only if
2627 * some other component hasn't already done so first.
2628 */
2629 valid = false;
2630 if (!isPreferredSizeSet()) {
2631 prefSize = null;
2632 }
2633 if (!isMinimumSizeSet()) {
2634 minSize = null;
2635 }
2636 if (!isMaximumSizeSet()) {
2637 maxSize = null;
2638 }
2639 if (parent != null && parent.valid) {
2640 parent.invalidate();
2641 }
2642 }
2643 }
2644
2645 /**
2646 * Creates a graphics context for this component. This method will
2647 * return <code>null</code> if this component is currently not
2648 * displayable.
2649 * @return a graphics context for this component, or <code>null</code>
2650 * if it has none
2651 * @see #paint
2652 * @since JDK1.0
2653 */
2654 public Graphics getGraphics() {
2655 if (peer instanceof LightweightPeer) {
2656 // This is for a lightweight component, need to
2657 // translate coordinate spaces and clip relative
2658 // to the parent.
2659 if (parent == null)
2660 return null;
2661 Graphics g = parent.getGraphics();
2662 if (g == null)
2663 return null;
2664 if (g instanceof ConstrainableGraphics) {
2665 ((ConstrainableGraphics) g).constrain(x, y, width,
2666 height);
2667 } else {
2668 g.translate(x, y);
2669 g.setClip(0, 0, width, height);
2670 }
2671 g.setFont(getFont());
2672 return g;
2673 } else {
2674 ComponentPeer peer = this .peer;
2675 return (peer != null) ? peer.getGraphics() : null;
2676 }
2677 }
2678
2679 final Graphics getGraphics_NoClientCode() {
2680 ComponentPeer peer = this .peer;
2681 if (peer instanceof LightweightPeer) {
2682 // This is for a lightweight component, need to
2683 // translate coordinate spaces and clip relative
2684 // to the parent.
2685 Container parent = this .parent;
2686 if (parent == null)
2687 return null;
2688 Graphics g = parent.getGraphics_NoClientCode();
2689 if (g == null)
2690 return null;
2691 if (g instanceof ConstrainableGraphics) {
2692 ((ConstrainableGraphics) g).constrain(x, y, width,
2693 height);
2694 } else {
2695 g.translate(x, y);
2696 g.setClip(0, 0, width, height);
2697 }
2698 g.setFont(getFont_NoClientCode());
2699 return g;
2700 } else {
2701 return (peer != null) ? peer.getGraphics() : null;
2702 }
2703 }
2704
2705 /**
2706 * Gets the font metrics for the specified font.
2707 * Warning: Since Font metrics are affected by the
2708 * {@link java.awt.font.FontRenderContext FontRenderContext} and
2709 * this method does not provide one, it can return only metrics for
2710 * the default render context which may not match that used when
2711 * rendering on the Component if {@link Graphics2D} functionality is being
2712 * used. Instead metrics can be obtained at rendering time by calling
2713 * {@link Graphics#getFontMetrics()} or text measurement APIs on the
2714 * {@link Font Font} class.
2715 * @param font the font for which font metrics is to be
2716 * obtained
2717 * @return the font metrics for <code>font</code>
2718 * @see #getFont
2719 * @see #getPeer
2720 * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
2721 * @see Toolkit#getFontMetrics(Font)
2722 * @since JDK1.0
2723 */
2724 public FontMetrics getFontMetrics(Font font) {
2725 // REMIND: PlatformFont flag should be obsolete soon...
2726 if (sun.font.FontManager.usePlatformFontMetrics()) {
2727 if (peer != null && !(peer instanceof LightweightPeer)) {
2728 return peer.getFontMetrics(font);
2729 }
2730 }
2731 return sun.font.FontDesignMetrics.getMetrics(font);
2732 }
2733
2734 /**
2735 * Sets the cursor image to the specified cursor. This cursor
2736 * image is displayed when the <code>contains</code> method for
2737 * this component returns true for the current cursor location, and
2738 * this Component is visible, displayable, and enabled. Setting the
2739 * cursor of a <code>Container</code> causes that cursor to be displayed
2740 * within all of the container's subcomponents, except for those
2741 * that have a non-<code>null</code> cursor.
2742 * <p>
2743 * The method may have no visual effect if the Java platform
2744 * implementation and/or the native system do not support
2745 * changing the mouse cursor shape.
2746 * @param cursor One of the constants defined
2747 * by the <code>Cursor</code> class;
2748 * if this parameter is <code>null</code>
2749 * then this component will inherit
2750 * the cursor of its parent
2751 * @see #isEnabled
2752 * @see #isShowing
2753 * @see #getCursor
2754 * @see #contains
2755 * @see Toolkit#createCustomCursor
2756 * @see Cursor
2757 * @since JDK1.1
2758 */
2759 public void setCursor(Cursor cursor) {
2760 this .cursor = cursor;
2761 updateCursorImmediately();
2762 }
2763
2764 /**
2765 * Updates the cursor. May not be invoked from the native
2766 * message pump.
2767 */
2768 final void updateCursorImmediately() {
2769 if (peer instanceof LightweightPeer) {
2770 Container nativeContainer = getNativeContainer();
2771
2772 if (nativeContainer == null)
2773 return;
2774
2775 ComponentPeer cPeer = nativeContainer.getPeer();
2776
2777 if (cPeer != null) {
2778 cPeer.updateCursorImmediately();
2779 }
2780 } else if (peer != null) {
2781 peer.updateCursorImmediately();
2782 }
2783 }
2784
2785 /**
2786 * Gets the cursor set in the component. If the component does
2787 * not have a cursor set, the cursor of its parent is returned.
2788 * If no cursor is set in the entire hierarchy,
2789 * <code>Cursor.DEFAULT_CURSOR</code> is returned.
2790 * @see #setCursor
2791 * @since JDK1.1
2792 */
2793 public Cursor getCursor() {
2794 return getCursor_NoClientCode();
2795 }
2796
2797 final Cursor getCursor_NoClientCode() {
2798 Cursor cursor = this .cursor;
2799 if (cursor != null) {
2800 return cursor;
2801 }
2802 Container parent = this .parent;
2803 if (parent != null) {
2804 return parent.getCursor_NoClientCode();
2805 } else {
2806 return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
2807 }
2808 }
2809
2810 /**
2811 * Returns whether the cursor has been explicitly set for this Component.
2812 * If this method returns <code>false</code>, this Component is inheriting
2813 * its cursor from an ancestor.
2814 *
2815 * @return <code>true</code> if the cursor has been explicitly set for this
2816 * Component; <code>false</code> otherwise.
2817 * @since 1.4
2818 */
2819 public boolean isCursorSet() {
2820 return (cursor != null);
2821 }
2822
2823 /**
2824 * Paints this component.
2825 * <p>
2826 * This method is called when the contents of the component should
2827 * be painted; such as when the component is first being shown or
2828 * is damaged and in need of repair. The clip rectangle in the
2829 * <code>Graphics</code> parameter is set to the area
2830 * which needs to be painted.
2831 * Subclasses of <code>Component</code> that override this
2832 * method need not call <code>super.paint(g)</code>.
2833 * <p>
2834 * For performance reasons, <code>Component</code>s with zero width
2835 * or height aren't considered to need painting when they are first shown,
2836 * and also aren't considered to need repair.
2837 * <p>
2838 * <b>Note</b>: For more information on the paint mechanisms utilitized
2839 * by AWT and Swing, including information on how to write the most
2840 * efficient painting code, see
2841 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2842 *
2843 * @param g the graphics context to use for painting
2844 * @see #update
2845 * @since JDK1.0
2846 */
2847 public void paint(Graphics g) {
2848 }
2849
2850 /**
2851 * Updates this component.
2852 * <p>
2853 * If this component is not a lightweight component, the
2854 * AWT calls the <code>update</code> method in response to
2855 * a call to <code>repaint</code>. You can assume that
2856 * the background is not cleared.
2857 * <p>
2858 * The <code>update</code> method of <code>Component</code>
2859 * calls this component's <code>paint</code> method to redraw
2860 * this component. This method is commonly overridden by subclasses
2861 * which need to do additional work in response to a call to
2862 * <code>repaint</code>.
2863 * Subclasses of Component that override this method should either
2864 * call <code>super.update(g)</code>, or call <code>paint(g)</code>
2865 * directly from their <code>update</code> method.
2866 * <p>
2867 * The origin of the graphics context, its
2868 * (<code>0</code>, <code>0</code>) coordinate point, is the
2869 * top-left corner of this component. The clipping region of the
2870 * graphics context is the bounding rectangle of this component.
2871 *
2872 * <p>
2873 * <b>Note</b>: For more information on the paint mechanisms utilitized
2874 * by AWT and Swing, including information on how to write the most
2875 * efficient painting code, see
2876 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2877 *
2878 * @param g the specified context to use for updating
2879 * @see #paint
2880 * @see #repaint()
2881 * @since JDK1.0
2882 */
2883 public void update(Graphics g) {
2884 paint(g);
2885 }
2886
2887 /**
2888 * Paints this component and all of its subcomponents.
2889 * <p>
2890 * The origin of the graphics context, its
2891 * (<code>0</code>, <code>0</code>) coordinate point, is the
2892 * top-left corner of this component. The clipping region of the
2893 * graphics context is the bounding rectangle of this component.
2894 *
2895 * @param g the graphics context to use for painting
2896 * @see #paint
2897 * @since JDK1.0
2898 */
2899 public void paintAll(Graphics g) {
2900 if (isShowing()) {
2901 GraphicsCallback.PeerPaintCallback.getInstance()
2902 .runOneComponent(
2903 this ,
2904 new Rectangle(0, 0, width, height),
2905 g,
2906 g.getClip(),
2907 GraphicsCallback.LIGHTWEIGHTS
2908 | GraphicsCallback.HEAVYWEIGHTS);
2909 }
2910 }
2911
2912 /**
2913 * Simulates the peer callbacks into java.awt for painting of
2914 * lightweight Components.
2915 * @param g the graphics context to use for painting
2916 * @see #paintAll
2917 */
2918 void lightweightPaint(Graphics g) {
2919 paint(g);
2920 }
2921
2922 /**
2923 * Paints all the heavyweight subcomponents.
2924 */
2925 void paintHeavyweightComponents(Graphics g) {
2926 }
2927
2928 /**
2929 * Repaints this component.
2930 * <p>
2931 * If this component is a lightweight component, this method
2932 * causes a call to this component's <code>paint</code>
2933 * method as soon as possible. Otherwise, this method causes
2934 * a call to this component's <code>update</code> method as soon
2935 * as possible.
2936 * <p>
2937 * <b>Note</b>: For more information on the paint mechanisms utilitized
2938 * by AWT and Swing, including information on how to write the most
2939 * efficient painting code, see
2940 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2941
2942 *
2943 * @see #update(Graphics)
2944 * @since JDK1.0
2945 */
2946 public void repaint() {
2947 repaint(0, 0, 0, width, height);
2948 }
2949
2950 /**
2951 * Repaints the component. If this component is a lightweight
2952 * component, this results in a call to <code>paint</code>
2953 * within <code>tm</code> milliseconds.
2954 * <p>
2955 * <b>Note</b>: For more information on the paint mechanisms utilitized
2956 * by AWT and Swing, including information on how to write the most
2957 * efficient painting code, see
2958 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2959 *
2960 * @param tm maximum time in milliseconds before update
2961 * @see #paint
2962 * @see #update(Graphics)
2963 * @since JDK1.0
2964 */
2965 public void repaint(long tm) {
2966 repaint(tm, 0, 0, width, height);
2967 }
2968
2969 /**
2970 * Repaints the specified rectangle of this component.
2971 * <p>
2972 * If this component is a lightweight component, this method
2973 * causes a call to this component's <code>paint</code> method
2974 * as soon as possible. Otherwise, this method causes a call to
2975 * this component's <code>update</code> method as soon as possible.
2976 * <p>
2977 * <b>Note</b>: For more information on the paint mechanisms utilitized
2978 * by AWT and Swing, including information on how to write the most
2979 * efficient painting code, see
2980 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2981 *
2982 * @param x the <i>x</i> coordinate
2983 * @param y the <i>y</i> coordinate
2984 * @param width the width
2985 * @param height the height
2986 * @see #update(Graphics)
2987 * @since JDK1.0
2988 */
2989 public void repaint(int x, int y, int width, int height) {
2990 repaint(0, x, y, width, height);
2991 }
2992
2993 /**
2994 * Repaints the specified rectangle of this component within
2995 * <code>tm</code> milliseconds.
2996 * <p>
2997 * If this component is a lightweight component, this method causes
2998 * a call to this component's <code>paint</code> method.
2999 * Otherwise, this method causes a call to this component's
3000 * <code>update</code> method.
3001 * <p>
3002 * <b>Note</b>: For more information on the paint mechanisms utilitized
3003 * by AWT and Swing, including information on how to write the most
3004 * efficient painting code, see
3005 * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
3006 *
3007 * @param tm maximum time in milliseconds before update
3008 * @param x the <i>x</i> coordinate
3009 * @param y the <i>y</i> coordinate
3010 * @param width the width
3011 * @param height the height
3012 * @see #update(Graphics)
3013 * @since JDK1.0
3014 */
3015 public void repaint(long tm, int x, int y, int width, int height) {
3016 if (this .peer instanceof LightweightPeer) {
3017 // Needs to be translated to parent coordinates since
3018 // a parent native container provides the actual repaint
3019 // services. Additionally, the request is restricted to
3020 // the bounds of the component.
3021 if (parent != null) {
3022 int px = this .x + ((x < 0) ? 0 : x);
3023 int py = this .y + ((y < 0) ? 0 : y);
3024 int pwidth = (width > this .width) ? this .width : width;
3025 int pheight = (height > this .height) ? this .height
3026 : height;
3027 parent.repaint(tm, px, py, pwidth, pheight);
3028 }
3029 } else {
3030 if (isVisible() && (this .peer != null) && (width > 0)
3031 && (height > 0)) {
3032 PaintEvent e = new PaintEvent(this , PaintEvent.UPDATE,
3033 new Rectangle(x, y, width, height));
3034 Toolkit.getEventQueue().postEvent(e);
3035 }
3036 }
3037 }
3038
3039 /**
3040 * Prints this component. Applications should override this method
3041 * for components that must do special processing before being
3042 * printed or should be printed differently than they are painted.
3043 * <p>
3044 * The default implementation of this method calls the
3045 * <code>paint</code> method.
3046 * <p>
3047 * The origin of the graphics context, its
3048 * (<code>0</code>, <code>0</code>) coordinate point, is the
3049 * top-left corner of this component. The clipping region of the
3050 * graphics context is the bounding rectangle of this component.
3051 * @param g the graphics context to use for printing
3052 * @see #paint(Graphics)
3053 * @since JDK1.0
3054 */
3055 public void print(Graphics g) {
3056 paint(g);
3057 }
3058
3059 /**
3060 * Prints this component and all of its subcomponents.
3061 * <p>
3062 * The origin of the graphics context, its
3063 * (<code>0</code>, <code>0</code>) coordinate point, is the
3064 * top-left corner of this component. The clipping region of the
3065 * graphics context is the bounding rectangle of this component.
3066 * @param g the graphics context to use for printing
3067 * @see #print(Graphics)
3068 * @since JDK1.0
3069 */
3070 public void printAll(Graphics g) {
3071 if (isShowing()) {
3072 GraphicsCallback.PeerPrintCallback.getInstance()
3073 .runOneComponent(
3074 this ,
3075 new Rectangle(0, 0, width, height),
3076 g,
3077 g.getClip(),
3078 GraphicsCallback.LIGHTWEIGHTS
3079 | GraphicsCallback.HEAVYWEIGHTS);
3080 }
3081 }
3082
3083 /**
3084 * Simulates the peer callbacks into java.awt for printing of
3085 * lightweight Components.
3086 * @param g the graphics context to use for printing
3087 * @see #printAll
3088 */
3089 void lightweightPrint(Graphics g) {
3090 print(g);
3091 }
3092
3093 /**
3094 * Prints all the heavyweight subcomponents.
3095 */
3096 void printHeavyweightComponents(Graphics g) {
3097 }
3098
3099 private Insets getInsets_NoClientCode() {
3100 ComponentPeer peer = this .peer;
3101 if (peer instanceof ContainerPeer) {
3102 return (Insets) ((ContainerPeer) peer).insets().clone();
3103 }
3104 return new Insets(0, 0, 0, 0);
3105 }
3106
3107 /**
3108 * Repaints the component when the image has changed.
3109 * This <code>imageUpdate</code> method of an <code>ImageObserver</code>
3110 * is called when more information about an
3111 * image which had been previously requested using an asynchronous
3112 * routine such as the <code>drawImage</code> method of
3113 * <code>Graphics</code> becomes available.
3114 * See the definition of <code>imageUpdate</code> for
3115 * more information on this method and its arguments.
3116 * <p>
3117 * The <code>imageUpdate</code> method of <code>Component</code>
3118 * incrementally draws an image on the component as more of the bits
3119 * of the image are available.
3120 * <p>
3121 * If the system property <code>awt.image.incrementaldraw</code>
3122 * is missing or has the value <code>true</code>, the image is
3123 * incrementally drawn. If the system property has any other value,
3124 * then the image is not drawn until it has been completely loaded.
3125 * <p>
3126 * Also, if incremental drawing is in effect, the value of the
3127 * system property <code>awt.image.redrawrate</code> is interpreted
3128 * as an integer to give the maximum redraw rate, in milliseconds. If
3129 * the system property is missing or cannot be interpreted as an
3130 * integer, the redraw rate is once every 100ms.
3131 * <p>
3132 * The interpretation of the <code>x</code>, <code>y</code>,
3133 * <code>width</code>, and <code>height</code> arguments depends on
3134 * the value of the <code>infoflags</code> argument.
3135 *
3136 * @param img the image being observed
3137 * @param infoflags see <code>imageUpdate</code> for more information
3138 * @param x the <i>x</i> coordinate
3139 * @param y the <i>y</i> coordinate
3140 * @param w the width
3141 * @param h the height
3142 * @return <code>false</code> if the infoflags indicate that the
3143 * image is completely loaded; <code>true</code> otherwise.
3144 *
3145 * @see java.awt.image.ImageObserver
3146 * @see Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver)
3147 * @see Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver)
3148 * @see Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver)
3149 * @see Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver)
3150 * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
3151 * @since JDK1.0
3152 */
3153 public boolean imageUpdate(Image img, int infoflags, int x, int y,
3154 int w, int h) {
3155 int rate = -1;
3156 if ((infoflags & (FRAMEBITS | ALLBITS)) != 0) {
3157 rate = 0;
3158 } else if ((infoflags & SOMEBITS) != 0) {
3159 if (isInc) {
3160 rate = incRate;
3161 if (rate < 0) {
3162 rate = 0;
3163 }
3164 }
3165 }
3166 if (rate >= 0) {
3167 repaint(rate, 0, 0, width, height);
3168 }
3169 return (infoflags & (ALLBITS | ABORT)) == 0;
3170 }
3171
3172 /**
3173 * Creates an image from the specified image producer.
3174 * @param producer the image producer
3175 * @return the image produced
3176 * @since JDK1.0
3177 */
3178 public Image createImage(ImageProducer producer) {
3179 ComponentPeer peer = this .peer;
3180 if ((peer != null) && !(peer instanceof LightweightPeer)) {
3181 return peer.createImage(producer);
3182 }
3183 return getToolkit().createImage(producer);
3184 }
3185
3186 /**
3187 * Creates an off-screen drawable image
3188 * to be used for double buffering.
3189 * @param width the specified width
3190 * @param height the specified height
3191 * @return an off-screen drawable image, which can be used for double
3192 * buffering. The return value may be <code>null</code> if the
3193 * component is not displayable. This will always happen if
3194 * <code>GraphicsEnvironment.isHeadless()</code> returns
3195 * <code>true</code>.
3196 * @see #isDisplayable
3197 * @see GraphicsEnvironment#isHeadless
3198 * @since JDK1.0
3199 */
3200 public Image createImage(int width, int height) {
3201 ComponentPeer peer = this .peer;
3202 if (peer instanceof LightweightPeer) {
3203 if (parent != null) {
3204 return parent.createImage(width, height);
3205 } else {
3206 return null;
3207 }
3208 } else {
3209 return (peer != null) ? peer.createImage(width, height)
3210 : null;
3211 }
3212 }
3213
3214 /**
3215 * Creates a volatile off-screen drawable image
3216 * to be used for double buffering.
3217 * @param width the specified width.
3218 * @param height the specified height.
3219 * @return an off-screen drawable image, which can be used for double
3220 * buffering. The return value may be <code>null</code> if the
3221 * component is not displayable. This will always happen if
3222 * <code>GraphicsEnvironment.isHeadless()</code> returns
3223 * <code>true</code>.
3224 * @see java.awt.image.VolatileImage
3225 * @see #isDisplayable
3226 * @see GraphicsEnvironment#isHeadless
3227 * @since 1.4
3228 */
3229 public VolatileImage createVolatileImage(int width, int height) {
3230 ComponentPeer peer = this .peer;
3231 if (peer instanceof LightweightPeer) {
3232 if (parent != null) {
3233 return parent.createVolatileImage(width, height);
3234 } else {
3235 return null;
3236 }
3237 } else {
3238 return (peer != null) ? peer.createVolatileImage(width,
3239 height) : null;
3240 }
3241 }
3242
3243 /**
3244 * Creates a volatile off-screen drawable image, with the given capabilities.
3245 * The contents of this image may be lost at any time due
3246 * to operating system issues, so the image must be managed
3247 * via the <code>VolatileImage</code> interface.
3248 * @param width the specified width.
3249 * @param height the specified height.
3250 * @param caps the image capabilities
3251 * @exception AWTException if an image with the specified capabilities cannot
3252 * be created
3253 * @return a VolatileImage object, which can be used
3254 * to manage surface contents loss and capabilities.
3255 * @see java.awt.image.VolatileImage
3256 * @since 1.4
3257 */
3258 public VolatileImage createVolatileImage(int width, int height,
3259 ImageCapabilities caps) throws AWTException {
3260 // REMIND : check caps
3261 return createVolatileImage(width, height);
3262 }
3263
3264 /**
3265 * Prepares an image for rendering on this component. The image
3266 * data is downloaded asynchronously in another thread and the
3267 * appropriate screen representation of the image is generated.
3268 * @param image the <code>Image</code> for which to
3269 * prepare a screen representation
3270 * @param observer the <code>ImageObserver</code> object
3271 * to be notified as the image is being prepared
3272 * @return <code>true</code> if the image has already been fully
3273 * prepared; <code>false</code> otherwise
3274 * @since JDK1.0
3275 */
3276 public boolean prepareImage(Image image, ImageObserver observer) {
3277 return prepareImage(image, -1, -1, observer);
3278 }
3279
3280 /**
3281 * Prepares an image for rendering on this component at the
3282 * specified width and height.
3283 * <p>
3284 * The image data is downloaded asynchronously in another thread,
3285 * and an appropriately scaled screen representation of the image is
3286 * generated.
3287 * @param image the instance of <code>Image</code>
3288 * for which to prepare a screen representation
3289 * @param width the width of the desired screen representation
3290 * @param height the height of the desired screen representation
3291 * @param observer the <code>ImageObserver</code> object
3292 * to be notified as the image is being prepared
3293 * @return <code>true</code> if the image has already been fully
3294 * prepared; <code>false</code> otherwise
3295 * @see java.awt.image.ImageObserver
3296 * @since JDK1.0
3297 */
3298 public boolean prepareImage(Image image, int width, int height,
3299 ImageObserver observer) {
3300 ComponentPeer peer = this .peer;
3301 if (peer instanceof LightweightPeer) {
3302 return (parent != null) ? parent.prepareImage(image, width,
3303 height, observer) : getToolkit().prepareImage(
3304 image, width, height, observer);
3305 } else {
3306 return (peer != null) ? peer.prepareImage(image, width,
3307 height, observer) : getToolkit().prepareImage(
3308 image, width, height, observer);
3309 }
3310 }
3311
3312 /**
3313 * Returns the status of the construction of a screen representation
3314 * of the specified image.
3315 * <p>
3316 * This method does not cause the image to begin loading. An
3317 * application must use the <code>prepareImage</code> method
3318 * to force the loading of an image.
3319 * <p>
3320 * Information on the flags returned by this method can be found
3321 * with the discussion of the <code>ImageObserver</code> interface.
3322 * @param image the <code>Image</code> object whose status
3323 * is being checked
3324 * @param observer the <code>ImageObserver</code>
3325 * object to be notified as the image is being prepared
3326 * @return the bitwise inclusive <b>OR</b> of
3327 * <code>ImageObserver</code> flags indicating what
3328 * information about the image is currently available
3329 * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3330 * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3331 * @see java.awt.image.ImageObserver
3332 * @since JDK1.0
3333 */
3334 public int checkImage(Image image, ImageObserver observer) {
3335 return checkImage(image, -1, -1, observer);
3336 }
3337
3338 /**
3339 * Returns the status of the construction of a screen representation
3340 * of the specified image.
3341 * <p>
3342 * This method does not cause the image to begin loading. An
3343 * application must use the <code>prepareImage</code> method
3344 * to force the loading of an image.
3345 * <p>
3346 * The <code>checkImage</code> method of <code>Component</code>
3347 * calls its peer's <code>checkImage</code> method to calculate
3348 * the flags. If this component does not yet have a peer, the
3349 * component's toolkit's <code>checkImage</code> method is called
3350 * instead.
3351 * <p>
3352 * Information on the flags returned by this method can be found
3353 * with the discussion of the <code>ImageObserver</code> interface.
3354 * @param image the <code>Image</code> object whose status
3355 * is being checked
3356 * @param width the width of the scaled version
3357 * whose status is to be checked
3358 * @param height the height of the scaled version
3359 * whose status is to be checked
3360 * @param observer the <code>ImageObserver</code> object
3361 * to be notified as the image is being prepared
3362 * @return the bitwise inclusive <b>OR</b> of
3363 * <code>ImageObserver</code> flags indicating what
3364 * information about the image is currently available
3365 * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3366 * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3367 * @see java.awt.image.ImageObserver
3368 * @since JDK1.0
3369 */
3370 public int checkImage(Image image, int width, int height,
3371 ImageObserver observer) {
3372 ComponentPeer peer = this .peer;
3373 if (peer instanceof LightweightPeer) {
3374 return (parent != null) ? parent.checkImage(image, width,
3375 height, observer) : getToolkit().checkImage(image,
3376 width, height, observer);
3377 } else {
3378 return (peer != null) ? peer.checkImage(image, width,
3379 height, observer) : getToolkit().checkImage(image,
3380 width, height, observer);
3381 }
3382 }
3383
3384 /**
3385 * Creates a new strategy for multi-buffering on this component.
3386 * Multi-buffering is useful for rendering performance. This method
3387 * attempts to create the best strategy available with the number of
3388 * buffers supplied. It will always create a <code>BufferStrategy</code>
3389 * with that number of buffers.
3390 * A page-flipping strategy is attempted first, then a blitting strategy
3391 * using accelerated buffers. Finally, an unaccelerated blitting
3392 * strategy is used.
3393 * <p>
3394 * Each time this method is called,
3395 * the existing buffer strategy for this component is discarded.
3396 * @param numBuffers number of buffers to create, including the front buffer
3397 * @exception IllegalArgumentException if numBuffers is less than 1.
3398 * @exception IllegalStateException if the component is not displayable
3399 * @see #isDisplayable
3400 * @see Window#getBufferStrategy()
3401 * @see Canvas#getBufferStrategy()
3402 * @since 1.4
3403 */
3404 void createBufferStrategy(int numBuffers) {
3405 BufferCapabilities bufferCaps;
3406 if (numBuffers > 1) {
3407 // Try to create a page-flipping strategy
3408 bufferCaps = new BufferCapabilities(new ImageCapabilities(
3409 true), new ImageCapabilities(true),
3410 BufferCapabilities.FlipContents.UNDEFINED);
3411 try {
3412 createBufferStrategy(numBuffers, bufferCaps);
3413 return; // Success
3414 } catch (AWTException e) {
3415 // Failed
3416 }
3417 }
3418 // Try a blitting (but still accelerated) strategy
3419 bufferCaps = new BufferCapabilities(
3420 new ImageCapabilities(true),
3421 new ImageCapabilities(true), null);
3422 try {
3423 createBufferStrategy(numBuffers, bufferCaps);
3424 return; // Success
3425 } catch (AWTException e) {
3426 // Failed
3427 }
3428 // Try an unaccelerated blitting strategy
3429 bufferCaps = new BufferCapabilities(
3430 new ImageCapabilities(false), new ImageCapabilities(
3431 false), null);
3432 try {
3433 createBufferStrategy(numBuffers, bufferCaps);
3434 return; // Success
3435 } catch (AWTException e) {
3436 // Failed
3437 }
3438 // Code should never reach here (an unaccelerated blitting
3439 // strategy should always work)
3440 throw new InternalError("Could not create a buffer strategy");
3441 }
3442
3443 /**
3444 * Creates a new strategy for multi-buffering on this component with the
3445 * required buffer capabilities. This is useful, for example, if only
3446 * accelerated memory or page flipping is desired (as specified by the
3447 * buffer capabilities).
3448 * <p>
3449 * Each time this method
3450 * is called, <code>dispose</code> will be invoked on the existing
3451 * <code>BufferStrategy</code>.
3452 * @param numBuffers number of buffers to create
3453 * @param caps the required capabilities for creating the buffer strategy;
3454 * cannot be <code>null</code>
3455 * @exception AWTException if the capabilities supplied could not be
3456 * supported or met; this may happen, for example, if there is not enough
3457 * accelerated memory currently available, or if page flipping is specified
3458 * but not possible.
3459 * @exception IllegalArgumentException if numBuffers is less than 1, or if
3460 * caps is <code>null</code>
3461 * @see Window#getBufferStrategy()
3462 * @see Canvas#getBufferStrategy()
3463 * @since 1.4
3464 */
3465 void createBufferStrategy(int numBuffers, BufferCapabilities caps)
3466 throws AWTException {
3467 // Check arguments
3468 if (numBuffers < 1) {
3469 throw new IllegalArgumentException(
3470 "Number of buffers must be at least 1");
3471 }
3472 if (caps == null) {
3473 throw new IllegalArgumentException(
3474 "No capabilities specified");
3475 }
3476 // Destroy old buffers
3477 if (bufferStrategy != null) {
3478 bufferStrategy.dispose();
3479 }
3480 if (numBuffers == 1) {
3481 bufferStrategy = new SingleBufferStrategy(caps);
3482 } else {
3483 // assert numBuffers > 1;
3484 if (caps.isPageFlipping()) {
3485 bufferStrategy = new FlipSubRegionBufferStrategy(
3486 numBuffers, caps);
3487 } else {
3488 bufferStrategy = new BltSubRegionBufferStrategy(
3489 numBuffers, caps);
3490 }
3491 }
3492 }
3493
3494 /**
3495 * @return the buffer strategy used by this component
3496 * @see Window#createBufferStrategy
3497 * @see Canvas#createBufferStrategy
3498 * @since 1.4
3499 */
3500 BufferStrategy getBufferStrategy() {
3501 return bufferStrategy;
3502 }
3503
3504 /**
3505 * @return the back buffer currently used by this component's
3506 * BufferStrategy. If there is no BufferStrategy or no
3507 * back buffer, this method returns null.
3508 */
3509 Image getBackBuffer() {
3510 if (bufferStrategy != null) {
3511 if (bufferStrategy instanceof BltBufferStrategy) {
3512 BltBufferStrategy bltBS = (BltBufferStrategy) bufferStrategy;
3513 return bltBS.getBackBuffer();
3514 } else if (bufferStrategy instanceof FlipBufferStrategy) {
3515 FlipBufferStrategy flipBS = (FlipBufferStrategy) bufferStrategy;
3516 return flipBS.getBackBuffer();
3517 }
3518 }
3519 return null;
3520 }
3521
3522 /**
3523 * Inner class for flipping buffers on a component. That component must
3524 * be a <code>Canvas</code> or <code>Window</code>.
3525 * @see Canvas
3526 * @see Window
3527 * @see java.awt.image.BufferStrategy
3528 * @author Michael Martak
3529 * @since 1.4
3530 */
3531 protected class FlipBufferStrategy extends BufferStrategy {
3532 /**
3533 * The number of buffers
3534 */
3535 protected int numBuffers; // = 0
3536 /**
3537 * The buffering capabilities
3538 */
3539 protected BufferCapabilities caps; // = null
3540 /**
3541 * The drawing buffer
3542 */
3543 protected Image drawBuffer; // = null
3544 /**
3545 * The drawing buffer as a volatile image
3546 */
3547 protected VolatileImage drawVBuffer; // = null
3548 /**
3549 * Whether or not the drawing buffer has been recently restored from
3550 * a lost state.
3551 */
3552 protected boolean validatedContents; // = false
3553 /**
3554 * Size of the back buffers. (Note: these fields were added in 6.0
3555 * but kept package-private to avoid exposing them in the spec.
3556 * None of these fields/methods really should have been marked
3557 * protected when they were introduced in 1.4, but now we just have
3558 * to live with that decision.)
3559 */
3560 int width;
3561 int height;
3562
3563 /**
3564 * Creates a new flipping buffer strategy for this component.
3565 * The component must be a <code>Canvas</code> or <code>Window</code>.
3566 * @see Canvas
3567 * @see Window
3568 * @param numBuffers the number of buffers
3569 * @param caps the capabilities of the buffers
3570 * @exception AWTException if the capabilities supplied could not be
3571 * supported or met
3572 * @exception ClassCastException if the component is not a canvas or
3573 * window.
3574 */
3575 protected FlipBufferStrategy(int numBuffers,
3576 BufferCapabilities caps) throws AWTException {
3577 if (!(Component.this instanceof Window)
3578 && !(Component.this instanceof Canvas)) {
3579 throw new ClassCastException(
3580 "Component must be a Canvas or Window");
3581 }
3582 this .numBuffers = numBuffers;
3583 this .caps = caps;
3584 createBuffers(numBuffers, caps);
3585 }
3586
3587 /**
3588 * Creates one or more complex, flipping buffers with the given
3589 * capabilities.
3590 * @param numBuffers number of buffers to create; must be greater than
3591 * one
3592 * @param caps the capabilities of the buffers.
3593 * <code>BufferCapabilities.isPageFlipping</code> must be
3594 * <code>true</code>.
3595 * @exception AWTException if the capabilities supplied could not be
3596 * supported or met
3597 * @exception IllegalStateException if the component has no peer
3598 * @exception IllegalArgumentException if numBuffers is less than two,
3599 * or if <code>BufferCapabilities.isPageFlipping</code> is not
3600 * <code>true</code>.
3601 * @see java.awt.BufferCapabilities#isPageFlipping()
3602 */
3603 protected void createBuffers(int numBuffers,
3604 BufferCapabilities caps) throws AWTException {
3605 if (numBuffers < 2) {
3606 throw new IllegalArgumentException(
3607 "Number of buffers cannot be less than two");
3608 } else if (peer == null) {
3609 throw new IllegalStateException(
3610 "Component must have a valid peer");
3611 } else if (caps == null || !caps.isPageFlipping()) {
3612 throw new IllegalArgumentException(
3613 "Page flipping capabilities must be specified");
3614 }
3615
3616 // save the current bounds
3617 width = getWidth();
3618 height = getHeight();
3619
3620 if (drawBuffer == null) {
3621 peer.createBuffers(numBuffers, caps);
3622 } else {
3623 // dispose the existing backbuffers
3624 drawBuffer = null;
3625 drawVBuffer = null;
3626 destroyBuffers();
3627 // ... then recreate the backbuffers
3628 peer.createBuffers(numBuffers, caps);
3629 }
3630 updateInternalBuffers();
3631 }
3632
3633 /**
3634 * Updates internal buffers (both volatile and non-volatile)
3635 * by requesting the back-buffer from the peer.
3636 */
3637 private void updateInternalBuffers() {
3638 // get the images associated with the draw buffer
3639 drawBuffer = getBackBuffer();
3640 if (drawBuffer instanceof VolatileImage) {
3641 drawVBuffer = (VolatileImage) drawBuffer;
3642 } else {
3643 drawVBuffer = null;
3644 }
3645 }
3646
3647 /**
3648 * @return direct access to the back buffer, as an image.
3649 * @exception IllegalStateException if the buffers have not yet
3650 * been created
3651 */
3652 protected Image getBackBuffer() {
3653 if (peer != null) {
3654 return peer.getBackBuffer();
3655 } else {
3656 throw new IllegalStateException(
3657 "Component must have a valid peer");
3658 }
3659 }
3660
3661 /**
3662 * Flipping moves the contents of the back buffer to the front buffer,
3663 * either by copying or by moving the video pointer.
3664 * @param flipAction an integer value describing the flipping action
3665 * for the contents of the back buffer. This should be one of the
3666 * values of the <code>BufferCapabilities.FlipContents</code>
3667 * property.
3668 * @exception IllegalStateException if the buffers have not yet
3669 * been created
3670 * @see java.awt.BufferCapabilities#getFlipContents()
3671 */
3672 protected void flip(BufferCapabilities.FlipContents flipAction) {
3673 if (peer != null) {
3674 peer.flip(flipAction);
3675 } else {
3676 throw new IllegalStateException(
3677 "Component must have a valid peer");
3678 }
3679 }
3680
3681 /**
3682 * Destroys the buffers created through this object
3683 */
3684 protected void destroyBuffers() {
3685 if (peer != null) {
3686 peer.destroyBuffers();
3687 } else {
3688 throw new IllegalStateException(
3689 "Component must have a valid peer");
3690 }
3691 }
3692
3693 /**
3694 * @return the buffering capabilities of this strategy
3695 */
3696 public BufferCapabilities getCapabilities() {
3697 return caps;
3698 }
3699
3700 /**
3701 * @return the graphics on the drawing buffer. This method may not
3702 * be synchronized for performance reasons; use of this method by multiple
3703 * threads should be handled at the application level. Disposal of the
3704 * graphics object must be handled by the application.
3705 */
3706 public Graphics getDrawGraphics() {
3707 revalidate();
3708 return drawBuffer.getGraphics();
3709 }
3710
3711 /**
3712 * Restore the drawing buffer if it has been lost
3713 */
3714 protected void revalidate() {
3715 revalidate(true);
3716 }
3717
3718 void revalidate(boolean checkSize) {
3719 validatedContents = false;
3720
3721 if (checkSize
3722 && (getWidth() != width || getHeight() != height)) {
3723 // component has been resized; recreate the backbuffers
3724 try {
3725 createBuffers(numBuffers, caps);
3726 } catch (AWTException e) {
3727 // shouldn't be possible
3728 }
3729 validatedContents = true;
3730 }
3731
3732 // get the buffers from the peer every time since they
3733 // might have been replaced in response to a display change event
3734 updateInternalBuffers();
3735
3736 // now validate the backbuffer
3737 if (drawVBuffer != null) {
3738 GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
3739 int returnCode = drawVBuffer.validate(gc);
3740 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
3741 try {
3742 createBuffers(numBuffers, caps);
3743 } catch (AWTException e) {
3744 // shouldn't be possible
3745 }
3746 if (drawVBuffer != null) {
3747 // backbuffers were recreated, so validate again
3748 drawVBuffer.validate(gc);
3749 }
3750 validatedContents = true;
3751 } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
3752 validatedContents = true;
3753 }
3754 }
3755 }
3756
3757 /**
3758 * @return whether the drawing buffer was lost since the last call to
3759 * <code>getDrawGraphics</code>
3760 */
3761 public boolean contentsLost() {
3762 if (drawVBuffer == null) {
3763 return false;
3764 }
3765 return drawVBuffer.contentsLost();
3766 }
3767
3768 /**
3769 * @return whether the drawing buffer was recently restored from a lost
3770 * state and reinitialized to the default background color (white)
3771 */
3772 public boolean contentsRestored() {
3773 return validatedContents;
3774 }
3775
3776 /**
3777 * Makes the next available buffer visible by either blitting or
3778 * flipping.
3779 */
3780 public void show() {
3781 flip(caps.getFlipContents());
3782 }
3783
3784 /**
3785 * {@inheritDoc}
3786 * @since 1.6
3787 */
3788 public void dispose() {
3789 if (Component.this .bufferStrategy == this ) {
3790 Component.this .bufferStrategy = null;
3791 if (peer != null) {
3792 destroyBuffers();
3793 }
3794 }
3795 }
3796
3797 } // Inner class FlipBufferStrategy
3798
3799 /**
3800 * Inner class for blitting offscreen surfaces to a component.
3801 *
3802 * @author Michael Martak
3803 * @since 1.4
3804 */
3805 protected class BltBufferStrategy extends BufferStrategy {
3806
3807 /**
3808 * The buffering capabilities
3809 */
3810 protected BufferCapabilities caps; // = null
3811 /**
3812 * The back buffers
3813 */
3814 protected VolatileImage[] backBuffers; // = null
3815 /**
3816 * Whether or not the drawing buffer has been recently restored from
3817 * a lost state.
3818 */
3819 protected boolean validatedContents; // = false
3820 /**
3821 * Size of the back buffers
3822 */
3823 protected int width;
3824 protected int height;
3825
3826 /**
3827 * Insets for the hosting Component. The size of the back buffer
3828 * is constrained by these.
3829 */
3830 private Insets insets;
3831
3832 /**
3833 * Creates a new blt buffer strategy around a component
3834 * @param numBuffers number of buffers to create, including the
3835 * front buffer
3836 * @param caps the capabilities of the buffers
3837 */
3838 protected BltBufferStrategy(int numBuffers,
3839 BufferCapabilities caps) {
3840 this .caps = caps;
3841 createBackBuffers(numBuffers - 1);
3842 }
3843
3844 /**
3845 * {@inheritDoc}
3846 * @since 1.6
3847 */
3848 public void dispose() {
3849 if (backBuffers != null) {
3850 for (int counter = backBuffers.length - 1; counter >= 0; counter--) {
3851 if (backBuffers[counter] != null) {
3852 backBuffers[counter].flush();
3853 backBuffers[counter] = null;
3854 }
3855 }
3856 }
3857 if (Component.this .bufferStrategy == this ) {
3858 Component.this .bufferStrategy = null;
3859 }
3860 }
3861
3862 /**
3863 * Creates the back buffers
3864 */
3865 protected void createBackBuffers(int numBuffers) {
3866 if (numBuffers == 0) {
3867 backBuffers = null;
3868 } else {
3869 // save the current bounds
3870 width = getWidth();
3871 height = getHeight();
3872 insets = getInsets_NoClientCode();
3873 int iWidth = width - insets.left - insets.right;
3874 int iHeight = height - insets.top - insets.bottom;
3875
3876 // It is possible for the component's width and/or height
3877 // to be 0 here. Force the size of the backbuffers to
3878 // be > 0 so that creating the image won't fail.
3879 iWidth = Math.max(1, iWidth);
3880 iHeight = Math.max(1, iHeight);
3881 if (backBuffers == null) {
3882 backBuffers = new VolatileImage[numBuffers];
3883 } else {
3884 // flush any existing backbuffers
3885 for (int i = 0; i < numBuffers; i++) {
3886 if (backBuffers[i] != null) {
3887 backBuffers[i].flush();
3888 backBuffers[i] = null;
3889 }
3890 }
3891 }
3892
3893 // create the backbuffers
3894 for (int i = 0; i < numBuffers; i++) {
3895 backBuffers[i] = createVolatileImage(iWidth,
3896 iHeight);
3897 }
3898 }
3899 }
3900
3901 /**
3902 * @return the buffering capabilities of this strategy
3903 */
3904 public BufferCapabilities getCapabilities() {
3905 return caps;
3906 }
3907
3908 /**
3909 * @return the draw graphics
3910 */
3911 public Graphics getDrawGraphics() {
3912 revalidate();
3913 Image backBuffer = getBackBuffer();
3914 if (backBuffer == null) {
3915 return getGraphics();
3916 }
3917 SunGraphics2D g = (SunGraphics2D) backBuffer.getGraphics();
3918 g.constrain(-insets.left, -insets.top, backBuffer
3919 .getWidth(null)
3920 + insets.left, backBuffer.getHeight(null)
3921 + insets.top);
3922 return g;
3923 }
3924
3925 /**
3926 * @return direct access to the back buffer, as an image.
3927 * If there is no back buffer, returns null.
3928 */
3929 Image getBackBuffer() {
3930 if (backBuffers != null) {
3931 return backBuffers[backBuffers.length - 1];
3932 } else {
3933 return null;
3934 }
3935 }
3936
3937 /**
3938 * Makes the next available buffer visible.
3939 */
3940 public void show() {
3941 showSubRegion(insets.left, insets.top,
3942 width - insets.right, height - insets.bottom);
3943 }
3944
3945 /**
3946 * Package-private method to present a specific rectangular area
3947 * of this buffer. This class currently shows only the entire
3948 * buffer, by calling showSubRegion() with the full dimensions of
3949 * the buffer. Subclasses (e.g., BltSubRegionBufferStrategy
3950 * and FlipSubRegionBufferStrategy) may have region-specific show
3951 * methods that call this method with actual sub regions of the
3952 * buffer.
3953 */
3954 void showSubRegion(int x1, int y1, int x2, int y2) {
3955 if (backBuffers == null) {
3956 return;
3957 }
3958 // Adjust location to be relative to client area.
3959 x1 -= insets.left;
3960 x2 -= insets.left;
3961 y1 -= insets.top;
3962 y2 -= insets.top;
3963 Graphics g = getGraphics_NoClientCode();
3964 if (g == null) {
3965 // Not showing, bail
3966 return;
3967 }
3968 try {
3969 // First image copy is in terms of Frame's coordinates, need
3970 // to translate to client area.
3971 g.translate(insets.left, insets.top);
3972 for (int i = 0; i < backBuffers.length; i++) {
3973 g.drawImage(backBuffers[i], x1, y1, x2, y2, x1, y1,
3974 x2, y2, null);
3975 g.dispose();
3976 g = null;
3977 g = backBuffers[i].getGraphics();
3978 }
3979 } finally {
3980 if (g != null) {
3981 g.dispose();
3982 }
3983 }
3984 }
3985
3986 /**
3987 * Restore the drawing buffer if it has been lost
3988 */
3989 protected void revalidate() {
3990 revalidate(true);
3991 }
3992
3993 void revalidate(boolean checkSize) {
3994 validatedContents = false;
3995
3996 if (backBuffers == null) {
3997 return;
3998 }
3999
4000 if (checkSize) {
4001 Insets insets = getInsets_NoClientCode();
4002 if (getWidth() != width || getHeight() != height
4003 || !insets.equals(this .insets)) {
4004 // component has been resized; recreate the backbuffers
4005 createBackBuffers(backBuffers.length);
4006 validatedContents = true;
4007 }
4008 }
4009
4010 // now validate the backbuffer
4011 GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
4012 int returnCode = backBuffers[backBuffers.length - 1]
4013 .validate(gc);
4014 if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
4015 if (checkSize) {
4016 createBackBuffers(backBuffers.length);
4017 // backbuffers were recreated, so validate again
4018 backBuffers[backBuffers.length - 1].validate(gc);
4019 }
4020 // else case means we're called from Swing on the toolkit
4021 // thread, don't recreate buffers as that'll deadlock
4022 // (creating VolatileImages invokes getting GraphicsConfig
4023 // which grabs treelock).
4024 validatedContents = true;
4025 } else if (returnCode == VolatileImage.IMAGE_RESTORED) {
4026 validatedContents = true;
4027 }
4028 }
4029
4030 /**
4031 * @return whether the drawing buffer was lost since the last call to
4032 * <code>getDrawGraphics</code>
4033 */
4034 public boolean contentsLost() {
4035 if (backBuffers == null) {
4036 return false;
4037 } else {
4038 return backBuffers[backBuffers.length - 1]
4039 .contentsLost();
4040 }
4041 }
4042
4043 /**
4044 * @return whether the drawing buffer was recently restored from a lost
4045 * state and reinitialized to the default background color (white)
4046 */
4047 public boolean contentsRestored() {
4048 return validatedContents;
4049 }
4050 } // Inner class BltBufferStrategy
4051
4052 /**
4053 * Private class to perform sub-region flipping.
4054 * REMIND: this subclass currently punts on subregions and
4055 * flips the entire buffer.
4056 */
4057 private class FlipSubRegionBufferStrategy extends
4058 FlipBufferStrategy implements SubRegionShowable {
4059
4060 protected FlipSubRegionBufferStrategy(int numBuffers,
4061 BufferCapabilities caps) throws AWTException {
4062 super (numBuffers, caps);
4063 }
4064
4065 public void show(int x1, int y1, int x2, int y2) {
4066 show();
4067 }
4068
4069 // This is invoked by Swing on the toolkit thread.
4070 public boolean validateAndShow(int x1, int y1, int x2, int y2) {
4071 revalidate(false);
4072 if (!contentsRestored() && !contentsLost()) {
4073 show();
4074 return !contentsLost();
4075 }
4076 return false;
4077 }
4078 }
4079
4080 /**
4081 * Private class to perform sub-region blitting. Swing will use
4082 * this subclass via the SubRegionShowable interface in order to
4083 * copy only the area changed during a repaint.
4084 * @see javax.swing.BufferStrategyPaintManager
4085 */
4086 private class BltSubRegionBufferStrategy extends BltBufferStrategy
4087 implements SubRegionShowable {
4088
4089 protected BltSubRegionBufferStrategy(int numBuffers,
4090 BufferCapabilities caps) {
4091 super (numBuffers, caps);
4092 }
4093
4094 public void show(int x1, int y1, int x2, int y2) {
4095 showSubRegion(x1, y1, x2, y2);
4096 }
4097
4098 // This method is called by Swing on the toolkit thread.
4099 public boolean validateAndShow(int x1, int y1, int x2, int y2) {
4100 revalidate(false);
4101 if (!contentsRestored() && !contentsLost()) {
4102 showSubRegion(x1, y1, x2, y2);
4103 return !contentsLost();
4104 }
4105 return false;
4106 }
4107 }
4108
4109 /**
4110 * Inner class for flipping buffers on a component. That component must
4111 * be a <code>Canvas</code> or <code>Window</code>.
4112 * @see Canvas
4113 * @see Window
4114 * @see java.awt.image.BufferStrategy
4115 * @author Michael Martak
4116 * @since 1.4
4117 */
4118 private class SingleBufferStrategy extends BufferStrategy {
4119
4120 private BufferCapabilities caps;
4121
4122 public SingleBufferStrategy(BufferCapabilities caps) {
4123 this .caps = caps;
4124 }
4125
4126 public BufferCapabilities getCapabilities() {
4127 return caps;
4128 }
4129
4130 public Graphics getDrawGraphics() {
4131 return getGraphics();
4132 }
4133
4134 public boolean contentsLost() {
4135 return false;
4136 }
4137
4138 public boolean contentsRestored() {
4139 return false;
4140 }
4141
4142 public void show() {
4143 // Do nothing
4144 }
4145 } // Inner class SingleBufferStrategy
4146
4147 /**
4148 * Sets whether or not paint messages received from the operating system
4149 * should be ignored. This does not affect paint events generated in
4150 * software by the AWT, unless they are an immediate response to an
4151 * OS-level paint message.
4152 * <p>
4153 * This is useful, for example, if running under full-screen mode and
4154 * better performance is desired, or if page-flipping is used as the
4155 * buffer strategy.
4156 *
4157 * @since 1.4
4158 * @see #getIgnoreRepaint
4159 * @see Canvas#createBufferStrategy
4160 * @see Window#createBufferStrategy
4161 * @see java.awt.image.BufferStrategy
4162 * @see GraphicsDevice#setFullScreenWindow
4163 */
4164 public void setIgnoreRepaint(boolean ignoreRepaint) {
4165 this .ignoreRepaint = ignoreRepaint;
4166 }
4167
4168 /**
4169 * @return whether or not paint messages received from the operating system
4170 * should be ignored.
4171 *
4172 * @since 1.4
4173 * @see #setIgnoreRepaint
4174 */
4175 public boolean getIgnoreRepaint() {
4176 return ignoreRepaint;
4177 }
4178
4179 /**
4180 * Checks whether this component "contains" the specified point,
4181 * where <code>x</code> and <code>y</code> are defined to be
4182 * relative to the coordinate system of this component.
4183 * @param x the <i>x</i> coordinate of the point
4184 * @param y the <i>y</i> coordinate of the point
4185 * @see #getComponentAt(int, int)
4186 * @since JDK1.1
4187 */
4188 public boolean contains(int x, int y) {
4189 return inside(x, y);
4190 }
4191
4192 /**
4193 * @deprecated As of JDK version 1.1,
4194 * replaced by contains(int, int).
4195 */
4196 @Deprecated
4197 public boolean inside(int x, int y) {
4198 return (x >= 0) && (x < width) && (y >= 0) && (y < height);
4199 }
4200
4201 /**
4202 * Checks whether this component "contains" the specified point,
4203 * where the point's <i>x</i> and <i>y</i> coordinates are defined
4204 * to be relative to the coordinate system of this component.
4205 * @param p the point
4206 * @see #getComponentAt(Point)
4207 * @since JDK1.1
4208 */
4209 public boolean contains(Point p) {
4210 return contains(p.x, p.y);
4211 }
4212
4213 /**
4214 * Determines if this component or one of its immediate
4215 * subcomponents contains the (<i>x</i>, <i>y</i>) location,
4216 * and if so, returns the containing component. This method only
4217 * looks one level deep. If the point (<i>x</i>, <i>y</i>) is
4218 * inside a subcomponent that itself has subcomponents, it does not
4219 * go looking down the subcomponent tree.
4220 * <p>
4221 * The <code>locate</code> method of <code>Component</code> simply
4222 * returns the component itself if the (<i>x</i>, <i>y</i>)
4223 * coordinate location is inside its bounding box, and <code>null</code>
4224 * otherwise.
4225 * @param x the <i>x</i> coordinate
4226 * @param y the <i>y</i> coordinate
4227 * @return the component or subcomponent that contains the
4228 * (<i>x</i>, <i>y</i>) location;
4229 * <code>null</code> if the location
4230 * is outside this component
4231 * @see #contains(int, int)
4232 * @since JDK1.0
4233 */
4234 public Component getComponentAt(int x, int y) {
4235 return locate(x, y);
4236 }
4237
4238 /**
4239 * @deprecated As of JDK version 1.1,
4240 * replaced by getComponentAt(int, int).
4241 */
4242 @Deprecated
4243 public Component locate(int x, int y) {
4244 return contains(x, y) ? this : null;
4245 }
4246
4247 /**
4248 * Returns the component or subcomponent that contains the
4249 * specified point.
4250 * @param p the point
4251 * @see java.awt.Component#contains
4252 * @since JDK1.1
4253 */
4254 public Component getComponentAt(Point p) {
4255 return getComponentAt(p.x, p.y);
4256 }
4257
4258 /**
4259 * @deprecated As of JDK version 1.1,
4260 * replaced by <code>dispatchEvent(AWTEvent e)</code>.
4261 */
4262 @Deprecated
4263 public void deliverEvent(Event e) {
4264 postEvent(e);
4265 }
4266
4267 /**
4268 * Dispatches an event to this component or one of its sub components.
4269 * Calls <code>processEvent</code> before returning for 1.1-style
4270 * events which have been enabled for the <code>Component</code>.
4271 * @param e the event
4272 */
4273 public final void dispatchEvent(AWTEvent e) {
4274 dispatchEventImpl(e);
4275 }
4276
4277 void dispatchEventImpl(AWTEvent e) {
4278 int id = e.getID();
4279
4280 // Check that this component belongs to this app-context
4281 AppContext compContext = appContext;
4282 if (compContext != null
4283 && !compContext.equals(AppContext.getAppContext())) {
4284 log.fine("Event " + e
4285 + " is being dispatched on the wrong AppContext");
4286 }
4287
4288 if (log.isLoggable(Level.FINEST)) {
4289 log.log(Level.FINEST, "{0}", e);
4290 }
4291
4292 /*
4293 * 0. Set timestamp and modifiers of current event.
4294 */
4295 EventQueue.setCurrentEventAndMostRecentTime(e);
4296
4297 /*
4298 * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
4299 * before we notify AWTEventListeners.
4300 */
4301
4302 if (e instanceof SunDropTargetEvent) {
4303 ((SunDropTargetEvent) e).dispatch();
4304 return;
4305 }
4306
4307 if (!e.focusManagerIsDispatching) {
4308 // Invoke the private focus retargeting method which provides
4309 // lightweight Component support
4310 if (e.isPosted) {
4311 e = KeyboardFocusManager.retargetFocusEvent(e);
4312 e.isPosted = true;
4313 }
4314
4315 // Now, with the event properly targeted to a lightweight
4316 // descendant if necessary, invoke the public focus retargeting
4317 // and dispatching function
4318 if (KeyboardFocusManager.getCurrentKeyboardFocusManager()
4319 .dispatchEvent(e)) {
4320 return;
4321 }
4322 }
4323 if (e instanceof FocusEvent && focusLog.isLoggable(Level.FINE)) {
4324 focusLog.fine("" + e);
4325 }
4326 // MouseWheel may need to be retargeted here so that
4327 // AWTEventListener sees the event go to the correct
4328 // Component. If the MouseWheelEvent needs to go to an ancestor,
4329 // the event is dispatched to the ancestor, and dispatching here
4330 // stops.
4331 if (id == MouseEvent.MOUSE_WHEEL && (!eventTypeEnabled(id))
4332 && (peer != null && !peer.handlesWheelScrolling())
4333 && (dispatchMouseWheelToAncestor((MouseWheelEvent) e))) {
4334 return;
4335 }
4336
4337 /*
4338 * 2. Allow the Toolkit to pass this to AWTEventListeners.
4339 */
4340 Toolkit toolkit = Toolkit.getDefaultToolkit();
4341 toolkit.notifyAWTEventListeners(e);
4342
4343 /*
4344 * 3. If no one has consumed a key event, allow the
4345 * KeyboardFocusManager to process it.
4346 */
4347 if (!e.isConsumed()) {
4348 if (e instanceof java.awt.event.KeyEvent) {
4349 KeyboardFocusManager.getCurrentKeyboardFocusManager()
4350 .processKeyEvent(this , (KeyEvent) e);
4351 if (e.isConsumed()) {
4352 return;
4353 }
4354 }
4355 }
4356
4357 /*
4358 * 4. Allow input methods to process the event
4359 */
4360 if (areInputMethodsEnabled()) {
4361 // We need to pass on InputMethodEvents since some host
4362 // input method adapters send them through the Java
4363 // event queue instead of directly to the component,
4364 // and the input context also handles the Java composition window
4365 if (((e instanceof InputMethodEvent) && !(this instanceof CompositionArea))
4366 ||
4367 // Otherwise, we only pass on input and focus events, because
4368 // a) input methods shouldn't know about semantic or component-level events
4369 // b) passing on the events takes time
4370 // c) isConsumed() is always true for semantic events.
4371 (e instanceof InputEvent)
4372 || (e instanceof FocusEvent)) {
4373 InputContext inputContext = getInputContext();
4374
4375 if (inputContext != null) {
4376 inputContext.dispatchEvent(e);
4377 if (e.isConsumed()) {
4378 if (e instanceof FocusEvent
4379 && focusLog.isLoggable(Level.FINER)) {
4380 focusLog.finer("3579: Skipping " + e);
4381 }
4382 return;
4383 }
4384 }
4385 }
4386 } else {
4387 // When non-clients get focus, we need to explicitly disable the native
4388 // input method. The native input method is actually not disabled when
4389 // the active/passive/peered clients loose focus.
4390 if (id == FocusEvent.FOCUS_GAINED) {
4391 InputContext inputContext = getInputContext();
4392 if (inputContext != null
4393 && inputContext instanceof sun.awt.im.InputContext) {
4394 ((sun.awt.im.InputContext) inputContext)
4395 .disableNativeIM();
4396 }
4397 }
4398 }
4399
4400 /*
4401 * 5. Pre-process any special events before delivery
4402 */
4403 switch (id) {
4404 // Handling of the PAINT and UPDATE events is now done in the
4405 // peer's handleEvent() method so the background can be cleared
4406 // selectively for non-native components on Windows only.
4407 // - Fred.Ecks@Eng.sun.com, 5-8-98
4408
4409 case KeyEvent.KEY_PRESSED:
4410 case KeyEvent.KEY_RELEASED:
4411 Container p = (Container) ((this instanceof Container) ? this
4412 : parent);
4413 if (p != null) {
4414 p.preProcessKeyEvent((KeyEvent) e);
4415 if (e.isConsumed()) {
4416 if (focusLog.isLoggable(Level.FINEST))
4417 focusLog.finest("Pre-process consumed event");
4418 return;
4419 }
4420 }
4421 break;
4422
4423 case WindowEvent.WINDOW_CLOSING:
4424 if (toolkit instanceof WindowClosingListener) {
4425 windowClosingException = ((WindowClosingListener) toolkit)
4426 .windowClosingNotify((WindowEvent) e);
4427 if (checkWindowClosingException()) {
4428 return;
4429 }
4430 }
4431 break;
4432
4433 default:
4434 break;
4435 }
4436
4437 /*
4438 * 6. Deliver event for normal processing
4439 */
4440 if (newEventsOnly) {
4441 // Filtering needs to really be moved to happen at a lower
4442 // level in order to get maximum performance gain; it is
4443 // here temporarily to ensure the API spec is honored.
4444 //
4445 if (eventEnabled(e)) {
4446 processEvent(e);
4447 }
4448 } else if (id == MouseEvent.MOUSE_WHEEL) {
4449 // newEventsOnly will be false for a listenerless ScrollPane, but
4450 // MouseWheelEvents still need to be dispatched to it so scrolling
4451 // can be done.
4452 autoProcessMouseWheel((MouseWheelEvent) e);
4453 } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {
4454 //
4455 // backward compatibility
4456 //
4457 Event olde = e.convertToOld();
4458 if (olde != null) {
4459 int key = olde.key;
4460 int modifiers = olde.modifiers;
4461
4462 postEvent(olde);
4463 if (olde.isConsumed()) {
4464 e.consume();
4465 }
4466 // if target changed key or modifier values, copy them
4467 // back to original event
4468 //
4469 switch (olde.id) {
4470 case Event.KEY_PRESS:
4471 case Event.KEY_RELEASE:
4472 case Event.KEY_ACTION:
4473 case Event.KEY_ACTION_RELEASE:
4474 if (olde.key != key) {
4475 ((KeyEvent) e).setKeyChar(olde
4476 .getKeyEventChar());
4477 }
4478 if (olde.modifiers != modifiers) {
4479 ((KeyEvent) e).setModifiers(olde.modifiers);
4480 }
4481 break;
4482 default:
4483 break;
4484 }
4485 }
4486 }
4487
4488 /*
4489 * 8. Special handling for 4061116 : Hook for browser to close modal
4490 * dialogs.
4491 */
4492 if (id == WindowEvent.WINDOW_CLOSING && !e.isConsumed()) {
4493 if (toolkit instanceof WindowClosingListener) {
4494 windowClosingException = ((WindowClosingListener) toolkit)
4495 .windowClosingDelivered((WindowEvent) e);
4496 if (checkWindowClosingException()) {
4497 return;
4498 }
4499 }
4500 }
4501
4502 /*
4503 * 9. Allow the peer to process the event.
4504 * Except KeyEvents, they will be processed by peer after
4505 * all KeyEventPostProcessors
4506 * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
4507 */
4508 if (!(e instanceof KeyEvent)) {
4509 ComponentPeer tpeer = peer;
4510 if (e instanceof FocusEvent
4511 && (tpeer == null || tpeer instanceof LightweightPeer)) {
4512 // if focus owner is lightweight then its native container
4513 // processes event
4514 Component source = (Component) e.getSource();
4515 if (source != null) {
4516 Container target = source.getNativeContainer();
4517 if (target != null) {
4518 tpeer = target.getPeer();
4519 }
4520 }
4521 }
4522 if (tpeer != null) {
4523 tpeer.handleEvent(e);
4524 }
4525 }
4526 } // dispatchEventImpl()
4527
4528 /*
4529 * If newEventsOnly is false, method is called so that ScrollPane can
4530 * override it and handle common-case mouse wheel scrolling. NOP
4531 * for Component.
4532 */
4533 void autoProcessMouseWheel(MouseWheelEvent e) {
4534 }
4535
4536 /*
4537 * Dispatch given MouseWheelEvent to the first ancestor for which
4538 * MouseWheelEvents are enabled.
4539 *
4540 * Returns whether or not event was dispatched to an ancestor
4541 */
4542 boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
4543 int newX, newY;
4544 newX = e.getX() + getX(); // Coordinates take into account at least
4545 newY = e.getY() + getY(); // the cursor's position relative to this
4546 // Component (e.getX()), and this Component's
4547 // position relative to its parent.
4548 MouseWheelEvent newMWE;
4549
4550 if (dbg.on) {
4551 dbg.println("Component.dispatchMouseWheelToAncestor");
4552 dbg.println("orig event src is of "
4553 + e.getSource().getClass());
4554 }
4555
4556 /* parent field for Window refers to the owning Window.
4557 * MouseWheelEvents should NOT be propagated into owning Windows
4558 */
4559 synchronized (getTreeLock()) {
4560 Container anc = getParent();
4561 while (anc != null && !anc.eventEnabled(e)) {
4562 // fix coordinates to be relative to new event source
4563 newX += anc.getX();
4564 newY += anc.getY();
4565
4566 if (!(anc instanceof Window)) {
4567 anc = anc.getParent();
4568 } else {
4569 break;
4570 }
4571 }
4572
4573 if (dbg.on)
4574 dbg.println("new event src is " + anc.getClass());
4575
4576 if (anc != null && anc.eventEnabled(e)) {
4577 // Change event to be from new source, with new x,y
4578 // For now, just create a new event - yucky
4579
4580 newMWE = new MouseWheelEvent(
4581 anc, // new source
4582 e.getID(), e.getWhen(), e.getModifiers(),
4583 newX, // x relative to new source
4584 newY, // y relative to new source
4585 e.getXOnScreen(), e.getYOnScreen(), e
4586 .getClickCount(), e.isPopupTrigger(), e
4587 .getScrollType(), e.getScrollAmount(),
4588 e.getWheelRotation());
4589 ((AWTEvent) e).copyPrivateDataInto(newMWE);
4590 anc.dispatchEventImpl(newMWE);
4591 }
4592 }
4593 return true;
4594 }
4595
4596 boolean checkWindowClosingException() {
4597 if (windowClosingException != null) {
4598 if (this instanceof Dialog) {
4599 ((Dialog) this ).interruptBlocking();
4600 } else {
4601 windowClosingException.fillInStackTrace();
4602 windowClosingException.printStackTrace();
4603 windowClosingException = null;
4604 }
4605 return true;
4606 }
4607 return false;
4608 }
4609
4610 boolean areInputMethodsEnabled() {
4611 // in 1.2, we assume input method support is required for all
4612 // components that handle key events, but components can turn off
4613 // input methods by calling enableInputMethods(false).
4614 return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)
4615 && ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
4616 }
4617
4618 // REMIND: remove when filtering is handled at lower level
4619 boolean eventEnabled(AWTEvent e) {
4620 return eventTypeEnabled(e.id);
4621 }
4622
4623 boolean eventTypeEnabled(int type) {
4624 switch (type) {
4625 case ComponentEvent.COMPONENT_MOVED:
4626 case ComponentEvent.COMPONENT_RESIZED:
4627 case ComponentEvent.COMPONENT_SHOWN:
4628 case ComponentEvent.COMPONENT_HIDDEN:
4629 if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
4630 || componentListener != null) {
4631 return true;
4632 }
4633 break;
4634 case FocusEvent.FOCUS_GAINED:
4635 case FocusEvent.FOCUS_LOST:
4636 if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0
4637 || focusListener != null) {
4638 return true;
4639 }
4640 break;
4641 case KeyEvent.KEY_PRESSED:
4642 case KeyEvent.KEY_RELEASED:
4643 case KeyEvent.KEY_TYPED:
4644 if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0
4645 || keyListener != null) {
4646 return true;
4647 }
4648 break;
4649 case MouseEvent.MOUSE_PRESSED:
4650 case MouseEvent.MOUSE_RELEASED:
4651 case MouseEvent.MOUSE_ENTERED:
4652 case MouseEvent.MOUSE_EXITED:
4653 case MouseEvent.MOUSE_CLICKED:
4654 if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
4655 || mouseListener != null) {
4656 return true;
4657 }
4658 break;
4659 case MouseEvent.MOUSE_MOVED:
4660 case MouseEvent.MOUSE_DRAGGED:
4661 if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
4662 || mouseMotionListener != null) {
4663 return true;
4664 }
4665 break;
4666 case MouseEvent.MOUSE_WHEEL:
4667 if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0
4668 || mouseWheelListener != null) {
4669 return true;
4670 }
4671 break;
4672 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4673 case InputMethodEvent.CARET_POSITION_CHANGED:
4674 if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0
4675 || inputMethodListener != null) {
4676 return true;
4677 }
4678 break;
4679 case HierarchyEvent.HIERARCHY_CHANGED:
4680 if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0
4681 || hierarchyListener != null) {
4682 return true;
4683 }
4684 break;
4685 case HierarchyEvent.ANCESTOR_MOVED:
4686 case HierarchyEvent.ANCESTOR_RESIZED:
4687 if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
4688 || hierarchyBoundsListener != null) {
4689 return true;
4690 }
4691 break;
4692 case ActionEvent.ACTION_PERFORMED:
4693 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {
4694 return true;
4695 }
4696 break;
4697 case TextEvent.TEXT_VALUE_CHANGED:
4698 if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {
4699 return true;
4700 }
4701 break;
4702 case ItemEvent.ITEM_STATE_CHANGED:
4703 if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {
4704 return true;
4705 }
4706 break;
4707 case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
4708 if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {
4709 return true;
4710 }
4711 break;
4712 default:
4713 break;
4714 }
4715 //
4716 // Always pass on events defined by external programs.
4717 //
4718 if (type > AWTEvent.RESERVED_ID_MAX) {
4719 return true;
4720 }
4721 return false;
4722 }
4723
4724 /**
4725 * @deprecated As of JDK version 1.1,
4726 * replaced by dispatchEvent(AWTEvent).
4727 */
4728 @Deprecated
4729 public boolean postEvent(Event e) {
4730 ComponentPeer peer = this .peer;
4731
4732 if (handleEvent(e)) {
4733 e.consume();
4734 return true;
4735 }
4736
4737 Component parent = this .parent;
4738 int eventx = e.x;
4739 int eventy = e.y;
4740 if (parent != null) {
4741 e.translate(x, y);
4742 if (parent.postEvent(e)) {
4743 e.consume();
4744 return true;
4745 }
4746 // restore coords
4747 e.x = eventx;
4748 e.y = eventy;
4749 }
4750 return false;
4751 }
4752
4753 // Event source interfaces
4754
4755 /**
4756 * Adds the specified component listener to receive component events from
4757 * this component.
4758 * If listener <code>l</code> is <code>null</code>,
4759 * no exception is thrown and no action is performed.
4760 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4761 * >AWT Threading Issues</a> for details on AWT's threading model.
4762 *
4763 * @param l the component listener
4764 * @see java.awt.event.ComponentEvent
4765 * @see java.awt.event.ComponentListener
4766 * @see #removeComponentListener
4767 * @see #getComponentListeners
4768 * @since JDK1.1
4769 */
4770 public synchronized void addComponentListener(ComponentListener l) {
4771 if (l == null) {
4772 return;
4773 }
4774 componentListener = AWTEventMulticaster.add(componentListener,
4775 l);
4776 newEventsOnly = true;
4777 }
4778
4779 /**
4780 * Removes the specified component listener so that it no longer
4781 * receives component events from this component. This method performs
4782 * no function, nor does it throw an exception, if the listener
4783 * specified by the argument was not previously added to this component.
4784 * If listener <code>l</code> is <code>null</code>,
4785 * no exception is thrown and no action is performed.
4786 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4787 * >AWT Threading Issues</a> for details on AWT's threading model.
4788 * @param l the component listener
4789 * @see java.awt.event.ComponentEvent
4790 * @see java.awt.event.ComponentListener
4791 * @see #addComponentListener
4792 * @see #getComponentListeners
4793 * @since JDK1.1
4794 */
4795 public synchronized void removeComponentListener(ComponentListener l) {
4796 if (l == null) {
4797 return;
4798 }
4799 componentListener = AWTEventMulticaster.remove(
4800 componentListener, l);
4801 }
4802
4803 /**
4804 * Returns an array of all the component listeners
4805 * registered on this component.
4806 *
4807 * @return all of this comonent's <code>ComponentListener</code>s
4808 * or an empty array if no component
4809 * listeners are currently registered
4810 *
4811 * @see #addComponentListener
4812 * @see #removeComponentListener
4813 * @since 1.4
4814 */
4815 public synchronized ComponentListener[] getComponentListeners() {
4816 return (ComponentListener[]) (getListeners(ComponentListener.class));
4817 }
4818
4819 /**
4820 * Adds the specified focus listener to receive focus events from
4821 * this component when this component gains input focus.
4822 * If listener <code>l</code> is <code>null</code>,
4823 * no exception is thrown and no action is performed.
4824 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4825 * >AWT Threading Issues</a> for details on AWT's threading model.
4826 *
4827 * @param l the focus listener
4828 * @see java.awt.event.FocusEvent
4829 * @see java.awt.event.FocusListener
4830 * @see #removeFocusListener
4831 * @see #getFocusListeners
4832 * @since JDK1.1
4833 */
4834 public synchronized void addFocusListener(FocusListener l) {
4835 if (l == null) {
4836 return;
4837 }
4838 focusListener = AWTEventMulticaster.add(focusListener, l);
4839 newEventsOnly = true;
4840
4841 // if this is a lightweight component, enable focus events
4842 // in the native container.
4843 if (peer instanceof LightweightPeer) {
4844 parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);
4845 }
4846 }
4847
4848 /**
4849 * Removes the specified focus listener so that it no longer
4850 * receives focus events from this component. This method performs
4851 * no function, nor does it throw an exception, if the listener
4852 * specified by the argument was not previously added to this component.
4853 * If listener <code>l</code> is <code>null</code>,
4854 * no exception is thrown and no action is performed.
4855 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4856 * >AWT Threading Issues</a> for details on AWT's threading model.
4857 *
4858 * @param l the focus listener
4859 * @see java.awt.event.FocusEvent
4860 * @see java.awt.event.FocusListener
4861 * @see #addFocusListener
4862 * @see #getFocusListeners
4863 * @since JDK1.1
4864 */
4865 public synchronized void removeFocusListener(FocusListener l) {
4866 if (l == null) {
4867 return;
4868 }
4869 focusListener = AWTEventMulticaster.remove(focusListener, l);
4870 }
4871
4872 /**
4873 * Returns an array of all the focus listeners
4874 * registered on this component.
4875 *
4876 * @return all of this component's <code>FocusListener</code>s
4877 * or an empty array if no component
4878 * listeners are currently registered
4879 *
4880 * @see #addFocusListener
4881 * @see #removeFocusListener
4882 * @since 1.4
4883 */
4884 public synchronized FocusListener[] getFocusListeners() {
4885 return (FocusListener[]) (getListeners(FocusListener.class));
4886 }
4887
4888 /**
4889 * Adds the specified hierarchy listener to receive hierarchy changed
4890 * events from this component when the hierarchy to which this container
4891 * belongs changes.
4892 * If listener <code>l</code> is <code>null</code>,
4893 * no exception is thrown and no action is performed.
4894 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4895 * >AWT Threading Issues</a> for details on AWT's threading model.
4896 *
4897 * @param l the hierarchy listener
4898 * @see java.awt.event.HierarchyEvent
4899 * @see java.awt.event.HierarchyListener
4900 * @see #removeHierarchyListener
4901 * @see #getHierarchyListeners
4902 * @since 1.3
4903 */
4904 public void addHierarchyListener(HierarchyListener l) {
4905 if (l == null) {
4906 return;
4907 }
4908 boolean notifyAncestors;
4909 synchronized (this ) {
4910 notifyAncestors = (hierarchyListener == null && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
4911 hierarchyListener = AWTEventMulticaster.add(
4912 hierarchyListener, l);
4913 notifyAncestors = (notifyAncestors && hierarchyListener != null);
4914 newEventsOnly = true;
4915 }
4916 if (notifyAncestors) {
4917 synchronized (getTreeLock()) {
4918 adjustListeningChildrenOnParent(
4919 AWTEvent.HIERARCHY_EVENT_MASK, 1);
4920 }
4921 }
4922 }
4923
4924 /**
4925 * Removes the specified hierarchy listener so that it no longer
4926 * receives hierarchy changed events from this component. This method
4927 * performs no function, nor does it throw an exception, if the listener
4928 * specified by the argument was not previously added to this component.
4929 * If listener <code>l</code> is <code>null</code>,
4930 * no exception is thrown and no action is performed.
4931 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4932 * >AWT Threading Issues</a> for details on AWT's threading model.
4933 *
4934 * @param l the hierarchy listener
4935 * @see java.awt.event.HierarchyEvent
4936 * @see java.awt.event.HierarchyListener
4937 * @see #addHierarchyListener
4938 * @see #getHierarchyListeners
4939 * @since 1.3
4940 */
4941 public void removeHierarchyListener(HierarchyListener l) {
4942 if (l == null) {
4943 return;
4944 }
4945 boolean notifyAncestors;
4946 synchronized (this ) {
4947 notifyAncestors = (hierarchyListener != null && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
4948 hierarchyListener = AWTEventMulticaster.remove(
4949 hierarchyListener, l);
4950 notifyAncestors = (notifyAncestors && hierarchyListener == null);
4951 }
4952 if (notifyAncestors) {
4953 synchronized (getTreeLock()) {
4954 adjustListeningChildrenOnParent(
4955 AWTEvent.HIERARCHY_EVENT_MASK, -1);
4956 }
4957 }
4958 }
4959
4960 /**
4961 * Returns an array of all the hierarchy listeners
4962 * registered on this component.
4963 *
4964 * @return all of this component's <code>HierarchyListener</code>s
4965 * or an empty array if no hierarchy
4966 * listeners are currently registered
4967 *
4968 * @see #addHierarchyListener
4969 * @see #removeHierarchyListener
4970 * @since 1.4
4971 */
4972 public synchronized HierarchyListener[] getHierarchyListeners() {
4973 return (HierarchyListener[]) (getListeners(HierarchyListener.class));
4974 }
4975
4976 /**
4977 * Adds the specified hierarchy bounds listener to receive hierarchy
4978 * bounds events from this component when the hierarchy to which this
4979 * container belongs changes.
4980 * If listener <code>l</code> is <code>null</code>,
4981 * no exception is thrown and no action is performed.
4982 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
4983 * >AWT Threading Issues</a> for details on AWT's threading model.
4984 *
4985 * @param l the hierarchy bounds listener
4986 * @see java.awt.event.HierarchyEvent
4987 * @see java.awt.event.HierarchyBoundsListener
4988 * @see #removeHierarchyBoundsListener
4989 * @see #getHierarchyBoundsListeners
4990 * @since 1.3
4991 */
4992 public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
4993 if (l == null) {
4994 return;
4995 }
4996 boolean notifyAncestors;
4997 synchronized (this ) {
4998 notifyAncestors = (hierarchyBoundsListener == null && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
4999 hierarchyBoundsListener = AWTEventMulticaster.add(
5000 hierarchyBoundsListener, l);
5001 notifyAncestors = (notifyAncestors && hierarchyBoundsListener != null);
5002 newEventsOnly = true;
5003 }
5004 if (notifyAncestors) {
5005 synchronized (getTreeLock()) {
5006 adjustListeningChildrenOnParent(
5007 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
5008 }
5009 }
5010 }
5011
5012 /**
5013 * Removes the specified hierarchy bounds listener so that it no longer
5014 * receives hierarchy bounds events from this component. This method
5015 * performs no function, nor does it throw an exception, if the listener
5016 * specified by the argument was not previously added to this component.
5017 * If listener <code>l</code> is <code>null</code>,
5018 * no exception is thrown and no action is performed.
5019 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5020 * >AWT Threading Issues</a> for details on AWT's threading model.
5021 *
5022 * @param l the hierarchy bounds listener
5023 * @see java.awt.event.HierarchyEvent
5024 * @see java.awt.event.HierarchyBoundsListener
5025 * @see #addHierarchyBoundsListener
5026 * @see #getHierarchyBoundsListeners
5027 * @since 1.3
5028 */
5029 public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
5030 if (l == null) {
5031 return;
5032 }
5033 boolean notifyAncestors;
5034 synchronized (this ) {
5035 notifyAncestors = (hierarchyBoundsListener != null && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
5036 hierarchyBoundsListener = AWTEventMulticaster.remove(
5037 hierarchyBoundsListener, l);
5038 notifyAncestors = (notifyAncestors && hierarchyBoundsListener == null);
5039 }
5040 if (notifyAncestors) {
5041 synchronized (getTreeLock()) {
5042 adjustListeningChildrenOnParent(
5043 AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);
5044 }
5045 }
5046 }
5047
5048 // Should only be called while holding the tree lock
5049 int numListening(long mask) {
5050 if (dbg.on) {
5051 // One mask or the other, but not neither or both.
5052 dbg.assertion(mask == AWTEvent.HIERARCHY_EVENT_MASK
5053 || mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
5054 }
5055 if ((mask == AWTEvent.HIERARCHY_EVENT_MASK && (hierarchyListener != null || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0))
5056 || (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK && (hierarchyBoundsListener != null || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {
5057 return 1;
5058 } else {
5059 return 0;
5060 }
5061 }
5062
5063 // Should only be called while holding tree lock
5064 int countHierarchyMembers() {
5065 return 1;
5066 }
5067
5068 // Should only be called while holding the tree lock
5069 int createHierarchyEvents(int id, Component changed,
5070 Container changedParent, long changeFlags,
5071 boolean enabledOnToolkit) {
5072 switch (id) {
5073 case HierarchyEvent.HIERARCHY_CHANGED:
5074 if (hierarchyListener != null
5075 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0
5076 || enabledOnToolkit) {
5077 HierarchyEvent e = new HierarchyEvent(this , id,
5078 changed, changedParent, changeFlags);
5079 dispatchEvent(e);
5080 return 1;
5081 }
5082 break;
5083 case HierarchyEvent.ANCESTOR_MOVED:
5084 case HierarchyEvent.ANCESTOR_RESIZED:
5085 if (dbg.on) {
5086 dbg.assertion(changeFlags == 0);
5087 }
5088 if (hierarchyBoundsListener != null
5089 || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
5090 || enabledOnToolkit) {
5091 HierarchyEvent e = new HierarchyEvent(this , id,
5092 changed, changedParent);
5093 dispatchEvent(e);
5094 return 1;
5095 }
5096 break;
5097 default:
5098 if (dbg.on) {
5099 dbg.assertion(false);
5100 }
5101 break;
5102 }
5103 return 0;
5104 }
5105
5106 /**
5107 * Returns an array of all the hierarchy bounds listeners
5108 * registered on this component.
5109 *
5110 * @return all of this component's <code>HierarchyBoundsListener</code>s
5111 * or an empty array if no hierarchy bounds
5112 * listeners are currently registered
5113 *
5114 * @see #addHierarchyBoundsListener
5115 * @see #removeHierarchyBoundsListener
5116 * @since 1.4
5117 */
5118 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {
5119 return (HierarchyBoundsListener[]) (getListeners(HierarchyBoundsListener.class));
5120 }
5121
5122 /*
5123 * Should only be called while holding the tree lock.
5124 * It's added only for overriding in java.awt.Window
5125 * because parent in Window is owner.
5126 */
5127 void adjustListeningChildrenOnParent(long mask, int num) {
5128 if (parent != null) {
5129 parent.adjustListeningChildren(mask, num);
5130 }
5131 }
5132
5133 /**
5134 * Adds the specified key listener to receive key events from
5135 * this component.
5136 * If l is null, no exception is thrown and no action is performed.
5137 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5138 * >AWT Threading Issues</a> for details on AWT's threading model.
5139 *
5140 * @param l the key listener.
5141 * @see java.awt.event.KeyEvent
5142 * @see java.awt.event.KeyListener
5143 * @see #removeKeyListener
5144 * @see #getKeyListeners
5145 * @since JDK1.1
5146 */
5147 public synchronized void addKeyListener(KeyListener l) {
5148 if (l == null) {
5149 return;
5150 }
5151 keyListener = AWTEventMulticaster.add(keyListener, l);
5152 newEventsOnly = true;
5153
5154 // if this is a lightweight component, enable key events
5155 // in the native container.
5156 if (peer instanceof LightweightPeer) {
5157 parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);
5158 }
5159 }
5160
5161 /**
5162 * Removes the specified key listener so that it no longer
5163 * receives key events from this component. This method performs
5164 * no function, nor does it throw an exception, if the listener
5165 * specified by the argument was not previously added to this component.
5166 * If listener <code>l</code> is <code>null</code>,
5167 * no exception is thrown and no action is performed.
5168 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5169 * >AWT Threading Issues</a> for details on AWT's threading model.
5170 *
5171 * @param l the key listener
5172 * @see java.awt.event.KeyEvent
5173 * @see java.awt.event.KeyListener
5174 * @see #addKeyListener
5175 * @see #getKeyListeners
5176 * @since JDK1.1
5177 */
5178 public synchronized void removeKeyListener(KeyListener l) {
5179 if (l == null) {
5180 return;
5181 }
5182 keyListener = AWTEventMulticaster.remove(keyListener, l);
5183 }
5184
5185 /**
5186 * Returns an array of all the key listeners
5187 * registered on this component.
5188 *
5189 * @return all of this component's <code>KeyListener</code>s
5190 * or an empty array if no key
5191 * listeners are currently registered
5192 *
5193 * @see #addKeyListener
5194 * @see #removeKeyListener
5195 * @since 1.4
5196 */
5197 public synchronized KeyListener[] getKeyListeners() {
5198 return (KeyListener[]) (getListeners(KeyListener.class));
5199 }
5200
5201 /**
5202 * Adds the specified mouse listener to receive mouse events from
5203 * this component.
5204 * If listener <code>l</code> is <code>null</code>,
5205 * no exception is thrown and no action is performed.
5206 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5207 * >AWT Threading Issues</a> for details on AWT's threading model.
5208 *
5209 * @param l the mouse listener
5210 * @see java.awt.event.MouseEvent
5211 * @see java.awt.event.MouseListener
5212 * @see #removeMouseListener
5213 * @see #getMouseListeners
5214 * @since JDK1.1
5215 */
5216 public synchronized void addMouseListener(MouseListener l) {
5217 if (l == null) {
5218 return;
5219 }
5220 mouseListener = AWTEventMulticaster.add(mouseListener, l);
5221 newEventsOnly = true;
5222
5223 // if this is a lightweight component, enable mouse events
5224 // in the native container.
5225 if (peer instanceof LightweightPeer) {
5226 parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);
5227 }
5228 }
5229
5230 /**
5231 * Removes the specified mouse listener so that it no longer
5232 * receives mouse events from this component. This method performs
5233 * no function, nor does it throw an exception, if the listener
5234 * specified by the argument was not previously added to this component.
5235 * If listener <code>l</code> is <code>null</code>,
5236 * no exception is thrown and no action is performed.
5237 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5238 * >AWT Threading Issues</a> for details on AWT's threading model.
5239 *
5240 * @param l the mouse listener
5241 * @see java.awt.event.MouseEvent
5242 * @see java.awt.event.MouseListener
5243 * @see #addMouseListener
5244 * @see #getMouseListeners
5245 * @since JDK1.1
5246 */
5247 public synchronized void removeMouseListener(MouseListener l) {
5248 if (l == null) {
5249 return;
5250 }
5251 mouseListener = AWTEventMulticaster.remove(mouseListener, l);
5252 }
5253
5254 /**
5255 * Returns an array of all the mouse listeners
5256 * registered on this component.
5257 *
5258 * @return all of this component's <code>MouseListener</code>s
5259 * or an empty array if no mouse
5260 * listeners are currently registered
5261 *
5262 * @see #addMouseListener
5263 * @see #removeMouseListener
5264 * @since 1.4
5265 */
5266 public synchronized MouseListener[] getMouseListeners() {
5267 return (MouseListener[]) (getListeners(MouseListener.class));
5268 }
5269
5270 /**
5271 * Adds the specified mouse motion listener to receive mouse motion
5272 * events from this component.
5273 * If listener <code>l</code> is <code>null</code>,
5274 * no exception is thrown and no action is performed.
5275 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5276 * >AWT Threading Issues</a> for details on AWT's threading model.
5277 *
5278 * @param l the mouse motion listener
5279 * @see java.awt.event.MouseEvent
5280 * @see java.awt.event.MouseMotionListener
5281 * @see #removeMouseMotionListener
5282 * @see #getMouseMotionListeners
5283 * @since JDK1.1
5284 */
5285 public synchronized void addMouseMotionListener(
5286 MouseMotionListener l) {
5287 if (l == null) {
5288 return;
5289 }
5290 mouseMotionListener = AWTEventMulticaster.add(
5291 mouseMotionListener, l);
5292 newEventsOnly = true;
5293
5294 // if this is a lightweight component, enable mouse events
5295 // in the native container.
5296 if (peer instanceof LightweightPeer) {
5297 parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
5298 }
5299 }
5300
5301 /**
5302 * Removes the specified mouse motion listener so that it no longer
5303 * receives mouse motion events from this component. This method performs
5304 * no function, nor does it throw an exception, if the listener
5305 * specified by the argument was not previously added to this component.
5306 * If listener <code>l</code> is <code>null</code>,
5307 * no exception is thrown and no action is performed.
5308 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5309 * >AWT Threading Issues</a> for details on AWT's threading model.
5310 *
5311 * @param l the mouse motion listener
5312 * @see java.awt.event.MouseEvent
5313 * @see java.awt.event.MouseMotionListener
5314 * @see #addMouseMotionListener
5315 * @see #getMouseMotionListeners
5316 * @since JDK1.1
5317 */
5318 public synchronized void removeMouseMotionListener(
5319 MouseMotionListener l) {
5320 if (l == null) {
5321 return;
5322 }
5323 mouseMotionListener = AWTEventMulticaster.remove(
5324 mouseMotionListener, l);
5325 }
5326
5327 /**
5328 * Returns an array of all the mouse motion listeners
5329 * registered on this component.
5330 *
5331 * @return all of this component's <code>MouseMotionListener</code>s
5332 * or an empty array if no mouse motion
5333 * listeners are currently registered
5334 *
5335 * @see #addMouseMotionListener
5336 * @see #removeMouseMotionListener
5337 * @since 1.4
5338 */
5339 public synchronized MouseMotionListener[] getMouseMotionListeners() {
5340 return (MouseMotionListener[]) (getListeners(MouseMotionListener.class));
5341 }
5342
5343 /**
5344 * Adds the specified mouse wheel listener to receive mouse wheel events
5345 * from this component. Containers also receive mouse wheel events from
5346 * sub-components.
5347 * <p>
5348 * For information on how mouse wheel events are dispatched, see
5349 * the class description for {@link MouseWheelEvent}.
5350 * <p>
5351 * If l is <code>null</code>, no exception is thrown and no
5352 * action is performed.
5353 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5354 * >AWT Threading Issues</a> for details on AWT's threading model.
5355 *
5356 * @param l the mouse wheel listener
5357 * @see java.awt.event.MouseWheelEvent
5358 * @see java.awt.event.MouseWheelListener
5359 * @see #removeMouseWheelListener
5360 * @see #getMouseWheelListeners
5361 * @since 1.4
5362 */
5363 public synchronized void addMouseWheelListener(MouseWheelListener l) {
5364 if (l == null) {
5365 return;
5366 }
5367 mouseWheelListener = AWTEventMulticaster.add(
5368 mouseWheelListener, l);
5369 newEventsOnly = true;
5370
5371 dbg
5372 .println("Component.addMouseWheelListener(): newEventsOnly = "
5373 + newEventsOnly);
5374
5375 // if this is a lightweight component, enable mouse events
5376 // in the native container.
5377 if (peer instanceof LightweightPeer) {
5378 parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
5379 }
5380 }
5381
5382 /**
5383 * Removes the specified mouse wheel listener so that it no longer
5384 * receives mouse wheel events from this component. This method performs
5385 * no function, nor does it throw an exception, if the listener
5386 * specified by the argument was not previously added to this component.
5387 * If l is null, no exception is thrown and no action is performed.
5388 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5389 * >AWT Threading Issues</a> for details on AWT's threading model.
5390 *
5391 * @param l the mouse wheel listener.
5392 * @see java.awt.event.MouseWheelEvent
5393 * @see java.awt.event.MouseWheelListener
5394 * @see #addMouseWheelListener
5395 * @see #getMouseWheelListeners
5396 * @since 1.4
5397 */
5398 public synchronized void removeMouseWheelListener(
5399 MouseWheelListener l) {
5400 if (l == null) {
5401 return;
5402 }
5403 mouseWheelListener = AWTEventMulticaster.remove(
5404 mouseWheelListener, l);
5405 }
5406
5407 /**
5408 * Returns an array of all the mouse wheel listeners
5409 * registered on this component.
5410 *
5411 * @return all of this component's <code>MouseWheelListener</code>s
5412 * or an empty array if no mouse wheel
5413 * listeners are currently registered
5414 *
5415 * @see #addMouseWheelListener
5416 * @see #removeMouseWheelListener
5417 * @since 1.4
5418 */
5419 public synchronized MouseWheelListener[] getMouseWheelListeners() {
5420 return (MouseWheelListener[]) (getListeners(MouseWheelListener.class));
5421 }
5422
5423 /**
5424 * Adds the specified input method listener to receive
5425 * input method events from this component. A component will
5426 * only receive input method events from input methods
5427 * if it also overrides <code>getInputMethodRequests</code> to return an
5428 * <code>InputMethodRequests</code> instance.
5429 * If listener <code>l</code> is <code>null</code>,
5430 * no exception is thrown and no action is performed.
5431 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5432 * >AWT Threading Issues</a> for details on AWT's threading model.
5433 *
5434 * @param l the input method listener
5435 * @see java.awt.event.InputMethodEvent
5436 * @see java.awt.event.InputMethodListener
5437 * @see #removeInputMethodListener
5438 * @see #getInputMethodListeners
5439 * @see #getInputMethodRequests
5440 * @since 1.2
5441 */
5442 public synchronized void addInputMethodListener(
5443 InputMethodListener l) {
5444 if (l == null) {
5445 return;
5446 }
5447 inputMethodListener = AWTEventMulticaster.add(
5448 inputMethodListener, l);
5449 newEventsOnly = true;
5450 }
5451
5452 /**
5453 * Removes the specified input method listener so that it no longer
5454 * receives input method events from this component. This method performs
5455 * no function, nor does it throw an exception, if the listener
5456 * specified by the argument was not previously added to this component.
5457 * If listener <code>l</code> is <code>null</code>,
5458 * no exception is thrown and no action is performed.
5459 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
5460 * >AWT Threading Issues</a> for details on AWT's threading model.
5461 *
5462 * @param l the input method listener
5463 * @see java.awt.event.InputMethodEvent
5464 * @see java.awt.event.InputMethodListener
5465 * @see #addInputMethodListener
5466 * @see #getInputMethodListeners
5467 * @since 1.2
5468 */
5469 public synchronized void removeInputMethodListener(
5470 InputMethodListener l) {
5471 if (l == null) {
5472 return;
5473 }
5474 inputMethodListener = AWTEventMulticaster.remove(
5475 inputMethodListener, l);
5476 }
5477
5478 /**
5479 * Returns an array of all the input method listeners
5480 * registered on this component.
5481 *
5482 * @return all of this component's <code>InputMethodListener</code>s
5483 * or an empty array if no input method
5484 * listeners are currently registered
5485 *
5486 * @see #addInputMethodListener
5487 * @see #removeInputMethodListener
5488 * @since 1.4
5489 */
5490 public synchronized InputMethodListener[] getInputMethodListeners() {
5491 return (InputMethodListener[]) (getListeners(InputMethodListener.class));
5492 }
5493
5494 /**
5495 * Returns an array of all the objects currently registered
5496 * as <code><em>Foo</em>Listener</code>s
5497 * upon this <code>Component</code>.
5498 * <code><em>Foo</em>Listener</code>s are registered using the
5499 * <code>add<em>Foo</em>Listener</code> method.
5500 *
5501 * <p>
5502 * You can specify the <code>listenerType</code> argument
5503 * with a class literal, such as
5504 * <code><em>Foo</em>Listener.class</code>.
5505 * For example, you can query a
5506 * <code>Component</code> <code>c</code>
5507 * for its mouse listeners with the following code:
5508 *
5509 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
5510 *
5511 * If no such listeners exist, this method returns an empty array.
5512 *
5513 * @param listenerType the type of listeners requested; this parameter
5514 * should specify an interface that descends from
5515 * <code>java.util.EventListener</code>
5516 * @return an array of all objects registered as
5517 * <code><em>Foo</em>Listener</code>s on this component,
5518 * or an empty array if no such listeners have been added
5519 * @exception ClassCastException if <code>listenerType</code>
5520 * doesn't specify a class or interface that implements
5521 * <code>java.util.EventListener</code>
5522 *
5523 * @see #getComponentListeners
5524 * @see #getFocusListeners
5525 * @see #getHierarchyListeners
5526 * @see #getHierarchyBoundsListeners
5527 * @see #getKeyListeners
5528 * @see #getMouseListeners
5529 * @see #getMouseMotionListeners
5530 * @see #getMouseWheelListeners
5531 * @see #getInputMethodListeners
5532 * @see #getPropertyChangeListeners
5533 *
5534 * @since 1.3
5535 */
5536 public <T extends EventListener> T[] getListeners(
5537 Class<T> listenerType) {
5538 EventListener l = null;
5539 if (listenerType == ComponentListener.class) {
5540 l = componentListener;
5541 } else if (listenerType == FocusListener.class) {
5542 l = focusListener;
5543 } else if (listenerType == HierarchyListener.class) {
5544 l = hierarchyListener;
5545 } else if (listenerType == HierarchyBoundsListener.class) {
5546 l = hierarchyBoundsListener;
5547 } else if (listenerType == KeyListener.class) {
5548 l = keyListener;
5549 } else if (listenerType == MouseListener.class) {
5550 l = mouseListener;
5551 } else if (listenerType == MouseMotionListener.class) {
5552 l = mouseMotionListener;
5553 } else if (listenerType == MouseWheelListener.class) {
5554 l = mouseWheelListener;
5555 } else if (listenerType == InputMethodListener.class) {
5556 l = inputMethodListener;
5557 } else if (listenerType == PropertyChangeListener.class) {
5558 return (T[]) getPropertyChangeListeners();
5559 }
5560 return AWTEventMulticaster.getListeners(l, listenerType);
5561 }
5562
5563 /**
5564 * Gets the input method request handler which supports
5565 * requests from input methods for this component. A component
5566 * that supports on-the-spot text input must override this
5567 * method to return an <code>InputMethodRequests</code> instance.
5568 * At the same time, it also has to handle input method events.
5569 *
5570 * @return the input method request handler for this component,
5571 * <code>null</code> by default
5572 * @see #addInputMethodListener
5573 * @since 1.2
5574 */
5575 public InputMethodRequests getInputMethodRequests() {
5576 return null;
5577 }
5578
5579 /**
5580 * Gets the input context used by this component for handling
5581 * the communication with input methods when text is entered
5582 * in this component. By default, the input context used for
5583 * the parent component is returned. Components may
5584 * override this to return a private input context.
5585 *
5586 * @return the input context used by this component;
5587 * <code>null</code> if no context can be determined
5588 * @since 1.2
5589 */
5590 public InputContext getInputContext() {
5591 Container parent = this .parent;
5592 if (parent == null) {
5593 return null;
5594 } else {
5595 return parent.getInputContext();
5596 }
5597 }
5598
5599 /**
5600 * Enables the events defined by the specified event mask parameter
5601 * to be delivered to this component.
5602 * <p>
5603 * Event types are automatically enabled when a listener for
5604 * that event type is added to the component.
5605 * <p>
5606 * This method only needs to be invoked by subclasses of
5607 * <code>Component</code> which desire to have the specified event
5608 * types delivered to <code>processEvent</code> regardless of whether
5609 * or not a listener is registered.
5610 * @param eventsToEnable the event mask defining the event types
5611 * @see #processEvent
5612 * @see #disableEvents
5613 * @see AWTEvent
5614 * @since JDK1.1
5615 */
5616 protected final void enableEvents(long eventsToEnable) {
5617 long notifyAncestors = 0;
5618 synchronized (this ) {
5619 if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
5620 && hierarchyListener == null
5621 && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {
5622 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5623 }
5624 if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
5625 && hierarchyBoundsListener == null
5626 && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {
5627 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5628 }
5629 eventMask |= eventsToEnable;
5630 newEventsOnly = true;
5631 }
5632
5633 // if this is a lightweight component, enable mouse events
5634 // in the native container.
5635 if (peer instanceof LightweightPeer) {
5636 parent.proxyEnableEvents(eventMask);
5637 }
5638 if (notifyAncestors != 0) {
5639 synchronized (getTreeLock()) {
5640 adjustListeningChildrenOnParent(notifyAncestors, 1);
5641 }
5642 }
5643 }
5644
5645 /**
5646 * Disables the events defined by the specified event mask parameter
5647 * from being delivered to this component.
5648 * @param eventsToDisable the event mask defining the event types
5649 * @see #enableEvents
5650 * @since JDK1.1
5651 */
5652 protected final void disableEvents(long eventsToDisable) {
5653 long notifyAncestors = 0;
5654 synchronized (this ) {
5655 if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
5656 && hierarchyListener == null
5657 && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
5658 notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5659 }
5660 if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
5661 && hierarchyBoundsListener == null
5662 && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
5663 notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5664 }
5665 eventMask &= ~eventsToDisable;
5666 }
5667 if (notifyAncestors != 0) {
5668 synchronized (getTreeLock()) {
5669 adjustListeningChildrenOnParent(notifyAncestors, -1);
5670 }
5671 }
5672 }
5673
5674 transient EventQueueItem[] eventCache;
5675
5676 /**
5677 * @see #isCoalescingEnabled
5678 * @see #checkCoalescing
5679 */
5680 transient private boolean coalescingEnabled = checkCoalescing();
5681
5682 /**
5683 * Weak map of known coalesceEvent overriders.
5684 * Value indicates whether overriden.
5685 * Bootstrap classes are not included.
5686 */
5687 private static final Map<Class<?>, Boolean> coalesceMap = new java.util.WeakHashMap<Class<?>, Boolean>();
5688
5689 /**
5690 * Indicates whether this class overrides coalesceEvents.
5691 * It is assumed that all classes that are loaded from the bootstrap
5692 * do not.
5693 * The boostrap class loader is assumed to be represented by null.
5694 * We do not check that the method really overrides
5695 * (it might be static, private or package private).
5696 */
5697 private boolean checkCoalescing() {
5698 if (getClass().getClassLoader() == null) {
5699 return false;
5700 }
5701 final Class<? extends Component> clazz = getClass();
5702 synchronized (coalesceMap) {
5703 // Check cache.
5704 Boolean value = coalesceMap.get(clazz);
5705 if (value != null) {
5706 return value;
5707 }
5708
5709 // Need to check non-bootstraps.
5710 Boolean enabled = java.security.AccessController
5711 .doPrivileged(new java.security.PrivilegedAction<Boolean>() {
5712 public Boolean run() {
5713 return isCoalesceEventsOverriden(clazz);
5714 }
5715 });
5716 coalesceMap.put(clazz, enabled);
5717 return enabled;
5718 }
5719 }
5720
5721 /**
5722 * Parameter types of coalesceEvents(AWTEvent,AWTEVent).
5723 */
5724 private static final Class[] coalesceEventsParams = {
5725 AWTEvent.class, AWTEvent.class };
5726
5727 /**
5728 * Indicates whether a class or its superclasses override coalesceEvents.
5729 * Must be called with lock on coalesceMap and privileged.
5730 * @see checkCoalsecing
5731 */
5732 private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
5733 assert Thread.holdsLock(coalesceMap);
5734
5735 // First check superclass - we may not need to bother ourselves.
5736 Class<?> super class = clazz.getSuperclass();
5737 if (super class == null) {
5738 // Only occurs on implementations that
5739 // do not use null to represent the bootsrap class loader.
5740 return false;
5741 }
5742 if (super class.getClassLoader() != null) {
5743 Boolean value = coalesceMap.get(super class);
5744 if (value == null) {
5745 // Not done already - recurse.
5746 if (isCoalesceEventsOverriden(super class)) {
5747 coalesceMap.put(super class, true);
5748 return true;
5749 }
5750 } else if (value) {
5751 return true;
5752 }
5753 }
5754
5755 try {
5756 // Throws if not overriden.
5757 clazz.getDeclaredMethod("coalesceEvents",
5758 coalesceEventsParams);
5759 return true;
5760 } catch (NoSuchMethodException e) {
5761 // Not present in this class.
5762 return false;
5763 }
5764 }
5765
5766 /**
5767 * Indicates whether coalesceEvents may do something.
5768 */
5769 final boolean isCoalescingEnabled() {
5770 return coalescingEnabled;
5771 }
5772
5773 /**
5774 * Potentially coalesce an event being posted with an existing
5775 * event. This method is called by <code>EventQueue.postEvent</code>
5776 * if an event with the same ID as the event to be posted is found in
5777 * the queue (both events must have this component as their source).
5778 * This method either returns a coalesced event which replaces
5779 * the existing event (and the new event is then discarded), or
5780 * <code>null</code> to indicate that no combining should be done
5781 * (add the second event to the end of the queue). Either event
5782 * parameter may be modified and returned, as the other one is discarded
5783 * unless <code>null</code> is returned.
5784 * <p>
5785 * This implementation of <code>coalesceEvents</code> coalesces
5786 * two event types: mouse move (and drag) events,
5787 * and paint (and update) events.
5788 * For mouse move events the last event is always returned, causing
5789 * intermediate moves to be discarded. For paint events, the new
5790 * event is coalesced into a complex <code>RepaintArea</code> in the peer.
5791 * The new <code>AWTEvent</code> is always returned.
5792 *
5793 * @param existingEvent the event already on the <code>EventQueue</code>
5794 * @param newEvent the event being posted to the
5795 * <code>EventQueue</code>
5796 * @return a coalesced event, or <code>null</code> indicating that no
5797 * coalescing was done
5798 */
5799 protected AWTEvent coalesceEvents(AWTEvent existingEvent,
5800 AWTEvent newEvent) {
5801 return null;
5802 }
5803
5804 /**
5805 * Processes events occurring on this component. By default this
5806 * method calls the appropriate
5807 * <code>process<event type>Event</code>
5808 * method for the given class of event.
5809 * <p>Note that if the event parameter is <code>null</code>
5810 * the behavior is unspecified and may result in an
5811 * exception.
5812 *
5813 * @param e the event
5814 * @see #processComponentEvent
5815 * @see #processFocusEvent
5816 * @see #processKeyEvent
5817 * @see #processMouseEvent
5818 * @see #processMouseMotionEvent
5819 * @see #processInputMethodEvent
5820 * @see #processHierarchyEvent
5821 * @see #processMouseWheelEvent
5822 * @since JDK1.1
5823 */
5824 protected void processEvent(AWTEvent e) {
5825 if (e instanceof FocusEvent) {
5826 processFocusEvent((FocusEvent) e);
5827
5828 } else if (e instanceof MouseEvent) {
5829 switch (e.getID()) {
5830 case MouseEvent.MOUSE_PRESSED:
5831 case MouseEvent.MOUSE_RELEASED:
5832 case MouseEvent.MOUSE_CLICKED:
5833 case MouseEvent.MOUSE_ENTERED:
5834 case MouseEvent.MOUSE_EXITED:
5835 processMouseEvent((MouseEvent) e);
5836 break;
5837 case MouseEvent.MOUSE_MOVED:
5838 case MouseEvent.MOUSE_DRAGGED:
5839 processMouseMotionEvent((MouseEvent) e);
5840 break;
5841 case MouseEvent.MOUSE_WHEEL:
5842 processMouseWheelEvent((MouseWheelEvent) e);
5843 break;
5844 }
5845
5846 } else if (e instanceof KeyEvent) {
5847 processKeyEvent((KeyEvent) e);
5848
5849 } else if (e instanceof ComponentEvent) {
5850 processComponentEvent((ComponentEvent) e);
5851 } else if (e instanceof InputMethodEvent) {
5852 processInputMethodEvent((InputMethodEvent) e);
5853 } else if (e instanceof HierarchyEvent) {
5854 switch (e.getID()) {
5855 case HierarchyEvent.HIERARCHY_CHANGED:
5856 processHierarchyEvent((HierarchyEvent) e);
5857 break;
5858 case HierarchyEvent.ANCESTOR_MOVED:
5859 case HierarchyEvent.ANCESTOR_RESIZED:
5860 processHierarchyBoundsEvent((HierarchyEvent) e);
5861 break;
5862 }
5863 }
5864 }
5865
5866 /**
5867 * Processes component events occurring on this component by
5868 * dispatching them to any registered
5869 * <code>ComponentListener</code> objects.
5870 * <p>
5871 * This method is not called unless component events are
5872 * enabled for this component. Component events are enabled
5873 * when one of the following occurs:
5874 * <p><ul>
5875 * <li>A <code>ComponentListener</code> object is registered
5876 * via <code>addComponentListener</code>.
5877 * <li>Component events are enabled via <code>enableEvents</code>.
5878 * </ul>
5879 * <p>Note that if the event parameter is <code>null</code>
5880 * the behavior is unspecified and may result in an
5881 * exception.
5882 *
5883 * @param e the component event
5884 * @see java.awt.event.ComponentEvent
5885 * @see java.awt.event.ComponentListener
5886 * @see #addComponentListener
5887 * @see #enableEvents
5888 * @since JDK1.1
5889 */
5890 protected void processComponentEvent(ComponentEvent e) {
5891 ComponentListener listener = componentListener;
5892 if (listener != null) {
5893 int id = e.getID();
5894 switch (id) {
5895 case ComponentEvent.COMPONENT_RESIZED:
5896 listener.componentResized(e);
5897 break;
5898 case ComponentEvent.COMPONENT_MOVED:
5899 listener.componentMoved(e);
5900 break;
5901 case ComponentEvent.COMPONENT_SHOWN:
5902 listener.componentShown(e);
5903 break;
5904 case ComponentEvent.COMPONENT_HIDDEN:
5905 listener.componentHidden(e);
5906 break;
5907 }
5908 }
5909 }
5910
5911 /**
5912 * Processes focus events occurring on this component by
5913 * dispatching them to any registered
5914 * <code>FocusListener</code> objects.
5915 * <p>
5916 * This method is not called unless focus events are
5917 * enabled for this component. Focus events are enabled
5918 * when one of the following occurs:
5919 * <p><ul>
5920 * <li>A <code>FocusListener</code> object is registered
5921 * via <code>addFocusListener</code>.
5922 * <li>Focus events are enabled via <code>enableEvents</code>.
5923 * </ul>
5924 * <p>
5925 * If focus events are enabled for a <code>Component</code>,
5926 * the current <code>KeyboardFocusManager</code> determines
5927 * whether or not a focus event should be dispatched to
5928 * registered <code>FocusListener</code> objects. If the
5929 * events are to be dispatched, the <code>KeyboardFocusManager</code>
5930 * calls the <code>Component</code>'s <code>dispatchEvent</code>
5931 * method, which results in a call to the <code>Component</code>'s
5932 * <code>processFocusEvent</code> method.
5933 * <p>
5934 * If focus events are enabled for a <code>Component</code>, calling
5935 * the <code>Component</code>'s <code>dispatchEvent</code> method
5936 * with a <code>FocusEvent</code> as the argument will result in a
5937 * call to the <code>Component</code>'s <code>processFocusEvent</code>
5938 * method regardless of the current <code>KeyboardFocusManager</code>.
5939 * <p>
5940 * <p>Note that if the event parameter is <code>null</code>
5941 * the behavior is unspecified and may result in an
5942 * exception.
5943 *
5944 * @param e the focus event
5945 * @see java.awt.event.FocusEvent
5946 * @see java.awt.event.FocusListener
5947 * @see java.awt.KeyboardFocusManager
5948 * @see #addFocusListener
5949 * @see #enableEvents
5950 * @see #dispatchEvent
5951 * @since JDK1.1
5952 */
5953 protected void processFocusEvent(FocusEvent e) {
5954 FocusListener listener = focusListener;
5955 if (listener != null) {
5956 int id = e.getID();
5957 switch (id) {
5958 case FocusEvent.FOCUS_GAINED:
5959 listener.focusGained(e);
5960 break;
5961 case FocusEvent.FOCUS_LOST:
5962 listener.focusLost(e);
5963 break;
5964 }
5965 }
5966 }
5967
5968 /**
5969 * Processes key events occurring on this component by
5970 * dispatching them to any registered
5971 * <code>KeyListener</code> objects.
5972 * <p>
5973 * This method is not called unless key events are
5974 * enabled for this component. Key events are enabled
5975 * when one of the following occurs:
5976 * <p><ul>
5977 * <li>A <code>KeyListener</code> object is registered
5978 * via <code>addKeyListener</code>.
5979 * <li>Key events are enabled via <code>enableEvents</code>.
5980 * </ul>
5981 *
5982 * <p>
5983 * If key events are enabled for a <code>Component</code>,
5984 * the current <code>KeyboardFocusManager</code> determines
5985 * whether or not a key event should be dispatched to
5986 * registered <code>KeyListener</code> objects. The
5987 * <code>DefaultKeyboardFocusManager</code> will not dispatch
5988 * key events to a <code>Component</code> that is not the focus
5989 * owner or is not showing.
5990 * <p>
5991 * As of J2SE 1.4, <code>KeyEvent</code>s are redirected to
5992 * the focus owner. Please see the
5993 * <a href="doc-files/FocusSpec.html">Focus Specification</a>
5994 * for further information.
5995 * <p>
5996 * Calling a <code>Component</code>'s <code>dispatchEvent</code>
5997 * method with a <code>KeyEvent</code> as the argument will
5998 * result in a call to the <code>Component</code>'s
5999 * <code>processKeyEvent</code> method regardless of the
6000 * current <code>KeyboardFocusManager</code> as long as the
6001 * component is showing, focused, and enabled, and key events
6002 * are enabled on it.
6003 * <p>If the event parameter is <code>null</code>
6004 * the behavior is unspecified and may result in an
6005 * exception.
6006 *
6007 * @param e the key event
6008 * @see java.awt.event.KeyEvent
6009 * @see java.awt.event.KeyListener
6010 * @see java.awt.KeyboardFocusManager
6011 * @see java.awt.DefaultKeyboardFocusManager
6012 * @see #processEvent
6013 * @see #dispatchEvent
6014 * @see #addKeyListener
6015 * @see #enableEvents
6016 * @see #isShowing
6017 * @since JDK1.1
6018 */
6019 protected void processKeyEvent(KeyEvent e) {
6020 KeyListener listener = keyListener;
6021 if (listener != null) {
6022 int id = e.getID();
6023 switch (id) {
6024 case KeyEvent.KEY_TYPED:
6025 listener.keyTyped(e);
6026 break;
6027 case KeyEvent.KEY_PRESSED:
6028 listener.keyPressed(e);
6029 break;
6030 case KeyEvent.KEY_RELEASED:
6031 listener.keyReleased(e);
6032 break;
6033 }
6034 }
6035 }
6036
6037 /**
6038 * Processes mouse events occurring on this component by
6039 * dispatching them to any registered
6040 * <code>MouseListener</code> objects.
6041 * <p>
6042 * This method is not called unless mouse events are
6043 * enabled for this component. Mouse events are enabled
6044 * when one of the following occurs:
6045 * <p><ul>
6046 * <li>A <code>MouseListener</code> object is registered
6047 * via <code>addMouseListener</code>.
6048 * <li>Mouse events are enabled via <code>enableEvents</code>.
6049 * </ul>
6050 * <p>Note that if the event parameter is <code>null</code>
6051 * the behavior is unspecified and may result in an
6052 * exception.
6053 *
6054 * @param e the mouse event
6055 * @see java.awt.event.MouseEvent
6056 * @see java.awt.event.MouseListener
6057 * @see #addMouseListener
6058 * @see #enableEvents
6059 * @since JDK1.1
6060 */
6061 protected void processMouseEvent(MouseEvent e) {
6062 MouseListener listener = mouseListener;
6063 if (listener != null) {
6064 int id = e.getID();
6065 switch (id) {
6066 case MouseEvent.MOUSE_PRESSED:
6067 listener.mousePressed(e);
6068 break;
6069 case MouseEvent.MOUSE_RELEASED:
6070 listener.mouseReleased(e);
6071 break;
6072 case MouseEvent.MOUSE_CLICKED:
6073 listener.mouseClicked(e);
6074 break;
6075 case MouseEvent.MOUSE_EXITED:
6076 listener.mouseExited(e);
6077 break;
6078 case MouseEvent.MOUSE_ENTERED:
6079 listener.mouseEntered(e);
6080 break;
6081 }
6082 }
6083 }
6084
6085 /**
6086 * Processes mouse motion events occurring on this component by
6087 * dispatching them to any registered
6088 * <code>MouseMotionListener</code> objects.
6089 * <p>
6090 * This method is not called unless mouse motion events are
6091 * enabled for this component. Mouse motion events are enabled
6092 * when one of the following occurs:
6093 * <p><ul>
6094 * <li>A <code>MouseMotionListener</code> object is registered
6095 * via <code>addMouseMotionListener</code>.
6096 * <li>Mouse motion events are enabled via <code>enableEvents</code>.
6097 * </ul>
6098 * <p>Note that if the event parameter is <code>null</code>
6099 * the behavior is unspecified and may result in an
6100 * exception.
6101 *
6102 * @param e the mouse motion event
6103 * @see java.awt.event.MouseEvent
6104 * @see java.awt.event.MouseMotionListener
6105 * @see #addMouseMotionListener
6106 * @see #enableEvents
6107 * @since JDK1.1
6108 */
6109 protected void processMouseMotionEvent(MouseEvent e) {
6110 MouseMotionListener listener = mouseMotionListener;
6111 if (listener != null) {
6112 int id = e.getID();
6113 switch (id) {
6114 case MouseEvent.MOUSE_MOVED:
6115 listener.mouseMoved(e);
6116 break;
6117 case MouseEvent.MOUSE_DRAGGED:
6118 listener.mouseDragged(e);
6119 break;
6120 }
6121 }
6122 }
6123
6124 /**
6125 * Processes mouse wheel events occurring on this component by
6126 * dispatching them to any registered
6127 * <code>MouseWheelListener</code> objects.
6128 * <p>
6129 * This method is not called unless mouse wheel events are
6130 * enabled for this component. Mouse wheel events are enabled
6131 * when one of the following occurs:
6132 * <p><ul>
6133 * <li>A <code>MouseWheelListener</code> object is registered
6134 * via <code>addMouseWheelListener</code>.
6135 * <li>Mouse wheel events are enabled via <code>enableEvents</code>.
6136 * </ul>
6137 * <p>
6138 * For information on how mouse wheel events are dispatched, see
6139 * the class description for {@link MouseWheelEvent}.
6140 * <p>
6141 * Note that if the event parameter is <code>null</code>
6142 * the behavior is unspecified and may result in an
6143 * exception.
6144 *
6145 * @param e the mouse wheel event
6146 * @see java.awt.event.MouseWheelEvent
6147 * @see java.awt.event.MouseWheelListener
6148 * @see #addMouseWheelListener
6149 * @see #enableEvents
6150 * @since 1.4
6151 */
6152 protected void processMouseWheelEvent(MouseWheelEvent e) {
6153 MouseWheelListener listener = mouseWheelListener;
6154 if (listener != null) {
6155 int id = e.getID();
6156 switch (id) {
6157 case MouseEvent.MOUSE_WHEEL:
6158 listener.mouseWheelMoved(e);
6159 break;
6160 }
6161 }
6162 }
6163
6164 boolean postsOldMouseEvents() {
6165 return false;
6166 }
6167
6168 /**
6169 * Processes input method events occurring on this component by
6170 * dispatching them to any registered
6171 * <code>InputMethodListener</code> objects.
6172 * <p>
6173 * This method is not called unless input method events
6174 * are enabled for this component. Input method events are enabled
6175 * when one of the following occurs:
6176 * <p><ul>
6177 * <li>An <code>InputMethodListener</code> object is registered
6178 * via <code>addInputMethodListener</code>.
6179 * <li>Input method events are enabled via <code>enableEvents</code>.
6180 * </ul>
6181 * <p>Note that if the event parameter is <code>null</code>
6182 * the behavior is unspecified and may result in an
6183 * exception.
6184 *
6185 * @param e the input method event
6186 * @see java.awt.event.InputMethodEvent
6187 * @see java.awt.event.InputMethodListener
6188 * @see #addInputMethodListener
6189 * @see #enableEvents
6190 * @since 1.2
6191 */
6192 protected void processInputMethodEvent(InputMethodEvent e) {
6193 InputMethodListener listener = inputMethodListener;
6194 if (listener != null) {
6195 int id = e.getID();
6196 switch (id) {
6197 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
6198 listener.inputMethodTextChanged(e);
6199 break;
6200 case InputMethodEvent.CARET_POSITION_CHANGED:
6201 listener.caretPositionChanged(e);
6202 break;
6203 }
6204 }
6205 }
6206
6207 /**
6208 * Processes hierarchy events occurring on this component by
6209 * dispatching them to any registered
6210 * <code>HierarchyListener</code> objects.
6211 * <p>
6212 * This method is not called unless hierarchy events
6213 * are enabled for this component. Hierarchy events are enabled
6214 * when one of the following occurs:
6215 * <p><ul>
6216 * <li>An <code>HierarchyListener</code> object is registered
6217 * via <code>addHierarchyListener</code>.
6218 * <li>Hierarchy events are enabled via <code>enableEvents</code>.
6219 * </ul>
6220 * <p>Note that if the event parameter is <code>null</code>
6221 * the behavior is unspecified and may result in an
6222 * exception.
6223 *
6224 * @param e the hierarchy event
6225 * @see java.awt.event.HierarchyEvent
6226 * @see java.awt.event.HierarchyListener
6227 * @see #addHierarchyListener
6228 * @see #enableEvents
6229 * @since 1.3
6230 */
6231 protected void processHierarchyEvent(HierarchyEvent e) {
6232 HierarchyListener listener = hierarchyListener;
6233 if (listener != null) {
6234 int id = e.getID();
6235 switch (id) {
6236 case HierarchyEvent.HIERARCHY_CHANGED:
6237 listener.hierarchyChanged(e);
6238 break;
6239 }
6240 }
6241 }
6242
6243 /**
6244 * Processes hierarchy bounds events occurring on this component by
6245 * dispatching them to any registered
6246 * <code>HierarchyBoundsListener</code> objects.
6247 * <p>
6248 * This method is not called unless hierarchy bounds events
6249 * are enabled for this component. Hierarchy bounds events are enabled
6250 * when one of the following occurs:
6251 * <p><ul>
6252 * <li>An <code>HierarchyBoundsListener</code> object is registered
6253 * via <code>addHierarchyBoundsListener</code>.
6254 * <li>Hierarchy bounds events are enabled via <code>enableEvents</code>.
6255 * </ul>
6256 * <p>Note that if the event parameter is <code>null</code>
6257 * the behavior is unspecified and may result in an
6258 * exception.
6259 *
6260 * @param e the hierarchy event
6261 * @see java.awt.event.HierarchyEvent
6262 * @see java.awt.event.HierarchyBoundsListener
6263 * @see #addHierarchyBoundsListener
6264 * @see #enableEvents
6265 * @since 1.3
6266 */
6267 protected void processHierarchyBoundsEvent(HierarchyEvent e) {
6268 HierarchyBoundsListener listener = hierarchyBoundsListener;
6269 if (listener != null) {
6270 int id = e.getID();
6271 switch (id) {
6272 case HierarchyEvent.ANCESTOR_MOVED:
6273 listener.ancestorMoved(e);
6274 break;
6275 case HierarchyEvent.ANCESTOR_RESIZED:
6276 listener.ancestorResized(e);
6277 break;
6278 }
6279 }
6280 }
6281
6282 /**
6283 * @deprecated As of JDK version 1.1
6284 * replaced by processEvent(AWTEvent).
6285 */
6286 @Deprecated
6287 public boolean handleEvent(Event evt) {
6288 switch (evt.id) {
6289 case Event.MOUSE_ENTER:
6290 return mouseEnter(evt, evt.x, evt.y);
6291
6292 case Event.MOUSE_EXIT:
6293 return mouseExit(evt, evt.x, evt.y);
6294
6295 case Event.MOUSE_MOVE:
6296 return mouseMove(evt, evt.x, evt.y);
6297
6298 case Event.MOUSE_DOWN:
6299 return mouseDown(evt, evt.x, evt.y);
6300
6301 case Event.MOUSE_DRAG:
6302 return mouseDrag(evt, evt.x, evt.y);
6303
6304 case Event.MOUSE_UP:
6305 return mouseUp(evt, evt.x, evt.y);
6306
6307 case Event.KEY_PRESS:
6308 case Event.KEY_ACTION:
6309 return keyDown(evt, evt.key);
6310
6311 case Event.KEY_RELEASE:
6312 case Event.KEY_ACTION_RELEASE:
6313 return keyUp(evt, evt.key);
6314
6315 case Event.ACTION_EVENT:
6316 return action(evt, evt.arg);
6317 case Event.GOT_FOCUS:
6318 return gotFocus(evt, evt.arg);
6319 case Event.LOST_FOCUS:
6320 return lostFocus(evt, evt.arg);
6321 }
6322 return false;
6323 }
6324
6325 /**
6326 * @deprecated As of JDK version 1.1,
6327 * replaced by processMouseEvent(MouseEvent).
6328 */
6329 @Deprecated
6330 public boolean mouseDown(Event evt, int x, int y) {
6331 return false;
6332 }
6333
6334 /**
6335 * @deprecated As of JDK version 1.1,
6336 * replaced by processMouseMotionEvent(MouseEvent).
6337 */
6338 @Deprecated
6339 public boolean mouseDrag(Event evt, int x, int y) {
6340 return false;
6341 }
6342
6343 /**
6344 * @deprecated As of JDK version 1.1,
6345 * replaced by processMouseEvent(MouseEvent).
6346 */
6347 @Deprecated
6348 public boolean mouseUp(Event evt, int x, int y) {
6349 return false;
6350 }
6351
6352 /**
6353 * @deprecated As of JDK version 1.1,
6354 * replaced by processMouseMotionEvent(MouseEvent).
6355 */
6356 @Deprecated
6357 public boolean mouseMove(Event evt, int x, int y) {
6358 return false;
6359 }
6360
6361 /**
6362 * @deprecated As of JDK version 1.1,
6363 * replaced by processMouseEvent(MouseEvent).
6364 */
6365 @Deprecated
6366 public boolean mouseEnter(Event evt, int x, int y) {
6367 return false;
6368 }
6369
6370 /**
6371 * @deprecated As of JDK version 1.1,
6372 * replaced by processMouseEvent(MouseEvent).
6373 */
6374 @Deprecated
6375 public boolean mouseExit(Event evt, int x, int y) {
6376 return false;
6377 }
6378
6379 /**
6380 * @deprecated As of JDK version 1.1,
6381 * replaced by processKeyEvent(KeyEvent).
6382 */
6383 @Deprecated
6384 public boolean keyDown(Event evt, int key) {
6385 return false;
6386 }
6387
6388 /**
6389 * @deprecated As of JDK version 1.1,
6390 * replaced by processKeyEvent(KeyEvent).
6391 */
6392 @Deprecated
6393 public boolean keyUp(Event evt, int key) {
6394 return false;
6395 }
6396
6397 /**
6398 * @deprecated As of JDK version 1.1,
6399 * should register this component as ActionListener on component
6400 * which fires action events.
6401 */
6402 @Deprecated
6403 public boolean action(Event evt, Object what) {
6404 return false;
6405 }
6406
6407 /**
6408 * Makes this <code>Component</code> displayable by connecting it to a
6409 * native screen resource.
6410 * This method is called internally by the toolkit and should
6411 * not be called directly by programs.
6412 * @see #isDisplayable
6413 * @see #removeNotify
6414 * @since JDK1.0
6415 */
6416 public void addNotify() {
6417 synchronized (getTreeLock()) {
6418 ComponentPeer peer = this .peer;
6419 if (peer == null || peer instanceof LightweightPeer) {
6420 if (peer == null) {
6421 // Update both the Component's peer variable and the local
6422 // variable we use for thread safety.
6423 this .peer = peer = getToolkit().createComponent(
6424 this );
6425 }
6426
6427 // This is a lightweight component which means it won't be
6428 // able to get window-related events by itself. If any
6429 // have been enabled, then the nearest native container must
6430 // be enabled.
6431 if (parent != null) {
6432 long mask = 0;
6433 if ((mouseListener != null)
6434 || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
6435 mask |= AWTEvent.MOUSE_EVENT_MASK;
6436 }
6437 if ((mouseMotionListener != null)
6438 || ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
6439 mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
6440 }
6441 if ((mouseWheelListener != null)
6442 || ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
6443 mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
6444 }
6445 if (focusListener != null
6446 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
6447 mask |= AWTEvent.FOCUS_EVENT_MASK;
6448 }
6449 if (keyListener != null
6450 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
6451 mask |= AWTEvent.KEY_EVENT_MASK;
6452 }
6453 if (mask != 0) {
6454 parent.proxyEnableEvents(mask);
6455 }
6456 }
6457 } else {
6458 // It's native. If the parent is lightweight it
6459 // will need some help.
6460 Container parent = this .parent;
6461 if (parent != null
6462 && parent.peer instanceof LightweightPeer) {
6463 nativeInLightFixer = new NativeInLightFixer();
6464 }
6465 }
6466 invalidate();
6467
6468 int npopups = (popups != null ? popups.size() : 0);
6469 for (int i = 0; i < npopups; i++) {
6470 PopupMenu popup = (PopupMenu) popups.elementAt(i);
6471 popup.addNotify();
6472 }
6473
6474 if (dropTarget != null)
6475 dropTarget.addNotify(peer);
6476
6477 peerFont = getFont();
6478
6479 // Update stacking order
6480 if (parent != null && parent.peer != null) {
6481 ContainerPeer parentContPeer = (ContainerPeer) parent.peer;
6482 // if our parent is lightweight and we are not
6483 // we should call restack on nearest heavyweight
6484 // container.
6485 if (parentContPeer instanceof LightweightPeer
6486 && !(peer instanceof LightweightPeer)) {
6487 Container hwParent = getNativeContainer();
6488 if (hwParent != null && hwParent.peer != null) {
6489 parentContPeer = (ContainerPeer) hwParent.peer;
6490 }
6491 }
6492 if (parentContPeer.isRestackSupported()) {
6493 parentContPeer.restack();
6494 }
6495 }
6496
6497 if (hierarchyListener != null
6498 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0
6499 || Toolkit
6500 .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6501 HierarchyEvent e = new HierarchyEvent(
6502 this ,
6503 HierarchyEvent.HIERARCHY_CHANGED,
6504 this ,
6505 parent,
6506 HierarchyEvent.DISPLAYABILITY_CHANGED
6507 | ((isRecursivelyVisible()) ? HierarchyEvent.SHOWING_CHANGED
6508 : 0));
6509 dispatchEvent(e);
6510 }
6511 }
6512 }
6513
6514 /**
6515 * Makes this <code>Component</code> undisplayable by destroying it native
6516 * screen resource.
6517 * <p>
6518 * This method is called by the toolkit internally and should
6519 * not be called directly by programs. Code overriding
6520 * this method should call <code>super.removeNotify</code> as
6521 * the first line of the overriding method.
6522 *
6523 * @see #isDisplayable
6524 * @see #addNotify
6525 * @since JDK1.0
6526 */
6527 public void removeNotify() {
6528 KeyboardFocusManager.clearMostRecentFocusOwner(this );
6529 if (KeyboardFocusManager.getCurrentKeyboardFocusManager()
6530 .getPermanentFocusOwner() == this ) {
6531 KeyboardFocusManager.getCurrentKeyboardFocusManager()
6532 .setGlobalPermanentFocusOwner(null);
6533 }
6534
6535 synchronized (getTreeLock()) {
6536 if (isFocusOwner()
6537 && KeyboardFocusManager
6538 .isAutoFocusTransferEnabled()
6539 && !nextFocusHelper()) {
6540 KeyboardFocusManager.getCurrentKeyboardFocusManager()
6541 .clearGlobalFocusOwner();
6542 }
6543
6544 int npopups = (popups != null ? popups.size() : 0);
6545 for (int i = 0; i < npopups; i++) {
6546 PopupMenu popup = (PopupMenu) popups.elementAt(i);
6547 popup.removeNotify();
6548 }
6549 // If there is any input context for this component, notify
6550 // that this component is being removed. (This has to be done
6551 // before hiding peer.)
6552 if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
6553 InputContext inputContext = getInputContext();
6554 if (inputContext != null) {
6555 inputContext.removeNotify(this );
6556 }
6557 }
6558
6559 if (nativeInLightFixer != null) {
6560 nativeInLightFixer.uninstall();
6561 }
6562
6563 ComponentPeer p = peer;
6564 if (p != null) {
6565
6566 if (bufferStrategy instanceof FlipBufferStrategy) {
6567 ((FlipBufferStrategy) bufferStrategy)
6568 .destroyBuffers();
6569 }
6570
6571 if (dropTarget != null)
6572 dropTarget.removeNotify(peer);
6573
6574 // Hide peer first to stop system events such as cursor moves.
6575 if (visible) {
6576 p.hide();
6577 }
6578
6579 peer = null; // Stop peer updates.
6580 peerFont = null;
6581
6582 Toolkit.getEventQueue().removeSourceEvents(this , false);
6583 KeyboardFocusManager.getCurrentKeyboardFocusManager()
6584 .discardKeyEvents(this );
6585
6586 p.dispose();
6587 }
6588
6589 if (hierarchyListener != null
6590 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0
6591 || Toolkit
6592 .enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6593 HierarchyEvent e = new HierarchyEvent(
6594 this ,
6595 HierarchyEvent.HIERARCHY_CHANGED,
6596 this ,
6597 parent,
6598 HierarchyEvent.DISPLAYABILITY_CHANGED
6599 | ((isRecursivelyVisible()) ? HierarchyEvent.SHOWING_CHANGED
6600 : 0));
6601 dispatchEvent(e);
6602 }
6603 }
6604 }
6605
6606 /**
6607 * @deprecated As of JDK version 1.1,
6608 * replaced by processFocusEvent(FocusEvent).
6609 */
6610 @Deprecated
6611 public boolean gotFocus(Event evt, Object what) {
6612 return false;
6613 }
6614
6615 /**
6616 * @deprecated As of JDK version 1.1,
6617 * replaced by processFocusEvent(FocusEvent).
6618 */
6619 @Deprecated
6620 public boolean lostFocus(Event evt, Object what) {
6621 return false;
6622 }
6623
6624 /**
6625 * Returns whether this <code>Component</code> can become the focus
6626 * owner.
6627 *
6628 * @return <code>true</code> if this <code>Component</code> is
6629 * focusable; <code>false</code> otherwise
6630 * @see #setFocusable
6631 * @since JDK1.1
6632 * @deprecated As of 1.4, replaced by <code>isFocusable()</code>.
6633 */
6634 @Deprecated
6635 public boolean isFocusTraversable() {
6636 if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
6637 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
6638 }
6639 return focusable;
6640 }
6641
6642 /**
6643 * Returns whether this Component can be focused.
6644 *
6645 * @return <code>true</code> if this Component is focusable;
6646 * <code>false</code> otherwise.
6647 * @see #setFocusable
6648 * @since 1.4
6649 */
6650 public boolean isFocusable() {
6651 return isFocusTraversable();
6652 }
6653
6654 /**
6655 * Sets the focusable state of this Component to the specified value. This
6656 * value overrides the Component's default focusability.
6657 *
6658 * @param focusable indicates whether this Component is focusable
6659 * @see #isFocusable
6660 * @since 1.4
6661 * @beaninfo
6662 * bound: true
6663 */
6664 public void setFocusable(boolean focusable) {
6665 boolean oldFocusable;
6666 synchronized (this ) {
6667 oldFocusable = this .focusable;
6668 this .focusable = focusable;
6669 }
6670 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
6671
6672 firePropertyChange("focusable", oldFocusable, focusable);
6673 if (oldFocusable && !focusable) {
6674 if (isFocusOwner()) {
6675 autoTransferFocus(true);
6676 }
6677 KeyboardFocusManager.clearMostRecentFocusOwner(this );
6678 }
6679 }
6680
6681 final boolean isFocusTraversableOverridden() {
6682 return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
6683 }
6684
6685 /**
6686 * Sets the focus traversal keys for a given traversal operation for this
6687 * Component.
6688 * <p>
6689 * The default values for a Component's focus traversal keys are
6690 * implementation-dependent. Sun recommends that all implementations for a
6691 * particular native platform use the same default values. The
6692 * recommendations for Windows and Unix are listed below. These
6693 * recommendations are used in the Sun AWT implementations.
6694 *
6695 * <table border=1 summary="Recommended default values for a Component's focus traversal keys">
6696 * <tr>
6697 * <th>Identifier</th>
6698 * <th>Meaning</th>
6699 * <th>Default</th>
6700 * </tr>
6701 * <tr>
6702 * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
6703 * <td>Normal forward keyboard traversal</td>
6704 * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
6705 * </tr>
6706 * <tr>
6707 * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
6708 * <td>Normal reverse keyboard traversal</td>
6709 * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
6710 * </tr>
6711 * <tr>
6712 * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
6713 * <td>Go up one focus traversal cycle</td>
6714 * <td>none</td>
6715 * </tr>
6716 * </table>
6717 *
6718 * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
6719 * recommended.
6720 * <p>
6721 * Using the AWTKeyStroke API, client code can specify on which of two
6722 * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
6723 * operation will occur. Regardless of which KeyEvent is specified,
6724 * however, all KeyEvents related to the focus traversal key, including the
6725 * associated KEY_TYPED event, will be consumed, and will not be dispatched
6726 * to any Component. It is a runtime error to specify a KEY_TYPED event as
6727 * mapping to a focus traversal operation, or to map the same event to
6728 * multiple default focus traversal operations.
6729 * <p>
6730 * If a value of null is specified for the Set, this Component inherits the
6731 * Set from its parent. If all ancestors of this Component have null
6732 * specified for the Set, then the current KeyboardFocusManager's default
6733 * Set is used.
6734 *
6735 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6736 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6737 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6738 * @param keystrokes the Set of AWTKeyStroke for the specified operation
6739 * @see #getFocusTraversalKeys
6740 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6741 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6742 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6743 * @throws IllegalArgumentException if id is not one of
6744 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6745 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6746 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
6747 * contains null, or if any Object in keystrokes is not an
6748 * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
6749 * or if any keystroke already maps to another focus traversal
6750 * operation for this Component
6751 * @since 1.4
6752 * @beaninfo
6753 * bound: true
6754 */
6755 public void setFocusTraversalKeys(int id,
6756 Set<? extends AWTKeyStroke> keystrokes) {
6757 if (id < 0
6758 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6759 throw new IllegalArgumentException(
6760 "invalid focus traversal key identifier");
6761 }
6762
6763 setFocusTraversalKeys_NoIDCheck(id, keystrokes);
6764 }
6765
6766 /**
6767 * Returns the Set of focus traversal keys for a given traversal operation
6768 * for this Component. (See
6769 * <code>setFocusTraversalKeys</code> for a full description of each key.)
6770 * <p>
6771 * If a Set of traversal keys has not been explicitly defined for this
6772 * Component, then this Component's parent's Set is returned. If no Set
6773 * has been explicitly defined for any of this Component's ancestors, then
6774 * the current KeyboardFocusManager's default Set is returned.
6775 *
6776 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6777 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6778 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6779 * @return the Set of AWTKeyStrokes for the specified operation. The Set
6780 * will be unmodifiable, and may be empty. null will never be
6781 * returned.
6782 * @see #setFocusTraversalKeys
6783 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6784 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6785 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6786 * @throws IllegalArgumentException if id is not one of
6787 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6788 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6789 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6790 * @since 1.4
6791 */
6792 public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
6793 if (id < 0
6794 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6795 throw new IllegalArgumentException(
6796 "invalid focus traversal key identifier");
6797 }
6798
6799 return getFocusTraversalKeys_NoIDCheck(id);
6800 }
6801
6802 // We define these methods so that Container does not need to repeat this
6803 // code. Container cannot call super.<method> because Container allows
6804 // DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method
6805 // would erroneously generate an IllegalArgumentException for
6806 // DOWN_CYCLE_TRAVERSAL_KEY.
6807 final void setFocusTraversalKeys_NoIDCheck(int id,
6808 Set<? extends AWTKeyStroke> keystrokes) {
6809 Set oldKeys;
6810
6811 synchronized (this ) {
6812 if (focusTraversalKeys == null) {
6813 initializeFocusTraversalKeys();
6814 }
6815
6816 if (keystrokes != null) {
6817 for (Iterator iter = keystrokes.iterator(); iter
6818 .hasNext();) {
6819 Object obj = iter.next();
6820
6821 if (obj == null) {
6822 throw new IllegalArgumentException(
6823 "cannot set null focus traversal key");
6824 }
6825
6826 // Fix for 6195828:
6827 //According to javadoc this method should throw IAE instead of ClassCastException
6828 if (!(obj instanceof AWTKeyStroke)) {
6829 throw new IllegalArgumentException(
6830 "object is expected to be AWTKeyStroke");
6831 }
6832 AWTKeyStroke keystroke = (AWTKeyStroke) obj;
6833
6834 if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
6835 throw new IllegalArgumentException(
6836 "focus traversal keys cannot map to KEY_TYPED events");
6837 }
6838
6839 for (int i = 0; i < focusTraversalKeys.length; i++) {
6840 if (i == id) {
6841 continue;
6842 }
6843
6844 if (getFocusTraversalKeys_NoIDCheck(i)
6845 .contains(keystroke)) {
6846 throw new IllegalArgumentException(
6847 "focus traversal keys must be unique for a Component");
6848 }
6849 }
6850 }
6851 }
6852
6853 oldKeys = focusTraversalKeys[id];
6854 focusTraversalKeys[id] = (keystrokes != null) ? Collections
6855 .unmodifiableSet(new HashSet(keystrokes)) : null;
6856 }
6857
6858 firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,
6859 keystrokes);
6860 }
6861
6862 final Set getFocusTraversalKeys_NoIDCheck(int id) {
6863 // Okay to return Set directly because it is an unmodifiable view
6864 Set keystrokes = (focusTraversalKeys != null) ? focusTraversalKeys[id]
6865 : null;
6866
6867 if (keystrokes != null) {
6868 return keystrokes;
6869 } else {
6870 Container parent = this .parent;
6871 if (parent != null) {
6872 return parent.getFocusTraversalKeys(id);
6873 } else {
6874 return KeyboardFocusManager
6875 .getCurrentKeyboardFocusManager()
6876 .getDefaultFocusTraversalKeys(id);
6877 }
6878 }
6879 }
6880
6881 /**
6882 * Returns whether the Set of focus traversal keys for the given focus
6883 * traversal operation has been explicitly defined for this Component. If
6884 * this method returns <code>false</code>, this Component is inheriting the
6885 * Set from an ancestor, or from the current KeyboardFocusManager.
6886 *
6887 * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6888 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6889 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6890 * @return <code>true</code> if the the Set of focus traversal keys for the
6891 * given focus traversal operation has been explicitly defined for
6892 * this Component; <code>false</code> otherwise.
6893 * @throws IllegalArgumentException if id is not one of
6894 * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6895 * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6896 * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6897 * @since 1.4
6898 */
6899 public boolean areFocusTraversalKeysSet(int id) {
6900 if (id < 0
6901 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6902 throw new IllegalArgumentException(
6903 "invalid focus traversal key identifier");
6904 }
6905
6906 return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
6907 }
6908
6909 /**
6910 * Sets whether focus traversal keys are enabled for this Component.
6911 * Components for which focus traversal keys are disabled receive key
6912 * events for focus traversal keys. Components for which focus traversal
6913 * keys are enabled do not see these events; instead, the events are
6914 * automatically converted to traversal operations.
6915 *
6916 * @param focusTraversalKeysEnabled whether focus traversal keys are
6917 * enabled for this Component
6918 * @see #getFocusTraversalKeysEnabled
6919 * @see #setFocusTraversalKeys
6920 * @see #getFocusTraversalKeys
6921 * @since 1.4
6922 * @beaninfo
6923 * bound: true
6924 */
6925 public void setFocusTraversalKeysEnabled(
6926 boolean focusTraversalKeysEnabled) {
6927 boolean oldFocusTraversalKeysEnabled;
6928 synchronized (this ) {
6929 oldFocusTraversalKeysEnabled = this .focusTraversalKeysEnabled;
6930 this .focusTraversalKeysEnabled = focusTraversalKeysEnabled;
6931 }
6932 firePropertyChange("focusTraversalKeysEnabled",
6933 oldFocusTraversalKeysEnabled, focusTraversalKeysEnabled);
6934 }
6935
6936 /**
6937 * Returns whether focus traversal keys are enabled for this Component.
6938 * Components for which focus traversal keys are disabled receive key
6939 * events for focus traversal keys. Components for which focus traversal
6940 * keys are enabled do not see these events; instead, the events are
6941 * automatically converted to traversal operations.
6942 *
6943 * @return whether focus traversal keys are enabled for this Component
6944 * @see #setFocusTraversalKeysEnabled
6945 * @see #setFocusTraversalKeys
6946 * @see #getFocusTraversalKeys
6947 * @since 1.4
6948 */
6949 public boolean getFocusTraversalKeysEnabled() {
6950 return focusTraversalKeysEnabled;
6951 }
6952
6953 /**
6954 * Requests that this Component get the input focus, and that this
6955 * Component's top-level ancestor become the focused Window. This
6956 * component must be displayable, focusable, visible and all of
6957 * its ancestors (with the exception of the top-level Window) must
6958 * be visible for the request to be granted. Every effort will be
6959 * made to honor the request; however, in some cases it may be
6960 * impossible to do so. Developers must never assume that this
6961 * Component is the focus owner until this Component receives a
6962 * FOCUS_GAINED event. If this request is denied because this
6963 * Component's top-level Window cannot become the focused Window,
6964 * the request will be remembered and will be granted when the
6965 * Window is later focused by the user.
6966 * <p>
6967 * This method cannot be used to set the focus owner to no Component at
6968 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
6969 * instead.
6970 * <p>
6971 * Because the focus behavior of this method is platform-dependent,
6972 * developers are strongly encouraged to use
6973 * <code>requestFocusInWindow</code> when possible.
6974 *
6975 * <p>Note: Not all focus transfers result from invoking this method. As
6976 * such, a component may receive focus without this or any of the other
6977 * {@code requestFocus} methods of {@code Component} being invoked.
6978 *
6979 * @see #requestFocusInWindow
6980 * @see java.awt.event.FocusEvent
6981 * @see #addFocusListener
6982 * @see #isFocusable
6983 * @see #isDisplayable
6984 * @see KeyboardFocusManager#clearGlobalFocusOwner
6985 * @since JDK1.0
6986 */
6987 public void requestFocus() {
6988 requestFocusHelper(false, true);
6989 }
6990
6991 void requestFocus(CausedFocusEvent.Cause cause) {
6992 requestFocusHelper(false, true, cause);
6993 }
6994
6995 /**
6996 * Requests that this <code>Component</code> get the input focus,
6997 * and that this <code>Component</code>'s top-level ancestor
6998 * become the focused <code>Window</code>. This component must be
6999 * displayable, focusable, visible and all of its ancestors (with
7000 * the exception of the top-level Window) must be visible for the
7001 * request to be granted. Every effort will be made to honor the
7002 * request; however, in some cases it may be impossible to do
7003 * so. Developers must never assume that this component is the
7004 * focus owner until this component receives a FOCUS_GAINED
7005 * event. If this request is denied because this component's
7006 * top-level window cannot become the focused window, the request
7007 * will be remembered and will be granted when the window is later
7008 * focused by the user.
7009 * <p>
7010 * This method returns a boolean value. If <code>false</code> is returned,
7011 * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7012 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7013 * extraordinary event, such as disposal of the component's peer, occurs
7014 * before the request can be granted by the native windowing system. Again,
7015 * while a return value of <code>true</code> indicates that the request is
7016 * likely to succeed, developers must never assume that this component is
7017 * the focus owner until this component receives a FOCUS_GAINED event.
7018 * <p>
7019 * This method cannot be used to set the focus owner to no component at
7020 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
7021 * instead.
7022 * <p>
7023 * Because the focus behavior of this method is platform-dependent,
7024 * developers are strongly encouraged to use
7025 * <code>requestFocusInWindow</code> when possible.
7026 * <p>
7027 * Every effort will be made to ensure that <code>FocusEvent</code>s
7028 * generated as a
7029 * result of this request will have the specified temporary value. However,
7030 * because specifying an arbitrary temporary state may not be implementable
7031 * on all native windowing systems, correct behavior for this method can be
7032 * guaranteed only for lightweight <code>Component</code>s.
7033 * This method is not intended
7034 * for general use, but exists instead as a hook for lightweight component
7035 * libraries, such as Swing.
7036 *
7037 * <p>Note: Not all focus transfers result from invoking this method. As
7038 * such, a component may receive focus without this or any of the other
7039 * {@code requestFocus} methods of {@code Component} being invoked.
7040 *
7041 * @param temporary true if the focus change is temporary,
7042 * such as when the window loses the focus; for
7043 * more information on temporary focus changes see the
7044 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7045 * @return <code>false</code> if the focus change request is guaranteed to
7046 * fail; <code>true</code> if it is likely to succeed
7047 * @see java.awt.event.FocusEvent
7048 * @see #addFocusListener
7049 * @see #isFocusable
7050 * @see #isDisplayable
7051 * @see KeyboardFocusManager#clearGlobalFocusOwner
7052 * @since 1.4
7053 */
7054 protected boolean requestFocus(boolean temporary) {
7055 return requestFocusHelper(temporary, true);
7056 }
7057
7058 boolean requestFocus(boolean temporary, CausedFocusEvent.Cause cause) {
7059 return requestFocusHelper(temporary, true, cause);
7060 }
7061
7062 /**
7063 * Requests that this Component get the input focus, if this
7064 * Component's top-level ancestor is already the focused
7065 * Window. This component must be displayable, focusable, visible
7066 * and all of its ancestors (with the exception of the top-level
7067 * Window) must be visible for the request to be granted. Every
7068 * effort will be made to honor the request; however, in some
7069 * cases it may be impossible to do so. Developers must never
7070 * assume that this Component is the focus owner until this
7071 * Component receives a FOCUS_GAINED event.
7072 * <p>
7073 * This method returns a boolean value. If <code>false</code> is returned,
7074 * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7075 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7076 * extraordinary event, such as disposal of the Component's peer, occurs
7077 * before the request can be granted by the native windowing system. Again,
7078 * while a return value of <code>true</code> indicates that the request is
7079 * likely to succeed, developers must never assume that this Component is
7080 * the focus owner until this Component receives a FOCUS_GAINED event.
7081 * <p>
7082 * This method cannot be used to set the focus owner to no Component at
7083 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
7084 * instead.
7085 * <p>
7086 * The focus behavior of this method can be implemented uniformly across
7087 * platforms, and thus developers are strongly encouraged to use this
7088 * method over <code>requestFocus</code> when possible. Code which relies
7089 * on <code>requestFocus</code> may exhibit different focus behavior on
7090 * different platforms.
7091 *
7092 * <p>Note: Not all focus transfers result from invoking this method. As
7093 * such, a component may receive focus without this or any of the other
7094 * {@code requestFocus} methods of {@code Component} being invoked.
7095 *
7096 * @return <code>false</code> if the focus change request is guaranteed to
7097 * fail; <code>true</code> if it is likely to succeed
7098 * @see #requestFocus
7099 * @see java.awt.event.FocusEvent
7100 * @see #addFocusListener
7101 * @see #isFocusable
7102 * @see #isDisplayable
7103 * @see KeyboardFocusManager#clearGlobalFocusOwner
7104 * @since 1.4
7105 */
7106 public boolean requestFocusInWindow() {
7107 return requestFocusHelper(false, false);
7108 }
7109
7110 boolean requestFocusInWindow(CausedFocusEvent.Cause cause) {
7111 return requestFocusHelper(false, false, cause);
7112 }
7113
7114 /**
7115 * Requests that this <code>Component</code> get the input focus,
7116 * if this <code>Component</code>'s top-level ancestor is already
7117 * the focused <code>Window</code>. This component must be
7118 * displayable, focusable, visible and all of its ancestors (with
7119 * the exception of the top-level Window) must be visible for the
7120 * request to be granted. Every effort will be made to honor the
7121 * request; however, in some cases it may be impossible to do
7122 * so. Developers must never assume that this component is the
7123 * focus owner until this component receives a FOCUS_GAINED event.
7124 * <p>
7125 * This method returns a boolean value. If <code>false</code> is returned,
7126 * the request is <b>guaranteed to fail</b>. If <code>true</code> is
7127 * returned, the request will succeed <b>unless</b> it is vetoed, or an
7128 * extraordinary event, such as disposal of the component's peer, occurs
7129 * before the request can be granted by the native windowing system. Again,
7130 * while a return value of <code>true</code> indicates that the request is
7131 * likely to succeed, developers must never assume that this component is
7132 * the focus owner until this component receives a FOCUS_GAINED event.
7133 * <p>
7134 * This method cannot be used to set the focus owner to no component at
7135 * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
7136 * instead.
7137 * <p>
7138 * The focus behavior of this method can be implemented uniformly across
7139 * platforms, and thus developers are strongly encouraged to use this
7140 * method over <code>requestFocus</code> when possible. Code which relies
7141 * on <code>requestFocus</code> may exhibit different focus behavior on
7142 * different platforms.
7143 * <p>
7144 * Every effort will be made to ensure that <code>FocusEvent</code>s
7145 * generated as a
7146 * result of this request will have the specified temporary value. However,
7147 * because specifying an arbitrary temporary state may not be implementable
7148 * on all native windowing systems, correct behavior for this method can be
7149 * guaranteed only for lightweight components. This method is not intended
7150 * for general use, but exists instead as a hook for lightweight component
7151 * libraries, such as Swing.
7152 *
7153 * <p>Note: Not all focus transfers result from invoking this method. As
7154 * such, a component may receive focus without this or any of the other
7155 * {@code requestFocus} methods of {@code Component} being invoked.
7156 *
7157 * @param temporary true if the focus change is temporary,
7158 * such as when the window loses the focus; for
7159 * more information on temporary focus changes see the
7160 *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
7161 * @return <code>false</code> if the focus change request is guaranteed to
7162 * fail; <code>true</code> if it is likely to succeed
7163 * @see #requestFocus
7164 * @see java.awt.event.FocusEvent
7165 * @see #addFocusListener
7166 * @see #isFocusable
7167 * @see #isDisplayable
7168 * @see KeyboardFocusManager#clearGlobalFocusOwner
7169 * @since 1.4
7170 */
7171 protected boolean requestFocusInWindow(boolean temporary) {
7172 return requestFocusHelper(temporary, false);
7173 }
7174
7175 boolean requestFocusInWindow(boolean temporary,
7176 CausedFocusEvent.Cause cause) {
7177 return requestFocusHelper(temporary, false, cause);
7178 }
7179
7180 final boolean requestFocusHelper(boolean temporary,
7181 boolean focusedWindowChangeAllowed) {
7182 return requestFocusHelper(temporary,
7183 focusedWindowChangeAllowed,
7184 CausedFocusEvent.Cause.UNKNOWN);
7185 }
7186
7187 final boolean requestFocusHelper(boolean temporary,
7188 boolean focusedWindowChangeAllowed,
7189 CausedFocusEvent.Cause cause) {
7190 if (!isRequestFocusAccepted(temporary,
7191 focusedWindowChangeAllowed, cause)) {
7192 focusLog.finest("requestFocus is not accepted");
7193 return false;
7194 }
7195
7196 // Update most-recent map
7197 KeyboardFocusManager.setMostRecentFocusOwner(this );
7198
7199 Component window = this ;
7200 while ((window != null) && !(window instanceof Window)) {
7201 if (!window.isVisible()) {
7202 focusLog.finest("component is recurively invisible");
7203 return false;
7204 }
7205 window = window.parent;
7206 }
7207
7208 ComponentPeer peer = this .peer;
7209 Component heavyweight = (peer instanceof LightweightPeer) ? getNativeContainer()
7210 : this ;
7211 if (heavyweight == null || !heavyweight.isVisible()) {
7212 focusLog
7213 .finest("Component is not a part of visible hierarchy");
7214 return false;
7215 }
7216 peer = heavyweight.peer;
7217 if (peer == null) {
7218 focusLog.finest("Peer is null");
7219 return false;
7220 }
7221
7222 // Focus this Component
7223 long time = EventQueue.getMostRecentEventTime();
7224 boolean success = peer.requestFocus(this , temporary,
7225 focusedWindowChangeAllowed, time, cause);
7226 if (!success) {
7227 KeyboardFocusManager.getCurrentKeyboardFocusManager(
7228 appContext).dequeueKeyEvents(time, this );
7229 focusLog.finest("Peer request failed");
7230 } else {
7231 if (focusLog.isLoggable(Level.FINEST))
7232 focusLog.finest("Pass for " + this );
7233 }
7234 return success;
7235 }
7236
7237 private boolean isRequestFocusAccepted(boolean temporary,
7238 boolean focusedWindowChangeAllowed,
7239 CausedFocusEvent.Cause cause) {
7240 if (!isFocusable() || !isVisible()) {
7241 focusLog.finest("Not focusable or not visible");
7242 return false;
7243 }
7244
7245 ComponentPeer peer = this .peer;
7246 if (peer == null) {
7247 focusLog.finest("peer is null");
7248 return false;
7249 }
7250
7251 Window window = getContainingWindow();
7252 if (window == null || !((Window) window).isFocusableWindow()) {
7253 focusLog.finest("Component doesn't have toplevel");
7254 return false;
7255 }
7256
7257 // We have passed all regular checks for focus request,
7258 // now let's call RequestFocusController and see what it says.
7259 Component focusOwner = KeyboardFocusManager
7260 .getMostRecentFocusOwner(window);
7261 if (focusOwner == null) {
7262 // sometimes most recent focus owner may be null, but focus owner is not
7263 // e.g. we reset most recent focus owner if user removes focus owner
7264 focusOwner = KeyboardFocusManager
7265 .getCurrentKeyboardFocusManager().getFocusOwner();
7266 if (focusOwner != null
7267 && getContainingWindow(focusOwner) != window) {
7268 focusOwner = null;
7269 }
7270 }
7271
7272 if (focusOwner == this || focusOwner == null) {
7273 // Controller is supposed to verify focus transfers and for this it
7274 // should know both from and to components. And it shouldn't verify
7275 // transfers from when these components are equal.
7276 focusLog.finest("focus owner is null or this");
7277 return true;
7278 }
7279
7280 if (CausedFocusEvent.Cause.ACTIVATION == cause) {
7281 // we shouldn't call RequestFocusController in case we are
7282 // in activation. We do request focus on component which
7283 // has got temporary focus lost and then on component which is
7284 // most recent focus owner. But most recent focus owner can be
7285 // changed by requestFocsuXXX() call only, so this transfer has
7286 // been already approved.
7287 focusLog.finest("cause is activation");
7288 return true;
7289 }
7290
7291 boolean ret = Component.requestFocusController
7292 .acceptRequestFocus(focusOwner, this , temporary,
7293 focusedWindowChangeAllowed, cause);
7294 if (focusLog.isLoggable(Level.FINEST)) {
7295 focusLog.log(Level.FINEST,
7296 "RequestFocusController returns {0}", ret);
7297 }
7298
7299 return ret;
7300 }
7301
7302 private static RequestFocusController requestFocusController = new DummyRequestFocusController();
7303
7304 // Swing access this method through reflection to implement InputVerifier's functionality.
7305 // Perhaps, we should make this method public (later ;)
7306 private static class DummyRequestFocusController implements
7307 RequestFocusController {
7308 public boolean acceptRequestFocus(Component from, Component to,
7309 boolean temporary, boolean focusedWindowChangeAllowed,
7310 CausedFocusEvent.Cause cause) {
7311 return true;
7312 }
7313 };
7314
7315 synchronized static void setRequestFocusController(
7316 RequestFocusController requestController) {
7317 if (requestController == null) {
7318 requestFocusController = new DummyRequestFocusController();
7319 } else {
7320 requestFocusController = requestController;
7321 }
7322 }
7323
7324 private void autoTransferFocus(boolean clearOnFailure) {
7325 Component toTest = KeyboardFocusManager
7326 .getCurrentKeyboardFocusManager().getFocusOwner();
7327 if (toTest != this ) {
7328 if (toTest != null) {
7329 toTest.autoTransferFocus(clearOnFailure);
7330 }
7331 return;
7332 }
7333
7334 // Check if there are pending focus requests. We shouldn't do
7335 // auto-transfer if user has already took care of this
7336 // component becoming ineligible to hold focus.
7337 if (!KeyboardFocusManager.isAutoFocusTransferEnabled()) {
7338 return;
7339 }
7340
7341 // the following code will execute only if this Component is the focus
7342 // owner
7343
7344 if (!(isDisplayable() && isVisible() && isEnabled() && isFocusable())) {
7345 doAutoTransfer(clearOnFailure);
7346 return;
7347 }
7348
7349 toTest = getParent();
7350
7351 while (toTest != null && !(toTest instanceof Window)) {
7352 if (!(toTest.isDisplayable() && toTest.isVisible() && (toTest
7353 .isEnabled() || toTest.isLightweight()))) {
7354 doAutoTransfer(clearOnFailure);
7355 return;
7356 }
7357 toTest = toTest.getParent();
7358 }
7359 }
7360
7361 private void doAutoTransfer(boolean clearOnFailure) {
7362 if (focusLog.isLoggable(Level.FINER)) {
7363 focusLog.log(Level.FINER, "this = " + this
7364 + ", clearOnFailure = " + clearOnFailure);
7365 }
7366 if (clearOnFailure) {
7367 if (!nextFocusHelper()) {
7368 if (focusLog.isLoggable(Level.FINER)) {
7369 focusLog.log(Level.FINER,
7370 "clear global focus owner");
7371 }
7372 KeyboardFocusManager.getCurrentKeyboardFocusManager()
7373 .clearGlobalFocusOwner();
7374 }
7375 } else {
7376 transferFocus();
7377 }
7378 }
7379
7380 /**
7381 * Transfers the focus to the next component, as though this Component were
7382 * the focus owner.
7383 * @see #requestFocus()
7384 * @since JDK1.1
7385 */
7386 public void transferFocus() {
7387 nextFocus();
7388 }
7389
7390 /**
7391 * Returns the Container which is the focus cycle root of this Component's
7392 * focus traversal cycle. Each focus traversal cycle has only a single
7393 * focus cycle root and each Component which is not a Container belongs to
7394 * only a single focus traversal cycle. Containers which are focus cycle
7395 * roots belong to two cycles: one rooted at the Container itself, and one
7396 * rooted at the Container's nearest focus-cycle-root ancestor. For such
7397 * Containers, this method will return the Container's nearest focus-cycle-
7398 * root ancestor.
7399 *
7400 * @return this Component's nearest focus-cycle-root ancestor
7401 * @see Container#isFocusCycleRoot()
7402 * @since 1.4
7403 */
7404 public Container getFocusCycleRootAncestor() {
7405 Container rootAncestor = this .parent;
7406 while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
7407 rootAncestor = rootAncestor.parent;
7408 }
7409 return rootAncestor;
7410 }
7411
7412 /**
7413 * Returns whether the specified Container is the focus cycle root of this
7414 * Component's focus traversal cycle. Each focus traversal cycle has only
7415 * a single focus cycle root and each Component which is not a Container
7416 * belongs to only a single focus traversal cycle.
7417 *
7418 * @param container the Container to be tested
7419 * @return <code>true</code> if the specified Container is a focus-cycle-
7420 * root of this Component; <code>false</code> otherwise
7421 * @see Container#isFocusCycleRoot()
7422 * @since 1.4
7423 */
7424 public boolean isFocusCycleRoot(Container container) {
7425 Container rootAncestor = getFocusCycleRootAncestor();
7426 return (rootAncestor == container);
7427 }
7428
7429 /**
7430 * @deprecated As of JDK version 1.1,
7431 * replaced by transferFocus().
7432 */
7433 @Deprecated
7434 public void nextFocus() {
7435 nextFocusHelper();
7436 }
7437
7438 private boolean nextFocusHelper() {
7439 Component toFocus = preNextFocusHelper();
7440 if (focusLog.isLoggable(Level.FINER)) {
7441 focusLog.log(Level.FINER, "toFocus = " + toFocus);
7442 }
7443 if (isFocusOwner() && toFocus == this ) {
7444 return false;
7445 }
7446 return postNextFocusHelper(toFocus,
7447 CausedFocusEvent.Cause.TRAVERSAL_FORWARD);
7448 }
7449
7450 Container getTraversalRoot() {
7451 return getFocusCycleRootAncestor();
7452 }
7453
7454 final Component preNextFocusHelper() {
7455 Container rootAncestor = getTraversalRoot();
7456 Component comp = this ;
7457 while (rootAncestor != null
7458 && !(rootAncestor.isShowing()
7459 && rootAncestor.isFocusable() && rootAncestor
7460 .isEnabled())) {
7461 comp = rootAncestor;
7462 rootAncestor = comp.getFocusCycleRootAncestor();
7463 }
7464 if (focusLog.isLoggable(Level.FINER)) {
7465 focusLog.log(Level.FINER, "comp = " + comp + ", root = "
7466 + rootAncestor);
7467 }
7468 if (rootAncestor != null) {
7469 FocusTraversalPolicy policy = rootAncestor
7470 .getFocusTraversalPolicy();
7471 Component toFocus = policy.getComponentAfter(rootAncestor,
7472 comp);
7473 if (focusLog.isLoggable(Level.FINER)) {
7474 focusLog.log(Level.FINER, "component after is "
7475 + toFocus);
7476 }
7477 if (toFocus == null) {
7478 toFocus = policy.getDefaultComponent(rootAncestor);
7479 if (focusLog.isLoggable(Level.FINER)) {
7480 focusLog.log(Level.FINER, "default component is "
7481 + toFocus);
7482 }
7483 }
7484 if (toFocus == null) {
7485 Applet applet = EmbeddedFrame
7486 .getAppletIfAncestorOf(this );
7487 if (applet != null) {
7488 toFocus = applet;
7489 }
7490 }
7491 return toFocus;
7492 }
7493 return null;
7494 }
7495
7496 static boolean postNextFocusHelper(Component toFocus,
7497 CausedFocusEvent.Cause cause) {
7498 if (toFocus != null) {
7499 if (focusLog.isLoggable(Level.FINER))
7500 focusLog.finer("Next component " + toFocus);
7501 boolean res = toFocus.requestFocusInWindow(cause);
7502 if (focusLog.isLoggable(Level.FINER))
7503 focusLog.finer("Request focus returned " + res);
7504 return res;
7505 }
7506 return false;
7507 }
7508
7509 /**
7510 * Transfers the focus to the previous component, as though this Component
7511 * were the focus owner.
7512 * @see #requestFocus()
7513 * @since 1.4
7514 */
7515 public void transferFocusBackward() {
7516 Container rootAncestor = getTraversalRoot();
7517 Component comp = this ;
7518 while (rootAncestor != null
7519 && !(rootAncestor.isShowing()
7520 && rootAncestor.isFocusable() && rootAncestor
7521 .isEnabled())) {
7522 comp = rootAncestor;
7523 rootAncestor = comp.getFocusCycleRootAncestor();
7524 }
7525 if (rootAncestor != null) {
7526 FocusTraversalPolicy policy = rootAncestor
7527 .getFocusTraversalPolicy();
7528 Component toFocus = policy.getComponentBefore(rootAncestor,
7529 comp);
7530 if (toFocus == null) {
7531 toFocus = policy.getDefaultComponent(rootAncestor);
7532 }
7533 if (toFocus != null) {
7534 toFocus
7535 .requestFocusInWindow(CausedFocusEvent.Cause.TRAVERSAL_BACKWARD);
7536 }
7537 }
7538 }
7539
7540 /**
7541 * Transfers the focus up one focus traversal cycle. Typically, the focus
7542 * owner is set to this Component's focus cycle root, and the current focus
7543 * cycle root is set to the new focus owner's focus cycle root. If,
7544 * however, this Component's focus cycle root is a Window, then the focus
7545 * owner is set to the focus cycle root's default Component to focus, and
7546 * the current focus cycle root is unchanged.
7547 *
7548 * @see #requestFocus()
7549 * @see Container#isFocusCycleRoot()
7550 * @see Container#setFocusCycleRoot(boolean)
7551 * @since 1.4
7552 */
7553 public void transferFocusUpCycle() {
7554 Container rootAncestor;
7555 for (rootAncestor = getFocusCycleRootAncestor(); rootAncestor != null
7556 && !(rootAncestor.isShowing()
7557 && rootAncestor.isFocusable() && rootAncestor
7558 .isEnabled()); rootAncestor = rootAncestor
7559 .getFocusCycleRootAncestor()) {
7560 }
7561
7562 if (rootAncestor != null) {
7563 Container rootAncestorRootAncestor = rootAncestor
7564 .getFocusCycleRootAncestor();
7565 KeyboardFocusManager
7566 .getCurrentKeyboardFocusManager()
7567 .setGlobalCurrentFocusCycleRoot(
7568 (rootAncestorRootAncestor != null) ? rootAncestorRootAncestor
7569 : rootAncestor);
7570 rootAncestor
7571 .requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
7572 } else {
7573 Window window = getContainingWindow();
7574
7575 if (window != null) {
7576 Component toFocus = window.getFocusTraversalPolicy()
7577 .getDefaultComponent(window);
7578 if (toFocus != null) {
7579 KeyboardFocusManager
7580 .getCurrentKeyboardFocusManager()
7581 .setGlobalCurrentFocusCycleRoot(window);
7582 toFocus
7583 .requestFocus(CausedFocusEvent.Cause.TRAVERSAL_UP);
7584 }
7585 }
7586 }
7587 }
7588
7589 /**
7590 * Returns <code>true</code> if this <code>Component</code> is the
7591 * focus owner. This method is obsolete, and has been replaced by
7592 * <code>isFocusOwner()</code>.
7593 *
7594 * @return <code>true</code> if this <code>Component</code> is the
7595 * focus owner; <code>false</code> otherwise
7596 * @since 1.2
7597 */
7598 public boolean hasFocus() {
7599 return (KeyboardFocusManager.getCurrentKeyboardFocusManager()
7600 .getFocusOwner() == this );
7601 }
7602
7603 /**
7604 * Returns <code>true</code> if this <code>Component</code> is the
7605 * focus owner.
7606 *
7607 * @return <code>true</code> if this <code>Component</code> is the
7608 * focus owner; <code>false</code> otherwise
7609 * @since 1.4
7610 */
7611 public boolean isFocusOwner() {
7612 return hasFocus();
7613 }
7614
7615 /**
7616 * Adds the specified popup menu to the component.
7617 * @param popup the popup menu to be added to the component.
7618 * @see #remove(MenuComponent)
7619 * @exception NullPointerException if {@code popup} is {@code null}
7620 * @since JDK1.1
7621 */
7622 public void add(PopupMenu popup) {
7623 synchronized (getTreeLock()) {
7624 if (popup.parent != null) {
7625 popup.parent.remove(popup);
7626 }
7627 if (popups == null) {
7628 popups = new Vector();
7629 }
7630 popups.addElement(popup);
7631 popup.parent = this ;
7632
7633 if (peer != null) {
7634 if (popup.peer == null) {
7635 popup.addNotify();
7636 }
7637 }
7638 }
7639 }
7640
7641 /**
7642 * Removes the specified popup menu from the component.
7643 * @param popup the popup menu to be removed
7644 * @see #add(PopupMenu)
7645 * @since JDK1.1
7646 */
7647 public void remove(MenuComponent popup) {
7648 synchronized (getTreeLock()) {
7649 if (popups == null) {
7650 return;
7651 }
7652 int index = popups.indexOf(popup);
7653 if (index >= 0) {
7654 PopupMenu pmenu = (PopupMenu) popup;
7655 if (pmenu.peer != null) {
7656 pmenu.removeNotify();
7657 }
7658 pmenu.parent = null;
7659 popups.removeElementAt(index);
7660 if (popups.size() == 0) {
7661 popups = null;
7662 }
7663 }
7664 }
7665 }
7666
7667 /**
7668 * Returns a string representing the state of this component. This
7669 * method is intended to be used only for debugging purposes, and the
7670 * content and format of the returned string may vary between
7671 * implementations. The returned string may be empty but may not be
7672 * <code>null</code>.
7673 *
7674 * @return a string representation of this component's state
7675 * @since JDK1.0
7676 */
7677 protected String paramString() {
7678 String this Name = getName();
7679 String str = (this Name != null ? this Name : "") + "," + x + ","
7680 + y + "," + width + "x" + height;
7681 if (!valid) {
7682 str += ",invalid";
7683 }
7684 if (!visible) {
7685 str += ",hidden";
7686 }
7687 if (!enabled) {
7688 str += ",disabled";
7689 }
7690 return str;
7691 }
7692
7693 /**
7694 * Returns a string representation of this component and its values.
7695 * @return a string representation of this component
7696 * @since JDK1.0
7697 */
7698 public String toString() {
7699 return getClass().getName() + "[" + paramString() + "]";
7700 }
7701
7702 /**
7703 * Prints a listing of this component to the standard system output
7704 * stream <code>System.out</code>.
7705 * @see java.lang.System#out
7706 * @since JDK1.0
7707 */
7708 public void list() {
7709 list(System.out, 0);
7710 }
7711
7712 /**
7713 * Prints a listing of this component to the specified output
7714 * stream.
7715 * @param out a print stream
7716 * @since JDK1.0
7717 */
7718 public void list(PrintStream out) {
7719 list(out, 0);
7720 }
7721
7722 /**
7723 * Prints out a list, starting at the specified indentation, to the
7724 * specified print stream.
7725 * @param out a print stream
7726 * @param indent number of spaces to indent
7727 * @see java.io.PrintStream#println(java.lang.Object)
7728 * @since JDK1.0
7729 */
7730 public void list(PrintStream out, int indent) {
7731 for (int i = 0; i < indent; i++) {
7732 out.print(" ");
7733 }
7734 out.println(this );
7735 }
7736
7737 /**
7738 * Prints a listing to the specified print writer.
7739 * @param out the print writer to print to
7740 * @since JDK1.1
7741 */
7742 public void list(PrintWriter out) {
7743 list(out, 0);
7744 }
7745
7746 /**
7747 * Prints out a list, starting at the specified indentation, to
7748 * the specified print writer.
7749 * @param out the print writer to print to
7750 * @param indent the number of spaces to indent
7751 * @see java.io.PrintStream#println(java.lang.Object)
7752 * @since JDK1.1
7753 */
7754 public void list(PrintWriter out, int indent) {
7755 for (int i = 0; i < indent; i++) {
7756 out.print(" ");
7757 }
7758 out.println(this );
7759 }
7760
7761 /*
7762 * Fetches the native container somewhere higher up in the component
7763 * tree that contains this component.
7764 */
7765 Container getNativeContainer() {
7766 Container p = parent;
7767 while (p != null && p.peer instanceof LightweightPeer) {
7768 p = p.getParent();
7769 }
7770 return p;
7771 }
7772
7773 /**
7774 * Adds a PropertyChangeListener to the listener list. The listener is
7775 * registered for all bound properties of this class, including the
7776 * following:
7777 * <ul>
7778 * <li>this Component's font ("font")</li>
7779 * <li>this Component's background color ("background")</li>
7780 * <li>this Component's foreground color ("foreground")</li>
7781 * <li>this Component's focusability ("focusable")</li>
7782 * <li>this Component's focus traversal keys enabled state
7783 * ("focusTraversalKeysEnabled")</li>
7784 * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
7785 * ("forwardFocusTraversalKeys")</li>
7786 * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
7787 * ("backwardFocusTraversalKeys")</li>
7788 * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
7789 * ("upCycleFocusTraversalKeys")</li>
7790 * <li>this Component's preferred size ("preferredSize")</li>
7791 * <li>this Component's minimum size ("minimumSize")</li>
7792 * <li>this Component's maximum size ("maximumSize")</li>
7793 * <li>this Component's name ("name")</li>
7794 * </ul>
7795 * Note that if this <code>Component</code> is inheriting a bound property, then no
7796 * event will be fired in response to a change in the inherited property.
7797 * <p>
7798 * If <code>listener</code> is <code>null</code>,
7799 * no exception is thrown and no action is performed.
7800 *
7801 * @param listener the property change listener to be added
7802 *
7803 * @see #removePropertyChangeListener
7804 * @see #getPropertyChangeListeners
7805 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7806 */
7807 public synchronized void addPropertyChangeListener(
7808 PropertyChangeListener listener) {
7809 if (listener == null) {
7810 return;
7811 }
7812 if (changeSupport == null) {
7813 changeSupport = new PropertyChangeSupport(this );
7814 }
7815 changeSupport.addPropertyChangeListener(listener);
7816 }
7817
7818 /**
7819 * Removes a PropertyChangeListener from the listener list. This method
7820 * should be used to remove PropertyChangeListeners that were registered
7821 * for all bound properties of this class.
7822 * <p>
7823 * If listener is null, no exception is thrown and no action is performed.
7824 *
7825 * @param listener the PropertyChangeListener to be removed
7826 *
7827 * @see #addPropertyChangeListener
7828 * @see #getPropertyChangeListeners
7829 * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
7830 */
7831 public synchronized void removePropertyChangeListener(
7832 PropertyChangeListener listener) {
7833 if (listener == null || changeSupport == null) {
7834 return;
7835 }
7836 changeSupport.removePropertyChangeListener(listener);
7837 }
7838
7839 /**
7840 * Returns an array of all the property change listeners
7841 * registered on this component.
7842 *
7843 * @return all of this component's <code>PropertyChangeListener</code>s
7844 * or an empty array if no property change
7845 * listeners are currently registered
7846 *
7847 * @see #addPropertyChangeListener
7848 * @see #removePropertyChangeListener
7849 * @see #getPropertyChangeListeners(java.lang.String)
7850 * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
7851 * @since 1.4
7852 */
7853 public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
7854 if (changeSupport == null) {
7855 return new PropertyChangeListener[0];
7856 }
7857 return changeSupport.getPropertyChangeListeners();
7858 }
7859
7860 /**
7861 * Adds a PropertyChangeListener to the listener list for a specific
7862 * property. The specified property may be user-defined, or one of the
7863 * following:
7864 * <ul>
7865 * <li>this Component's font ("font")</li>
7866 * <li>this Component's background color ("background")</li>
7867 * <li>this Component's foreground color ("foreground")</li>
7868 * <li>this Component's focusability ("focusable")</li>
7869 * <li>this Component's focus traversal keys enabled state
7870 * ("focusTraversalKeysEnabled")</li>
7871 * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
7872 * ("forwardFocusTraversalKeys")</li>
7873 * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
7874 * ("backwardFocusTraversalKeys")</li>
7875 * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
7876 * ("upCycleFocusTraversalKeys")</li>
7877 * </ul>
7878 * Note that if this <code>Component</code> is inheriting a bound property, then no
7879 * event will be fired in response to a change in the inherited property.
7880 * <p>
7881 * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
7882 * no exception is thrown and no action is taken.
7883 *
7884 * @param propertyName one of the property names listed above
7885 * @param listener the property change listener to be added
7886 *
7887 * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7888 * @see #getPropertyChangeListeners(java.lang.String)
7889 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7890 */
7891 public synchronized void addPropertyChangeListener(
7892 String propertyName, PropertyChangeListener listener) {
7893 if (listener == null) {
7894 return;
7895 }
7896 if (changeSupport == null) {
7897 changeSupport = new PropertyChangeSupport(this );
7898 }
7899 changeSupport.addPropertyChangeListener(propertyName, listener);
7900 }
7901
7902 /**
7903 * Removes a <code>PropertyChangeListener</code> from the listener
7904 * list for a specific property. This method should be used to remove
7905 * <code>PropertyChangeListener</code>s
7906 * that were registered for a specific bound property.
7907 * <p>
7908 * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
7909 * no exception is thrown and no action is taken.
7910 *
7911 * @param propertyName a valid property name
7912 * @param listener the PropertyChangeListener to be removed
7913 *
7914 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7915 * @see #getPropertyChangeListeners(java.lang.String)
7916 * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
7917 */
7918 public synchronized void removePropertyChangeListener(
7919 String propertyName, PropertyChangeListener listener) {
7920 if (listener == null || changeSupport == null) {
7921 return;
7922 }
7923 changeSupport.removePropertyChangeListener(propertyName,
7924 listener);
7925 }
7926
7927 /**
7928 * Returns an array of all the listeners which have been associated
7929 * with the named property.
7930 *
7931 * @return all of the <code>PropertyChangeListener</code>s associated with
7932 * the named property; if no such listeners have been added or
7933 * if <code>propertyName</code> is <code>null</code>, an empty
7934 * array is returned
7935 *
7936 * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7937 * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7938 * @see #getPropertyChangeListeners
7939 * @since 1.4
7940 */
7941 public synchronized PropertyChangeListener[] getPropertyChangeListeners(
7942 String propertyName) {
7943 if (changeSupport == null) {
7944 return new PropertyChangeListener[0];
7945 }
7946 return changeSupport.getPropertyChangeListeners(propertyName);
7947 }
7948
7949 /**
7950 * Support for reporting bound property changes for Object properties.
7951 * This method can be called when a bound property has changed and it will
7952 * send the appropriate PropertyChangeEvent to any registered
7953 * PropertyChangeListeners.
7954 *
7955 * @param propertyName the property whose value has changed
7956 * @param oldValue the property's previous value
7957 * @param newValue the property's new value
7958 */
7959 protected void firePropertyChange(String propertyName,
7960 Object oldValue, Object newValue) {
7961 PropertyChangeSupport changeSupport = this .changeSupport;
7962 if (changeSupport == null
7963 || (oldValue != null && newValue != null && oldValue
7964 .equals(newValue))) {
7965 return;
7966 }
7967 changeSupport.firePropertyChange(propertyName, oldValue,
7968 newValue);
7969 }
7970
7971 /**
7972 * Support for reporting bound property changes for boolean properties.
7973 * This method can be called when a bound property has changed and it will
7974 * send the appropriate PropertyChangeEvent to any registered
7975 * PropertyChangeListeners.
7976 *
7977 * @param propertyName the property whose value has changed
7978 * @param oldValue the property's previous value
7979 * @param newValue the property's new value
7980 * @since 1.4
7981 */
7982 protected void firePropertyChange(String propertyName,
7983 boolean oldValue, boolean newValue) {
7984 PropertyChangeSupport changeSupport = this .changeSupport;
7985 if (changeSupport == null || oldValue == newValue) {
7986 return;
7987 }
7988 changeSupport.firePropertyChange(propertyName, oldValue,
7989 newValue);
7990 }
7991
7992 /**
7993 * Support for reporting bound property changes for integer properties.
7994 * This method can be called when a bound property has changed and it will
7995 * send the appropriate PropertyChangeEvent to any registered
7996 * PropertyChangeListeners.
7997 *
7998 * @param propertyName the property whose value has changed
7999 * @param oldValue the property's previous value
8000 * @param newValue the property's new value
8001 * @since 1.4
8002 */
8003 protected void firePropertyChange(String propertyName,
8004 int oldValue, int newValue) {
8005 PropertyChangeSupport changeSupport = this .changeSupport;
8006 if (changeSupport == null || oldValue == newValue) {
8007 return;
8008 }
8009 changeSupport.firePropertyChange(propertyName, oldValue,
8010 newValue);
8011 }
8012
8013 /**
8014 * Reports a bound property change.
8015 *
8016 * @param propertyName the programmatic name of the property
8017 * that was changed
8018 * @param oldValue the old value of the property (as a byte)
8019 * @param newValue the new value of the property (as a byte)
8020 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8021 * java.lang.Object)
8022 * @since 1.5
8023 */
8024 public void firePropertyChange(String propertyName, byte oldValue,
8025 byte newValue) {
8026 if (changeSupport == null || oldValue == newValue) {
8027 return;
8028 }
8029 firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte
8030 .valueOf(newValue));
8031 }
8032
8033 /**
8034 * Reports a bound property change.
8035 *
8036 * @param propertyName the programmatic name of the property
8037 * that was changed
8038 * @param oldValue the old value of the property (as a char)
8039 * @param newValue the new value of the property (as a char)
8040 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8041 * java.lang.Object)
8042 * @since 1.5
8043 */
8044 public void firePropertyChange(String propertyName, char oldValue,
8045 char newValue) {
8046 if (changeSupport == null || oldValue == newValue) {
8047 return;
8048 }
8049 firePropertyChange(propertyName, new Character(oldValue),
8050 new Character(newValue));
8051 }
8052
8053 /**
8054 * Reports a bound property change.
8055 *
8056 * @param propertyName the programmatic name of the property
8057 * that was changed
8058 * @param oldValue the old value of the property (as a short)
8059 * @param newValue the old value of the property (as a short)
8060 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8061 * java.lang.Object)
8062 * @since 1.5
8063 */
8064 public void firePropertyChange(String propertyName, short oldValue,
8065 short newValue) {
8066 if (changeSupport == null || oldValue == newValue) {
8067 return;
8068 }
8069 firePropertyChange(propertyName, Short.valueOf(oldValue), Short
8070 .valueOf(newValue));
8071 }
8072
8073 /**
8074 * Reports a bound property change.
8075 *
8076 * @param propertyName the programmatic name of the property
8077 * that was changed
8078 * @param oldValue the old value of the property (as a long)
8079 * @param newValue the new value of the property (as a long)
8080 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8081 * java.lang.Object)
8082 * @since 1.5
8083 */
8084 public void firePropertyChange(String propertyName, long oldValue,
8085 long newValue) {
8086 if (changeSupport == null || oldValue == newValue) {
8087 return;
8088 }
8089 firePropertyChange(propertyName, Long.valueOf(oldValue), Long
8090 .valueOf(newValue));
8091 }
8092
8093 /**
8094 * Reports a bound property change.
8095 *
8096 * @param propertyName the programmatic name of the property
8097 * that was changed
8098 * @param oldValue the old value of the property (as a float)
8099 * @param newValue the new value of the property (as a float)
8100 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8101 * java.lang.Object)
8102 * @since 1.5
8103 */
8104 public void firePropertyChange(String propertyName, float oldValue,
8105 float newValue) {
8106 if (changeSupport == null || oldValue == newValue) {
8107 return;
8108 }
8109 firePropertyChange(propertyName, Float.valueOf(oldValue), Float
8110 .valueOf(newValue));
8111 }
8112
8113 /**
8114 * Reports a bound property change.
8115 *
8116 * @param propertyName the programmatic name of the property
8117 * that was changed
8118 * @param oldValue the old value of the property (as a double)
8119 * @param newValue the new value of the property (as a double)
8120 * @see #firePropertyChange(java.lang.String, java.lang.Object,
8121 * java.lang.Object)
8122 * @since 1.5
8123 */
8124 public void firePropertyChange(String propertyName,
8125 double oldValue, double newValue) {
8126 if (changeSupport == null || oldValue == newValue) {
8127 return;
8128 }
8129 firePropertyChange(propertyName, Double.valueOf(oldValue),
8130 Double.valueOf(newValue));
8131 }
8132
8133 // Serialization support.
8134
8135 /**
8136 * Component Serialized Data Version.
8137 *
8138 * @serial
8139 */
8140 private int componentSerializedDataVersion = 4;
8141
8142 /**
8143 * This hack is for Swing serialization. It will invoke
8144 * the Swing package private method <code>compWriteObjectNotify</code>.
8145 */
8146 private void doSwingSerialization() {
8147 Package swingPackage = Package.getPackage("javax.swing");
8148 // For Swing serialization to correctly work Swing needs to
8149 // be notified before Component does it's serialization. This
8150 // hack accomodates this.
8151 //
8152 // Swing classes MUST be loaded by the bootstrap class loader,
8153 // otherwise we don't consider them.
8154 for (Class klass = Component.this .getClass(); klass != null; klass = klass
8155 .getSuperclass()) {
8156 if (klass.getPackage() == swingPackage
8157 && klass.getClassLoader() == null) {
8158 final Class swingClass = klass;
8159 // Find the first override of the compWriteObjectNotify method
8160 Method[] methods = (Method[]) AccessController
8161 .doPrivileged(new PrivilegedAction() {
8162 public Object run() {
8163 return swingClass.getDeclaredMethods();
8164 }
8165 });
8166 for (int counter = methods.length - 1; counter >= 0; counter--) {
8167 final Method method = methods[counter];
8168 if (method.getName()
8169 .equals("compWriteObjectNotify")) {
8170 // We found it, use doPrivileged to make it accessible
8171 // to use.
8172 AccessController
8173 .doPrivileged(new PrivilegedAction() {
8174 public Object run() {
8175 method.setAccessible(true);
8176 return null;
8177 }
8178 });
8179 // Invoke the method
8180 try {
8181 method.invoke(this , (Object[]) null);
8182 } catch (IllegalAccessException iae) {
8183 } catch (InvocationTargetException ite) {
8184 }
8185 // We're done, bail.
8186 return;
8187 }
8188 }
8189 }
8190 }
8191 }
8192
8193 /**
8194 * Writes default serializable fields to stream. Writes
8195 * a variety of serializable listeners as optional data.
8196 * The non-serializable listeners are detected and
8197 * no attempt is made to serialize them.
8198 *
8199 * @param s the <code>ObjectOutputStream</code> to write
8200 * @serialData <code>null</code> terminated sequence of
8201 * 0 or more pairs; the pair consists of a <code>String</code>
8202 * and an <code>Object</code>; the <code>String</code> indicates
8203 * the type of object and is one of the following (as of 1.4):
8204 * <code>componentListenerK</code> indicating an
8205 * <code>ComponentListener</code> object;
8206 * <code>focusListenerK</code> indicating an
8207 * <code>FocusListener</code> object;
8208 * <code>keyListenerK</code> indicating an
8209 * <code>KeyListener</code> object;
8210 * <code>mouseListenerK</code> indicating an
8211 * <code>MouseListener</code> object;
8212 * <code>mouseMotionListenerK</code> indicating an
8213 * <code>MouseMotionListener</code> object;
8214 * <code>inputMethodListenerK</code> indicating an
8215 * <code>InputMethodListener</code> object;
8216 * <code>hierarchyListenerK</code> indicating an
8217 * <code>HierarchyListener</code> object;
8218 * <code>hierarchyBoundsListenerK</code> indicating an
8219 * <code>HierarchyBoundsListener</code> object;
8220 * <code>mouseWheelListenerK</code> indicating an
8221 * <code>MouseWheelListener</code> object
8222 * @serialData an optional <code>ComponentOrientation</code>
8223 * (after <code>inputMethodListener</code>, as of 1.2)
8224 *
8225 * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
8226 * @see #componentListenerK
8227 * @see #focusListenerK
8228 * @see #keyListenerK
8229 * @see #mouseListenerK
8230 * @see #mouseMotionListenerK
8231 * @see #inputMethodListenerK
8232 * @see #hierarchyListenerK
8233 * @see #hierarchyBoundsListenerK
8234 * @see #mouseWheelListenerK
8235 * @see #readObject(ObjectInputStream)
8236 */
8237 private void writeObject(ObjectOutputStream s) throws IOException {
8238 doSwingSerialization();
8239
8240 s.defaultWriteObject();
8241
8242 AWTEventMulticaster.save(s, componentListenerK,
8243 componentListener);
8244 AWTEventMulticaster.save(s, focusListenerK, focusListener);
8245 AWTEventMulticaster.save(s, keyListenerK, keyListener);
8246 AWTEventMulticaster.save(s, mouseListenerK, mouseListener);
8247 AWTEventMulticaster.save(s, mouseMotionListenerK,
8248 mouseMotionListener);
8249 AWTEventMulticaster.save(s, inputMethodListenerK,
8250 inputMethodListener);
8251
8252 s.writeObject(null);
8253 s.writeObject(componentOrientation);
8254
8255 AWTEventMulticaster.save(s, hierarchyListenerK,
8256 hierarchyListener);
8257 AWTEventMulticaster.save(s, hierarchyBoundsListenerK,
8258 hierarchyBoundsListener);
8259 s.writeObject(null);
8260
8261 AWTEventMulticaster.save(s, mouseWheelListenerK,
8262 mouseWheelListener);
8263 s.writeObject(null);
8264
8265 }
8266
8267 /**
8268 * Reads the <code>ObjectInputStream</code> and if it isn't
8269 * <code>null</code> adds a listener to receive a variety
8270 * of events fired by the component.
8271 * Unrecognized keys or values will be ignored.
8272 *
8273 * @param s the <code>ObjectInputStream</code> to read
8274 * @see #writeObject(ObjectOutputStream)
8275 */
8276 private void readObject(ObjectInputStream s)
8277 throws ClassNotFoundException, IOException {
8278 s.defaultReadObject();
8279
8280 appContext = AppContext.getAppContext();
8281 coalescingEnabled = checkCoalescing();
8282 if (componentSerializedDataVersion < 4) {
8283 // These fields are non-transient and rely on default
8284 // serialization. However, the default values are insufficient,
8285 // so we need to set them explicitly for object data streams prior
8286 // to 1.4.
8287 focusable = true;
8288 isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
8289 initializeFocusTraversalKeys();
8290 focusTraversalKeysEnabled = true;
8291 }
8292
8293 Object keyOrNull;
8294 while (null != (keyOrNull = s.readObject())) {
8295 String key = ((String) keyOrNull).intern();
8296
8297 if (componentListenerK == key)
8298 addComponentListener((ComponentListener) (s
8299 .readObject()));
8300
8301 else if (focusListenerK == key)
8302 addFocusListener((FocusListener) (s.readObject()));
8303
8304 else if (keyListenerK == key)
8305 addKeyListener((KeyListener) (s.readObject()));
8306
8307 else if (mouseListenerK == key)
8308 addMouseListener((MouseListener) (s.readObject()));
8309
8310 else if (mouseMotionListenerK == key)
8311 addMouseMotionListener((MouseMotionListener) (s
8312 .readObject()));
8313
8314 else if (inputMethodListenerK == key)
8315 addInputMethodListener((InputMethodListener) (s
8316 .readObject()));
8317
8318 else
8319 // skip value for unrecognized key
8320 s.readObject();
8321
8322 }
8323
8324 // Read the component's orientation if it's present
8325 Object orient = null;
8326
8327 try {
8328 orient = s.readObject();
8329 } catch (java.io.OptionalDataException e) {
8330 // JDK 1.1 instances will not have this optional data.
8331 // e.eof will be true to indicate that there is no more
8332 // data available for this object.
8333 // If e.eof is not true, throw the exception as it
8334 // might have been caused by reasons unrelated to
8335 // componentOrientation.
8336
8337 if (!e.eof) {
8338 throw (e);
8339 }
8340 }
8341
8342 if (orient != null) {
8343 componentOrientation = (ComponentOrientation) orient;
8344 } else {
8345 componentOrientation = ComponentOrientation.UNKNOWN;
8346 }
8347
8348 try {
8349 while (null != (keyOrNull = s.readObject())) {
8350 String key = ((String) keyOrNull).intern();
8351
8352 if (hierarchyListenerK == key) {
8353 addHierarchyListener((HierarchyListener) (s
8354 .readObject()));
8355 } else if (hierarchyBoundsListenerK == key) {
8356 addHierarchyBoundsListener((HierarchyBoundsListener) (s
8357 .readObject()));
8358 } else {
8359 // skip value for unrecognized key
8360 s.readObject();
8361 }
8362 }
8363 } catch (java.io.OptionalDataException e) {
8364 // JDK 1.1/1.2 instances will not have this optional data.
8365 // e.eof will be true to indicate that there is no more
8366 // data available for this object.
8367 // If e.eof is not true, throw the exception as it
8368 // might have been caused by reasons unrelated to
8369 // hierarchy and hierarchyBounds listeners.
8370
8371 if (!e.eof) {
8372 throw (e);
8373 }
8374 }
8375
8376 try {
8377 while (null != (keyOrNull = s.readObject())) {
8378 String key = ((String) keyOrNull).intern();
8379
8380 if (mouseWheelListenerK == key) {
8381 addMouseWheelListener((MouseWheelListener) (s
8382 .readObject()));
8383 } else {
8384 // skip value for unrecognized key
8385 s.readObject();
8386 }
8387 }
8388 } catch (java.io.OptionalDataException e) {
8389 // pre-1.3 instances will not have this optional data.
8390 // e.eof will be true to indicate that there is no more
8391 // data available for this object.
8392 // If e.eof is not true, throw the exception as it
8393 // might have been caused by reasons unrelated to
8394 // mouse wheel listeners
8395
8396 if (!e.eof) {
8397 throw (e);
8398 }
8399 }
8400
8401 if (popups != null) {
8402 int npopups = popups.size();
8403 for (int i = 0; i < npopups; i++) {
8404 PopupMenu popup = (PopupMenu) popups.elementAt(i);
8405 popup.parent = this ;
8406 }
8407 }
8408 }
8409
8410 /**
8411 * Sets the language-sensitive orientation that is to be used to order
8412 * the elements or text within this component. Language-sensitive
8413 * <code>LayoutManager</code> and <code>Component</code>
8414 * subclasses will use this property to
8415 * determine how to lay out and draw components.
8416 * <p>
8417 * At construction time, a component's orientation is set to
8418 * <code>ComponentOrientation.UNKNOWN</code>,
8419 * indicating that it has not been specified
8420 * explicitly. The UNKNOWN orientation behaves the same as
8421 * <code>ComponentOrientation.LEFT_TO_RIGHT</code>.
8422 * <p>
8423 * To set the orientation of a single component, use this method.
8424 * To set the orientation of an entire component
8425 * hierarchy, use
8426 * {@link #applyComponentOrientation applyComponentOrientation}.
8427 *
8428 * @see ComponentOrientation
8429 *
8430 * @author Laura Werner, IBM
8431 * @beaninfo
8432 * bound: true
8433 */
8434 public void setComponentOrientation(ComponentOrientation o) {
8435 ComponentOrientation oldValue = componentOrientation;
8436 componentOrientation = o;
8437
8438 // This is a bound property, so report the change to
8439 // any registered listeners. (Cheap if there are none.)
8440 firePropertyChange("componentOrientation", oldValue, o);
8441
8442 // This could change the preferred size of the Component.
8443 if (valid) {
8444 invalidate();
8445 }
8446 }
8447
8448 /**
8449 * Retrieves the language-sensitive orientation that is to be used to order
8450 * the elements or text within this component. <code>LayoutManager</code>
8451 * and <code>Component</code>
8452 * subclasses that wish to respect orientation should call this method to
8453 * get the component's orientation before performing layout or drawing.
8454 *
8455 * @see ComponentOrientation
8456 *
8457 * @author Laura Werner, IBM
8458 */
8459 public ComponentOrientation getComponentOrientation() {
8460 return componentOrientation;
8461 }
8462
8463 /**
8464 * Sets the <code>ComponentOrientation</code> property of this component
8465 * and all components contained within it.
8466 *
8467 * @param orientation the new component orientation of this component and
8468 * the components contained within it.
8469 * @exception NullPointerException if <code>orientation</code> is null.
8470 * @see #setComponentOrientation
8471 * @see #getComponentOrientation
8472 * @since 1.4
8473 */
8474 public void applyComponentOrientation(
8475 ComponentOrientation orientation) {
8476 if (orientation == null) {
8477 throw new NullPointerException();
8478 }
8479 setComponentOrientation(orientation);
8480 }
8481
8482 transient NativeInLightFixer nativeInLightFixer;
8483
8484 /**
8485 * Checks that this component meets the prerequesites to be focus owner:
8486 * - it is enabled, visible, focusable
8487 * - it's parents are all enabled and showing
8488 * - top-level window is focusable
8489 * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
8490 * this component as focus owner
8491 * @since 1.5
8492 */
8493 final boolean canBeFocusOwner() {
8494 // - it is enabled, visible, focusable
8495 if (!(isEnabled() && isDisplayable() && isVisible() && isFocusable())) {
8496 return false;
8497 }
8498
8499 // - it's parents are all enabled and showing
8500 synchronized (getTreeLock()) {
8501 if (parent != null) {
8502 return parent.canContainFocusOwner(this );
8503 }
8504 }
8505 return true;
8506 }
8507
8508 /**
8509 * This odd class is to help out a native component that has been
8510 * embedded in a lightweight component. Moving lightweight
8511 * components around and changing their visibility is not seen
8512 * by the native window system. This is a feature for lightweights,
8513 * but a problem for native components that depend upon the
8514 * lightweights. An instance of this class listens to the lightweight
8515 * parents of an associated native component (the outer class).
8516 *
8517 * @author Timothy Prinzing
8518 */
8519 final class NativeInLightFixer implements ComponentListener,
8520 ContainerListener {
8521
8522 NativeInLightFixer() {
8523 lightParents = new Vector();
8524 install(parent);
8525 }
8526
8527 void install(Container parent) {
8528 lightParents.clear();
8529 Container p = parent;
8530 boolean isLwParentsVisible = true;
8531 // stash a reference to the components that are being observed so that
8532 // we can reliably remove ourself as a listener later.
8533 for (; p.peer instanceof LightweightPeer; p = p.parent) {
8534
8535 // register listeners and stash a reference
8536 p.addComponentListener(this );
8537 p.addContainerListener(this );
8538 lightParents.addElement(p);
8539 isLwParentsVisible &= p.isVisible();
8540 }
8541 // register with the native host (native parent of associated native)
8542 // to get notified if the top-level lightweight is removed.
8543 nativeHost = p;
8544 p.addContainerListener(this );
8545
8546 // kick start the fixup. Since the event isn't looked at
8547 // we can simulate movement notification.
8548 componentMoved(null);
8549 if (!isLwParentsVisible) {
8550 synchronized (getTreeLock()) {
8551 if (peer != null) {
8552 peer.hide();
8553 }
8554 }
8555 }
8556 }
8557
8558 void uninstall() {
8559 if (nativeHost != null) {
8560 removeReferences();
8561 }
8562 }
8563
8564 // --- ComponentListener -------------------------------------------
8565
8566 /**
8567 * Invoked when one of the lightweight parents has been resized.
8568 * This doesn't change the position of the native child so it
8569 * is ignored.
8570 */
8571 public void componentResized(ComponentEvent e) {
8572 }
8573
8574 /**
8575 * Invoked when one of the lightweight parents has been moved.
8576 * The native peer must be told of the new position which is
8577 * relative to the native container that is hosting the
8578 * lightweight components.
8579 */
8580 public void componentMoved(ComponentEvent e) {
8581 synchronized (getTreeLock()) {
8582 int nativeX = x;
8583 int nativeY = y;
8584 for (Component c = parent; (c != null)
8585 && (c.peer instanceof LightweightPeer); c = c.parent) {
8586
8587 nativeX += c.x;
8588 nativeY += c.y;
8589 }
8590 if (peer != null) {
8591 peer.setBounds(nativeX, nativeY, width, height,
8592 ComponentPeer.SET_LOCATION);
8593 }
8594 }
8595 }
8596
8597 /**
8598 * Invoked when a lightweight parent component has been
8599 * shown. The associated native component must also be
8600 * shown if it hasn't had an overriding hide done on it.
8601 */
8602 public void componentShown(ComponentEvent e) {
8603 if (shouldShow()) {
8604 synchronized (getTreeLock()) {
8605 if (peer != null) {
8606 peer.show();
8607 }
8608 }
8609 }
8610 }
8611
8612 /**
8613 * Invoked when one of the lightweight parents become visible.
8614 * Returns true if component and all its lightweight
8615 * parents are visible.
8616 */
8617 private boolean shouldShow() {
8618 boolean isLwParentsVisible = visible;
8619 for (int i = lightParents.size() - 1; i >= 0
8620 && isLwParentsVisible; i--) {
8621 isLwParentsVisible &= ((Container) lightParents
8622 .elementAt(i)).isVisible();
8623 }
8624 return isLwParentsVisible;
8625 }
8626
8627 /**
8628 * Invoked when component has been hidden.
8629 */
8630 public void componentHidden(ComponentEvent e) {
8631 if (visible) {
8632 synchronized (getTreeLock()) {
8633 if (peer != null) {
8634 peer.hide();
8635 }
8636 }
8637 }
8638 }
8639
8640 // --- ContainerListener ------------------------------------
8641
8642 /**
8643 * Invoked when a component has been added to a lightweight
8644 * parent. This doesn't effect the native component.
8645 */
8646 public void componentAdded(ContainerEvent e) {
8647 }
8648
8649 /**
8650 * Invoked when a lightweight parent has been removed.
8651 * This means the services of this listener are no longer
8652 * required and it should remove all references (ie
8653 * registered listeners).
8654 */
8655 public void componentRemoved(ContainerEvent e) {
8656 Component c = e.getChild();
8657 if (c == Component.this ) {
8658 removeReferences();
8659 } else {
8660 int n = lightParents.size();
8661 for (int i = 0; i < n; i++) {
8662 Container p = (Container) lightParents.elementAt(i);
8663 if (p == c) {
8664 removeReferences();
8665 break;
8666 }
8667 }
8668 }
8669 }
8670
8671 /**
8672 * Removes references to this object so it can be
8673 * garbage collected.
8674 */
8675 void removeReferences() {
8676 int n = lightParents.size();
8677 for (int i = 0; i < n; i++) {
8678 Container c = (Container) lightParents.elementAt(i);
8679 c.removeComponentListener(this );
8680 c.removeContainerListener(this );
8681 }
8682 nativeHost.removeContainerListener(this );
8683 lightParents.clear();
8684 nativeHost = null;
8685 }
8686
8687 Vector lightParents;
8688 Container nativeHost;
8689 }
8690
8691 /**
8692 * Returns the <code>Window</code> ancestor of the component.
8693 * @return Window ancestor of the component or component by itself if it is Window;
8694 * null, if component is not a part of window hierarchy
8695 */
8696 Window getContainingWindow() {
8697 return getContainingWindow(this );
8698 }
8699
8700 /**
8701 * Returns the <code>Window</code> ancestor of the component <code>comp</code>.
8702 * @return Window ancestor of the component or component by itself if it is Window;
8703 * null, if component is not a part of window hierarchy
8704 */
8705 static Window getContainingWindow(Component comp) {
8706 while (comp != null && !(comp instanceof Window)) {
8707 comp = comp.getParent();
8708 }
8709
8710 return (Window) comp;
8711 }
8712
8713 /**
8714 * Initialize JNI field and method IDs
8715 */
8716 private static native void initIDs();
8717
8718 /*
8719 * --- Accessibility Support ---
8720 *
8721 * Component will contain all of the methods in interface Accessible,
8722 * though it won't actually implement the interface - that will be up
8723 * to the individual objects which extend Component.
8724 */
8725
8726 AccessibleContext accessibleContext = null;
8727
8728 /**
8729 * Gets the <code>AccessibleContext</code> associated
8730 * with this <code>Component</code>.
8731 * The method implemented by this base
8732 * class returns null. Classes that extend <code>Component</code>
8733 * should implement this method to return the
8734 * <code>AccessibleContext</code> associated with the subclass.
8735 *
8736 *
8737 * @return the <code>AccessibleContext</code> of this
8738 * <code>Component</code>
8739 * @since 1.3
8740 */
8741 public AccessibleContext getAccessibleContext() {
8742 return accessibleContext;
8743 }
8744
8745 /**
8746 * Inner class of Component used to provide default support for
8747 * accessibility. This class is not meant to be used directly by
8748 * application developers, but is instead meant only to be
8749 * subclassed by component developers.
8750 * <p>
8751 * The class used to obtain the accessible role for this object.
8752 * @since 1.3
8753 */
8754 protected abstract class AccessibleAWTComponent extends
8755 AccessibleContext implements Serializable,
8756 AccessibleComponent {
8757
8758 private static final long serialVersionUID = 642321655757800191L;
8759
8760 /**
8761 * Though the class is abstract, this should be called by
8762 * all sub-classes.
8763 */
8764 protected AccessibleAWTComponent() {
8765 }
8766
8767 protected ComponentListener accessibleAWTComponentHandler = null;
8768 protected FocusListener accessibleAWTFocusHandler = null;
8769
8770 /**
8771 * Fire PropertyChange listener, if one is registered,
8772 * when shown/hidden..
8773 * @since 1.3
8774 */
8775 protected class AccessibleAWTComponentHandler implements
8776 ComponentListener {
8777 public void componentHidden(ComponentEvent e) {
8778 if (accessibleContext != null) {
8779 accessibleContext
8780 .firePropertyChange(
8781 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8782 AccessibleState.VISIBLE, null);
8783 }
8784 }
8785
8786 public void componentShown(ComponentEvent e) {
8787 if (accessibleContext != null) {
8788 accessibleContext
8789 .firePropertyChange(
8790 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8791 null, AccessibleState.VISIBLE);
8792 }
8793 }
8794
8795 public void componentMoved(ComponentEvent e) {
8796 }
8797
8798 public void componentResized(ComponentEvent e) {
8799 }
8800 } // inner class AccessibleAWTComponentHandler
8801
8802 /**
8803 * Fire PropertyChange listener, if one is registered,
8804 * when focus events happen
8805 * @since 1.3
8806 */
8807 protected class AccessibleAWTFocusHandler implements
8808 FocusListener {
8809 public void focusGained(FocusEvent event) {
8810 if (accessibleContext != null) {
8811 accessibleContext
8812 .firePropertyChange(
8813 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8814 null, AccessibleState.FOCUSED);
8815 }
8816 }
8817
8818 public void focusLost(FocusEvent event) {
8819 if (accessibleContext != null) {
8820 accessibleContext
8821 .firePropertyChange(
8822 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
8823 AccessibleState.FOCUSED, null);
8824 }
8825 }
8826 } // inner class AccessibleAWTFocusHandler
8827
8828 /**
8829 * Adds a <code>PropertyChangeListener</code> to the listener list.
8830 *
8831 * @param listener the property change listener to be added
8832 */
8833 public void addPropertyChangeListener(
8834 PropertyChangeListener listener) {
8835 if (accessibleAWTComponentHandler == null) {
8836 accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
8837 Component.this
8838 .addComponentListener(accessibleAWTComponentHandler);
8839 }
8840 if (accessibleAWTFocusHandler == null) {
8841 accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
8842 Component.this
8843 .addFocusListener(accessibleAWTFocusHandler);
8844 }
8845 super .addPropertyChangeListener(listener);
8846 }
8847
8848 /**
8849 * Remove a PropertyChangeListener from the listener list.
8850 * This removes a PropertyChangeListener that was registered
8851 * for all properties.
8852 *
8853 * @param listener The PropertyChangeListener to be removed
8854 */
8855 public void removePropertyChangeListener(
8856 PropertyChangeListener listener) {
8857 if (accessibleAWTComponentHandler != null) {
8858 Component.this
8859 .removeComponentListener(accessibleAWTComponentHandler);
8860 accessibleAWTComponentHandler = null;
8861 }
8862 if (accessibleAWTFocusHandler != null) {
8863 Component.this
8864 .removeFocusListener(accessibleAWTFocusHandler);
8865 accessibleAWTFocusHandler = null;
8866 }
8867 super .removePropertyChangeListener(listener);
8868 }
8869
8870 // AccessibleContext methods
8871 //
8872 /**
8873 * Gets the accessible name of this object. This should almost never
8874 * return <code>java.awt.Component.getName()</code>,
8875 * as that generally isn't a localized name,
8876 * and doesn't have meaning for the user. If the
8877 * object is fundamentally a text object (e.g. a menu item), the
8878 * accessible name should be the text of the object (e.g. "save").
8879 * If the object has a tooltip, the tooltip text may also be an
8880 * appropriate String to return.
8881 *
8882 * @return the localized name of the object -- can be
8883 * <code>null</code> if this
8884 * object does not have a name
8885 * @see javax.accessibility.AccessibleContext#setAccessibleName
8886 */
8887 public String getAccessibleName() {
8888 return accessibleName;
8889 }
8890
8891 /**
8892 * Gets the accessible description of this object. This should be
8893 * a concise, localized description of what this object is - what
8894 * is its meaning to the user. If the object has a tooltip, the
8895 * tooltip text may be an appropriate string to return, assuming
8896 * it contains a concise description of the object (instead of just
8897 * the name of the object - e.g. a "Save" icon on a toolbar that
8898 * had "save" as the tooltip text shouldn't return the tooltip
8899 * text as the description, but something like "Saves the current
8900 * text document" instead).
8901 *
8902 * @return the localized description of the object -- can be
8903 * <code>null</code> if this object does not have a description
8904 * @see javax.accessibility.AccessibleContext#setAccessibleDescription
8905 */
8906 public String getAccessibleDescription() {
8907 return accessibleDescription;
8908 }
8909
8910 /**
8911 * Gets the role of this object.
8912 *
8913 * @return an instance of <code>AccessibleRole</code>
8914 * describing the role of the object
8915 * @see javax.accessibility.AccessibleRole
8916 */
8917 public AccessibleRole getAccessibleRole() {
8918 return AccessibleRole.AWT_COMPONENT;
8919 }
8920
8921 /**
8922 * Gets the state of this object.
8923 *
8924 * @return an instance of <code>AccessibleStateSet</code>
8925 * containing the current state set of the object
8926 * @see javax.accessibility.AccessibleState
8927 */
8928 public AccessibleStateSet getAccessibleStateSet() {
8929 return Component.this .getAccessibleStateSet();
8930 }
8931
8932 /**
8933 * Gets the <code>Accessible</code> parent of this object.
8934 * If the parent of this object implements <code>Accessible</code>,
8935 * this method should simply return <code>getParent</code>.
8936 *
8937 * @return the <code>Accessible</code> parent of this
8938 * object -- can be <code>null</code> if this
8939 * object does not have an <code>Accessible</code> parent
8940 */
8941 public Accessible getAccessibleParent() {
8942 if (accessibleParent != null) {
8943 return accessibleParent;
8944 } else {
8945 Container parent = getParent();
8946 if (parent instanceof Accessible) {
8947 return (Accessible) parent;
8948 }
8949 }
8950 return null;
8951 }
8952
8953 /**
8954 * Gets the index of this object in its accessible parent.
8955 *
8956 * @return the index of this object in its parent; or -1 if this
8957 * object does not have an accessible parent
8958 * @see #getAccessibleParent
8959 */
8960 public int getAccessibleIndexInParent() {
8961 return Component.this .getAccessibleIndexInParent();
8962 }
8963
8964 /**
8965 * Returns the number of accessible children in the object. If all
8966 * of the children of this object implement <code>Accessible</code>,
8967 * then this method should return the number of children of this object.
8968 *
8969 * @return the number of accessible children in the object
8970 */
8971 public int getAccessibleChildrenCount() {
8972 return 0; // Components don't have children
8973 }
8974
8975 /**
8976 * Returns the nth <code>Accessible</code> child of the object.
8977 *
8978 * @param i zero-based index of child
8979 * @return the nth <code>Accessible</code> child of the object
8980 */
8981 public Accessible getAccessibleChild(int i) {
8982 return null; // Components don't have children
8983 }
8984
8985 /**
8986 * Returns the locale of this object.
8987 *
8988 * @return the locale of this object
8989 */
8990 public Locale getLocale() {
8991 return Component.this .getLocale();
8992 }
8993
8994 /**
8995 * Gets the <code>AccessibleComponent</code> associated
8996 * with this object if one exists.
8997 * Otherwise return <code>null</code>.
8998 *
8999 * @return the component
9000 */
9001 public AccessibleComponent getAccessibleComponent() {
9002 return this ;
9003 }
9004
9005 // AccessibleComponent methods
9006 //
9007 /**
9008 * Gets the background color of this object.
9009 *
9010 * @return the background color, if supported, of the object;
9011 * otherwise, <code>null</code>
9012 */
9013 public Color getBackground() {
9014 return Component.this .getBackground();
9015 }
9016
9017 /**
9018 * Sets the background color of this object.
9019 * (For transparency, see <code>isOpaque</code>.)
9020 *
9021 * @param c the new <code>Color</code> for the background
9022 * @see Component#isOpaque
9023 */
9024 public void setBackground(Color c) {
9025 Component.this .setBackground(c);
9026 }
9027
9028 /**
9029 * Gets the foreground color of this object.
9030 *
9031 * @return the foreground color, if supported, of the object;
9032 * otherwise, <code>null</code>
9033 */
9034 public Color getForeground() {
9035 return Component.this .getForeground();
9036 }
9037
9038 /**
9039 * Sets the foreground color of this object.
9040 *
9041 * @param c the new <code>Color</code> for the foreground
9042 */
9043 public void setForeground(Color c) {
9044 Component.this .setForeground(c);
9045 }
9046
9047 /**
9048 * Gets the <code>Cursor</code> of this object.
9049 *
9050 * @return the <code>Cursor</code>, if supported,
9051 * of the object; otherwise, <code>null</code>
9052 */
9053 public Cursor getCursor() {
9054 return Component.this .getCursor();
9055 }
9056
9057 /**
9058 * Sets the <code>Cursor</code> of this object.
9059 * <p>
9060 * The method may have no visual effect if the Java platform
9061 * implementation and/or the native system do not support
9062 * changing the mouse cursor shape.
9063 * @param cursor the new <code>Cursor</code> for the object
9064 */
9065 public void setCursor(Cursor cursor) {
9066 Component.this .setCursor(cursor);
9067 }
9068
9069 /**
9070 * Gets the <code>Font</code> of this object.
9071 *
9072 * @return the <code>Font</code>, if supported,
9073 * for the object; otherwise, <code>null</code>
9074 */
9075 public Font getFont() {
9076 return Component.this .getFont();
9077 }
9078
9079 /**
9080 * Sets the <code>Font</code> of this object.
9081 *
9082 * @param f the new <code>Font</code> for the object
9083 */
9084 public void setFont(Font f) {
9085 Component.this .setFont(f);
9086 }
9087
9088 /**
9089 * Gets the <code>FontMetrics</code> of this object.
9090 *
9091 * @param f the <code>Font</code>
9092 * @return the <code>FontMetrics</code>, if supported,
9093 * the object; otherwise, <code>null</code>
9094 * @see #getFont
9095 */
9096 public FontMetrics getFontMetrics(Font f) {
9097 if (f == null) {
9098 return null;
9099 } else {
9100 return Component.this .getFontMetrics(f);
9101 }
9102 }
9103
9104 /**
9105 * Determines if the object is enabled.
9106 *
9107 * @return true if object is enabled; otherwise, false
9108 */
9109 public boolean isEnabled() {
9110 return Component.this .isEnabled();
9111 }
9112
9113 /**
9114 * Sets the enabled state of the object.
9115 *
9116 * @param b if true, enables this object; otherwise, disables it
9117 */
9118 public void setEnabled(boolean b) {
9119 boolean old = Component.this .isEnabled();
9120 Component.this .setEnabled(b);
9121 if (b != old) {
9122 if (accessibleContext != null) {
9123 if (b) {
9124 accessibleContext
9125 .firePropertyChange(
9126 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9127 null, AccessibleState.ENABLED);
9128 } else {
9129 accessibleContext
9130 .firePropertyChange(
9131 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9132 AccessibleState.ENABLED, null);
9133 }
9134 }
9135 }
9136 }
9137
9138 /**
9139 * Determines if the object is visible. Note: this means that the
9140 * object intends to be visible; however, it may not in fact be
9141 * showing on the screen because one of the objects that this object
9142 * is contained by is not visible. To determine if an object is
9143 * showing on the screen, use <code>isShowing</code>.
9144 *
9145 * @return true if object is visible; otherwise, false
9146 */
9147 public boolean isVisible() {
9148 return Component.this .isVisible();
9149 }
9150
9151 /**
9152 * Sets the visible state of the object.
9153 *
9154 * @param b if true, shows this object; otherwise, hides it
9155 */
9156 public void setVisible(boolean b) {
9157 boolean old = Component.this .isVisible();
9158 Component.this .setVisible(b);
9159 if (b != old) {
9160 if (accessibleContext != null) {
9161 if (b) {
9162 accessibleContext
9163 .firePropertyChange(
9164 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9165 null, AccessibleState.VISIBLE);
9166 } else {
9167 accessibleContext
9168 .firePropertyChange(
9169 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
9170 AccessibleState.VISIBLE, null);
9171 }
9172 }
9173 }
9174 }
9175
9176 /**
9177 * Determines if the object is showing. This is determined by checking
9178 * the visibility of the object and ancestors of the object. Note:
9179 * this will return true even if the object is obscured by another
9180 * (for example, it happens to be underneath a menu that was pulled
9181 * down).
9182 *
9183 * @return true if object is showing; otherwise, false
9184 */
9185 public boolean isShowing() {
9186 return Component.this .isShowing();
9187 }
9188
9189 /**
9190 * Checks whether the specified point is within this object's bounds,
9191 * where the point's x and y coordinates are defined to be relative to
9192 * the coordinate system of the object.
9193 *
9194 * @param p the <code>Point</code> relative to the
9195 * coordinate system of the object
9196 * @return true if object contains <code>Point</code>; otherwise false
9197 */
9198 public boolean contains(Point p) {
9199 return Component.this .contains(p);
9200 }
9201
9202 /**
9203 * Returns the location of the object on the screen.
9204 *
9205 * @return location of object on screen -- can be
9206 * <code>null</code> if this object is not on the screen
9207 */
9208 public Point getLocationOnScreen() {
9209 synchronized (Component.this .getTreeLock()) {
9210 if (Component.this .isShowing()) {
9211 return Component.this .getLocationOnScreen();
9212 } else {
9213 return null;
9214 }
9215 }
9216 }
9217
9218 /**
9219 * Gets the location of the object relative to the parent in the form
9220 * of a point specifying the object's top-left corner in the screen's
9221 * coordinate space.
9222 *
9223 * @return an instance of Point representing the top-left corner of
9224 * the object's bounds in the coordinate space of the screen;
9225 * <code>null</code> if this object or its parent are not on the screen
9226 */
9227 public Point getLocation() {
9228 return Component.this .getLocation();
9229 }
9230
9231 /**
9232 * Sets the location of the object relative to the parent.
9233 * @param p the coordinates of the object
9234 */
9235 public void setLocation(Point p) {
9236 Component.this .setLocation(p);
9237 }
9238
9239 /**
9240 * Gets the bounds of this object in the form of a Rectangle object.
9241 * The bounds specify this object's width, height, and location
9242 * relative to its parent.
9243 *
9244 * @return a rectangle indicating this component's bounds;
9245 * <code>null</code> if this object is not on the screen
9246 */
9247 public Rectangle getBounds() {
9248 return Component.this .getBounds();
9249 }
9250
9251 /**
9252 * Sets the bounds of this object in the form of a
9253 * <code>Rectangle</code> object.
9254 * The bounds specify this object's width, height, and location
9255 * relative to its parent.
9256 *
9257 * @param r a rectangle indicating this component's bounds
9258 */
9259 public void setBounds(Rectangle r) {
9260 Component.this .setBounds(r);
9261 }
9262
9263 /**
9264 * Returns the size of this object in the form of a
9265 * <code>Dimension</code> object. The height field of the
9266 * <code>Dimension</code> object contains this objects's
9267 * height, and the width field of the <code>Dimension</code>
9268 * object contains this object's width.
9269 *
9270 * @return a <code>Dimension</code> object that indicates
9271 * the size of this component; <code>null</code> if
9272 * this object is not on the screen
9273 */
9274 public Dimension getSize() {
9275 return Component.this .getSize();
9276 }
9277
9278 /**
9279 * Resizes this object so that it has width and height.
9280 *
9281 * @param d - the dimension specifying the new size of the object
9282 */
9283 public void setSize(Dimension d) {
9284 Component.this .setSize(d);
9285 }
9286
9287 /**
9288 * Returns the <code>Accessible</code> child,
9289 * if one exists, contained at the local
9290 * coordinate <code>Point</code>. Otherwise returns
9291 * <code>null</code>.
9292 *
9293 * @param p the point defining the top-left corner of
9294 * the <code>Accessible</code>, given in the
9295 * coordinate space of the object's parent
9296 * @return the <code>Accessible</code>, if it exists,
9297 * at the specified location; else <code>null</code>
9298 */
9299 public Accessible getAccessibleAt(Point p) {
9300 return null; // Components don't have children
9301 }
9302
9303 /**
9304 * Returns whether this object can accept focus or not.
9305 *
9306 * @return true if object can accept focus; otherwise false
9307 */
9308 public boolean isFocusTraversable() {
9309 return Component.this .isFocusTraversable();
9310 }
9311
9312 /**
9313 * Requests focus for this object.
9314 */
9315 public void requestFocus() {
9316 Component.this .requestFocus();
9317 }
9318
9319 /**
9320 * Adds the specified focus listener to receive focus events from this
9321 * component.
9322 *
9323 * @param l the focus listener
9324 */
9325 public void addFocusListener(FocusListener l) {
9326 Component.this .addFocusListener(l);
9327 }
9328
9329 /**
9330 * Removes the specified focus listener so it no longer receives focus
9331 * events from this component.
9332 *
9333 * @param l the focus listener
9334 */
9335 public void removeFocusListener(FocusListener l) {
9336 Component.this .removeFocusListener(l);
9337 }
9338
9339 } // inner class AccessibleAWTComponent
9340
9341 /**
9342 * Gets the index of this object in its accessible parent.
9343 * If this object does not have an accessible parent, returns
9344 * -1.
9345 *
9346 * @return the index of this object in its accessible parent
9347 */
9348 int getAccessibleIndexInParent() {
9349 synchronized (getTreeLock()) {
9350 int index = -1;
9351 Container parent = this .getParent();
9352 if (parent != null && parent instanceof Accessible) {
9353 Component ca[] = parent.getComponents();
9354 for (int i = 0; i < ca.length; i++) {
9355 if (ca[i] instanceof Accessible) {
9356 index++;
9357 }
9358 if (this .equals(ca[i])) {
9359 return index;
9360 }
9361 }
9362 }
9363 return -1;
9364 }
9365 }
9366
9367 /**
9368 * Gets the current state set of this object.
9369 *
9370 * @return an instance of <code>AccessibleStateSet</code>
9371 * containing the current state set of the object
9372 * @see AccessibleState
9373 */
9374 AccessibleStateSet getAccessibleStateSet() {
9375 synchronized (getTreeLock()) {
9376 AccessibleStateSet states = new AccessibleStateSet();
9377 if (this .isEnabled()) {
9378 states.add(AccessibleState.ENABLED);
9379 }
9380 if (this .isFocusTraversable()) {
9381 states.add(AccessibleState.FOCUSABLE);
9382 }
9383 if (this .isVisible()) {
9384 states.add(AccessibleState.VISIBLE);
9385 }
9386 if (this .isShowing()) {
9387 states.add(AccessibleState.SHOWING);
9388 }
9389 if (this .isFocusOwner()) {
9390 states.add(AccessibleState.FOCUSED);
9391 }
9392 if (this instanceof Accessible) {
9393 AccessibleContext ac = ((Accessible) this )
9394 .getAccessibleContext();
9395 if (ac != null) {
9396 Accessible ap = ac.getAccessibleParent();
9397 if (ap != null) {
9398 AccessibleContext pac = ap
9399 .getAccessibleContext();
9400 if (pac != null) {
9401 AccessibleSelection as = pac
9402 .getAccessibleSelection();
9403 if (as != null) {
9404 states.add(AccessibleState.SELECTABLE);
9405 int i = ac.getAccessibleIndexInParent();
9406 if (i >= 0) {
9407 if (as.isAccessibleChildSelected(i)) {
9408 states
9409 .add(AccessibleState.SELECTED);
9410 }
9411 }
9412 }
9413 }
9414 }
9415 }
9416 }
9417 if (Component.isInstanceOf(this , "javax.swing.JComponent")) {
9418 if (((javax.swing.JComponent) this ).isOpaque()) {
9419 states.add(AccessibleState.OPAQUE);
9420 }
9421 }
9422 return states;
9423 }
9424 }
9425
9426 /**
9427 * Checks that the given object is instance of the given class.
9428 * @param obj Object to be checked
9429 * @param className The name of the class. Must be fully-qualified class name.
9430 * @return true, if this object is instanceof given class,
9431 * false, otherwise, or if obj or className is null
9432 */
9433 static boolean isInstanceOf(Object obj, String className) {
9434 if (obj == null)
9435 return false;
9436 if (className == null)
9437 return false;
9438
9439 Class cls = obj.getClass();
9440 while (cls != null) {
9441 if (cls.getName().equals(className)) {
9442 return true;
9443 }
9444 cls = cls.getSuperclass();
9445 }
9446 return false;
9447 }
9448
9449 }
|