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: // - [email protected], 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: }
|