Path: blob/master/src/java.desktop/share/classes/java/awt/Component.java
41152 views
/*1* Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.awt;2627import java.applet.Applet;28import java.awt.dnd.DropTarget;29import java.awt.event.ActionEvent;30import java.awt.event.AdjustmentEvent;31import java.awt.event.ComponentEvent;32import java.awt.event.ComponentListener;33import java.awt.event.FocusEvent;34import java.awt.event.FocusListener;35import java.awt.event.HierarchyBoundsListener;36import java.awt.event.HierarchyEvent;37import java.awt.event.HierarchyListener;38import java.awt.event.InputEvent;39import java.awt.event.InputMethodEvent;40import java.awt.event.InputMethodListener;41import java.awt.event.ItemEvent;42import java.awt.event.KeyEvent;43import java.awt.event.KeyListener;44import java.awt.event.MouseEvent;45import java.awt.event.MouseListener;46import java.awt.event.MouseMotionListener;47import java.awt.event.MouseWheelEvent;48import java.awt.event.MouseWheelListener;49import java.awt.event.PaintEvent;50import java.awt.event.TextEvent;51import java.awt.im.InputContext;52import java.awt.im.InputMethodRequests;53import java.awt.image.BufferStrategy;54import java.awt.image.ColorModel;55import java.awt.image.ImageObserver;56import java.awt.image.ImageProducer;57import java.awt.image.VolatileImage;58import java.awt.peer.ComponentPeer;59import java.awt.peer.ContainerPeer;60import java.awt.peer.LightweightPeer;61import java.beans.PropertyChangeListener;62import java.beans.PropertyChangeSupport;63import java.beans.Transient;64import java.io.IOException;65import java.io.ObjectInputStream;66import java.io.ObjectOutputStream;67import java.io.PrintStream;68import java.io.PrintWriter;69import java.io.Serial;70import java.io.Serializable;71import java.security.AccessControlContext;72import java.security.AccessController;73import java.util.Collections;74import java.util.EventListener;75import java.util.HashSet;76import java.util.Locale;77import java.util.Map;78import java.util.Objects;79import java.util.Set;80import java.util.Vector;8182import javax.accessibility.Accessible;83import javax.accessibility.AccessibleComponent;84import javax.accessibility.AccessibleContext;85import javax.accessibility.AccessibleRole;86import javax.accessibility.AccessibleSelection;87import javax.accessibility.AccessibleState;88import javax.accessibility.AccessibleStateSet;89import javax.swing.JComponent;90import javax.swing.JRootPane;9192import sun.awt.AWTAccessor;93import sun.awt.AppContext;94import sun.awt.ComponentFactory;95import sun.awt.ConstrainableGraphics;96import sun.awt.EmbeddedFrame;97import sun.awt.RequestFocusController;98import sun.awt.SubRegionShowable;99import sun.awt.SunToolkit;100import sun.awt.dnd.SunDropTargetEvent;101import sun.awt.im.CompositionArea;102import sun.awt.image.VSyncedBSManager;103import sun.font.FontManager;104import sun.font.FontManagerFactory;105import sun.font.SunFontManager;106import sun.java2d.SunGraphics2D;107import sun.java2d.SunGraphicsEnvironment;108import sun.java2d.pipe.Region;109import sun.java2d.pipe.hw.ExtendedBufferCapabilities;110import sun.security.action.GetPropertyAction;111import sun.swing.SwingAccessor;112import sun.util.logging.PlatformLogger;113114import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_DEFAULT;115import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON;116117/**118* A <em>component</em> is an object having a graphical representation119* that can be displayed on the screen and that can interact with the120* user. Examples of components are the buttons, checkboxes, and scrollbars121* of a typical graphical user interface. <p>122* The {@code Component} class is the abstract superclass of123* the nonmenu-related Abstract Window Toolkit components. Class124* {@code Component} can also be extended directly to create a125* lightweight component. A lightweight component is a component that is126* not associated with a native window. On the contrary, a heavyweight127* component is associated with a native window. The {@link #isLightweight()}128* method may be used to distinguish between the two kinds of the components.129* <p>130* Lightweight and heavyweight components may be mixed in a single component131* hierarchy. However, for correct operating of such a mixed hierarchy of132* components, the whole hierarchy must be valid. When the hierarchy gets133* invalidated, like after changing the bounds of components, or134* adding/removing components to/from containers, the whole hierarchy must be135* validated afterwards by means of the {@link Container#validate()} method136* invoked on the top-most invalid container of the hierarchy.137*138* <h2>Serialization</h2>139* It is important to note that only AWT listeners which conform140* to the {@code Serializable} protocol will be saved when141* the object is stored. If an AWT object has listeners that142* aren't marked serializable, they will be dropped at143* {@code writeObject} time. Developers will need, as always,144* to consider the implications of making an object serializable.145* One situation to watch out for is this:146* <pre>147* import java.awt.*;148* import java.awt.event.*;149* import java.io.Serializable;150*151* class MyApp implements ActionListener, Serializable152* {153* BigObjectThatShouldNotBeSerializedWithAButton bigOne;154* Button aButton = new Button();155*156* MyApp()157* {158* // Oops, now aButton has a listener with a reference159* // to bigOne!160* aButton.addActionListener(this);161* }162*163* public void actionPerformed(ActionEvent e)164* {165* System.out.println("Hello There");166* }167* }168* </pre>169* In this example, serializing {@code aButton} by itself170* will cause {@code MyApp} and everything it refers to171* to be serialized as well. The problem is that the listener172* is serializable by coincidence, not by design. To separate173* the decisions about {@code MyApp} and the174* {@code ActionListener} being serializable one can use a175* nested class, as in the following example:176* <pre>177* import java.awt.*;178* import java.awt.event.*;179* import java.io.Serializable;180*181* class MyApp implements java.io.Serializable182* {183* BigObjectThatShouldNotBeSerializedWithAButton bigOne;184* Button aButton = new Button();185*186* static class MyActionListener implements ActionListener187* {188* public void actionPerformed(ActionEvent e)189* {190* System.out.println("Hello There");191* }192* }193*194* MyApp()195* {196* aButton.addActionListener(new MyActionListener());197* }198* }199* </pre>200* <p>201* <b>Note</b>: For more information on the paint mechanisms utilized202* by AWT and Swing, including information on how to write the most203* efficient painting code, see204* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.205* <p>206* For details on the focus subsystem, see207* <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">208* How to Use the Focus Subsystem</a>,209* a section in <em>The Java Tutorial</em>, and the210* <a href="doc-files/FocusSpec.html">Focus Specification</a>211* for more information.212*213* @author Arthur van Hoff214* @author Sami Shaio215*/216public abstract class Component implements ImageObserver, MenuContainer,217Serializable218{219220private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Component");221private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Component");222private static final PlatformLogger focusLog = PlatformLogger.getLogger("java.awt.focus.Component");223private static final PlatformLogger mixingLog = PlatformLogger.getLogger("java.awt.mixing.Component");224225/**226* The peer of the component. The peer implements the component's227* behavior. The peer is set when the {@code Component} is228* added to a container that also is a peer.229* @see #addNotify230* @see #removeNotify231*/232transient volatile ComponentPeer peer;233234/**235* The parent of the object. It may be {@code null}236* for top-level components.237* @see #getParent238*/239transient Container parent;240241/**242* The {@code AppContext} of the component. Applets/Plugin may243* change the AppContext.244*/245transient AppContext appContext;246247/**248* The x position of the component in the parent's coordinate system.249*250* @serial251* @see #getLocation252*/253int x;254255/**256* The y position of the component in the parent's coordinate system.257*258* @serial259* @see #getLocation260*/261int y;262263/**264* The width of the component.265*266* @serial267* @see #getSize268*/269int width;270271/**272* The height of the component.273*274* @serial275* @see #getSize276*/277int height;278279/**280* The foreground color for this component.281* {@code foreground} can be {@code null}.282*283* @serial284* @see #getForeground285* @see #setForeground286*/287Color foreground;288289/**290* The background color for this component.291* {@code background} can be {@code null}.292*293* @serial294* @see #getBackground295* @see #setBackground296*/297Color background;298299/**300* The font used by this component.301* The {@code font} can be {@code null}.302*303* @serial304* @see #getFont305* @see #setFont306*/307volatile Font font;308309/**310* The font which the peer is currently using.311* ({@code null} if no peer exists.)312*/313Font peerFont;314315/**316* The cursor displayed when pointer is over this component.317* This value can be {@code null}.318*319* @serial320* @see #getCursor321* @see #setCursor322*/323Cursor cursor;324325/**326* The locale for the component.327*328* @serial329* @see #getLocale330* @see #setLocale331*/332Locale locale;333334/**335* A reference to a {@code GraphicsConfiguration} object336* used to describe the characteristics of a graphics337* destination.338* This value can be {@code null}.339*340* @since 1.3341* @serial342* @see GraphicsConfiguration343* @see #getGraphicsConfiguration344*/345private transient volatile GraphicsConfiguration graphicsConfig;346347/**348* A reference to a {@code BufferStrategy} object349* used to manipulate the buffers on this component.350*351* @since 1.4352* @see java.awt.image.BufferStrategy353* @see #getBufferStrategy()354*/355private transient BufferStrategy bufferStrategy = null;356357/**358* True when the object should ignore all repaint events.359*360* @since 1.4361* @serial362* @see #setIgnoreRepaint363* @see #getIgnoreRepaint364*/365boolean ignoreRepaint = false;366367/**368* True when the object is visible. An object that is not369* visible is not drawn on the screen.370*371* @serial372* @see #isVisible373* @see #setVisible374*/375boolean visible = true;376377/**378* True when the object is enabled. An object that is not379* enabled does not interact with the user.380*381* @serial382* @see #isEnabled383* @see #setEnabled384*/385boolean enabled = true;386387/**388* True when the object is valid. An invalid object needs to389* be laid out. This flag is set to false when the object390* size is changed.391*392* @serial393* @see #isValid394* @see #validate395* @see #invalidate396*/397private volatile boolean valid = false;398399/**400* The {@code DropTarget} associated with this component.401*402* @since 1.2403* @serial404* @see #setDropTarget405* @see #getDropTarget406*/407DropTarget dropTarget;408409/**410* @serial411* @see #add412*/413Vector<PopupMenu> popups;414415/**416* A component's name.417* This field can be {@code null}.418*419* @serial420* @see #getName421* @see #setName(String)422*/423private String name;424425/**426* A bool to determine whether the name has427* been set explicitly. {@code nameExplicitlySet} will428* be false if the name has not been set and429* true if it has.430*431* @serial432* @see #getName433* @see #setName(String)434*/435private boolean nameExplicitlySet = false;436437/**438* Indicates whether this Component can be focused.439*440* @serial441* @see #setFocusable442* @see #isFocusable443* @since 1.4444*/445private boolean focusable = true;446447private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;448private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;449private static final int FOCUS_TRAVERSABLE_SET = 2;450451/**452* Tracks whether this Component is relying on default focus traversability.453*454* @serial455* @since 1.4456*/457private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;458459/**460* The focus traversal keys. These keys will generate focus traversal461* behavior for Components for which focus traversal keys are enabled. If a462* value of null is specified for a traversal key, this Component inherits463* that traversal key from its parent. If all ancestors of this Component464* have null specified for that traversal key, then the current465* KeyboardFocusManager's default traversal key is used.466*467* @serial468* @see #setFocusTraversalKeys469* @see #getFocusTraversalKeys470* @since 1.4471*/472@SuppressWarnings("serial") // Not statically typed as Serializable473Set<AWTKeyStroke>[] focusTraversalKeys;474475private static final String[] focusTraversalKeyPropertyNames = {476"forwardFocusTraversalKeys",477"backwardFocusTraversalKeys",478"upCycleFocusTraversalKeys",479"downCycleFocusTraversalKeys"480};481482/**483* Indicates whether focus traversal keys are enabled for this Component.484* Components for which focus traversal keys are disabled receive key485* events for focus traversal keys. Components for which focus traversal486* keys are enabled do not see these events; instead, the events are487* automatically converted to traversal operations.488*489* @serial490* @see #setFocusTraversalKeysEnabled491* @see #getFocusTraversalKeysEnabled492* @since 1.4493*/494private boolean focusTraversalKeysEnabled = true;495496/**497* The locking object for AWT component-tree and layout operations.498*499* @see #getTreeLock500*/501static final Object LOCK = new AWTTreeLock();502static class AWTTreeLock {}503504/*505* The component's AccessControlContext.506*/507@SuppressWarnings("removal")508private transient volatile AccessControlContext acc =509AccessController.getContext();510511/**512* Minimum size.513* (This field perhaps should have been transient).514*515* @serial516*/517Dimension minSize;518519/**520* Whether or not setMinimumSize has been invoked with a non-null value.521*/522boolean minSizeSet;523524/**525* Preferred size.526* (This field perhaps should have been transient).527*528* @serial529*/530Dimension prefSize;531532/**533* Whether or not setPreferredSize has been invoked with a non-null value.534*/535boolean prefSizeSet;536537/**538* Maximum size539*540* @serial541*/542Dimension maxSize;543544/**545* Whether or not setMaximumSize has been invoked with a non-null value.546*/547boolean maxSizeSet;548549/**550* The orientation for this component.551* @see #getComponentOrientation552* @see #setComponentOrientation553*/554transient ComponentOrientation componentOrientation555= ComponentOrientation.UNKNOWN;556557/**558* {@code newEventsOnly} will be true if the event is559* one of the event types enabled for the component.560* It will then allow for normal processing to561* continue. If it is false the event is passed562* to the component's parent and up the ancestor563* tree until the event has been consumed.564*565* @serial566* @see #dispatchEvent567*/568boolean newEventsOnly = false;569transient ComponentListener componentListener;570transient FocusListener focusListener;571transient HierarchyListener hierarchyListener;572transient HierarchyBoundsListener hierarchyBoundsListener;573transient KeyListener keyListener;574transient MouseListener mouseListener;575transient MouseMotionListener mouseMotionListener;576transient MouseWheelListener mouseWheelListener;577transient InputMethodListener inputMethodListener;578579/** Internal, constants for serialization */580static final String actionListenerK = "actionL";581static final String adjustmentListenerK = "adjustmentL";582static final String componentListenerK = "componentL";583static final String containerListenerK = "containerL";584static final String focusListenerK = "focusL";585static final String itemListenerK = "itemL";586static final String keyListenerK = "keyL";587static final String mouseListenerK = "mouseL";588static final String mouseMotionListenerK = "mouseMotionL";589static final String mouseWheelListenerK = "mouseWheelL";590static final String textListenerK = "textL";591static final String ownedWindowK = "ownedL";592static final String windowListenerK = "windowL";593static final String inputMethodListenerK = "inputMethodL";594static final String hierarchyListenerK = "hierarchyL";595static final String hierarchyBoundsListenerK = "hierarchyBoundsL";596static final String windowStateListenerK = "windowStateL";597static final String windowFocusListenerK = "windowFocusL";598599/**600* The {@code eventMask} is ONLY set by subclasses via601* {@code enableEvents}.602* The mask should NOT be set when listeners are registered603* so that we can distinguish the difference between when604* listeners request events and subclasses request them.605* One bit is used to indicate whether input methods are606* enabled; this bit is set by {@code enableInputMethods} and is607* on by default.608*609* @serial610* @see #enableInputMethods611* @see AWTEvent612*/613long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK;614615/**616* Static properties for incremental drawing.617* @see #imageUpdate618*/619static boolean isInc;620static int incRate;621static {622/* ensure that the necessary native libraries are loaded */623Toolkit.loadLibraries();624/* initialize JNI field and method ids */625if (!GraphicsEnvironment.isHeadless()) {626initIDs();627}628629@SuppressWarnings("removal")630String s = java.security.AccessController.doPrivileged(631new GetPropertyAction("awt.image.incrementaldraw"));632isInc = (s == null || s.equals("true"));633634@SuppressWarnings("removal")635String s2 = java.security.AccessController.doPrivileged(636new GetPropertyAction("awt.image.redrawrate"));637incRate = (s2 != null) ? Integer.parseInt(s2) : 100;638}639640/**641* Ease-of-use constant for {@code getAlignmentY()}.642* Specifies an alignment to the top of the component.643* @see #getAlignmentY644*/645public static final float TOP_ALIGNMENT = 0.0f;646647/**648* Ease-of-use constant for {@code getAlignmentY} and649* {@code getAlignmentX}. Specifies an alignment to650* the center of the component651* @see #getAlignmentX652* @see #getAlignmentY653*/654public static final float CENTER_ALIGNMENT = 0.5f;655656/**657* Ease-of-use constant for {@code getAlignmentY}.658* Specifies an alignment to the bottom of the component.659* @see #getAlignmentY660*/661public static final float BOTTOM_ALIGNMENT = 1.0f;662663/**664* Ease-of-use constant for {@code getAlignmentX}.665* Specifies an alignment to the left side of the component.666* @see #getAlignmentX667*/668public static final float LEFT_ALIGNMENT = 0.0f;669670/**671* Ease-of-use constant for {@code getAlignmentX}.672* Specifies an alignment to the right side of the component.673* @see #getAlignmentX674*/675public static final float RIGHT_ALIGNMENT = 1.0f;676677/**678* Use serialVersionUID from JDK 1.1 for interoperability.679*/680@Serial681private static final long serialVersionUID = -7644114512714619750L;682683/**684* If any {@code PropertyChangeListeners} have been registered,685* the {@code changeSupport} field describes them.686*687* @serial688* @since 1.2689* @see #addPropertyChangeListener690* @see #removePropertyChangeListener691* @see #firePropertyChange692*/693private PropertyChangeSupport changeSupport;694695/*696* In some cases using "this" as an object to synchronize by697* can lead to a deadlock if client code also uses synchronization698* by a component object. For every such situation revealed we should699* consider possibility of replacing "this" with the package private700* objectLock object introduced below. So far there are 3 issues known:701* - CR 6708322 (the getName/setName methods);702* - CR 6608764 (the PropertyChangeListener machinery);703* - CR 7108598 (the Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods).704*705* Note: this field is considered final, though readObject() prohibits706* initializing final fields.707*/708private transient Object objectLock = new Object();709Object getObjectLock() {710return objectLock;711}712713/*714* Returns the acc this component was constructed with.715*/716@SuppressWarnings("removal")717final AccessControlContext getAccessControlContext() {718if (acc == null) {719throw new SecurityException("Component is missing AccessControlContext");720}721return acc;722}723724/**725* Whether the component is packed or not;726*/727boolean isPacked = false;728729/**730* Pseudoparameter for direct Geometry API (setLocation, setBounds setSize731* to signal setBounds what's changing. Should be used under TreeLock.732* This is only needed due to the inability to change the cross-calling733* order of public and deprecated methods.734*/735private int boundsOp = ComponentPeer.DEFAULT_OPERATION;736737/**738* Enumeration of the common ways the baseline of a component can739* change as the size changes. The baseline resize behavior is740* primarily for layout managers that need to know how the741* position of the baseline changes as the component size changes.742* In general the baseline resize behavior will be valid for sizes743* greater than or equal to the minimum size (the actual minimum744* size; not a developer specified minimum size). For sizes745* smaller than the minimum size the baseline may change in a way746* other than the baseline resize behavior indicates. Similarly,747* as the size approaches {@code Integer.MAX_VALUE} and/or748* {@code Short.MAX_VALUE} the baseline may change in a way749* other than the baseline resize behavior indicates.750*751* @see #getBaselineResizeBehavior752* @see #getBaseline(int,int)753* @since 1.6754*/755public enum BaselineResizeBehavior {756/**757* Indicates the baseline remains fixed relative to the758* y-origin. That is, {@code getBaseline} returns759* the same value regardless of the height or width. For example, a760* {@code JLabel} containing non-empty text with a761* vertical alignment of {@code TOP} should have a762* baseline type of {@code CONSTANT_ASCENT}.763*/764CONSTANT_ASCENT,765766/**767* Indicates the baseline remains fixed relative to the height768* and does not change as the width is varied. That is, for769* any height H the difference between H and770* {@code getBaseline(w, H)} is the same. For example, a771* {@code JLabel} containing non-empty text with a772* vertical alignment of {@code BOTTOM} should have a773* baseline type of {@code CONSTANT_DESCENT}.774*/775CONSTANT_DESCENT,776777/**778* Indicates the baseline remains a fixed distance from779* the center of the component. That is, for any height H the780* difference between {@code getBaseline(w, H)} and781* {@code H / 2} is the same (plus or minus one depending upon782* rounding error).783* <p>784* Because of possible rounding errors it is recommended785* you ask for the baseline with two consecutive heights and use786* the return value to determine if you need to pad calculations787* by 1. The following shows how to calculate the baseline for788* any height:789* <pre>790* Dimension preferredSize = component.getPreferredSize();791* int baseline = getBaseline(preferredSize.width,792* preferredSize.height);793* int nextBaseline = getBaseline(preferredSize.width,794* preferredSize.height + 1);795* // Amount to add to height when calculating where baseline796* // lands for a particular height:797* int padding = 0;798* // Where the baseline is relative to the mid point799* int baselineOffset = baseline - height / 2;800* if (preferredSize.height % 2 == 0 &&801* baseline != nextBaseline) {802* padding = 1;803* }804* else if (preferredSize.height % 2 == 1 &&805* baseline == nextBaseline) {806* baselineOffset--;807* padding = 1;808* }809* // The following calculates where the baseline lands for810* // the height z:811* int calculatedBaseline = (z + padding) / 2 + baselineOffset;812* </pre>813*/814CENTER_OFFSET,815816/**817* Indicates the baseline resize behavior can not be expressed using818* any of the other constants. This may also indicate the baseline819* varies with the width of the component. This is also returned820* by components that do not have a baseline.821*/822OTHER823}824825/*826* The shape set with the applyCompoundShape() method. It includes the result827* of the HW/LW mixing related shape computation. It may also include828* the user-specified shape of the component.829* The 'null' value means the component has normal shape (or has no shape at all)830* and applyCompoundShape() will skip the following shape identical to normal.831*/832private transient Region compoundShape = null;833834/*835* Represents the shape of this lightweight component to be cut out from836* heavyweight components should they intersect. Possible values:837* 1. null - consider the shape rectangular838* 2. EMPTY_REGION - nothing gets cut out (children still get cut out)839* 3. non-empty - this shape gets cut out.840*/841private transient Region mixingCutoutRegion = null;842843/*844* Indicates whether addNotify() is complete845* (i.e. the peer is created).846*/847private transient boolean isAddNotifyComplete = false;848849/**850* Should only be used in subclass getBounds to check that part of bounds851* is actually changing852*/853int getBoundsOp() {854assert Thread.holdsLock(getTreeLock());855return boundsOp;856}857858void setBoundsOp(int op) {859assert Thread.holdsLock(getTreeLock());860if (op == ComponentPeer.RESET_OPERATION) {861boundsOp = ComponentPeer.DEFAULT_OPERATION;862} else863if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {864boundsOp = op;865}866}867868// Whether this Component has had the background erase flag869// specified via SunToolkit.disableBackgroundErase(). This is870// needed in order to make this function work on X11 platforms,871// where currently there is no chance to interpose on the creation872// of the peer and therefore the call to XSetBackground.873transient boolean backgroundEraseDisabled;874875static {876AWTAccessor.setComponentAccessor(new AWTAccessor.ComponentAccessor() {877public void setBackgroundEraseDisabled(Component comp, boolean disabled) {878comp.backgroundEraseDisabled = disabled;879}880public boolean getBackgroundEraseDisabled(Component comp) {881return comp.backgroundEraseDisabled;882}883public Rectangle getBounds(Component comp) {884return new Rectangle(comp.x, comp.y, comp.width, comp.height);885}886public void setGraphicsConfiguration(Component comp,887GraphicsConfiguration gc)888{889comp.setGraphicsConfiguration(gc);890}891public void requestFocus(Component comp, FocusEvent.Cause cause) {892comp.requestFocus(cause);893}894public boolean canBeFocusOwner(Component comp) {895return comp.canBeFocusOwner();896}897898public boolean isVisible(Component comp) {899return comp.isVisible_NoClientCode();900}901public void setRequestFocusController902(RequestFocusController requestController)903{904Component.setRequestFocusController(requestController);905}906public AppContext getAppContext(Component comp) {907return comp.appContext;908}909public void setAppContext(Component comp, AppContext appContext) {910comp.appContext = appContext;911}912public Container getParent(Component comp) {913return comp.getParent_NoClientCode();914}915public void setParent(Component comp, Container parent) {916comp.parent = parent;917}918public void setSize(Component comp, int width, int height) {919comp.width = width;920comp.height = height;921}922public Point getLocation(Component comp) {923return comp.location_NoClientCode();924}925public void setLocation(Component comp, int x, int y) {926comp.x = x;927comp.y = y;928}929public boolean isEnabled(Component comp) {930return comp.isEnabledImpl();931}932public boolean isDisplayable(Component comp) {933return comp.peer != null;934}935public Cursor getCursor(Component comp) {936return comp.getCursor_NoClientCode();937}938@SuppressWarnings("unchecked")939public <T extends ComponentPeer> T getPeer(Component comp) {940return (T) comp.peer;941}942public void setPeer(Component comp, ComponentPeer peer) {943comp.peer = peer;944}945public boolean isLightweight(Component comp) {946return (comp.peer instanceof LightweightPeer);947}948public boolean getIgnoreRepaint(Component comp) {949return comp.ignoreRepaint;950}951public int getWidth(Component comp) {952return comp.width;953}954public int getHeight(Component comp) {955return comp.height;956}957public int getX(Component comp) {958return comp.x;959}960public int getY(Component comp) {961return comp.y;962}963public Color getForeground(Component comp) {964return comp.foreground;965}966public Color getBackground(Component comp) {967return comp.background;968}969public void setBackground(Component comp, Color background) {970comp.background = background;971}972public Font getFont(Component comp) {973return comp.getFont_NoClientCode();974}975public void processEvent(Component comp, AWTEvent e) {976comp.processEvent(e);977}978979@SuppressWarnings("removal")980public AccessControlContext getAccessControlContext(Component comp) {981return comp.getAccessControlContext();982}983984public void revalidateSynchronously(Component comp) {985comp.revalidateSynchronously();986}987988@Override989public void createBufferStrategy(Component comp, int numBuffers,990BufferCapabilities caps) throws AWTException {991comp.createBufferStrategy(numBuffers, caps);992}993994@Override995public BufferStrategy getBufferStrategy(Component comp) {996return comp.getBufferStrategy();997}998});999}10001001/**1002* Constructs a new component. Class {@code Component} can be1003* extended directly to create a lightweight component that does not1004* utilize an opaque native window. A lightweight component must be1005* hosted by a native container somewhere higher up in the component1006* tree (for example, by a {@code Frame} object).1007*/1008protected Component() {1009appContext = AppContext.getAppContext();1010}10111012@SuppressWarnings({"rawtypes", "unchecked"})1013void initializeFocusTraversalKeys() {1014focusTraversalKeys = new Set[3];1015}10161017/**1018* Constructs a name for this component. Called by {@code getName}1019* when the name is {@code null}.1020*/1021String constructComponentName() {1022return null; // For strict compliance with prior platform versions, a Component1023// that doesn't set its name should return null from1024// getName()1025}10261027/**1028* Gets the name of the component.1029* @return this component's name1030* @see #setName1031* @since 1.11032*/1033public String getName() {1034if (name == null && !nameExplicitlySet) {1035synchronized(getObjectLock()) {1036if (name == null && !nameExplicitlySet)1037name = constructComponentName();1038}1039}1040return name;1041}10421043/**1044* Sets the name of the component to the specified string.1045* @param name the string that is to be this1046* component's name1047* @see #getName1048* @since 1.11049*/1050public void setName(String name) {1051String oldName;1052synchronized(getObjectLock()) {1053oldName = this.name;1054this.name = name;1055nameExplicitlySet = true;1056}1057firePropertyChange("name", oldName, name);1058}10591060/**1061* Gets the parent of this component.1062* @return the parent container of this component1063* @since 1.01064*/1065public Container getParent() {1066return getParent_NoClientCode();1067}10681069// NOTE: This method may be called by privileged threads.1070// This functionality is implemented in a package-private method1071// to insure that it cannot be overridden by client subclasses.1072// DO NOT INVOKE CLIENT CODE ON THIS THREAD!1073final Container getParent_NoClientCode() {1074return parent;1075}10761077// This method is overridden in the Window class to return null,1078// because the parent field of the Window object contains1079// the owner of the window, not its parent.1080Container getContainer() {1081return getParent_NoClientCode();1082}10831084/**1085* Associate a {@code DropTarget} with this component.1086* The {@code Component} will receive drops only if it1087* is enabled.1088*1089* @see #isEnabled1090* @param dt The DropTarget1091*/10921093public synchronized void setDropTarget(DropTarget dt) {1094if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))1095return;10961097DropTarget old;10981099if ((old = dropTarget) != null) {1100dropTarget.removeNotify();11011102DropTarget t = dropTarget;11031104dropTarget = null;11051106try {1107t.setComponent(null);1108} catch (IllegalArgumentException iae) {1109// ignore it.1110}1111}11121113// if we have a new one, and we have a peer, add it!11141115if ((dropTarget = dt) != null) {1116try {1117dropTarget.setComponent(this);1118dropTarget.addNotify();1119} catch (IllegalArgumentException iae) {1120if (old != null) {1121try {1122old.setComponent(this);1123dropTarget.addNotify();1124} catch (IllegalArgumentException iae1) {1125// ignore it!1126}1127}1128}1129}1130}11311132/**1133* Gets the {@code DropTarget} associated with this1134* {@code Component}.1135*1136* @return the drop target1137*/11381139public synchronized DropTarget getDropTarget() { return dropTarget; }11401141/**1142* Gets the {@code GraphicsConfiguration} associated with this1143* {@code Component}.1144* If the {@code Component} has not been assigned a specific1145* {@code GraphicsConfiguration},1146* the {@code GraphicsConfiguration} of the1147* {@code Component} object's top-level container is1148* returned.1149* If the {@code Component} has been created, but not yet added1150* to a {@code Container}, this method returns {@code null}.1151*1152* @return the {@code GraphicsConfiguration} used by this1153* {@code Component} or {@code null}1154* @since 1.31155*/1156public GraphicsConfiguration getGraphicsConfiguration() {1157return getGraphicsConfiguration_NoClientCode();1158}11591160final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {1161return graphicsConfig;1162}11631164void setGraphicsConfiguration(GraphicsConfiguration gc) {1165synchronized(getTreeLock()) {1166if (updateGraphicsData(gc)) {1167removeNotify();1168addNotify();1169}1170}1171}11721173final boolean updateGraphicsData(GraphicsConfiguration gc) {1174GraphicsConfiguration oldConfig = graphicsConfig;1175// First, update own graphics configuration1176boolean ret = updateSelfGraphicsData(gc);1177// Second, update children graphics configurations1178ret |= updateChildGraphicsData(gc);1179// Third, fire PropertyChange if needed1180if (oldConfig != gc) {1181/*1182* If component is moved from one screen to another screen or shown1183* for the first time graphicsConfiguration property is fired to1184* enable the component to recalculate any rendering data, if needed1185*/1186firePropertyChange("graphicsConfiguration", oldConfig, gc);1187}1188return ret;1189}11901191private boolean updateSelfGraphicsData(GraphicsConfiguration gc) {1192checkTreeLock();1193if (graphicsConfig == gc) {1194return false;1195}1196graphicsConfig = gc;11971198ComponentPeer peer = this.peer;1199if (peer != null) {1200return peer.updateGraphicsData(gc);1201}1202return false;1203}12041205boolean updateChildGraphicsData(GraphicsConfiguration gc) {1206return false;1207}12081209/**1210* Checks that this component's {@code GraphicsDevice}1211* {@code idString} matches the string argument.1212*/1213void checkGD(String stringID) {1214if (graphicsConfig != null) {1215if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {1216throw new IllegalArgumentException(1217"adding a container to a container on a different GraphicsDevice");1218}1219}1220}12211222/**1223* Gets this component's locking object (the object that owns the thread1224* synchronization monitor) for AWT component-tree and layout1225* operations.1226* @return this component's locking object1227*/1228public final Object getTreeLock() {1229return LOCK;1230}12311232final void checkTreeLock() {1233if (!Thread.holdsLock(getTreeLock())) {1234throw new IllegalStateException("This function should be called while holding treeLock");1235}1236}12371238/**1239* Gets the toolkit of this component. Note that1240* the frame that contains a component controls which1241* toolkit is used by that component. Therefore if the component1242* is moved from one frame to another, the toolkit it uses may change.1243* @return the toolkit of this component1244* @since 1.01245*/1246public Toolkit getToolkit() {1247return getToolkitImpl();1248}12491250/*1251* This is called by the native code, so client code can't1252* be called on the toolkit thread.1253*/1254final Toolkit getToolkitImpl() {1255Container parent = this.parent;1256if (parent != null) {1257return parent.getToolkitImpl();1258}1259return Toolkit.getDefaultToolkit();1260}12611262final ComponentFactory getComponentFactory() {1263final Toolkit toolkit = getToolkit();1264if (toolkit instanceof ComponentFactory) {1265return (ComponentFactory) toolkit;1266}1267throw new AWTError("UI components are unsupported by: " + toolkit);1268}12691270/**1271* Determines whether this component is valid. A component is valid1272* when it is correctly sized and positioned within its parent1273* container and all its children are also valid.1274* In order to account for peers' size requirements, components are invalidated1275* before they are first shown on the screen. By the time the parent container1276* is fully realized, all its components will be valid.1277* @return {@code true} if the component is valid, {@code false}1278* otherwise1279* @see #validate1280* @see #invalidate1281* @since 1.01282*/1283public boolean isValid() {1284return (peer != null) && valid;1285}12861287/**1288* Determines whether this component is displayable. A component is1289* displayable when it is connected to a native screen resource.1290* <p>1291* A component is made displayable either when it is added to1292* a displayable containment hierarchy or when its containment1293* hierarchy is made displayable.1294* A containment hierarchy is made displayable when its ancestor1295* window is either packed or made visible.1296* <p>1297* A component is made undisplayable either when it is removed from1298* a displayable containment hierarchy or when its containment hierarchy1299* is made undisplayable. A containment hierarchy is made1300* undisplayable when its ancestor window is disposed.1301*1302* @return {@code true} if the component is displayable,1303* {@code false} otherwise1304* @see Container#add(Component)1305* @see Window#pack1306* @see Window#show1307* @see Container#remove(Component)1308* @see Window#dispose1309* @since 1.21310*/1311public boolean isDisplayable() {1312return peer != null;1313}13141315/**1316* Determines whether this component should be visible when its1317* parent is visible. Components are1318* initially visible, with the exception of top level components such1319* as {@code Frame} objects.1320* @return {@code true} if the component is visible,1321* {@code false} otherwise1322* @see #setVisible1323* @since 1.01324*/1325@Transient1326public boolean isVisible() {1327return isVisible_NoClientCode();1328}1329final boolean isVisible_NoClientCode() {1330return visible;1331}13321333/**1334* Determines whether this component will be displayed on the screen.1335* @return {@code true} if the component and all of its ancestors1336* until a toplevel window or null parent are visible,1337* {@code false} otherwise1338*/1339boolean isRecursivelyVisible() {1340return visible && (parent == null || parent.isRecursivelyVisible());1341}13421343/**1344* Determines the bounds of a visible part of the component relative to its1345* parent.1346*1347* @return the visible part of bounds1348*/1349private Rectangle getRecursivelyVisibleBounds() {1350final Component container = getContainer();1351final Rectangle bounds = getBounds();1352if (container == null) {1353// we are top level window or haven't a container, return our bounds1354return bounds;1355}1356// translate the container's bounds to our coordinate space1357final Rectangle parentsBounds = container.getRecursivelyVisibleBounds();1358parentsBounds.setLocation(0, 0);1359return parentsBounds.intersection(bounds);1360}13611362/**1363* Translates absolute coordinates into coordinates in the coordinate1364* space of this component.1365*/1366Point pointRelativeToComponent(Point absolute) {1367Point compCoords = getLocationOnScreen();1368return new Point(absolute.x - compCoords.x,1369absolute.y - compCoords.y);1370}13711372/**1373* Assuming that mouse location is stored in PointerInfo passed1374* to this method, it finds a Component that is in the same1375* Window as this Component and is located under the mouse pointer.1376* If no such Component exists, null is returned.1377* NOTE: this method should be called under the protection of1378* tree lock, as it is done in Component.getMousePosition() and1379* Container.getMousePosition(boolean).1380*/1381Component findUnderMouseInWindow(PointerInfo pi) {1382if (!isShowing()) {1383return null;1384}1385Window win = getContainingWindow();1386Toolkit toolkit = Toolkit.getDefaultToolkit();1387if (!(toolkit instanceof ComponentFactory)) {1388return null;1389}1390if (!((ComponentFactory) toolkit).getMouseInfoPeer().isWindowUnderMouse(win)) {1391return null;1392}1393final boolean INCLUDE_DISABLED = true;1394Point relativeToWindow = win.pointRelativeToComponent(pi.getLocation());1395Component inTheSameWindow = win.findComponentAt(relativeToWindow.x,1396relativeToWindow.y,1397INCLUDE_DISABLED);1398return inTheSameWindow;1399}14001401/**1402* Returns the position of the mouse pointer in this {@code Component}'s1403* coordinate space if the {@code Component} is directly under the mouse1404* pointer, otherwise returns {@code null}.1405* If the {@code Component} is not showing on the screen, this method1406* returns {@code null} even if the mouse pointer is above the area1407* where the {@code Component} would be displayed.1408* If the {@code Component} is partially or fully obscured by other1409* {@code Component}s or native windows, this method returns a non-null1410* value only if the mouse pointer is located above the unobscured part of the1411* {@code Component}.1412* <p>1413* For {@code Container}s it returns a non-null value if the mouse is1414* above the {@code Container} itself or above any of its descendants.1415* Use {@link Container#getMousePosition(boolean)} if you need to exclude children.1416* <p>1417* Sometimes the exact mouse coordinates are not important, and the only thing1418* that matters is whether a specific {@code Component} is under the mouse1419* pointer. If the return value of this method is {@code null}, mouse1420* pointer is not directly above the {@code Component}.1421*1422* @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true1423* @see #isShowing1424* @see Container#getMousePosition1425* @return mouse coordinates relative to this {@code Component}, or null1426* @since 1.51427*/1428public Point getMousePosition() throws HeadlessException {1429if (GraphicsEnvironment.isHeadless()) {1430throw new HeadlessException();1431}14321433@SuppressWarnings("removal")1434PointerInfo pi = java.security.AccessController.doPrivileged(1435new java.security.PrivilegedAction<PointerInfo>() {1436public PointerInfo run() {1437return MouseInfo.getPointerInfo();1438}1439}1440);14411442synchronized (getTreeLock()) {1443Component inTheSameWindow = findUnderMouseInWindow(pi);1444if (!isSameOrAncestorOf(inTheSameWindow, true)) {1445return null;1446}1447return pointRelativeToComponent(pi.getLocation());1448}1449}14501451/**1452* Overridden in Container. Must be called under TreeLock.1453*/1454boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {1455return comp == this;1456}14571458/**1459* Determines whether this component is showing on screen. This means1460* that the component must be visible, and it must be in a container1461* that is visible and showing.1462* <p>1463* <strong>Note:</strong> sometimes there is no way to detect whether the1464* {@code Component} is actually visible to the user. This can happen when:1465* <ul>1466* <li>the component has been added to a visible {@code ScrollPane} but1467* the {@code Component} is not currently in the scroll pane's view port.1468* <li>the {@code Component} is obscured by another {@code Component} or1469* {@code Container}.1470* </ul>1471* @return {@code true} if the component is showing,1472* {@code false} otherwise1473* @see #setVisible1474* @since 1.01475*/1476public boolean isShowing() {1477if (visible && (peer != null)) {1478Container parent = this.parent;1479return (parent == null) || parent.isShowing();1480}1481return false;1482}14831484/**1485* Determines whether this component is enabled. An enabled component1486* can respond to user input and generate events. Components are1487* enabled initially by default. A component may be enabled or disabled by1488* calling its {@code setEnabled} method.1489* @return {@code true} if the component is enabled,1490* {@code false} otherwise1491* @see #setEnabled1492* @since 1.01493*/1494public boolean isEnabled() {1495return isEnabledImpl();1496}14971498/*1499* This is called by the native code, so client code can't1500* be called on the toolkit thread.1501*/1502final boolean isEnabledImpl() {1503return enabled;1504}15051506/**1507* Enables or disables this component, depending on the value of the1508* parameter {@code b}. An enabled component can respond to user1509* input and generate events. Components are enabled initially by default.1510*1511* <p>Note: Disabling a lightweight component does not prevent it from1512* receiving MouseEvents.1513* <p>Note: Disabling a heavyweight container prevents all components1514* in this container from receiving any input events. But disabling a1515* lightweight container affects only this container.1516*1517* @param b If {@code true}, this component is1518* enabled; otherwise this component is disabled1519* @see #isEnabled1520* @see #isLightweight1521* @since 1.11522*/1523public void setEnabled(boolean b) {1524enable(b);1525}15261527/**1528* @deprecated As of JDK version 1.1,1529* replaced by {@code setEnabled(boolean)}.1530*/1531@Deprecated1532public void enable() {1533if (!enabled) {1534synchronized (getTreeLock()) {1535enabled = true;1536ComponentPeer peer = this.peer;1537if (peer != null) {1538peer.setEnabled(true);1539if (visible && !getRecursivelyVisibleBounds().isEmpty()) {1540updateCursorImmediately();1541}1542}1543}1544if (accessibleContext != null) {1545accessibleContext.firePropertyChange(1546AccessibleContext.ACCESSIBLE_STATE_PROPERTY,1547null, AccessibleState.ENABLED);1548}1549}1550}15511552/**1553* Enables or disables this component.1554*1555* @param b {@code true} to enable this component;1556* otherwise {@code false}1557*1558* @deprecated As of JDK version 1.1,1559* replaced by {@code setEnabled(boolean)}.1560*/1561@Deprecated1562public void enable(boolean b) {1563if (b) {1564enable();1565} else {1566disable();1567}1568}15691570/**1571* @deprecated As of JDK version 1.1,1572* replaced by {@code setEnabled(boolean)}.1573*/1574@Deprecated1575public void disable() {1576if (enabled) {1577KeyboardFocusManager.clearMostRecentFocusOwner(this);1578synchronized (getTreeLock()) {1579enabled = false;1580// A disabled lw container is allowed to contain a focus owner.1581if ((isFocusOwner() || (containsFocus() && !isLightweight())) &&1582KeyboardFocusManager.isAutoFocusTransferEnabled())1583{1584// Don't clear the global focus owner. If transferFocus1585// fails, we want the focus to stay on the disabled1586// Component so that keyboard traversal, et. al. still1587// makes sense to the user.1588transferFocus(false);1589}1590ComponentPeer peer = this.peer;1591if (peer != null) {1592peer.setEnabled(false);1593if (visible && !getRecursivelyVisibleBounds().isEmpty()) {1594updateCursorImmediately();1595}1596}1597}1598if (accessibleContext != null) {1599accessibleContext.firePropertyChange(1600AccessibleContext.ACCESSIBLE_STATE_PROPERTY,1601null, AccessibleState.ENABLED);1602}1603}1604}16051606/**1607* Returns true if this component is painted to an offscreen image1608* ("buffer") that's copied to the screen later. Component1609* subclasses that support double buffering should override this1610* method to return true if double buffering is enabled.1611*1612* @return false by default1613*/1614public boolean isDoubleBuffered() {1615return false;1616}16171618/**1619* Enables or disables input method support for this component. If input1620* method support is enabled and the component also processes key events,1621* incoming events are offered to1622* the current input method and will only be processed by the component or1623* dispatched to its listeners if the input method does not consume them.1624* By default, input method support is enabled.1625*1626* @param enable true to enable, false to disable1627* @see #processKeyEvent1628* @since 1.21629*/1630public void enableInputMethods(boolean enable) {1631if (enable) {1632if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)1633return;16341635// If this component already has focus, then activate the1636// input method by dispatching a synthesized focus gained1637// event.1638if (isFocusOwner()) {1639InputContext inputContext = getInputContext();1640if (inputContext != null) {1641FocusEvent focusGainedEvent =1642new FocusEvent(this, FocusEvent.FOCUS_GAINED);1643inputContext.dispatchEvent(focusGainedEvent);1644}1645}16461647eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK;1648} else {1649if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {1650InputContext inputContext = getInputContext();1651if (inputContext != null) {1652inputContext.endComposition();1653inputContext.removeNotify(this);1654}1655}1656eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK;1657}1658}16591660/**1661* Shows or hides this component depending on the value of parameter1662* {@code b}.1663* <p>1664* This method changes layout-related information, and therefore,1665* invalidates the component hierarchy.1666*1667* @param b if {@code true}, shows this component;1668* otherwise, hides this component1669* @see #isVisible1670* @see #invalidate1671* @since 1.11672*/1673public void setVisible(boolean b) {1674show(b);1675}16761677/**1678* @deprecated As of JDK version 1.1,1679* replaced by {@code setVisible(boolean)}.1680*/1681@Deprecated1682public void show() {1683if (!visible) {1684synchronized (getTreeLock()) {1685visible = true;1686mixOnShowing();1687ComponentPeer peer = this.peer;1688if (peer != null) {1689peer.setVisible(true);1690createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,1691this, parent,1692HierarchyEvent.SHOWING_CHANGED,1693Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));1694if (peer instanceof LightweightPeer) {1695repaint();1696}1697updateCursorImmediately();1698}16991700if (componentListener != null ||1701(eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||1702Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {1703ComponentEvent e = new ComponentEvent(this,1704ComponentEvent.COMPONENT_SHOWN);1705Toolkit.getEventQueue().postEvent(e);1706}1707}1708Container parent = this.parent;1709if (parent != null) {1710parent.invalidate();1711}1712}1713}17141715/**1716* Makes this component visible or invisible.1717*1718* @param b {@code true} to make this component visible;1719* otherwise {@code false}1720*1721* @deprecated As of JDK version 1.1,1722* replaced by {@code setVisible(boolean)}.1723*/1724@Deprecated1725public void show(boolean b) {1726if (b) {1727show();1728} else {1729hide();1730}1731}17321733boolean containsFocus() {1734return isFocusOwner();1735}17361737void clearMostRecentFocusOwnerOnHide() {1738KeyboardFocusManager.clearMostRecentFocusOwner(this);1739}17401741void clearCurrentFocusCycleRootOnHide() {1742/* do nothing */1743}17441745/**1746* @deprecated As of JDK version 1.1,1747* replaced by {@code setVisible(boolean)}.1748*/1749@Deprecated1750public void hide() {1751isPacked = false;17521753if (visible) {1754clearCurrentFocusCycleRootOnHide();1755clearMostRecentFocusOwnerOnHide();1756synchronized (getTreeLock()) {1757visible = false;1758mixOnHiding(isLightweight());1759if (containsFocus() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {1760transferFocus(true);1761}1762ComponentPeer peer = this.peer;1763if (peer != null) {1764peer.setVisible(false);1765createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,1766this, parent,1767HierarchyEvent.SHOWING_CHANGED,1768Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));1769if (peer instanceof LightweightPeer) {1770repaint();1771}1772updateCursorImmediately();1773}1774if (componentListener != null ||1775(eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||1776Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {1777ComponentEvent e = new ComponentEvent(this,1778ComponentEvent.COMPONENT_HIDDEN);1779Toolkit.getEventQueue().postEvent(e);1780}1781}1782Container parent = this.parent;1783if (parent != null) {1784parent.invalidate();1785}1786}1787}17881789/**1790* Gets the foreground color of this component.1791* @return this component's foreground color; if this component does1792* not have a foreground color, the foreground color of its parent1793* is returned1794* @see #setForeground1795* @since 1.01796*/1797@Transient1798public Color getForeground() {1799Color foreground = this.foreground;1800if (foreground != null) {1801return foreground;1802}1803Container parent = this.parent;1804return (parent != null) ? parent.getForeground() : null;1805}18061807/**1808* Sets the foreground color of this component.1809* @param c the color to become this component's1810* foreground color; if this parameter is {@code null}1811* then this component will inherit1812* the foreground color of its parent1813* @see #getForeground1814* @since 1.01815*/1816public void setForeground(Color c) {1817Color oldColor = foreground;1818ComponentPeer peer = this.peer;1819foreground = c;1820if (peer != null) {1821c = getForeground();1822if (c != null) {1823peer.setForeground(c);1824}1825}1826// This is a bound property, so report the change to1827// any registered listeners. (Cheap if there are none.)1828firePropertyChange("foreground", oldColor, c);1829}18301831/**1832* Returns whether the foreground color has been explicitly set for this1833* Component. If this method returns {@code false}, this Component is1834* inheriting its foreground color from an ancestor.1835*1836* @return {@code true} if the foreground color has been explicitly1837* set for this Component; {@code false} otherwise.1838* @since 1.41839*/1840public boolean isForegroundSet() {1841return (foreground != null);1842}18431844/**1845* Gets the background color of this component.1846* @return this component's background color; if this component does1847* not have a background color,1848* the background color of its parent is returned1849* @see #setBackground1850* @since 1.01851*/1852@Transient1853public Color getBackground() {1854Color background = this.background;1855if (background != null) {1856return background;1857}1858Container parent = this.parent;1859return (parent != null) ? parent.getBackground() : null;1860}18611862/**1863* Sets the background color of this component.1864* <p>1865* The background color affects each component differently and the1866* parts of the component that are affected by the background color1867* may differ between operating systems.1868*1869* @param c the color to become this component's color;1870* if this parameter is {@code null}, then this1871* component will inherit the background color of its parent1872* @see #getBackground1873* @since 1.01874*/1875public void setBackground(Color c) {1876Color oldColor = background;1877ComponentPeer peer = this.peer;1878background = c;1879if (peer != null) {1880c = getBackground();1881if (c != null) {1882peer.setBackground(c);1883}1884}1885// This is a bound property, so report the change to1886// any registered listeners. (Cheap if there are none.)1887firePropertyChange("background", oldColor, c);1888}18891890/**1891* Returns whether the background color has been explicitly set for this1892* Component. If this method returns {@code false}, this Component is1893* inheriting its background color from an ancestor.1894*1895* @return {@code true} if the background color has been explicitly1896* set for this Component; {@code false} otherwise.1897* @since 1.41898*/1899public boolean isBackgroundSet() {1900return (background != null);1901}19021903/**1904* Gets the font of this component.1905* @return this component's font; if a font has not been set1906* for this component, the font of its parent is returned1907* @see #setFont1908* @since 1.01909*/1910@Transient1911public Font getFont() {1912return getFont_NoClientCode();1913}19141915// NOTE: This method may be called by privileged threads.1916// This functionality is implemented in a package-private method1917// to insure that it cannot be overridden by client subclasses.1918// DO NOT INVOKE CLIENT CODE ON THIS THREAD!1919final Font getFont_NoClientCode() {1920Font font = this.font;1921if (font != null) {1922return font;1923}1924Container parent = this.parent;1925return (parent != null) ? parent.getFont_NoClientCode() : null;1926}19271928/**1929* Sets the font of this component.1930* <p>1931* This method changes layout-related information, and therefore,1932* invalidates the component hierarchy.1933*1934* @param f the font to become this component's font;1935* if this parameter is {@code null} then this1936* component will inherit the font of its parent1937* @see #getFont1938* @see #invalidate1939* @since 1.01940*/1941public void setFont(Font f) {1942Font oldFont, newFont;1943synchronized(getTreeLock()) {1944oldFont = font;1945newFont = font = f;1946ComponentPeer peer = this.peer;1947if (peer != null) {1948f = getFont();1949if (f != null) {1950peer.setFont(f);1951peerFont = f;1952}1953}1954}1955// This is a bound property, so report the change to1956// any registered listeners. (Cheap if there are none.)1957firePropertyChange("font", oldFont, newFont);19581959// This could change the preferred size of the Component.1960// Fix for 6213660. Should compare old and new fonts and do not1961// call invalidate() if they are equal.1962if (f != oldFont && (oldFont == null ||1963!oldFont.equals(f))) {1964invalidateIfValid();1965}1966}19671968/**1969* Returns whether the font has been explicitly set for this Component. If1970* this method returns {@code false}, this Component is inheriting its1971* font from an ancestor.1972*1973* @return {@code true} if the font has been explicitly set for this1974* Component; {@code false} otherwise.1975* @since 1.41976*/1977public boolean isFontSet() {1978return (font != null);1979}19801981/**1982* Gets the locale of this component.1983* @return this component's locale; if this component does not1984* have a locale, the locale of its parent is returned1985* @see #setLocale1986* @exception IllegalComponentStateException if the {@code Component}1987* does not have its own locale and has not yet been added to1988* a containment hierarchy such that the locale can be determined1989* from the containing parent1990* @since 1.11991*/1992public Locale getLocale() {1993Locale locale = this.locale;1994if (locale != null) {1995return locale;1996}1997Container parent = this.parent;19981999if (parent == null) {2000throw new IllegalComponentStateException("This component must have a parent in order to determine its locale");2001} else {2002return parent.getLocale();2003}2004}20052006/**2007* Sets the locale of this component. This is a bound property.2008* <p>2009* This method changes layout-related information, and therefore,2010* invalidates the component hierarchy.2011*2012* @param l the locale to become this component's locale2013* @see #getLocale2014* @see #invalidate2015* @since 1.12016*/2017public void setLocale(Locale l) {2018Locale oldValue = locale;2019locale = l;20202021// This is a bound property, so report the change to2022// any registered listeners. (Cheap if there are none.)2023firePropertyChange("locale", oldValue, l);20242025// This could change the preferred size of the Component.2026invalidateIfValid();2027}20282029/**2030* Gets the instance of {@code ColorModel} used to display2031* the component on the output device.2032* @return the color model used by this component2033* @see java.awt.image.ColorModel2034* @see java.awt.peer.ComponentPeer#getColorModel()2035* @see Toolkit#getColorModel()2036* @since 1.02037*/2038public ColorModel getColorModel() {2039ComponentPeer peer = this.peer;2040if ((peer != null) && ! (peer instanceof LightweightPeer)) {2041return peer.getColorModel();2042} else if (GraphicsEnvironment.isHeadless()) {2043return ColorModel.getRGBdefault();2044} // else2045return getToolkit().getColorModel();2046}20472048/**2049* Gets the location of this component in the form of a2050* point specifying the component's top-left corner.2051* The location will be relative to the parent's coordinate space.2052* <p>2053* Due to the asynchronous nature of native event handling, this2054* method can return outdated values (for instance, after several calls2055* of {@code setLocation()} in rapid succession). For this2056* reason, the recommended method of obtaining a component's position is2057* within {@code java.awt.event.ComponentListener.componentMoved()},2058* which is called after the operating system has finished moving the2059* component.2060* </p>2061* @return an instance of {@code Point} representing2062* the top-left corner of the component's bounds in2063* the coordinate space of the component's parent2064* @see #setLocation2065* @see #getLocationOnScreen2066* @since 1.12067*/2068public Point getLocation() {2069return location();2070}20712072/**2073* Gets the location of this component in the form of a point2074* specifying the component's top-left corner in the screen's2075* coordinate space.2076* @return an instance of {@code Point} representing2077* the top-left corner of the component's bounds in the2078* coordinate space of the screen2079* @throws IllegalComponentStateException if the2080* component is not showing on the screen2081* @see #setLocation2082* @see #getLocation2083*/2084public Point getLocationOnScreen() {2085synchronized (getTreeLock()) {2086return getLocationOnScreen_NoTreeLock();2087}2088}20892090/*2091* a package private version of getLocationOnScreen2092* used by GlobalCursormanager to update cursor2093*/2094final Point getLocationOnScreen_NoTreeLock() {2095ComponentPeer peer = this.peer;2096if (peer != null && isShowing()) {2097if (peer instanceof LightweightPeer) {2098// lightweight component location needs to be translated2099// relative to a native component.2100Container host = getNativeContainer();2101Point pt = host.peer.getLocationOnScreen();2102for(Component c = this; c != host; c = c.getContainer()) {2103pt.x += c.x;2104pt.y += c.y;2105}2106return pt;2107} else {2108Point pt = peer.getLocationOnScreen();2109return pt;2110}2111} else {2112throw new IllegalComponentStateException("component must be showing on the screen to determine its location");2113}2114}211521162117/**2118* Returns the location of this component's top left corner.2119*2120* @return the location of this component's top left corner2121* @deprecated As of JDK version 1.1,2122* replaced by {@code getLocation()}.2123*/2124@Deprecated2125public Point location() {2126return location_NoClientCode();2127}21282129private Point location_NoClientCode() {2130return new Point(x, y);2131}21322133/**2134* Moves this component to a new location. The top-left corner of2135* the new location is specified by the {@code x} and {@code y}2136* parameters in the coordinate space of this component's parent.2137* <p>2138* This method changes layout-related information, and therefore,2139* invalidates the component hierarchy.2140*2141* @param x the <i>x</i>-coordinate of the new location's2142* top-left corner in the parent's coordinate space2143* @param y the <i>y</i>-coordinate of the new location's2144* top-left corner in the parent's coordinate space2145* @see #getLocation2146* @see #setBounds2147* @see #invalidate2148* @since 1.12149*/2150public void setLocation(int x, int y) {2151move(x, y);2152}21532154/**2155* Moves this component to a new location.2156*2157* @param x the <i>x</i>-coordinate of the new location's2158* top-left corner in the parent's coordinate space2159* @param y the <i>y</i>-coordinate of the new location's2160* top-left corner in the parent's coordinate space2161*2162* @deprecated As of JDK version 1.1,2163* replaced by {@code setLocation(int, int)}.2164*/2165@Deprecated2166public void move(int x, int y) {2167synchronized(getTreeLock()) {2168setBoundsOp(ComponentPeer.SET_LOCATION);2169setBounds(x, y, width, height);2170}2171}21722173/**2174* Moves this component to a new location. The top-left corner of2175* the new location is specified by point {@code p}. Point2176* {@code p} is given in the parent's coordinate space.2177* <p>2178* This method changes layout-related information, and therefore,2179* invalidates the component hierarchy.2180*2181* @param p the point defining the top-left corner2182* of the new location, given in the coordinate space of this2183* component's parent2184* @see #getLocation2185* @see #setBounds2186* @see #invalidate2187* @since 1.12188*/2189public void setLocation(Point p) {2190setLocation(p.x, p.y);2191}21922193/**2194* Returns the size of this component in the form of a2195* {@code Dimension} object. The {@code height}2196* field of the {@code Dimension} object contains2197* this component's height, and the {@code width}2198* field of the {@code Dimension} object contains2199* this component's width.2200* @return a {@code Dimension} object that indicates the2201* size of this component2202* @see #setSize2203* @since 1.12204*/2205public Dimension getSize() {2206return size();2207}22082209/**2210* Returns the size of this component in the form of a2211* {@code Dimension} object.2212*2213* @return the {@code Dimension} object that indicates the2214* size of this component2215* @deprecated As of JDK version 1.1,2216* replaced by {@code getSize()}.2217*/2218@Deprecated2219public Dimension size() {2220return new Dimension(width, height);2221}22222223/**2224* Resizes this component so that it has width {@code width}2225* and height {@code height}.2226* <p>2227* This method changes layout-related information, and therefore,2228* invalidates the component hierarchy.2229*2230* @param width the new width of this component in pixels2231* @param height the new height of this component in pixels2232* @see #getSize2233* @see #setBounds2234* @see #invalidate2235* @since 1.12236*/2237public void setSize(int width, int height) {2238resize(width, height);2239}22402241/**2242* Resizes this component.2243*2244* @param width the new width of the component2245* @param height the new height of the component2246* @deprecated As of JDK version 1.1,2247* replaced by {@code setSize(int, int)}.2248*/2249@Deprecated2250public void resize(int width, int height) {2251synchronized(getTreeLock()) {2252setBoundsOp(ComponentPeer.SET_SIZE);2253setBounds(x, y, width, height);2254}2255}22562257/**2258* Resizes this component so that it has width {@code d.width}2259* and height {@code d.height}.2260* <p>2261* This method changes layout-related information, and therefore,2262* invalidates the component hierarchy.2263*2264* @param d the dimension specifying the new size2265* of this component2266* @throws NullPointerException if {@code d} is {@code null}2267* @see #setSize2268* @see #setBounds2269* @see #invalidate2270* @since 1.12271*/2272public void setSize(Dimension d) {2273resize(d);2274}22752276/**2277* Resizes this component so that it has width {@code d.width}2278* and height {@code d.height}.2279*2280* @param d the new size of this component2281* @deprecated As of JDK version 1.1,2282* replaced by {@code setSize(Dimension)}.2283*/2284@Deprecated2285public void resize(Dimension d) {2286setSize(d.width, d.height);2287}22882289/**2290* Gets the bounds of this component in the form of a2291* {@code Rectangle} object. The bounds specify this2292* component's width, height, and location relative to2293* its parent.2294* @return a rectangle indicating this component's bounds2295* @see #setBounds2296* @see #getLocation2297* @see #getSize2298*/2299public Rectangle getBounds() {2300return bounds();2301}23022303/**2304* Returns the bounding rectangle of this component.2305*2306* @return the bounding rectangle for this component2307* @deprecated As of JDK version 1.1,2308* replaced by {@code getBounds()}.2309*/2310@Deprecated2311public Rectangle bounds() {2312return new Rectangle(x, y, width, height);2313}23142315/**2316* Moves and resizes this component. The new location of the top-left2317* corner is specified by {@code x} and {@code y}, and the2318* new size is specified by {@code width} and {@code height}.2319* <p>2320* This method changes layout-related information, and therefore,2321* invalidates the component hierarchy.2322*2323* @param x the new <i>x</i>-coordinate of this component2324* @param y the new <i>y</i>-coordinate of this component2325* @param width the new {@code width} of this component2326* @param height the new {@code height} of this2327* component2328* @see #getBounds2329* @see #setLocation(int, int)2330* @see #setLocation(Point)2331* @see #setSize(int, int)2332* @see #setSize(Dimension)2333* @see #invalidate2334* @since 1.12335*/2336public void setBounds(int x, int y, int width, int height) {2337reshape(x, y, width, height);2338}23392340/**2341* Reshapes the bounding rectangle for this component.2342*2343* @param x the <i>x</i> coordinate of the upper left corner of the rectangle2344* @param y the <i>y</i> coordinate of the upper left corner of the rectangle2345* @param width the width of the rectangle2346* @param height the height of the rectangle2347*2348* @deprecated As of JDK version 1.1,2349* replaced by {@code setBounds(int, int, int, int)}.2350*/2351@Deprecated2352public void reshape(int x, int y, int width, int height) {2353synchronized (getTreeLock()) {2354try {2355setBoundsOp(ComponentPeer.SET_BOUNDS);2356boolean resized = (this.width != width) || (this.height != height);2357boolean moved = (this.x != x) || (this.y != y);2358if (!resized && !moved) {2359return;2360}2361int oldX = this.x;2362int oldY = this.y;2363int oldWidth = this.width;2364int oldHeight = this.height;2365this.x = x;2366this.y = y;2367this.width = width;2368this.height = height;23692370if (resized) {2371isPacked = false;2372}23732374boolean needNotify = true;2375mixOnReshaping();2376if (peer != null) {2377// LightweightPeer is an empty stub so can skip peer.reshape2378if (!(peer instanceof LightweightPeer)) {2379reshapeNativePeer(x, y, width, height, getBoundsOp());2380// Check peer actually changed coordinates2381resized = (oldWidth != this.width) || (oldHeight != this.height);2382moved = (oldX != this.x) || (oldY != this.y);2383// fix for 5025858: do not send ComponentEvents for toplevel2384// windows here as it is done from peer or native code when2385// the window is really resized or moved, otherwise some2386// events may be sent twice2387if (this instanceof Window) {2388needNotify = false;2389}2390}2391if (resized) {2392invalidate();2393}2394if (parent != null) {2395parent.invalidateIfValid();2396}2397}2398if (needNotify) {2399notifyNewBounds(resized, moved);2400}2401repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight);2402} finally {2403setBoundsOp(ComponentPeer.RESET_OPERATION);2404}2405}2406}24072408private void repaintParentIfNeeded(int oldX, int oldY, int oldWidth,2409int oldHeight)2410{2411if (parent != null && peer instanceof LightweightPeer && isShowing()) {2412// Have the parent redraw the area this component occupied.2413parent.repaint(oldX, oldY, oldWidth, oldHeight);2414// Have the parent redraw the area this component *now* occupies.2415repaint();2416}2417}24182419private void reshapeNativePeer(int x, int y, int width, int height, int op) {2420// native peer might be offset by more than direct2421// parent since parent might be lightweight.2422int nativeX = x;2423int nativeY = y;2424for (Component c = parent;2425(c != null) && (c.peer instanceof LightweightPeer);2426c = c.parent)2427{2428nativeX += c.x;2429nativeY += c.y;2430}2431peer.setBounds(nativeX, nativeY, width, height, op);2432}24332434@SuppressWarnings("deprecation")2435private void notifyNewBounds(boolean resized, boolean moved) {2436if (componentListener != null2437|| (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 02438|| Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK))2439{2440if (resized) {2441ComponentEvent e = new ComponentEvent(this,2442ComponentEvent.COMPONENT_RESIZED);2443Toolkit.getEventQueue().postEvent(e);2444}2445if (moved) {2446ComponentEvent e = new ComponentEvent(this,2447ComponentEvent.COMPONENT_MOVED);2448Toolkit.getEventQueue().postEvent(e);2449}2450} else {2451if (this instanceof Container && ((Container)this).countComponents() > 0) {2452boolean enabledOnToolkit =2453Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);2454if (resized) {24552456((Container)this).createChildHierarchyEvents(2457HierarchyEvent.ANCESTOR_RESIZED, 0, enabledOnToolkit);2458}2459if (moved) {2460((Container)this).createChildHierarchyEvents(2461HierarchyEvent.ANCESTOR_MOVED, 0, enabledOnToolkit);2462}2463}2464}2465}24662467/**2468* Moves and resizes this component to conform to the new2469* bounding rectangle {@code r}. This component's new2470* position is specified by {@code r.x} and {@code r.y},2471* and its new size is specified by {@code r.width} and2472* {@code r.height}2473* <p>2474* This method changes layout-related information, and therefore,2475* invalidates the component hierarchy.2476*2477* @param r the new bounding rectangle for this component2478* @throws NullPointerException if {@code r} is {@code null}2479* @see #getBounds2480* @see #setLocation(int, int)2481* @see #setLocation(Point)2482* @see #setSize(int, int)2483* @see #setSize(Dimension)2484* @see #invalidate2485* @since 1.12486*/2487public void setBounds(Rectangle r) {2488setBounds(r.x, r.y, r.width, r.height);2489}249024912492/**2493* Returns the current x coordinate of the components origin.2494* This method is preferable to writing2495* {@code component.getBounds().x},2496* or {@code component.getLocation().x} because it doesn't2497* cause any heap allocations.2498*2499* @return the current x coordinate of the components origin2500* @since 1.22501*/2502public int getX() {2503return x;2504}250525062507/**2508* Returns the current y coordinate of the components origin.2509* This method is preferable to writing2510* {@code component.getBounds().y},2511* or {@code component.getLocation().y} because it2512* doesn't cause any heap allocations.2513*2514* @return the current y coordinate of the components origin2515* @since 1.22516*/2517public int getY() {2518return y;2519}252025212522/**2523* Returns the current width of this component.2524* This method is preferable to writing2525* {@code component.getBounds().width},2526* or {@code component.getSize().width} because it2527* doesn't cause any heap allocations.2528*2529* @return the current width of this component2530* @since 1.22531*/2532public int getWidth() {2533return width;2534}253525362537/**2538* Returns the current height of this component.2539* This method is preferable to writing2540* {@code component.getBounds().height},2541* or {@code component.getSize().height} because it2542* doesn't cause any heap allocations.2543*2544* @return the current height of this component2545* @since 1.22546*/2547public int getHeight() {2548return height;2549}25502551/**2552* Stores the bounds of this component into "return value" <b>rv</b> and2553* return <b>rv</b>. If rv is {@code null} a new2554* {@code Rectangle} is allocated.2555* This version of {@code getBounds} is useful if the caller2556* wants to avoid allocating a new {@code Rectangle} object2557* on the heap.2558*2559* @param rv the return value, modified to the components bounds2560* @return rv2561*/2562public Rectangle getBounds(Rectangle rv) {2563if (rv == null) {2564return new Rectangle(getX(), getY(), getWidth(), getHeight());2565}2566else {2567rv.setBounds(getX(), getY(), getWidth(), getHeight());2568return rv;2569}2570}25712572/**2573* Stores the width/height of this component into "return value" <b>rv</b>2574* and return <b>rv</b>. If rv is {@code null} a new2575* {@code Dimension} object is allocated. This version of2576* {@code getSize} is useful if the caller wants to avoid2577* allocating a new {@code Dimension} object on the heap.2578*2579* @param rv the return value, modified to the components size2580* @return rv2581*/2582public Dimension getSize(Dimension rv) {2583if (rv == null) {2584return new Dimension(getWidth(), getHeight());2585}2586else {2587rv.setSize(getWidth(), getHeight());2588return rv;2589}2590}25912592/**2593* Stores the x,y origin of this component into "return value" <b>rv</b>2594* and return <b>rv</b>. If rv is {@code null} a new2595* {@code Point} is allocated.2596* This version of {@code getLocation} is useful if the2597* caller wants to avoid allocating a new {@code Point}2598* object on the heap.2599*2600* @param rv the return value, modified to the components location2601* @return rv2602*/2603public Point getLocation(Point rv) {2604if (rv == null) {2605return new Point(getX(), getY());2606}2607else {2608rv.setLocation(getX(), getY());2609return rv;2610}2611}26122613/**2614* Returns true if this component is completely opaque, returns2615* false by default.2616* <p>2617* An opaque component paints every pixel within its2618* rectangular region. A non-opaque component paints only some of2619* its pixels, allowing the pixels underneath it to "show through".2620* A component that does not fully paint its pixels therefore2621* provides a degree of transparency.2622* <p>2623* Subclasses that guarantee to always completely paint their2624* contents should override this method and return true.2625*2626* @return true if this component is completely opaque2627* @see #isLightweight2628* @since 1.22629*/2630public boolean isOpaque() {2631if (peer == null) {2632return false;2633}2634else {2635return !isLightweight();2636}2637}263826392640/**2641* A lightweight component doesn't have a native toolkit peer.2642* Subclasses of {@code Component} and {@code Container},2643* other than the ones defined in this package like {@code Button}2644* or {@code Scrollbar}, are lightweight.2645* All of the Swing components are lightweights.2646* <p>2647* This method will always return {@code false} if this component2648* is not displayable because it is impossible to determine the2649* weight of an undisplayable component.2650*2651* @return true if this component has a lightweight peer; false if2652* it has a native peer or no peer2653* @see #isDisplayable2654* @since 1.22655*/2656public boolean isLightweight() {2657return peer instanceof LightweightPeer;2658}265926602661/**2662* Sets the preferred size of this component to a constant2663* value. Subsequent calls to {@code getPreferredSize} will always2664* return this value. Setting the preferred size to {@code null}2665* restores the default behavior.2666*2667* @param preferredSize The new preferred size, or null2668* @see #getPreferredSize2669* @see #isPreferredSizeSet2670* @since 1.52671*/2672public void setPreferredSize(Dimension preferredSize) {2673Dimension old;2674// If the preferred size was set, use it as the old value, otherwise2675// use null to indicate we didn't previously have a set preferred2676// size.2677if (prefSizeSet) {2678old = this.prefSize;2679}2680else {2681old = null;2682}2683this.prefSize = preferredSize;2684prefSizeSet = (preferredSize != null);2685firePropertyChange("preferredSize", old, preferredSize);2686}268726882689/**2690* Returns true if the preferred size has been set to a2691* non-{@code null} value otherwise returns false.2692*2693* @return true if {@code setPreferredSize} has been invoked2694* with a non-null value.2695* @since 1.52696*/2697public boolean isPreferredSizeSet() {2698return prefSizeSet;2699}270027012702/**2703* Gets the preferred size of this component.2704* @return a dimension object indicating this component's preferred size2705* @see #getMinimumSize2706* @see LayoutManager2707*/2708public Dimension getPreferredSize() {2709return preferredSize();2710}271127122713/**2714* Returns the component's preferred size.2715*2716* @return the component's preferred size2717* @deprecated As of JDK version 1.1,2718* replaced by {@code getPreferredSize()}.2719*/2720@Deprecated2721public Dimension preferredSize() {2722/* Avoid grabbing the lock if a reasonable cached size value2723* is available.2724*/2725Dimension dim = prefSize;2726if (dim == null || !(isPreferredSizeSet() || isValid())) {2727synchronized (getTreeLock()) {2728prefSize = (peer != null) ?2729peer.getPreferredSize() :2730getMinimumSize();2731dim = prefSize;2732}2733}2734return new Dimension(dim);2735}27362737/**2738* Sets the minimum size of this component to a constant2739* value. Subsequent calls to {@code getMinimumSize} will always2740* return this value. Setting the minimum size to {@code null}2741* restores the default behavior.2742*2743* @param minimumSize the new minimum size of this component2744* @see #getMinimumSize2745* @see #isMinimumSizeSet2746* @since 1.52747*/2748public void setMinimumSize(Dimension minimumSize) {2749Dimension old;2750// If the minimum size was set, use it as the old value, otherwise2751// use null to indicate we didn't previously have a set minimum2752// size.2753if (minSizeSet) {2754old = this.minSize;2755}2756else {2757old = null;2758}2759this.minSize = minimumSize;2760minSizeSet = (minimumSize != null);2761firePropertyChange("minimumSize", old, minimumSize);2762}27632764/**2765* Returns whether or not {@code setMinimumSize} has been2766* invoked with a non-null value.2767*2768* @return true if {@code setMinimumSize} has been invoked with a2769* non-null value.2770* @since 1.52771*/2772public boolean isMinimumSizeSet() {2773return minSizeSet;2774}27752776/**2777* Gets the minimum size of this component.2778* @return a dimension object indicating this component's minimum size2779* @see #getPreferredSize2780* @see LayoutManager2781*/2782public Dimension getMinimumSize() {2783return minimumSize();2784}27852786/**2787* Returns the minimum size of this component.2788*2789* @return the minimum size of this component2790* @deprecated As of JDK version 1.1,2791* replaced by {@code getMinimumSize()}.2792*/2793@Deprecated2794public Dimension minimumSize() {2795/* Avoid grabbing the lock if a reasonable cached size value2796* is available.2797*/2798Dimension dim = minSize;2799if (dim == null || !(isMinimumSizeSet() || isValid())) {2800synchronized (getTreeLock()) {2801minSize = (peer != null) ?2802peer.getMinimumSize() :2803size();2804dim = minSize;2805}2806}2807return new Dimension(dim);2808}28092810/**2811* Sets the maximum size of this component to a constant2812* value. Subsequent calls to {@code getMaximumSize} will always2813* return this value. Setting the maximum size to {@code null}2814* restores the default behavior.2815*2816* @param maximumSize a {@code Dimension} containing the2817* desired maximum allowable size2818* @see #getMaximumSize2819* @see #isMaximumSizeSet2820* @since 1.52821*/2822public void setMaximumSize(Dimension maximumSize) {2823// If the maximum size was set, use it as the old value, otherwise2824// use null to indicate we didn't previously have a set maximum2825// size.2826Dimension old;2827if (maxSizeSet) {2828old = this.maxSize;2829}2830else {2831old = null;2832}2833this.maxSize = maximumSize;2834maxSizeSet = (maximumSize != null);2835firePropertyChange("maximumSize", old, maximumSize);2836}28372838/**2839* Returns true if the maximum size has been set to a non-{@code null}2840* value otherwise returns false.2841*2842* @return true if {@code maximumSize} is non-{@code null},2843* false otherwise2844* @since 1.52845*/2846public boolean isMaximumSizeSet() {2847return maxSizeSet;2848}28492850/**2851* Gets the maximum size of this component.2852* @return a dimension object indicating this component's maximum size2853* @see #getMinimumSize2854* @see #getPreferredSize2855* @see LayoutManager2856*/2857public Dimension getMaximumSize() {2858if (isMaximumSizeSet()) {2859return new Dimension(maxSize);2860}2861return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);2862}28632864/**2865* Returns the alignment along the x axis. This specifies how2866* the component would like to be aligned relative to other2867* components. The value should be a number between 0 and 12868* where 0 represents alignment along the origin, 1 is aligned2869* the furthest away from the origin, 0.5 is centered, etc.2870*2871* @return the horizontal alignment of this component2872*/2873public float getAlignmentX() {2874return CENTER_ALIGNMENT;2875}28762877/**2878* Returns the alignment along the y axis. This specifies how2879* the component would like to be aligned relative to other2880* components. The value should be a number between 0 and 12881* where 0 represents alignment along the origin, 1 is aligned2882* the furthest away from the origin, 0.5 is centered, etc.2883*2884* @return the vertical alignment of this component2885*/2886public float getAlignmentY() {2887return CENTER_ALIGNMENT;2888}28892890/**2891* Returns the baseline. The baseline is measured from the top of2892* the component. This method is primarily meant for2893* {@code LayoutManager}s to align components along their2894* baseline. A return value less than 0 indicates this component2895* does not have a reasonable baseline and that2896* {@code LayoutManager}s should not align this component on2897* its baseline.2898* <p>2899* The default implementation returns -1. Subclasses that support2900* baseline should override appropriately. If a value >= 0 is2901* returned, then the component has a valid baseline for any2902* size >= the minimum size and {@code getBaselineResizeBehavior}2903* can be used to determine how the baseline changes with size.2904*2905* @param width the width to get the baseline for2906* @param height the height to get the baseline for2907* @return the baseline or < 0 indicating there is no reasonable2908* baseline2909* @throws IllegalArgumentException if width or height is < 02910* @see #getBaselineResizeBehavior2911* @see java.awt.FontMetrics2912* @since 1.62913*/2914public int getBaseline(int width, int height) {2915if (width < 0 || height < 0) {2916throw new IllegalArgumentException(2917"Width and height must be >= 0");2918}2919return -1;2920}29212922/**2923* Returns an enum indicating how the baseline of the component2924* changes as the size changes. This method is primarily meant for2925* layout managers and GUI builders.2926* <p>2927* The default implementation returns2928* {@code BaselineResizeBehavior.OTHER}. Subclasses that have a2929* baseline should override appropriately. Subclasses should2930* never return {@code null}; if the baseline can not be2931* calculated return {@code BaselineResizeBehavior.OTHER}. Callers2932* should first ask for the baseline using2933* {@code getBaseline} and if a value >= 0 is returned use2934* this method. It is acceptable for this method to return a2935* value other than {@code BaselineResizeBehavior.OTHER} even if2936* {@code getBaseline} returns a value less than 0.2937*2938* @return an enum indicating how the baseline changes as the component2939* size changes2940* @see #getBaseline(int, int)2941* @since 1.62942*/2943public BaselineResizeBehavior getBaselineResizeBehavior() {2944return BaselineResizeBehavior.OTHER;2945}29462947/**2948* Prompts the layout manager to lay out this component. This is2949* usually called when the component (more specifically, container)2950* is validated.2951* @see #validate2952* @see LayoutManager2953*/2954public void doLayout() {2955layout();2956}29572958/**2959* @deprecated As of JDK version 1.1,2960* replaced by {@code doLayout()}.2961*/2962@Deprecated2963public void layout() {2964}29652966/**2967* Validates this component.2968* <p>2969* The meaning of the term <i>validating</i> is defined by the ancestors of2970* this class. See {@link Container#validate} for more details.2971*2972* @see #invalidate2973* @see #doLayout()2974* @see LayoutManager2975* @see Container#validate2976* @since 1.02977*/2978public void validate() {2979synchronized (getTreeLock()) {2980ComponentPeer peer = this.peer;2981boolean wasValid = isValid();2982if (!wasValid && peer != null) {2983Font newfont = getFont();2984Font oldfont = peerFont;2985if (newfont != null && !Objects.equals(oldfont, newfont)) {2986peer.setFont(newfont);2987peerFont = newfont;2988}2989peer.layout();2990}2991valid = true;2992if (!wasValid) {2993mixOnValidating();2994}2995}2996}29972998/**2999* Invalidates this component and its ancestors.3000* <p>3001* By default, all the ancestors of the component up to the top-most3002* container of the hierarchy are marked invalid. If the {@code3003* java.awt.smartInvalidate} system property is set to {@code true},3004* invalidation stops on the nearest validate root of this component.3005* Marking a container <i>invalid</i> indicates that the container needs to3006* be laid out.3007* <p>3008* This method is called automatically when any layout-related information3009* changes (e.g. setting the bounds of the component, or adding the3010* component to a container).3011* <p>3012* This method might be called often, so it should work fast.3013*3014* @see #validate3015* @see #doLayout3016* @see LayoutManager3017* @see java.awt.Container#isValidateRoot3018* @since 1.03019*/3020public void invalidate() {3021synchronized (getTreeLock()) {3022/* Nullify cached layout and size information.3023* For efficiency, propagate invalidate() upwards only if3024* some other component hasn't already done so first.3025*/3026valid = false;3027if (!isPreferredSizeSet()) {3028prefSize = null;3029}3030if (!isMinimumSizeSet()) {3031minSize = null;3032}3033if (!isMaximumSizeSet()) {3034maxSize = null;3035}3036invalidateParent();3037}3038}30393040/**3041* Invalidates the parent of this component if any.3042*3043* This method MUST BE invoked under the TreeLock.3044*/3045void invalidateParent() {3046if (parent != null) {3047parent.invalidateIfValid();3048}3049}30503051/** Invalidates the component unless it is already invalid.3052*/3053final void invalidateIfValid() {3054if (isValid()) {3055invalidate();3056}3057}30583059/**3060* Revalidates the component hierarchy up to the nearest validate root.3061* <p>3062* This method first invalidates the component hierarchy starting from this3063* component up to the nearest validate root. Afterwards, the component3064* hierarchy is validated starting from the nearest validate root.3065* <p>3066* This is a convenience method supposed to help application developers3067* avoid looking for validate roots manually. Basically, it's equivalent to3068* first calling the {@link #invalidate()} method on this component, and3069* then calling the {@link #validate()} method on the nearest validate3070* root.3071*3072* @see Container#isValidateRoot3073* @since 1.73074*/3075public void revalidate() {3076revalidateSynchronously();3077}30783079/**3080* Revalidates the component synchronously.3081*/3082final void revalidateSynchronously() {3083synchronized (getTreeLock()) {3084invalidate();30853086Container root = getContainer();3087if (root == null) {3088// There's no parents. Just validate itself.3089validate();3090} else {3091while (!root.isValidateRoot()) {3092if (root.getContainer() == null) {3093// If there's no validate roots, we'll validate the3094// topmost container3095break;3096}30973098root = root.getContainer();3099}31003101root.validate();3102}3103}3104}31053106/**3107* Creates a graphics context for this component. This method will3108* return {@code null} if this component is currently not3109* displayable.3110* @return a graphics context for this component, or {@code null}3111* if it has none3112* @see #paint3113* @since 1.03114*/3115public Graphics getGraphics() {3116if (peer instanceof LightweightPeer) {3117// This is for a lightweight component, need to3118// translate coordinate spaces and clip relative3119// to the parent.3120if (parent == null) return null;3121Graphics g = parent.getGraphics();3122if (g == null) return null;3123if (g instanceof ConstrainableGraphics) {3124((ConstrainableGraphics) g).constrain(x, y, width, height);3125} else {3126g.translate(x,y);3127g.setClip(0, 0, width, height);3128}3129g.setFont(getFont());3130return g;3131} else {3132ComponentPeer peer = this.peer;3133return (peer != null) ? peer.getGraphics() : null;3134}3135}31363137final Graphics getGraphics_NoClientCode() {3138ComponentPeer peer = this.peer;3139if (peer instanceof LightweightPeer) {3140// This is for a lightweight component, need to3141// translate coordinate spaces and clip relative3142// to the parent.3143Container parent = this.parent;3144if (parent == null) return null;3145Graphics g = parent.getGraphics_NoClientCode();3146if (g == null) return null;3147if (g instanceof ConstrainableGraphics) {3148((ConstrainableGraphics) g).constrain(x, y, width, height);3149} else {3150g.translate(x,y);3151g.setClip(0, 0, width, height);3152}3153g.setFont(getFont_NoClientCode());3154return g;3155} else {3156return (peer != null) ? peer.getGraphics() : null;3157}3158}31593160/**3161* Gets the font metrics for the specified font.3162* Warning: Since Font metrics are affected by the3163* {@link java.awt.font.FontRenderContext FontRenderContext} and3164* this method does not provide one, it can return only metrics for3165* the default render context which may not match that used when3166* rendering on the Component if {@link Graphics2D} functionality is being3167* used. Instead metrics can be obtained at rendering time by calling3168* {@link Graphics#getFontMetrics()} or text measurement APIs on the3169* {@link Font Font} class.3170* @param font the font for which font metrics is to be3171* obtained3172* @return the font metrics for {@code font}3173* @see #getFont3174* @see java.awt.peer.ComponentPeer#getFontMetrics(Font)3175* @see Toolkit#getFontMetrics(Font)3176* @since 1.03177*/3178public FontMetrics getFontMetrics(Font font) {3179// This is an unsupported hack, but left in for a customer.3180// Do not remove.3181FontManager fm = FontManagerFactory.getInstance();3182if (fm instanceof SunFontManager3183&& ((SunFontManager) fm).usePlatformFontMetrics()) {31843185if (peer != null &&3186!(peer instanceof LightweightPeer)) {3187return peer.getFontMetrics(font);3188}3189}3190return sun.font.FontDesignMetrics.getMetrics(font);3191}31923193/**3194* Sets the cursor image to the specified cursor. This cursor3195* image is displayed when the {@code contains} method for3196* this component returns true for the current cursor location, and3197* this Component is visible, displayable, and enabled. Setting the3198* cursor of a {@code Container} causes that cursor to be displayed3199* within all of the container's subcomponents, except for those3200* that have a non-{@code null} cursor.3201* <p>3202* The method may have no visual effect if the Java platform3203* implementation and/or the native system do not support3204* changing the mouse cursor shape.3205* @param cursor One of the constants defined3206* by the {@code Cursor} class;3207* if this parameter is {@code null}3208* then this component will inherit3209* the cursor of its parent3210* @see #isEnabled3211* @see #isShowing3212* @see #getCursor3213* @see #contains3214* @see Toolkit#createCustomCursor3215* @see Cursor3216* @since 1.13217*/3218public void setCursor(Cursor cursor) {3219this.cursor = cursor;3220updateCursorImmediately();3221}32223223/**3224* Updates the cursor. May not be invoked from the native3225* message pump.3226*/3227final void updateCursorImmediately() {3228if (peer instanceof LightweightPeer) {3229Container nativeContainer = getNativeContainer();32303231if (nativeContainer == null) return;32323233ComponentPeer cPeer = nativeContainer.peer;32343235if (cPeer != null) {3236cPeer.updateCursorImmediately();3237}3238} else if (peer != null) {3239peer.updateCursorImmediately();3240}3241}32423243/**3244* Gets the cursor set in the component. If the component does3245* not have a cursor set, the cursor of its parent is returned.3246* If no cursor is set in the entire hierarchy,3247* {@code Cursor.DEFAULT_CURSOR} is returned.3248*3249* @return the cursor for this component3250* @see #setCursor3251* @since 1.13252*/3253public Cursor getCursor() {3254return getCursor_NoClientCode();3255}32563257final Cursor getCursor_NoClientCode() {3258Cursor cursor = this.cursor;3259if (cursor != null) {3260return cursor;3261}3262Container parent = this.parent;3263if (parent != null) {3264return parent.getCursor_NoClientCode();3265} else {3266return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);3267}3268}32693270/**3271* Returns whether the cursor has been explicitly set for this Component.3272* If this method returns {@code false}, this Component is inheriting3273* its cursor from an ancestor.3274*3275* @return {@code true} if the cursor has been explicitly set for this3276* Component; {@code false} otherwise.3277* @since 1.43278*/3279public boolean isCursorSet() {3280return (cursor != null);3281}32823283/**3284* Paints this component.3285* <p>3286* This method is called when the contents of the component should3287* be painted; such as when the component is first being shown or3288* is damaged and in need of repair. The clip rectangle in the3289* {@code Graphics} parameter is set to the area3290* which needs to be painted.3291* Subclasses of {@code Component} that override this3292* method need not call {@code super.paint(g)}.3293* <p>3294* For performance reasons, {@code Component}s with zero width3295* or height aren't considered to need painting when they are first shown,3296* and also aren't considered to need repair.3297* <p>3298* <b>Note</b>: For more information on the paint mechanisms utilitized3299* by AWT and Swing, including information on how to write the most3300* efficient painting code, see3301* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.3302*3303* @param g the graphics context to use for painting3304* @see #update3305* @since 1.03306*/3307public void paint(Graphics g) {3308}33093310/**3311* Updates this component.3312* <p>3313* If this component is not a lightweight component, the3314* AWT calls the {@code update} method in response to3315* a call to {@code repaint}. You can assume that3316* the background is not cleared.3317* <p>3318* The {@code update} method of {@code Component}3319* calls this component's {@code paint} method to redraw3320* this component. This method is commonly overridden by subclasses3321* which need to do additional work in response to a call to3322* {@code repaint}.3323* Subclasses of Component that override this method should either3324* call {@code super.update(g)}, or call {@code paint(g)}3325* directly from their {@code update} method.3326* <p>3327* The origin of the graphics context, its3328* ({@code 0}, {@code 0}) coordinate point, is the3329* top-left corner of this component. The clipping region of the3330* graphics context is the bounding rectangle of this component.3331*3332* <p>3333* <b>Note</b>: For more information on the paint mechanisms utilitized3334* by AWT and Swing, including information on how to write the most3335* efficient painting code, see3336* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.3337*3338* @param g the specified context to use for updating3339* @see #paint3340* @see #repaint()3341* @since 1.03342*/3343public void update(Graphics g) {3344paint(g);3345}33463347/**3348* Paints this component and all of its subcomponents.3349* <p>3350* The origin of the graphics context, its3351* ({@code 0}, {@code 0}) coordinate point, is the3352* top-left corner of this component. The clipping region of the3353* graphics context is the bounding rectangle of this component.3354*3355* @param g the graphics context to use for painting3356* @see #paint3357* @since 1.03358*/3359public void paintAll(Graphics g) {3360if (isShowing()) {3361GraphicsCallback.PeerPaintCallback.getInstance().3362runOneComponent(this, new Rectangle(0, 0, width, height),3363g, g.getClip(),3364GraphicsCallback.LIGHTWEIGHTS |3365GraphicsCallback.HEAVYWEIGHTS);3366}3367}33683369/**3370* Simulates the peer callbacks into java.awt for painting of3371* lightweight Components.3372* @param g the graphics context to use for painting3373* @see #paintAll3374*/3375void lightweightPaint(Graphics g) {3376paint(g);3377}33783379/**3380* Paints all the heavyweight subcomponents.3381*/3382void paintHeavyweightComponents(Graphics g) {3383}33843385/**3386* Repaints this component.3387* <p>3388* If this component is a lightweight component, this method3389* causes a call to this component's {@code paint}3390* method as soon as possible. Otherwise, this method causes3391* a call to this component's {@code update} method as soon3392* as possible.3393* <p>3394* <b>Note</b>: For more information on the paint mechanisms utilitized3395* by AWT and Swing, including information on how to write the most3396* efficient painting code, see3397* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.33983399*3400* @see #update(Graphics)3401* @since 1.03402*/3403public void repaint() {3404repaint(0, 0, 0, width, height);3405}34063407/**3408* Repaints the component. If this component is a lightweight3409* component, this results in a call to {@code paint}3410* within {@code tm} milliseconds.3411* <p>3412* <b>Note</b>: For more information on the paint mechanisms utilitized3413* by AWT and Swing, including information on how to write the most3414* efficient painting code, see3415* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.3416*3417* @param tm maximum time in milliseconds before update3418* @see #paint3419* @see #update(Graphics)3420* @since 1.03421*/3422public void repaint(long tm) {3423repaint(tm, 0, 0, width, height);3424}34253426/**3427* Repaints the specified rectangle of this component.3428* <p>3429* If this component is a lightweight component, this method3430* causes a call to this component's {@code paint} method3431* as soon as possible. Otherwise, this method causes a call to3432* this component's {@code update} method as soon as possible.3433* <p>3434* <b>Note</b>: For more information on the paint mechanisms utilitized3435* by AWT and Swing, including information on how to write the most3436* efficient painting code, see3437* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.3438*3439* @param x the <i>x</i> coordinate3440* @param y the <i>y</i> coordinate3441* @param width the width3442* @param height the height3443* @see #update(Graphics)3444* @since 1.03445*/3446public void repaint(int x, int y, int width, int height) {3447repaint(0, x, y, width, height);3448}34493450/**3451* Repaints the specified rectangle of this component within3452* {@code tm} milliseconds.3453* <p>3454* If this component is a lightweight component, this method causes3455* a call to this component's {@code paint} method.3456* Otherwise, this method causes a call to this component's3457* {@code update} method.3458* <p>3459* <b>Note</b>: For more information on the paint mechanisms utilitized3460* by AWT and Swing, including information on how to write the most3461* efficient painting code, see3462* <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>.3463*3464* @param tm maximum time in milliseconds before update3465* @param x the <i>x</i> coordinate3466* @param y the <i>y</i> coordinate3467* @param width the width3468* @param height the height3469* @see #update(Graphics)3470* @since 1.03471*/3472public void repaint(long tm, int x, int y, int width, int height) {3473if (this.peer instanceof LightweightPeer) {3474// Needs to be translated to parent coordinates since3475// a parent native container provides the actual repaint3476// services. Additionally, the request is restricted to3477// the bounds of the component.3478if (parent != null) {3479if (x < 0) {3480width += x;3481x = 0;3482}3483if (y < 0) {3484height += y;3485y = 0;3486}34873488int pwidth = (width > this.width) ? this.width : width;3489int pheight = (height > this.height) ? this.height : height;34903491if (pwidth <= 0 || pheight <= 0) {3492return;3493}34943495int px = this.x + x;3496int py = this.y + y;3497parent.repaint(tm, px, py, pwidth, pheight);3498}3499} else {3500if (isVisible() && (this.peer != null) &&3501(width > 0) && (height > 0)) {3502PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,3503new Rectangle(x, y, width, height));3504SunToolkit.postEvent(SunToolkit.targetToAppContext(this), e);3505}3506}3507}35083509/**3510* Prints this component. Applications should override this method3511* for components that must do special processing before being3512* printed or should be printed differently than they are painted.3513* <p>3514* The default implementation of this method calls the3515* {@code paint} method.3516* <p>3517* The origin of the graphics context, its3518* ({@code 0}, {@code 0}) coordinate point, is the3519* top-left corner of this component. The clipping region of the3520* graphics context is the bounding rectangle of this component.3521* @param g the graphics context to use for printing3522* @see #paint(Graphics)3523* @since 1.03524*/3525public void print(Graphics g) {3526paint(g);3527}35283529/**3530* Prints this component and all of its subcomponents.3531* <p>3532* The origin of the graphics context, its3533* ({@code 0}, {@code 0}) coordinate point, is the3534* top-left corner of this component. The clipping region of the3535* graphics context is the bounding rectangle of this component.3536* @param g the graphics context to use for printing3537* @see #print(Graphics)3538* @since 1.03539*/3540public void printAll(Graphics g) {3541if (isShowing()) {3542GraphicsCallback.PeerPrintCallback.getInstance().3543runOneComponent(this, new Rectangle(0, 0, width, height),3544g, g.getClip(),3545GraphicsCallback.LIGHTWEIGHTS |3546GraphicsCallback.HEAVYWEIGHTS);3547}3548}35493550/**3551* Simulates the peer callbacks into java.awt for printing of3552* lightweight Components.3553* @param g the graphics context to use for printing3554* @see #printAll3555*/3556void lightweightPrint(Graphics g) {3557print(g);3558}35593560/**3561* Prints all the heavyweight subcomponents.3562*/3563void printHeavyweightComponents(Graphics g) {3564}35653566private Insets getInsets_NoClientCode() {3567ComponentPeer peer = this.peer;3568if (peer instanceof ContainerPeer) {3569return (Insets)((ContainerPeer)peer).getInsets().clone();3570}3571return new Insets(0, 0, 0, 0);3572}35733574/**3575* Repaints the component when the image has changed.3576* This {@code imageUpdate} method of an {@code ImageObserver}3577* is called when more information about an3578* image which had been previously requested using an asynchronous3579* routine such as the {@code drawImage} method of3580* {@code Graphics} becomes available.3581* See the definition of {@code imageUpdate} for3582* more information on this method and its arguments.3583* <p>3584* The {@code imageUpdate} method of {@code Component}3585* incrementally draws an image on the component as more of the bits3586* of the image are available.3587* <p>3588* If the system property {@code awt.image.incrementaldraw}3589* is missing or has the value {@code true}, the image is3590* incrementally drawn. If the system property has any other value,3591* then the image is not drawn until it has been completely loaded.3592* <p>3593* Also, if incremental drawing is in effect, the value of the3594* system property {@code awt.image.redrawrate} is interpreted3595* as an integer to give the maximum redraw rate, in milliseconds. If3596* the system property is missing or cannot be interpreted as an3597* integer, the redraw rate is once every 100ms.3598* <p>3599* The interpretation of the {@code x}, {@code y},3600* {@code width}, and {@code height} arguments depends on3601* the value of the {@code infoflags} argument.3602*3603* @param img the image being observed3604* @param infoflags see {@code imageUpdate} for more information3605* @param x the <i>x</i> coordinate3606* @param y the <i>y</i> coordinate3607* @param w the width3608* @param h the height3609* @return {@code false} if the infoflags indicate that the3610* image is completely loaded; {@code true} otherwise.3611*3612* @see java.awt.image.ImageObserver3613* @see Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver)3614* @see Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver)3615* @see Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver)3616* @see Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver)3617* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)3618* @since 1.03619*/3620public boolean imageUpdate(Image img, int infoflags,3621int x, int y, int w, int h) {3622int rate = -1;3623if ((infoflags & (FRAMEBITS|ALLBITS)) != 0) {3624rate = 0;3625} else if ((infoflags & SOMEBITS) != 0) {3626if (isInc) {3627rate = incRate;3628if (rate < 0) {3629rate = 0;3630}3631}3632}3633if (rate >= 0) {3634repaint(rate, 0, 0, width, height);3635}3636return (infoflags & (ALLBITS|ABORT)) == 0;3637}36383639/**3640* Creates an image from the specified image producer.3641* @param producer the image producer3642* @return the image produced3643* @since 1.03644*/3645public Image createImage(ImageProducer producer) {3646return getToolkit().createImage(producer);3647}36483649/**3650* Creates an off-screen drawable image to be used for double buffering.3651*3652* @param width the specified width3653* @param height the specified height3654* @return an off-screen drawable image, which can be used for double3655* buffering. The {@code null} value if the component is not3656* displayable or {@code GraphicsEnvironment.isHeadless()} returns3657* {@code true}.3658* @see #isDisplayable3659* @see GraphicsEnvironment#isHeadless3660* @since 1.03661*/3662public Image createImage(int width, int height) {3663ComponentPeer peer = this.peer;3664if (peer instanceof LightweightPeer) {3665if (parent != null) { return parent.createImage(width, height); }3666else { return null;}3667} else {3668return (peer != null) ? peer.createImage(width, height) : null;3669}3670}36713672/**3673* Creates a volatile off-screen drawable image to be used for double3674* buffering.3675*3676* @param width the specified width3677* @param height the specified height3678* @return an off-screen drawable image, which can be used for double3679* buffering. The {@code null} value if the component is not3680* displayable or {@code GraphicsEnvironment.isHeadless()} returns3681* {@code true}.3682* @see java.awt.image.VolatileImage3683* @see #isDisplayable3684* @see GraphicsEnvironment#isHeadless3685* @since 1.43686*/3687public VolatileImage createVolatileImage(int width, int height) {3688ComponentPeer peer = this.peer;3689if (peer instanceof LightweightPeer) {3690if (parent != null) {3691return parent.createVolatileImage(width, height);3692}3693else { return null;}3694} else {3695return (peer != null) ?3696peer.createVolatileImage(width, height) : null;3697}3698}36993700/**3701* Creates a volatile off-screen drawable image, with the given3702* capabilities. The contents of this image may be lost at any time due to3703* operating system issues, so the image must be managed via the3704* {@code VolatileImage} interface.3705*3706* @param width the specified width3707* @param height the specified height3708* @param caps the image capabilities3709* @return a VolatileImage object, which can be used to manage surface3710* contents loss and capabilities. The {@code null} value if the3711* component is not displayable or3712* {@code GraphicsEnvironment.isHeadless()} returns {@code true}.3713* @throws AWTException if an image with the specified capabilities cannot3714* be created3715* @see java.awt.image.VolatileImage3716* @since 1.43717*/3718public VolatileImage createVolatileImage(int width, int height,3719ImageCapabilities caps)3720throws AWTException {3721// REMIND : check caps3722return createVolatileImage(width, height);3723}37243725/**3726* Prepares an image for rendering on this component. The image3727* data is downloaded asynchronously in another thread and the3728* appropriate screen representation of the image is generated.3729* @param image the {@code Image} for which to3730* prepare a screen representation3731* @param observer the {@code ImageObserver} object3732* to be notified as the image is being prepared3733* @return {@code true} if the image has already been fully3734* prepared; {@code false} otherwise3735* @since 1.03736*/3737public boolean prepareImage(Image image, ImageObserver observer) {3738return prepareImage(image, -1, -1, observer);3739}37403741/**3742* Prepares an image for rendering on this component at the3743* specified width and height.3744* <p>3745* The image data is downloaded asynchronously in another thread,3746* and an appropriately scaled screen representation of the image is3747* generated.3748* @param image the instance of {@code Image}3749* for which to prepare a screen representation3750* @param width the width of the desired screen representation3751* @param height the height of the desired screen representation3752* @param observer the {@code ImageObserver} object3753* to be notified as the image is being prepared3754* @return {@code true} if the image has already been fully3755* prepared; {@code false} otherwise3756* @see java.awt.image.ImageObserver3757* @since 1.03758*/3759public boolean prepareImage(Image image, int width, int height,3760ImageObserver observer) {3761return getToolkit().prepareImage(image, width, height, observer);3762}37633764/**3765* Returns the status of the construction of a screen representation3766* of the specified image.3767* <p>3768* This method does not cause the image to begin loading. An3769* application must use the {@code prepareImage} method3770* to force the loading of an image.3771* <p>3772* Information on the flags returned by this method can be found3773* with the discussion of the {@code ImageObserver} interface.3774* @param image the {@code Image} object whose status3775* is being checked3776* @param observer the {@code ImageObserver}3777* object to be notified as the image is being prepared3778* @return the bitwise inclusive <b>OR</b> of3779* {@code ImageObserver} flags indicating what3780* information about the image is currently available3781* @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)3782* @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)3783* @see java.awt.image.ImageObserver3784* @since 1.03785*/3786public int checkImage(Image image, ImageObserver observer) {3787return checkImage(image, -1, -1, observer);3788}37893790/**3791* Returns the status of the construction of a screen representation3792* of the specified image.3793* <p>3794* This method does not cause the image to begin loading. An3795* application must use the {@code prepareImage} method3796* to force the loading of an image.3797* <p>3798* The {@code checkImage} method of {@code Component}3799* calls its peer's {@code checkImage} method to calculate3800* the flags. If this component does not yet have a peer, the3801* component's toolkit's {@code checkImage} method is called3802* instead.3803* <p>3804* Information on the flags returned by this method can be found3805* with the discussion of the {@code ImageObserver} interface.3806* @param image the {@code Image} object whose status3807* is being checked3808* @param width the width of the scaled version3809* whose status is to be checked3810* @param height the height of the scaled version3811* whose status is to be checked3812* @param observer the {@code ImageObserver} object3813* to be notified as the image is being prepared3814* @return the bitwise inclusive <b>OR</b> of3815* {@code ImageObserver} flags indicating what3816* information about the image is currently available3817* @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)3818* @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)3819* @see java.awt.image.ImageObserver3820* @since 1.03821*/3822public int checkImage(Image image, int width, int height,3823ImageObserver observer) {3824return getToolkit().checkImage(image, width, height, observer);3825}38263827/**3828* Creates a new strategy for multi-buffering on this component.3829* Multi-buffering is useful for rendering performance. This method3830* attempts to create the best strategy available with the number of3831* buffers supplied. It will always create a {@code BufferStrategy}3832* with that number of buffers.3833* A page-flipping strategy is attempted first, then a blitting strategy3834* using accelerated buffers. Finally, an unaccelerated blitting3835* strategy is used.3836* <p>3837* Each time this method is called,3838* the existing buffer strategy for this component is discarded.3839* @param numBuffers number of buffers to create, including the front buffer3840* @exception IllegalArgumentException if numBuffers is less than 1.3841* @exception IllegalStateException if the component is not displayable3842* @see #isDisplayable3843* @see Window#getBufferStrategy()3844* @see Canvas#getBufferStrategy()3845* @since 1.43846*/3847void createBufferStrategy(int numBuffers) {3848BufferCapabilities bufferCaps;3849if (numBuffers > 1) {3850// Try to create a page-flipping strategy3851bufferCaps = new BufferCapabilities(new ImageCapabilities(true),3852new ImageCapabilities(true),3853BufferCapabilities.FlipContents.UNDEFINED);3854try {3855createBufferStrategy(numBuffers, bufferCaps);3856return; // Success3857} catch (AWTException e) {3858// Failed3859}3860}3861// Try a blitting (but still accelerated) strategy3862bufferCaps = new BufferCapabilities(new ImageCapabilities(true),3863new ImageCapabilities(true),3864null);3865try {3866createBufferStrategy(numBuffers, bufferCaps);3867return; // Success3868} catch (AWTException e) {3869// Failed3870}3871// Try an unaccelerated blitting strategy3872bufferCaps = new BufferCapabilities(new ImageCapabilities(false),3873new ImageCapabilities(false),3874null);3875try {3876createBufferStrategy(numBuffers, bufferCaps);3877return; // Success3878} catch (AWTException e) {3879// Code should never reach here (an unaccelerated blitting3880// strategy should always work)3881throw new InternalError("Could not create a buffer strategy", e);3882}3883}38843885/**3886* Creates a new strategy for multi-buffering on this component with the3887* required buffer capabilities. This is useful, for example, if only3888* accelerated memory or page flipping is desired (as specified by the3889* buffer capabilities).3890* <p>3891* Each time this method3892* is called, {@code dispose} will be invoked on the existing3893* {@code BufferStrategy}.3894* @param numBuffers number of buffers to create3895* @param caps the required capabilities for creating the buffer strategy;3896* cannot be {@code null}3897* @exception AWTException if the capabilities supplied could not be3898* supported or met; this may happen, for example, if there is not enough3899* accelerated memory currently available, or if page flipping is specified3900* but not possible.3901* @exception IllegalArgumentException if numBuffers is less than 1, or if3902* caps is {@code null}3903* @see Window#getBufferStrategy()3904* @see Canvas#getBufferStrategy()3905* @since 1.43906*/3907void createBufferStrategy(int numBuffers,3908BufferCapabilities caps) throws AWTException {3909// Check arguments3910if (numBuffers < 1) {3911throw new IllegalArgumentException(3912"Number of buffers must be at least 1");3913}3914if (caps == null) {3915throw new IllegalArgumentException("No capabilities specified");3916}3917// Destroy old buffers3918if (bufferStrategy != null) {3919bufferStrategy.dispose();3920}3921if (numBuffers == 1) {3922bufferStrategy = new SingleBufferStrategy(caps);3923} else {3924SunGraphicsEnvironment sge = (SunGraphicsEnvironment)3925GraphicsEnvironment.getLocalGraphicsEnvironment();3926if (!caps.isPageFlipping() && sge.isFlipStrategyPreferred(peer)) {3927caps = new ProxyCapabilities(caps);3928}3929// assert numBuffers > 1;3930if (caps.isPageFlipping()) {3931bufferStrategy = new FlipSubRegionBufferStrategy(numBuffers, caps);3932} else {3933bufferStrategy = new BltSubRegionBufferStrategy(numBuffers, caps);3934}3935}3936}39373938/**3939* This is a proxy capabilities class used when a FlipBufferStrategy3940* is created instead of the requested Blit strategy.3941*3942* @see sun.java2d.SunGraphicsEnvironment#isFlipStrategyPreferred(ComponentPeer)3943*/3944private class ProxyCapabilities extends ExtendedBufferCapabilities {3945private BufferCapabilities orig;3946private ProxyCapabilities(BufferCapabilities orig) {3947super(orig.getFrontBufferCapabilities(),3948orig.getBackBufferCapabilities(),3949orig.getFlipContents() ==3950BufferCapabilities.FlipContents.BACKGROUND ?3951BufferCapabilities.FlipContents.BACKGROUND :3952BufferCapabilities.FlipContents.COPIED);3953this.orig = orig;3954}3955}39563957/**3958* @return the buffer strategy used by this component3959* @see Window#createBufferStrategy3960* @see Canvas#createBufferStrategy3961* @since 1.43962*/3963BufferStrategy getBufferStrategy() {3964return bufferStrategy;3965}39663967/**3968* @return the back buffer currently used by this component's3969* BufferStrategy. If there is no BufferStrategy or no3970* back buffer, this method returns null.3971*/3972Image getBackBuffer() {3973if (bufferStrategy != null) {3974if (bufferStrategy instanceof BltBufferStrategy) {3975BltBufferStrategy bltBS = (BltBufferStrategy)bufferStrategy;3976return bltBS.getBackBuffer();3977} else if (bufferStrategy instanceof FlipBufferStrategy) {3978FlipBufferStrategy flipBS = (FlipBufferStrategy)bufferStrategy;3979return flipBS.getBackBuffer();3980}3981}3982return null;3983}39843985/**3986* Inner class for flipping buffers on a component. That component must3987* be a {@code Canvas} or {@code Window} or {@code Applet}.3988* @see Canvas3989* @see Window3990* @see Applet3991* @see java.awt.image.BufferStrategy3992* @author Michael Martak3993* @since 1.43994*/3995protected class FlipBufferStrategy extends BufferStrategy {3996/**3997* The number of buffers3998*/3999protected int numBuffers; // = 04000/**4001* The buffering capabilities4002*/4003protected BufferCapabilities caps; // = null4004/**4005* The drawing buffer4006*/4007protected Image drawBuffer; // = null4008/**4009* The drawing buffer as a volatile image4010*/4011protected VolatileImage drawVBuffer; // = null4012/**4013* Whether or not the drawing buffer has been recently restored from4014* a lost state.4015*/4016protected boolean validatedContents; // = false40174018/**4019* Size of the back buffers. (Note: these fields were added in 6.04020* but kept package-private to avoid exposing them in the spec.4021* None of these fields/methods really should have been marked4022* protected when they were introduced in 1.4, but now we just have4023* to live with that decision.)4024*/40254026/**4027* The width of the back buffers4028*/4029private int width;40304031/**4032* The height of the back buffers4033*/4034private int height;40354036/**4037* Creates a new flipping buffer strategy for this component.4038* The component must be a {@code Canvas} or {@code Window} or4039* {@code Applet}.4040* @see Canvas4041* @see Window4042* @see Applet4043* @param numBuffers the number of buffers4044* @param caps the capabilities of the buffers4045* @exception AWTException if the capabilities supplied could not be4046* supported or met4047* @exception ClassCastException if the component is not a canvas or4048* window.4049* @exception IllegalStateException if the component has no peer4050* @exception IllegalArgumentException if {@code numBuffers} is less than two,4051* or if {@code BufferCapabilities.isPageFlipping} is not4052* {@code true}.4053* @see #createBuffers(int, BufferCapabilities)4054*/4055@SuppressWarnings("removal")4056protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)4057throws AWTException4058{4059if (!(Component.this instanceof Window) &&4060!(Component.this instanceof Canvas) &&4061!(Component.this instanceof Applet))4062{4063throw new ClassCastException(4064"Component must be a Canvas or Window or Applet");4065}4066this.numBuffers = numBuffers;4067this.caps = caps;4068createBuffers(numBuffers, caps);4069}40704071/**4072* Creates one or more complex, flipping buffers with the given4073* capabilities.4074* @param numBuffers number of buffers to create; must be greater than4075* one4076* @param caps the capabilities of the buffers.4077* {@code BufferCapabilities.isPageFlipping} must be4078* {@code true}.4079* @exception AWTException if the capabilities supplied could not be4080* supported or met4081* @exception IllegalStateException if the component has no peer4082* @exception IllegalArgumentException if numBuffers is less than two,4083* or if {@code BufferCapabilities.isPageFlipping} is not4084* {@code true}.4085* @see java.awt.BufferCapabilities#isPageFlipping()4086*/4087protected void createBuffers(int numBuffers, BufferCapabilities caps)4088throws AWTException4089{4090if (numBuffers < 2) {4091throw new IllegalArgumentException(4092"Number of buffers cannot be less than two");4093} else if (peer == null) {4094throw new IllegalStateException(4095"Component must have a valid peer");4096} else if (caps == null || !caps.isPageFlipping()) {4097throw new IllegalArgumentException(4098"Page flipping capabilities must be specified");4099}41004101// save the current bounds4102width = getWidth();4103height = getHeight();41044105if (drawBuffer != null) {4106// dispose the existing backbuffers4107invalidate();4108// ... then recreate the backbuffers4109}41104111if (caps instanceof ExtendedBufferCapabilities) {4112ExtendedBufferCapabilities ebc =4113(ExtendedBufferCapabilities)caps;4114if (ebc.getVSync() == VSYNC_ON) {4115// if this buffer strategy is not allowed to be v-synced,4116// change the caps that we pass to the peer but keep on4117// trying to create v-synced buffers;4118// do not throw IAE here in case it is disallowed, see4119// ExtendedBufferCapabilities for more info4120if (!VSyncedBSManager.vsyncAllowed(this)) {4121caps = ebc.derive(VSYNC_DEFAULT);4122}4123}4124}41254126peer.createBuffers(numBuffers, caps);4127updateInternalBuffers();4128}41294130/**4131* Updates internal buffers (both volatile and non-volatile)4132* by requesting the back-buffer from the peer.4133*/4134private void updateInternalBuffers() {4135// get the images associated with the draw buffer4136drawBuffer = getBackBuffer();4137if (drawBuffer instanceof VolatileImage) {4138drawVBuffer = (VolatileImage)drawBuffer;4139} else {4140drawVBuffer = null;4141}4142}41434144/**4145* @return direct access to the back buffer, as an image.4146* @exception IllegalStateException if the buffers have not yet4147* been created4148*/4149protected Image getBackBuffer() {4150if (peer != null) {4151return peer.getBackBuffer();4152} else {4153throw new IllegalStateException(4154"Component must have a valid peer");4155}4156}41574158/**4159* Flipping moves the contents of the back buffer to the front buffer,4160* either by copying or by moving the video pointer.4161* @param flipAction an integer value describing the flipping action4162* for the contents of the back buffer. This should be one of the4163* values of the {@code BufferCapabilities.FlipContents}4164* property.4165* @exception IllegalStateException if the buffers have not yet4166* been created4167* @see java.awt.BufferCapabilities#getFlipContents()4168*/4169protected void flip(BufferCapabilities.FlipContents flipAction) {4170if (peer != null) {4171Image backBuffer = getBackBuffer();4172if (backBuffer != null) {4173peer.flip(0, 0,4174backBuffer.getWidth(null),4175backBuffer.getHeight(null), flipAction);4176}4177} else {4178throw new IllegalStateException(4179"Component must have a valid peer");4180}4181}41824183void flipSubRegion(int x1, int y1, int x2, int y2,4184BufferCapabilities.FlipContents flipAction)4185{4186if (peer != null) {4187peer.flip(x1, y1, x2, y2, flipAction);4188} else {4189throw new IllegalStateException(4190"Component must have a valid peer");4191}4192}41934194/**4195* Destroys the buffers and invalidates the state of FlipBufferStrategy.4196*/4197private void invalidate() {4198drawBuffer = null;4199drawVBuffer = null;4200destroyBuffers();4201}42024203/**4204* Destroys the buffers created through this object4205*/4206protected void destroyBuffers() {4207VSyncedBSManager.releaseVsync(this);4208if (peer != null) {4209peer.destroyBuffers();4210} else {4211throw new IllegalStateException(4212"Component must have a valid peer");4213}4214}42154216/**4217* @return the buffering capabilities of this strategy4218*/4219public BufferCapabilities getCapabilities() {4220if (caps instanceof ProxyCapabilities) {4221return ((ProxyCapabilities)caps).orig;4222} else {4223return caps;4224}4225}42264227/**4228* @return the graphics on the drawing buffer. This method may not4229* be synchronized for performance reasons; use of this method by multiple4230* threads should be handled at the application level. Disposal of the4231* graphics object must be handled by the application.4232*/4233public Graphics getDrawGraphics() {4234revalidate();4235return drawBuffer.getGraphics();4236}42374238/**4239* Restore the drawing buffer if it has been lost4240*/4241protected void revalidate() {4242validatedContents = false;4243if (getWidth() != width || getHeight() != height4244|| drawBuffer == null) {4245// component has been resized or the peer was recreated;4246// recreate the backbuffers4247try {4248createBuffers(numBuffers, caps);4249} catch (AWTException e) {4250// shouldn't be possible4251}4252validatedContents = true;4253}42544255// get the buffers from the peer every time since they4256// might have been replaced in response to a display change event4257updateInternalBuffers();42584259// now validate the backbuffer4260if (drawVBuffer != null) {4261GraphicsConfiguration gc =4262getGraphicsConfiguration_NoClientCode();4263int returnCode = drawVBuffer.validate(gc);4264if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {4265try {4266createBuffers(numBuffers, caps);4267} catch (AWTException e) {4268// shouldn't be possible4269}4270if (drawVBuffer != null) {4271// backbuffers were recreated, so validate again4272drawVBuffer.validate(gc);4273}4274validatedContents = true;4275} else if (returnCode == VolatileImage.IMAGE_RESTORED) {4276validatedContents = true;4277}4278}4279}42804281/**4282* @return whether the drawing buffer was lost since the last call to4283* {@code getDrawGraphics}4284*/4285public boolean contentsLost() {4286if (drawVBuffer == null) {4287return false;4288}4289return drawVBuffer.contentsLost();4290}42914292/**4293* @return whether the drawing buffer was recently restored from a lost4294* state and reinitialized to the default background color (white)4295*/4296public boolean contentsRestored() {4297return validatedContents;4298}42994300/**4301* Makes the next available buffer visible by either blitting or4302* flipping.4303*/4304public void show() {4305flip(caps.getFlipContents());4306}43074308/**4309* Makes specified region of the next available buffer visible4310* by either blitting or flipping.4311*/4312void showSubRegion(int x1, int y1, int x2, int y2) {4313flipSubRegion(x1, y1, x2, y2, caps.getFlipContents());4314}43154316/**4317* {@inheritDoc}4318* @since 1.64319*/4320public void dispose() {4321if (Component.this.bufferStrategy == this) {4322Component.this.bufferStrategy = null;4323if (peer != null) {4324invalidate();4325}4326}4327}43284329} // Inner class FlipBufferStrategy43304331/**4332* Inner class for blitting offscreen surfaces to a component.4333*4334* @author Michael Martak4335* @since 1.44336*/4337protected class BltBufferStrategy extends BufferStrategy {43384339/**4340* The buffering capabilities4341*/4342protected BufferCapabilities caps; // = null4343/**4344* The back buffers4345*/4346protected VolatileImage[] backBuffers; // = null4347/**4348* Whether or not the drawing buffer has been recently restored from4349* a lost state.4350*/4351protected boolean validatedContents; // = false4352/**4353* Width of the back buffers4354*/4355protected int width;4356/**4357* Height of the back buffers4358*/4359protected int height;43604361/**4362* Insets for the hosting Component. The size of the back buffer4363* is constrained by these.4364*/4365private Insets insets;43664367/**4368* Creates a new blt buffer strategy around a component4369* @param numBuffers number of buffers to create, including the4370* front buffer4371* @param caps the capabilities of the buffers4372*/4373protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) {4374this.caps = caps;4375createBackBuffers(numBuffers - 1);4376}43774378/**4379* {@inheritDoc}4380* @since 1.64381*/4382public void dispose() {4383if (backBuffers != null) {4384for (int counter = backBuffers.length - 1; counter >= 0;4385counter--) {4386if (backBuffers[counter] != null) {4387backBuffers[counter].flush();4388backBuffers[counter] = null;4389}4390}4391}4392if (Component.this.bufferStrategy == this) {4393Component.this.bufferStrategy = null;4394}4395}43964397/**4398* Creates the back buffers4399*4400* @param numBuffers the number of buffers to create4401*/4402protected void createBackBuffers(int numBuffers) {4403if (numBuffers == 0) {4404backBuffers = null;4405} else {4406// save the current bounds4407width = getWidth();4408height = getHeight();4409insets = getInsets_NoClientCode();4410int iWidth = width - insets.left - insets.right;4411int iHeight = height - insets.top - insets.bottom;44124413// It is possible for the component's width and/or height4414// to be 0 here. Force the size of the backbuffers to4415// be > 0 so that creating the image won't fail.4416iWidth = Math.max(1, iWidth);4417iHeight = Math.max(1, iHeight);4418if (backBuffers == null) {4419backBuffers = new VolatileImage[numBuffers];4420} else {4421// flush any existing backbuffers4422for (int i = 0; i < numBuffers; i++) {4423if (backBuffers[i] != null) {4424backBuffers[i].flush();4425backBuffers[i] = null;4426}4427}4428}44294430// create the backbuffers4431for (int i = 0; i < numBuffers; i++) {4432backBuffers[i] = createVolatileImage(iWidth, iHeight);4433}4434}4435}44364437/**4438* @return the buffering capabilities of this strategy4439*/4440public BufferCapabilities getCapabilities() {4441return caps;4442}44434444/**4445* @return the draw graphics4446*/4447public Graphics getDrawGraphics() {4448revalidate();4449Image backBuffer = getBackBuffer();4450if (backBuffer == null) {4451return getGraphics();4452}4453SunGraphics2D g = (SunGraphics2D)backBuffer.getGraphics();4454g.constrain(-insets.left, -insets.top,4455backBuffer.getWidth(null) + insets.left,4456backBuffer.getHeight(null) + insets.top);4457return g;4458}44594460/**4461* @return direct access to the back buffer, as an image.4462* If there is no back buffer, returns null.4463*/4464Image getBackBuffer() {4465if (backBuffers != null) {4466return backBuffers[backBuffers.length - 1];4467} else {4468return null;4469}4470}44714472/**4473* Makes the next available buffer visible.4474*/4475public void show() {4476showSubRegion(insets.left, insets.top,4477width - insets.right,4478height - insets.bottom);4479}44804481/**4482* Package-private method to present a specific rectangular area4483* of this buffer. This class currently shows only the entire4484* buffer, by calling showSubRegion() with the full dimensions of4485* the buffer. Subclasses (e.g., BltSubRegionBufferStrategy4486* and FlipSubRegionBufferStrategy) may have region-specific show4487* methods that call this method with actual sub regions of the4488* buffer.4489*/4490void showSubRegion(int x1, int y1, int x2, int y2) {4491if (backBuffers == null) {4492return;4493}4494// Adjust location to be relative to client area.4495x1 -= insets.left;4496x2 -= insets.left;4497y1 -= insets.top;4498y2 -= insets.top;4499Graphics g = getGraphics_NoClientCode();4500if (g == null) {4501// Not showing, bail4502return;4503}4504try {4505// First image copy is in terms of Frame's coordinates, need4506// to translate to client area.4507g.translate(insets.left, insets.top);4508for (int i = 0; i < backBuffers.length; i++) {4509g.drawImage(backBuffers[i],4510x1, y1, x2, y2,4511x1, y1, x2, y2,4512null);4513g.dispose();4514g = null;4515g = backBuffers[i].getGraphics();4516}4517} finally {4518if (g != null) {4519g.dispose();4520}4521}4522}45234524/**4525* Restore the drawing buffer if it has been lost4526*/4527protected void revalidate() {4528revalidate(true);4529}45304531void revalidate(boolean checkSize) {4532validatedContents = false;45334534if (backBuffers == null) {4535return;4536}45374538if (checkSize) {4539Insets insets = getInsets_NoClientCode();4540if (getWidth() != width || getHeight() != height ||4541!insets.equals(this.insets)) {4542// component has been resized; recreate the backbuffers4543createBackBuffers(backBuffers.length);4544validatedContents = true;4545}4546}45474548// now validate the backbuffer4549GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();4550int returnCode =4551backBuffers[backBuffers.length - 1].validate(gc);4552if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {4553if (checkSize) {4554createBackBuffers(backBuffers.length);4555// backbuffers were recreated, so validate again4556backBuffers[backBuffers.length - 1].validate(gc);4557}4558// else case means we're called from Swing on the toolkit4559// thread, don't recreate buffers as that'll deadlock4560// (creating VolatileImages invokes getting GraphicsConfig4561// which grabs treelock).4562validatedContents = true;4563} else if (returnCode == VolatileImage.IMAGE_RESTORED) {4564validatedContents = true;4565}4566}45674568/**4569* @return whether the drawing buffer was lost since the last call to4570* {@code getDrawGraphics}4571*/4572public boolean contentsLost() {4573if (backBuffers == null) {4574return false;4575} else {4576return backBuffers[backBuffers.length - 1].contentsLost();4577}4578}45794580/**4581* @return whether the drawing buffer was recently restored from a lost4582* state and reinitialized to the default background color (white)4583*/4584public boolean contentsRestored() {4585return validatedContents;4586}4587} // Inner class BltBufferStrategy45884589/**4590* Private class to perform sub-region flipping.4591*/4592private class FlipSubRegionBufferStrategy extends FlipBufferStrategy4593implements SubRegionShowable4594{45954596protected FlipSubRegionBufferStrategy(int numBuffers,4597BufferCapabilities caps)4598throws AWTException4599{4600super(numBuffers, caps);4601}46024603public void show(int x1, int y1, int x2, int y2) {4604showSubRegion(x1, y1, x2, y2);4605}46064607// This is invoked by Swing on the toolkit thread.4608public boolean showIfNotLost(int x1, int y1, int x2, int y2) {4609if (!contentsLost()) {4610showSubRegion(x1, y1, x2, y2);4611return !contentsLost();4612}4613return false;4614}4615}46164617/**4618* Private class to perform sub-region blitting. Swing will use4619* this subclass via the SubRegionShowable interface in order to4620* copy only the area changed during a repaint.4621* See javax.swing.BufferStrategyPaintManager.4622*/4623private class BltSubRegionBufferStrategy extends BltBufferStrategy4624implements SubRegionShowable4625{46264627protected BltSubRegionBufferStrategy(int numBuffers,4628BufferCapabilities caps)4629{4630super(numBuffers, caps);4631}46324633public void show(int x1, int y1, int x2, int y2) {4634showSubRegion(x1, y1, x2, y2);4635}46364637// This method is called by Swing on the toolkit thread.4638public boolean showIfNotLost(int x1, int y1, int x2, int y2) {4639if (!contentsLost()) {4640showSubRegion(x1, y1, x2, y2);4641return !contentsLost();4642}4643return false;4644}4645}46464647/**4648* Inner class for flipping buffers on a component. That component must4649* be a {@code Canvas} or {@code Window}.4650* @see Canvas4651* @see Window4652* @see java.awt.image.BufferStrategy4653* @author Michael Martak4654* @since 1.44655*/4656private class SingleBufferStrategy extends BufferStrategy {46574658private BufferCapabilities caps;46594660public SingleBufferStrategy(BufferCapabilities caps) {4661this.caps = caps;4662}4663public BufferCapabilities getCapabilities() {4664return caps;4665}4666public Graphics getDrawGraphics() {4667return getGraphics();4668}4669public boolean contentsLost() {4670return false;4671}4672public boolean contentsRestored() {4673return false;4674}4675public void show() {4676// Do nothing4677}4678} // Inner class SingleBufferStrategy46794680/**4681* Sets whether or not paint messages received from the operating system4682* should be ignored. This does not affect paint events generated in4683* software by the AWT, unless they are an immediate response to an4684* OS-level paint message.4685* <p>4686* This is useful, for example, if running under full-screen mode and4687* better performance is desired, or if page-flipping is used as the4688* buffer strategy.4689*4690* @param ignoreRepaint {@code true} if the paint messages from the OS4691* should be ignored; otherwise {@code false}4692*4693* @since 1.44694* @see #getIgnoreRepaint4695* @see Canvas#createBufferStrategy4696* @see Window#createBufferStrategy4697* @see java.awt.image.BufferStrategy4698* @see GraphicsDevice#setFullScreenWindow4699*/4700public void setIgnoreRepaint(boolean ignoreRepaint) {4701this.ignoreRepaint = ignoreRepaint;4702}47034704/**4705* @return whether or not paint messages received from the operating system4706* should be ignored.4707*4708* @since 1.44709* @see #setIgnoreRepaint4710*/4711public boolean getIgnoreRepaint() {4712return ignoreRepaint;4713}47144715/**4716* Checks whether this component "contains" the specified point,4717* where {@code x} and {@code y} are defined to be4718* relative to the coordinate system of this component.4719*4720* @param x the <i>x</i> coordinate of the point4721* @param y the <i>y</i> coordinate of the point4722* @return {@code true} if the point is within the component;4723* otherwise {@code false}4724* @see #getComponentAt(int, int)4725* @since 1.14726*/4727public boolean contains(int x, int y) {4728return inside(x, y);4729}47304731/**4732* Checks whether the point is inside of this component.4733*4734* @param x the <i>x</i> coordinate of the point4735* @param y the <i>y</i> coordinate of the point4736* @return {@code true} if the point is within the component;4737* otherwise {@code false}4738* @deprecated As of JDK version 1.1,4739* replaced by contains(int, int).4740*/4741@Deprecated4742public boolean inside(int x, int y) {4743return (x >= 0) && (x < width) && (y >= 0) && (y < height);4744}47454746/**4747* Checks whether this component "contains" the specified point,4748* where the point's <i>x</i> and <i>y</i> coordinates are defined4749* to be relative to the coordinate system of this component.4750*4751* @param p the point4752* @return {@code true} if the point is within the component;4753* otherwise {@code false}4754* @throws NullPointerException if {@code p} is {@code null}4755* @see #getComponentAt(Point)4756* @since 1.14757*/4758public boolean contains(Point p) {4759return contains(p.x, p.y);4760}47614762/**4763* Determines if this component or one of its immediate4764* subcomponents contains the (<i>x</i>, <i>y</i>) location,4765* and if so, returns the containing component. This method only4766* looks one level deep. If the point (<i>x</i>, <i>y</i>) is4767* inside a subcomponent that itself has subcomponents, it does not4768* go looking down the subcomponent tree.4769* <p>4770* The {@code locate} method of {@code Component} simply4771* returns the component itself if the (<i>x</i>, <i>y</i>)4772* coordinate location is inside its bounding box, and {@code null}4773* otherwise.4774* @param x the <i>x</i> coordinate4775* @param y the <i>y</i> coordinate4776* @return the component or subcomponent that contains the4777* (<i>x</i>, <i>y</i>) location;4778* {@code null} if the location4779* is outside this component4780* @see #contains(int, int)4781* @since 1.04782*/4783public Component getComponentAt(int x, int y) {4784return locate(x, y);4785}47864787/**4788* Returns the component occupying the position specified (this component,4789* or immediate child component, or null if neither4790* of the first two occupies the location).4791*4792* @param x the <i>x</i> coordinate to search for components at4793* @param y the <i>y</i> coordinate to search for components at4794* @return the component at the specified location or {@code null}4795* @deprecated As of JDK version 1.1,4796* replaced by getComponentAt(int, int).4797*/4798@Deprecated4799public Component locate(int x, int y) {4800return contains(x, y) ? this : null;4801}48024803/**4804* Returns the component or subcomponent that contains the4805* specified point.4806* @param p the point4807* @return the component at the specified location or {@code null}4808* @see java.awt.Component#contains4809* @since 1.14810*/4811public Component getComponentAt(Point p) {4812return getComponentAt(p.x, p.y);4813}48144815/**4816* @param e the event to deliver4817* @deprecated As of JDK version 1.1,4818* replaced by {@code dispatchEvent(AWTEvent e)}.4819*/4820@Deprecated4821public void deliverEvent(Event e) {4822postEvent(e);4823}48244825/**4826* Dispatches an event to this component or one of its sub components.4827* Calls {@code processEvent} before returning for 1.1-style4828* events which have been enabled for the {@code Component}.4829* @param e the event4830*/4831public final void dispatchEvent(AWTEvent e) {4832dispatchEventImpl(e);4833}48344835@SuppressWarnings("deprecation")4836void dispatchEventImpl(AWTEvent e) {4837int id = e.getID();48384839// Check that this component belongs to this app-context4840AppContext compContext = appContext;4841if (compContext != null && !compContext.equals(AppContext.getAppContext())) {4842if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {4843eventLog.fine("Event " + e + " is being dispatched on the wrong AppContext");4844}4845}48464847if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {4848eventLog.finest("{0}", e);4849}48504851/*4852* 0. Set timestamp and modifiers of current event.4853*/4854if (!(e instanceof KeyEvent)) {4855// Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).4856EventQueue.setCurrentEventAndMostRecentTime(e);4857}48584859/*4860* 1. Pre-dispatchers. Do any necessary retargeting/reordering here4861* before we notify AWTEventListeners.4862*/48634864if (e instanceof SunDropTargetEvent) {4865((SunDropTargetEvent)e).dispatch();4866return;4867}48684869if (!e.focusManagerIsDispatching) {4870// Invoke the private focus retargeting method which provides4871// lightweight Component support4872if (e.isPosted) {4873e = KeyboardFocusManager.retargetFocusEvent(e);4874e.isPosted = true;4875}48764877// Now, with the event properly targeted to a lightweight4878// descendant if necessary, invoke the public focus retargeting4879// and dispatching function4880if (KeyboardFocusManager.getCurrentKeyboardFocusManager().4881dispatchEvent(e))4882{4883return;4884}4885}4886if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) {4887focusLog.finest("" + e);4888}4889// MouseWheel may need to be retargeted here so that4890// AWTEventListener sees the event go to the correct4891// Component. If the MouseWheelEvent needs to go to an ancestor,4892// the event is dispatched to the ancestor, and dispatching here4893// stops.4894if (id == MouseEvent.MOUSE_WHEEL &&4895(!eventTypeEnabled(id)) &&4896(peer != null && !peer.handlesWheelScrolling()) &&4897(dispatchMouseWheelToAncestor((MouseWheelEvent)e)))4898{4899return;4900}49014902/*4903* 2. Allow the Toolkit to pass this to AWTEventListeners.4904*/4905Toolkit toolkit = Toolkit.getDefaultToolkit();4906toolkit.notifyAWTEventListeners(e);490749084909/*4910* 3. If no one has consumed a key event, allow the4911* KeyboardFocusManager to process it.4912*/4913if (!e.isConsumed()) {4914if (e instanceof java.awt.event.KeyEvent) {4915KeyboardFocusManager.getCurrentKeyboardFocusManager().4916processKeyEvent(this, (KeyEvent)e);4917if (e.isConsumed()) {4918return;4919}4920}4921}49224923/*4924* 4. Allow input methods to process the event4925*/4926if (areInputMethodsEnabled()) {4927// We need to pass on InputMethodEvents since some host4928// input method adapters send them through the Java4929// event queue instead of directly to the component,4930// and the input context also handles the Java composition window4931if(((e instanceof InputMethodEvent) && !(this instanceof CompositionArea))4932||4933// Otherwise, we only pass on input and focus events, because4934// a) input methods shouldn't know about semantic or component-level events4935// b) passing on the events takes time4936// c) isConsumed() is always true for semantic events.4937(e instanceof InputEvent) || (e instanceof FocusEvent)) {4938InputContext inputContext = getInputContext();493949404941if (inputContext != null) {4942inputContext.dispatchEvent(e);4943if (e.isConsumed()) {4944if ((e instanceof FocusEvent) && focusLog.isLoggable(PlatformLogger.Level.FINEST)) {4945focusLog.finest("3579: Skipping " + e);4946}4947return;4948}4949}4950}4951} else {4952// When non-clients get focus, we need to explicitly disable the native4953// input method. The native input method is actually not disabled when4954// the active/passive/peered clients loose focus.4955if (id == FocusEvent.FOCUS_GAINED) {4956InputContext inputContext = getInputContext();4957if (inputContext != null && inputContext instanceof sun.awt.im.InputContext) {4958((sun.awt.im.InputContext)inputContext).disableNativeIM();4959}4960}4961}496249634964/*4965* 5. Pre-process any special events before delivery4966*/4967switch(id) {4968// Handling of the PAINT and UPDATE events is now done in the4969// peer's handleEvent() method so the background can be cleared4970// selectively for non-native components on Windows only.4971// - [email protected], 5-8-9849724973case KeyEvent.KEY_PRESSED:4974case KeyEvent.KEY_RELEASED:4975Container p = (Container)((this instanceof Container) ? this : parent);4976if (p != null) {4977p.preProcessKeyEvent((KeyEvent)e);4978if (e.isConsumed()) {4979if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {4980focusLog.finest("Pre-process consumed event");4981}4982return;4983}4984}4985break;49864987default:4988break;4989}49904991/*4992* 6. Deliver event for normal processing4993*/4994if (newEventsOnly) {4995// Filtering needs to really be moved to happen at a lower4996// level in order to get maximum performance gain; it is4997// here temporarily to ensure the API spec is honored.4998//4999if (eventEnabled(e)) {5000processEvent(e);5001}5002} else if (id == MouseEvent.MOUSE_WHEEL) {5003// newEventsOnly will be false for a listenerless ScrollPane, but5004// MouseWheelEvents still need to be dispatched to it so scrolling5005// can be done.5006autoProcessMouseWheel((MouseWheelEvent)e);5007} else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {5008//5009// backward compatibility5010//5011Event olde = e.convertToOld();5012if (olde != null) {5013int key = olde.key;5014int modifiers = olde.modifiers;50155016postEvent(olde);5017if (olde.isConsumed()) {5018e.consume();5019}5020// if target changed key or modifier values, copy them5021// back to original event5022//5023switch(olde.id) {5024case Event.KEY_PRESS:5025case Event.KEY_RELEASE:5026case Event.KEY_ACTION:5027case Event.KEY_ACTION_RELEASE:5028if (olde.key != key) {5029((KeyEvent)e).setKeyChar(olde.getKeyEventChar());5030}5031if (olde.modifiers != modifiers) {5032((KeyEvent)e).setModifiers(olde.modifiers);5033}5034break;5035default:5036break;5037}5038}5039}50405041/*5042* 9. Allow the peer to process the event.5043* Except KeyEvents, they will be processed by peer after5044* all KeyEventPostProcessors5045* (see DefaultKeyboardFocusManager.dispatchKeyEvent())5046*/5047if (!(e instanceof KeyEvent)) {5048ComponentPeer tpeer = peer;5049if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {5050// if focus owner is lightweight then its native container5051// processes event5052Component source = (Component)e.getSource();5053if (source != null) {5054Container target = source.getNativeContainer();5055if (target != null) {5056tpeer = target.peer;5057}5058}5059}5060if (tpeer != null) {5061tpeer.handleEvent(e);5062}5063}50645065if (SunToolkit.isTouchKeyboardAutoShowEnabled() &&5066(toolkit instanceof SunToolkit) &&5067((e instanceof MouseEvent) || (e instanceof FocusEvent))) {5068((SunToolkit)toolkit).showOrHideTouchKeyboard(this, e);5069}5070} // dispatchEventImpl()50715072/*5073* If newEventsOnly is false, method is called so that ScrollPane can5074* override it and handle common-case mouse wheel scrolling. NOP5075* for Component.5076*/5077void autoProcessMouseWheel(MouseWheelEvent e) {}50785079/*5080* Dispatch given MouseWheelEvent to the first ancestor for which5081* MouseWheelEvents are enabled.5082*5083* Returns whether or not event was dispatched to an ancestor5084*/5085@SuppressWarnings("deprecation")5086boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {5087int newX, newY;5088newX = e.getX() + getX(); // Coordinates take into account at least5089newY = e.getY() + getY(); // the cursor's position relative to this5090// Component (e.getX()), and this Component's5091// position relative to its parent.5092MouseWheelEvent newMWE;50935094if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {5095eventLog.finest("dispatchMouseWheelToAncestor");5096eventLog.finest("orig event src is of " + e.getSource().getClass());5097}50985099/* parent field for Window refers to the owning Window.5100* MouseWheelEvents should NOT be propagated into owning Windows5101*/5102synchronized (getTreeLock()) {5103Container anc = getParent();5104while (anc != null && !anc.eventEnabled(e)) {5105// fix coordinates to be relative to new event source5106newX += anc.getX();5107newY += anc.getY();51085109if (!(anc instanceof Window)) {5110anc = anc.getParent();5111}5112else {5113break;5114}5115}51165117if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {5118eventLog.finest("new event src is " + anc.getClass());5119}51205121if (anc != null && anc.eventEnabled(e)) {5122// Change event to be from new source, with new x,y5123// For now, just create a new event - yucky51245125newMWE = new MouseWheelEvent(anc, // new source5126e.getID(),5127e.getWhen(),5128e.getModifiers(),5129newX, // x relative to new source5130newY, // y relative to new source5131e.getXOnScreen(),5132e.getYOnScreen(),5133e.getClickCount(),5134e.isPopupTrigger(),5135e.getScrollType(),5136e.getScrollAmount(),5137e.getWheelRotation(),5138e.getPreciseWheelRotation());5139((AWTEvent)e).copyPrivateDataInto(newMWE);5140// When dispatching a wheel event to5141// ancestor, there is no need trying to find descendant5142// lightweights to dispatch event to.5143// If we dispatch the event to toplevel ancestor,5144// this could enclose the loop: 6480024.5145anc.dispatchEventToSelf(newMWE);5146if (newMWE.isConsumed()) {5147e.consume();5148}5149return true;5150}5151}5152return false;5153}51545155boolean areInputMethodsEnabled() {5156// in 1.2, we assume input method support is required for all5157// components that handle key events, but components can turn off5158// input methods by calling enableInputMethods(false).5159return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&5160((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);5161}51625163// REMIND: remove when filtering is handled at lower level5164boolean eventEnabled(AWTEvent e) {5165return eventTypeEnabled(e.id);5166}51675168boolean eventTypeEnabled(int type) {5169switch(type) {5170case ComponentEvent.COMPONENT_MOVED:5171case ComponentEvent.COMPONENT_RESIZED:5172case ComponentEvent.COMPONENT_SHOWN:5173case ComponentEvent.COMPONENT_HIDDEN:5174if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||5175componentListener != null) {5176return true;5177}5178break;5179case FocusEvent.FOCUS_GAINED:5180case FocusEvent.FOCUS_LOST:5181if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 ||5182focusListener != null) {5183return true;5184}5185break;5186case KeyEvent.KEY_PRESSED:5187case KeyEvent.KEY_RELEASED:5188case KeyEvent.KEY_TYPED:5189if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 ||5190keyListener != null) {5191return true;5192}5193break;5194case MouseEvent.MOUSE_PRESSED:5195case MouseEvent.MOUSE_RELEASED:5196case MouseEvent.MOUSE_ENTERED:5197case MouseEvent.MOUSE_EXITED:5198case MouseEvent.MOUSE_CLICKED:5199if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 ||5200mouseListener != null) {5201return true;5202}5203break;5204case MouseEvent.MOUSE_MOVED:5205case MouseEvent.MOUSE_DRAGGED:5206if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 ||5207mouseMotionListener != null) {5208return true;5209}5210break;5211case MouseEvent.MOUSE_WHEEL:5212if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 ||5213mouseWheelListener != null) {5214return true;5215}5216break;5217case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:5218case InputMethodEvent.CARET_POSITION_CHANGED:5219if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 ||5220inputMethodListener != null) {5221return true;5222}5223break;5224case HierarchyEvent.HIERARCHY_CHANGED:5225if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||5226hierarchyListener != null) {5227return true;5228}5229break;5230case HierarchyEvent.ANCESTOR_MOVED:5231case HierarchyEvent.ANCESTOR_RESIZED:5232if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||5233hierarchyBoundsListener != null) {5234return true;5235}5236break;5237case ActionEvent.ACTION_PERFORMED:5238if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {5239return true;5240}5241break;5242case TextEvent.TEXT_VALUE_CHANGED:5243if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {5244return true;5245}5246break;5247case ItemEvent.ITEM_STATE_CHANGED:5248if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {5249return true;5250}5251break;5252case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:5253if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {5254return true;5255}5256break;5257default:5258break;5259}5260//5261// Always pass on events defined by external programs.5262//5263if (type > AWTEvent.RESERVED_ID_MAX) {5264return true;5265}5266return false;5267}52685269/**5270* @deprecated As of JDK version 1.1,5271* replaced by dispatchEvent(AWTEvent).5272*/5273@Deprecated5274public boolean postEvent(Event e) {5275ComponentPeer peer = this.peer;52765277if (handleEvent(e)) {5278e.consume();5279return true;5280}52815282Component parent = this.parent;5283int eventx = e.x;5284int eventy = e.y;5285if (parent != null) {5286e.translate(x, y);5287if (parent.postEvent(e)) {5288e.consume();5289return true;5290}5291// restore coords5292e.x = eventx;5293e.y = eventy;5294}5295return false;5296}52975298// Event source interfaces52995300/**5301* Adds the specified component listener to receive component events from5302* this component.5303* If listener {@code l} is {@code null},5304* no exception is thrown and no action is performed.5305* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5306* >AWT Threading Issues</a> for details on AWT's threading model.5307*5308* @param l the component listener5309* @see java.awt.event.ComponentEvent5310* @see java.awt.event.ComponentListener5311* @see #removeComponentListener5312* @see #getComponentListeners5313* @since 1.15314*/5315public synchronized void addComponentListener(ComponentListener l) {5316if (l == null) {5317return;5318}5319componentListener = AWTEventMulticaster.add(componentListener, l);5320newEventsOnly = true;5321}53225323/**5324* Removes the specified component listener so that it no longer5325* receives component events from this component. This method performs5326* no function, nor does it throw an exception, if the listener5327* specified by the argument was not previously added to this component.5328* If listener {@code l} is {@code null},5329* no exception is thrown and no action is performed.5330* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5331* >AWT Threading Issues</a> for details on AWT's threading model.5332* @param l the component listener5333* @see java.awt.event.ComponentEvent5334* @see java.awt.event.ComponentListener5335* @see #addComponentListener5336* @see #getComponentListeners5337* @since 1.15338*/5339public synchronized void removeComponentListener(ComponentListener l) {5340if (l == null) {5341return;5342}5343componentListener = AWTEventMulticaster.remove(componentListener, l);5344}53455346/**5347* Returns an array of all the component listeners5348* registered on this component.5349*5350* @return all {@code ComponentListener}s of this component5351* or an empty array if no component5352* listeners are currently registered5353*5354* @see #addComponentListener5355* @see #removeComponentListener5356* @since 1.45357*/5358public synchronized ComponentListener[] getComponentListeners() {5359return getListeners(ComponentListener.class);5360}53615362/**5363* Adds the specified focus listener to receive focus events from5364* this component when this component gains input focus.5365* If listener {@code l} is {@code null},5366* no exception is thrown and no action is performed.5367* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5368* >AWT Threading Issues</a> for details on AWT's threading model.5369*5370* @param l the focus listener5371* @see java.awt.event.FocusEvent5372* @see java.awt.event.FocusListener5373* @see #removeFocusListener5374* @see #getFocusListeners5375* @since 1.15376*/5377public synchronized void addFocusListener(FocusListener l) {5378if (l == null) {5379return;5380}5381focusListener = AWTEventMulticaster.add(focusListener, l);5382newEventsOnly = true;53835384// if this is a lightweight component, enable focus events5385// in the native container.5386if (peer instanceof LightweightPeer) {5387parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);5388}5389}53905391/**5392* Removes the specified focus listener so that it no longer5393* receives focus events from this component. This method performs5394* no function, nor does it throw an exception, if the listener5395* specified by the argument was not previously added to this component.5396* If listener {@code l} is {@code null},5397* no exception is thrown and no action is performed.5398* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5399* >AWT Threading Issues</a> for details on AWT's threading model.5400*5401* @param l the focus listener5402* @see java.awt.event.FocusEvent5403* @see java.awt.event.FocusListener5404* @see #addFocusListener5405* @see #getFocusListeners5406* @since 1.15407*/5408public synchronized void removeFocusListener(FocusListener l) {5409if (l == null) {5410return;5411}5412focusListener = AWTEventMulticaster.remove(focusListener, l);5413}54145415/**5416* Returns an array of all the focus listeners5417* registered on this component.5418*5419* @return all of this component's {@code FocusListener}s5420* or an empty array if no component5421* listeners are currently registered5422*5423* @see #addFocusListener5424* @see #removeFocusListener5425* @since 1.45426*/5427public synchronized FocusListener[] getFocusListeners() {5428return getListeners(FocusListener.class);5429}54305431/**5432* Adds the specified hierarchy listener to receive hierarchy changed5433* events from this component when the hierarchy to which this container5434* belongs changes.5435* If listener {@code l} is {@code null},5436* no exception is thrown and no action is performed.5437* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5438* >AWT Threading Issues</a> for details on AWT's threading model.5439*5440* @param l the hierarchy listener5441* @see java.awt.event.HierarchyEvent5442* @see java.awt.event.HierarchyListener5443* @see #removeHierarchyListener5444* @see #getHierarchyListeners5445* @since 1.35446*/5447public void addHierarchyListener(HierarchyListener l) {5448if (l == null) {5449return;5450}5451boolean notifyAncestors;5452synchronized (this) {5453notifyAncestors =5454(hierarchyListener == null &&5455(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);5456hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);5457notifyAncestors = (notifyAncestors && hierarchyListener != null);5458newEventsOnly = true;5459}5460if (notifyAncestors) {5461synchronized (getTreeLock()) {5462adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,54631);5464}5465}5466}54675468/**5469* Removes the specified hierarchy listener so that it no longer5470* receives hierarchy changed events from this component. This method5471* performs no function, nor does it throw an exception, if the listener5472* specified by the argument was not previously added to this component.5473* If listener {@code l} is {@code null},5474* no exception is thrown and no action is performed.5475* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5476* >AWT Threading Issues</a> for details on AWT's threading model.5477*5478* @param l the hierarchy listener5479* @see java.awt.event.HierarchyEvent5480* @see java.awt.event.HierarchyListener5481* @see #addHierarchyListener5482* @see #getHierarchyListeners5483* @since 1.35484*/5485public void removeHierarchyListener(HierarchyListener l) {5486if (l == null) {5487return;5488}5489boolean notifyAncestors;5490synchronized (this) {5491notifyAncestors =5492(hierarchyListener != null &&5493(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);5494hierarchyListener =5495AWTEventMulticaster.remove(hierarchyListener, l);5496notifyAncestors = (notifyAncestors && hierarchyListener == null);5497}5498if (notifyAncestors) {5499synchronized (getTreeLock()) {5500adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,5501-1);5502}5503}5504}55055506/**5507* Returns an array of all the hierarchy listeners5508* registered on this component.5509*5510* @return all of this component's {@code HierarchyListener}s5511* or an empty array if no hierarchy5512* listeners are currently registered5513*5514* @see #addHierarchyListener5515* @see #removeHierarchyListener5516* @since 1.45517*/5518public synchronized HierarchyListener[] getHierarchyListeners() {5519return getListeners(HierarchyListener.class);5520}55215522/**5523* Adds the specified hierarchy bounds listener to receive hierarchy5524* bounds events from this component when the hierarchy to which this5525* container belongs changes.5526* If listener {@code l} is {@code null},5527* no exception is thrown and no action is performed.5528* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5529* >AWT Threading Issues</a> for details on AWT's threading model.5530*5531* @param l the hierarchy bounds listener5532* @see java.awt.event.HierarchyEvent5533* @see java.awt.event.HierarchyBoundsListener5534* @see #removeHierarchyBoundsListener5535* @see #getHierarchyBoundsListeners5536* @since 1.35537*/5538public void addHierarchyBoundsListener(HierarchyBoundsListener l) {5539if (l == null) {5540return;5541}5542boolean notifyAncestors;5543synchronized (this) {5544notifyAncestors =5545(hierarchyBoundsListener == null &&5546(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);5547hierarchyBoundsListener =5548AWTEventMulticaster.add(hierarchyBoundsListener, l);5549notifyAncestors = (notifyAncestors &&5550hierarchyBoundsListener != null);5551newEventsOnly = true;5552}5553if (notifyAncestors) {5554synchronized (getTreeLock()) {5555adjustListeningChildrenOnParent(5556AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);5557}5558}5559}55605561/**5562* Removes the specified hierarchy bounds listener so that it no longer5563* receives hierarchy bounds events from this component. This method5564* performs no function, nor does it throw an exception, if the listener5565* specified by the argument was not previously added to this component.5566* If listener {@code l} is {@code null},5567* no exception is thrown and no action is performed.5568* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5569* >AWT Threading Issues</a> for details on AWT's threading model.5570*5571* @param l the hierarchy bounds listener5572* @see java.awt.event.HierarchyEvent5573* @see java.awt.event.HierarchyBoundsListener5574* @see #addHierarchyBoundsListener5575* @see #getHierarchyBoundsListeners5576* @since 1.35577*/5578public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {5579if (l == null) {5580return;5581}5582boolean notifyAncestors;5583synchronized (this) {5584notifyAncestors =5585(hierarchyBoundsListener != null &&5586(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);5587hierarchyBoundsListener =5588AWTEventMulticaster.remove(hierarchyBoundsListener, l);5589notifyAncestors = (notifyAncestors &&5590hierarchyBoundsListener == null);5591}5592if (notifyAncestors) {5593synchronized (getTreeLock()) {5594adjustListeningChildrenOnParent(5595AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);5596}5597}5598}55995600// Should only be called while holding the tree lock5601int numListening(long mask) {5602// One mask or the other, but not neither or both.5603if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {5604if ((mask != AWTEvent.HIERARCHY_EVENT_MASK) &&5605(mask != AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK))5606{5607eventLog.fine("Assertion failed");5608}5609}5610if ((mask == AWTEvent.HIERARCHY_EVENT_MASK &&5611(hierarchyListener != null ||5612(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) ||5613(mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK &&5614(hierarchyBoundsListener != null ||5615(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {5616return 1;5617} else {5618return 0;5619}5620}56215622// Should only be called while holding tree lock5623int countHierarchyMembers() {5624return 1;5625}5626// Should only be called while holding the tree lock5627int createHierarchyEvents(int id, Component changed,5628Container changedParent, long changeFlags,5629boolean enabledOnToolkit) {5630switch (id) {5631case HierarchyEvent.HIERARCHY_CHANGED:5632if (hierarchyListener != null ||5633(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||5634enabledOnToolkit) {5635HierarchyEvent e = new HierarchyEvent(this, id, changed,5636changedParent,5637changeFlags);5638dispatchEvent(e);5639return 1;5640}5641break;5642case HierarchyEvent.ANCESTOR_MOVED:5643case HierarchyEvent.ANCESTOR_RESIZED:5644if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {5645if (changeFlags != 0) {5646eventLog.fine("Assertion (changeFlags == 0) failed");5647}5648}5649if (hierarchyBoundsListener != null ||5650(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||5651enabledOnToolkit) {5652HierarchyEvent e = new HierarchyEvent(this, id, changed,5653changedParent);5654dispatchEvent(e);5655return 1;5656}5657break;5658default:5659// assert false5660if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {5661eventLog.fine("This code must never be reached");5662}5663break;5664}5665return 0;5666}56675668/**5669* Returns an array of all the hierarchy bounds listeners5670* registered on this component.5671*5672* @return all of this component's {@code HierarchyBoundsListener}s5673* or an empty array if no hierarchy bounds5674* listeners are currently registered5675*5676* @see #addHierarchyBoundsListener5677* @see #removeHierarchyBoundsListener5678* @since 1.45679*/5680public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {5681return getListeners(HierarchyBoundsListener.class);5682}56835684/*5685* Should only be called while holding the tree lock.5686* It's added only for overriding in java.awt.Window5687* because parent in Window is owner.5688*/5689void adjustListeningChildrenOnParent(long mask, int num) {5690if (parent != null) {5691parent.adjustListeningChildren(mask, num);5692}5693}56945695/**5696* Adds the specified key listener to receive key events from5697* this component.5698* If l is null, no exception is thrown and no action is performed.5699* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5700* >AWT Threading Issues</a> for details on AWT's threading model.5701*5702* @param l the key listener.5703* @see java.awt.event.KeyEvent5704* @see java.awt.event.KeyListener5705* @see #removeKeyListener5706* @see #getKeyListeners5707* @since 1.15708*/5709public synchronized void addKeyListener(KeyListener l) {5710if (l == null) {5711return;5712}5713keyListener = AWTEventMulticaster.add(keyListener, l);5714newEventsOnly = true;57155716// if this is a lightweight component, enable key events5717// in the native container.5718if (peer instanceof LightweightPeer) {5719parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);5720}5721}57225723/**5724* Removes the specified key listener so that it no longer5725* receives key events from this component. This method performs5726* no function, nor does it throw an exception, if the listener5727* specified by the argument was not previously added to this component.5728* If listener {@code l} is {@code null},5729* no exception is thrown and no action is performed.5730* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5731* >AWT Threading Issues</a> for details on AWT's threading model.5732*5733* @param l the key listener5734* @see java.awt.event.KeyEvent5735* @see java.awt.event.KeyListener5736* @see #addKeyListener5737* @see #getKeyListeners5738* @since 1.15739*/5740public synchronized void removeKeyListener(KeyListener l) {5741if (l == null) {5742return;5743}5744keyListener = AWTEventMulticaster.remove(keyListener, l);5745}57465747/**5748* Returns an array of all the key listeners5749* registered on this component.5750*5751* @return all of this component's {@code KeyListener}s5752* or an empty array if no key5753* listeners are currently registered5754*5755* @see #addKeyListener5756* @see #removeKeyListener5757* @since 1.45758*/5759public synchronized KeyListener[] getKeyListeners() {5760return getListeners(KeyListener.class);5761}57625763/**5764* Adds the specified mouse listener to receive mouse events from5765* this component.5766* If listener {@code l} is {@code null},5767* no exception is thrown and no action is performed.5768* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5769* >AWT Threading Issues</a> for details on AWT's threading model.5770*5771* @param l the mouse listener5772* @see java.awt.event.MouseEvent5773* @see java.awt.event.MouseListener5774* @see #removeMouseListener5775* @see #getMouseListeners5776* @since 1.15777*/5778public synchronized void addMouseListener(MouseListener l) {5779if (l == null) {5780return;5781}5782mouseListener = AWTEventMulticaster.add(mouseListener,l);5783newEventsOnly = true;57845785// if this is a lightweight component, enable mouse events5786// in the native container.5787if (peer instanceof LightweightPeer) {5788parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);5789}5790}57915792/**5793* Removes the specified mouse listener so that it no longer5794* receives mouse events from this component. This method performs5795* no function, nor does it throw an exception, if the listener5796* specified by the argument was not previously added to this component.5797* If listener {@code l} is {@code null},5798* no exception is thrown and no action is performed.5799* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5800* >AWT Threading Issues</a> for details on AWT's threading model.5801*5802* @param l the mouse listener5803* @see java.awt.event.MouseEvent5804* @see java.awt.event.MouseListener5805* @see #addMouseListener5806* @see #getMouseListeners5807* @since 1.15808*/5809public synchronized void removeMouseListener(MouseListener l) {5810if (l == null) {5811return;5812}5813mouseListener = AWTEventMulticaster.remove(mouseListener, l);5814}58155816/**5817* Returns an array of all the mouse listeners5818* registered on this component.5819*5820* @return all of this component's {@code MouseListener}s5821* or an empty array if no mouse5822* listeners are currently registered5823*5824* @see #addMouseListener5825* @see #removeMouseListener5826* @since 1.45827*/5828public synchronized MouseListener[] getMouseListeners() {5829return getListeners(MouseListener.class);5830}58315832/**5833* Adds the specified mouse motion listener to receive mouse motion5834* events from this component.5835* If listener {@code l} is {@code null},5836* no exception is thrown and no action is performed.5837* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5838* >AWT Threading Issues</a> for details on AWT's threading model.5839*5840* @param l the mouse motion listener5841* @see java.awt.event.MouseEvent5842* @see java.awt.event.MouseMotionListener5843* @see #removeMouseMotionListener5844* @see #getMouseMotionListeners5845* @since 1.15846*/5847public synchronized void addMouseMotionListener(MouseMotionListener l) {5848if (l == null) {5849return;5850}5851mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l);5852newEventsOnly = true;58535854// if this is a lightweight component, enable mouse events5855// in the native container.5856if (peer instanceof LightweightPeer) {5857parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);5858}5859}58605861/**5862* Removes the specified mouse motion listener so that it no longer5863* receives mouse motion events from this component. This method performs5864* no function, nor does it throw an exception, if the listener5865* specified by the argument was not previously added to this component.5866* If listener {@code l} is {@code null},5867* no exception is thrown and no action is performed.5868* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5869* >AWT Threading Issues</a> for details on AWT's threading model.5870*5871* @param l the mouse motion listener5872* @see java.awt.event.MouseEvent5873* @see java.awt.event.MouseMotionListener5874* @see #addMouseMotionListener5875* @see #getMouseMotionListeners5876* @since 1.15877*/5878public synchronized void removeMouseMotionListener(MouseMotionListener l) {5879if (l == null) {5880return;5881}5882mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);5883}58845885/**5886* Returns an array of all the mouse motion listeners5887* registered on this component.5888*5889* @return all of this component's {@code MouseMotionListener}s5890* or an empty array if no mouse motion5891* listeners are currently registered5892*5893* @see #addMouseMotionListener5894* @see #removeMouseMotionListener5895* @since 1.45896*/5897public synchronized MouseMotionListener[] getMouseMotionListeners() {5898return getListeners(MouseMotionListener.class);5899}59005901/**5902* Adds the specified mouse wheel listener to receive mouse wheel events5903* from this component. Containers also receive mouse wheel events from5904* sub-components.5905* <p>5906* For information on how mouse wheel events are dispatched, see5907* the class description for {@link MouseWheelEvent}.5908* <p>5909* If l is {@code null}, no exception is thrown and no5910* action is performed.5911* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5912* >AWT Threading Issues</a> for details on AWT's threading model.5913*5914* @param l the mouse wheel listener5915* @see java.awt.event.MouseWheelEvent5916* @see java.awt.event.MouseWheelListener5917* @see #removeMouseWheelListener5918* @see #getMouseWheelListeners5919* @since 1.45920*/5921public synchronized void addMouseWheelListener(MouseWheelListener l) {5922if (l == null) {5923return;5924}5925mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l);5926newEventsOnly = true;59275928// if this is a lightweight component, enable mouse events5929// in the native container.5930if (peer instanceof LightweightPeer) {5931parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);5932}5933}59345935/**5936* Removes the specified mouse wheel listener so that it no longer5937* receives mouse wheel events from this component. This method performs5938* no function, nor does it throw an exception, if the listener5939* specified by the argument was not previously added to this component.5940* If l is null, no exception is thrown and no action is performed.5941* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"5942* >AWT Threading Issues</a> for details on AWT's threading model.5943*5944* @param l the mouse wheel listener.5945* @see java.awt.event.MouseWheelEvent5946* @see java.awt.event.MouseWheelListener5947* @see #addMouseWheelListener5948* @see #getMouseWheelListeners5949* @since 1.45950*/5951public synchronized void removeMouseWheelListener(MouseWheelListener l) {5952if (l == null) {5953return;5954}5955mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);5956}59575958/**5959* Returns an array of all the mouse wheel listeners5960* registered on this component.5961*5962* @return all of this component's {@code MouseWheelListener}s5963* or an empty array if no mouse wheel5964* listeners are currently registered5965*5966* @see #addMouseWheelListener5967* @see #removeMouseWheelListener5968* @since 1.45969*/5970public synchronized MouseWheelListener[] getMouseWheelListeners() {5971return getListeners(MouseWheelListener.class);5972}59735974/**5975* Adds the specified input method listener to receive5976* input method events from this component. A component will5977* only receive input method events from input methods5978* if it also overrides {@code getInputMethodRequests} to return an5979* {@code InputMethodRequests} instance.5980* If listener {@code l} is {@code null},5981* no exception is thrown and no action is performed.5982* <p>Refer to5983* <a href="{@docRoot}/java.desktop/java/awt/doc-files/AWTThreadIssues.html#ListenersThreads"5984* >AWT Threading Issues</a> for details on AWT's threading model.5985*5986* @param l the input method listener5987* @see java.awt.event.InputMethodEvent5988* @see java.awt.event.InputMethodListener5989* @see #removeInputMethodListener5990* @see #getInputMethodListeners5991* @see #getInputMethodRequests5992* @since 1.25993*/5994public synchronized void addInputMethodListener(InputMethodListener l) {5995if (l == null) {5996return;5997}5998inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);5999newEventsOnly = true;6000}60016002/**6003* Removes the specified input method listener so that it no longer6004* receives input method events from this component. This method performs6005* no function, nor does it throw an exception, if the listener6006* specified by the argument was not previously added to this component.6007* If listener {@code l} is {@code null},6008* no exception is thrown and no action is performed.6009* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"6010* >AWT Threading Issues</a> for details on AWT's threading model.6011*6012* @param l the input method listener6013* @see java.awt.event.InputMethodEvent6014* @see java.awt.event.InputMethodListener6015* @see #addInputMethodListener6016* @see #getInputMethodListeners6017* @since 1.26018*/6019public synchronized void removeInputMethodListener(InputMethodListener l) {6020if (l == null) {6021return;6022}6023inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);6024}60256026/**6027* Returns an array of all the input method listeners6028* registered on this component.6029*6030* @return all of this component's {@code InputMethodListener}s6031* or an empty array if no input method6032* listeners are currently registered6033*6034* @see #addInputMethodListener6035* @see #removeInputMethodListener6036* @since 1.46037*/6038public synchronized InputMethodListener[] getInputMethodListeners() {6039return getListeners(InputMethodListener.class);6040}60416042/**6043* Returns an array of all the objects currently registered6044* as <code><em>Foo</em>Listener</code>s6045* upon this {@code Component}.6046* <code><em>Foo</em>Listener</code>s are registered using the6047* <code>add<em>Foo</em>Listener</code> method.6048*6049* <p>6050* You can specify the {@code listenerType} argument6051* with a class literal, such as6052* <code><em>Foo</em>Listener.class</code>.6053* For example, you can query a6054* {@code Component c}6055* for its mouse listeners with the following code:6056*6057* <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>6058*6059* If no such listeners exist, this method returns an empty array.6060*6061* @param <T> the type of the listeners6062* @param listenerType the type of listeners requested; this parameter6063* should specify an interface that descends from6064* {@code java.util.EventListener}6065* @return an array of all objects registered as6066* <code><em>Foo</em>Listener</code>s on this component,6067* or an empty array if no such listeners have been added6068* @exception ClassCastException if {@code listenerType}6069* doesn't specify a class or interface that implements6070* {@code java.util.EventListener}6071* @throws NullPointerException if {@code listenerType} is {@code null}6072* @see #getComponentListeners6073* @see #getFocusListeners6074* @see #getHierarchyListeners6075* @see #getHierarchyBoundsListeners6076* @see #getKeyListeners6077* @see #getMouseListeners6078* @see #getMouseMotionListeners6079* @see #getMouseWheelListeners6080* @see #getInputMethodListeners6081* @see #getPropertyChangeListeners6082*6083* @since 1.36084*/6085@SuppressWarnings("unchecked")6086public <T extends EventListener> T[] getListeners(Class<T> listenerType) {6087EventListener l = null;6088if (listenerType == ComponentListener.class) {6089l = componentListener;6090} else if (listenerType == FocusListener.class) {6091l = focusListener;6092} else if (listenerType == HierarchyListener.class) {6093l = hierarchyListener;6094} else if (listenerType == HierarchyBoundsListener.class) {6095l = hierarchyBoundsListener;6096} else if (listenerType == KeyListener.class) {6097l = keyListener;6098} else if (listenerType == MouseListener.class) {6099l = mouseListener;6100} else if (listenerType == MouseMotionListener.class) {6101l = mouseMotionListener;6102} else if (listenerType == MouseWheelListener.class) {6103l = mouseWheelListener;6104} else if (listenerType == InputMethodListener.class) {6105l = inputMethodListener;6106} else if (listenerType == PropertyChangeListener.class) {6107return (T[])getPropertyChangeListeners();6108}6109return AWTEventMulticaster.getListeners(l, listenerType);6110}61116112/**6113* Gets the input method request handler which supports6114* requests from input methods for this component. A component6115* that supports on-the-spot text input must override this6116* method to return an {@code InputMethodRequests} instance.6117* At the same time, it also has to handle input method events.6118*6119* @return the input method request handler for this component,6120* {@code null} by default6121* @see #addInputMethodListener6122* @since 1.26123*/6124public InputMethodRequests getInputMethodRequests() {6125return null;6126}61276128/**6129* Gets the input context used by this component for handling6130* the communication with input methods when text is entered6131* in this component. By default, the input context used for6132* the parent component is returned. Components may6133* override this to return a private input context.6134*6135* @return the input context used by this component;6136* {@code null} if no context can be determined6137* @since 1.26138*/6139public InputContext getInputContext() {6140Container parent = this.parent;6141if (parent == null) {6142return null;6143} else {6144return parent.getInputContext();6145}6146}61476148/**6149* Enables the events defined by the specified event mask parameter6150* to be delivered to this component.6151* <p>6152* Event types are automatically enabled when a listener for6153* that event type is added to the component.6154* <p>6155* This method only needs to be invoked by subclasses of6156* {@code Component} which desire to have the specified event6157* types delivered to {@code processEvent} regardless of whether6158* or not a listener is registered.6159* @param eventsToEnable the event mask defining the event types6160* @see #processEvent6161* @see #disableEvents6162* @see AWTEvent6163* @since 1.16164*/6165protected final void enableEvents(long eventsToEnable) {6166long notifyAncestors = 0;6167synchronized (this) {6168if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&6169hierarchyListener == null &&6170(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {6171notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;6172}6173if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&6174hierarchyBoundsListener == null &&6175(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {6176notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;6177}6178eventMask |= eventsToEnable;6179newEventsOnly = true;6180}61816182// if this is a lightweight component, enable mouse events6183// in the native container.6184if (peer instanceof LightweightPeer) {6185parent.proxyEnableEvents(eventMask);6186}6187if (notifyAncestors != 0) {6188synchronized (getTreeLock()) {6189adjustListeningChildrenOnParent(notifyAncestors, 1);6190}6191}6192}61936194/**6195* Disables the events defined by the specified event mask parameter6196* from being delivered to this component.6197* @param eventsToDisable the event mask defining the event types6198* @see #enableEvents6199* @since 1.16200*/6201protected final void disableEvents(long eventsToDisable) {6202long notifyAncestors = 0;6203synchronized (this) {6204if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&6205hierarchyListener == null &&6206(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {6207notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;6208}6209if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 &&6210hierarchyBoundsListener == null &&6211(eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {6212notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;6213}6214eventMask &= ~eventsToDisable;6215}6216if (notifyAncestors != 0) {6217synchronized (getTreeLock()) {6218adjustListeningChildrenOnParent(notifyAncestors, -1);6219}6220}6221}62226223transient sun.awt.EventQueueItem[] eventCache;62246225/**6226* @see #isCoalescingEnabled6227* @see #checkCoalescing6228*/6229private transient boolean coalescingEnabled = checkCoalescing();62306231/**6232* Weak map of known coalesceEvent overriders.6233* Value indicates whether overriden.6234* Bootstrap classes are not included.6235*/6236private static final Map<Class<?>, Boolean> coalesceMap =6237new java.util.WeakHashMap<Class<?>, Boolean>();62386239/**6240* Indicates whether this class overrides coalesceEvents.6241* It is assumed that all classes that are loaded from the bootstrap6242* do not.6243* The bootstrap class loader is assumed to be represented by null.6244* We do not check that the method really overrides6245* (it might be static, private or package private).6246*/6247private boolean checkCoalescing() {6248if (getClass().getClassLoader()==null) {6249return false;6250}6251final Class<? extends Component> clazz = getClass();6252synchronized (coalesceMap) {6253// Check cache.6254Boolean value = coalesceMap.get(clazz);6255if (value != null) {6256return value;6257}62586259// Need to check non-bootstraps.6260@SuppressWarnings("removal")6261Boolean enabled = java.security.AccessController.doPrivileged(6262new java.security.PrivilegedAction<Boolean>() {6263public Boolean run() {6264return isCoalesceEventsOverriden(clazz);6265}6266}6267);6268coalesceMap.put(clazz, enabled);6269return enabled;6270}6271}62726273/**6274* Parameter types of coalesceEvents(AWTEvent,AWTEVent).6275*/6276private static final Class<?>[] coalesceEventsParams = {6277AWTEvent.class, AWTEvent.class6278};62796280/**6281* Indicates whether a class or its superclasses override coalesceEvents.6282* Must be called with lock on coalesceMap and privileged.6283* @see #checkCoalescing6284*/6285private static boolean isCoalesceEventsOverriden(Class<?> clazz) {6286assert Thread.holdsLock(coalesceMap);62876288// First check superclass - we may not need to bother ourselves.6289Class<?> superclass = clazz.getSuperclass();6290if (superclass == null) {6291// Only occurs on implementations that6292// do not use null to represent the bootstrap class loader.6293return false;6294}6295if (superclass.getClassLoader() != null) {6296Boolean value = coalesceMap.get(superclass);6297if (value == null) {6298// Not done already - recurse.6299if (isCoalesceEventsOverriden(superclass)) {6300coalesceMap.put(superclass, true);6301return true;6302}6303} else if (value) {6304return true;6305}6306}63076308try {6309// Throws if not overriden.6310clazz.getDeclaredMethod(6311"coalesceEvents", coalesceEventsParams6312);6313return true;6314} catch (NoSuchMethodException e) {6315// Not present in this class.6316return false;6317}6318}63196320/**6321* Indicates whether coalesceEvents may do something.6322*/6323final boolean isCoalescingEnabled() {6324return coalescingEnabled;6325}632663276328/**6329* Potentially coalesce an event being posted with an existing6330* event. This method is called by {@code EventQueue.postEvent}6331* if an event with the same ID as the event to be posted is found in6332* the queue (both events must have this component as their source).6333* This method either returns a coalesced event which replaces6334* the existing event (and the new event is then discarded), or6335* {@code null} to indicate that no combining should be done6336* (add the second event to the end of the queue). Either event6337* parameter may be modified and returned, as the other one is discarded6338* unless {@code null} is returned.6339* <p>6340* This implementation of {@code coalesceEvents} coalesces6341* two event types: mouse move (and drag) events,6342* and paint (and update) events.6343* For mouse move events the last event is always returned, causing6344* intermediate moves to be discarded. For paint events, the new6345* event is coalesced into a complex {@code RepaintArea} in the peer.6346* The new {@code AWTEvent} is always returned.6347*6348* @param existingEvent the event already on the {@code EventQueue}6349* @param newEvent the event being posted to the6350* {@code EventQueue}6351* @return a coalesced event, or {@code null} indicating that no6352* coalescing was done6353*/6354protected AWTEvent coalesceEvents(AWTEvent existingEvent,6355AWTEvent newEvent) {6356return null;6357}63586359/**6360* Processes events occurring on this component. By default this6361* method calls the appropriate6362* <code>process<event type>Event</code>6363* method for the given class of event.6364* <p>Note that if the event parameter is {@code null}6365* the behavior is unspecified and may result in an6366* exception.6367*6368* @param e the event6369* @see #processComponentEvent6370* @see #processFocusEvent6371* @see #processKeyEvent6372* @see #processMouseEvent6373* @see #processMouseMotionEvent6374* @see #processInputMethodEvent6375* @see #processHierarchyEvent6376* @see #processMouseWheelEvent6377* @since 1.16378*/6379protected void processEvent(AWTEvent e) {6380if (e instanceof FocusEvent) {6381processFocusEvent((FocusEvent)e);63826383} else if (e instanceof MouseEvent) {6384switch(e.getID()) {6385case MouseEvent.MOUSE_PRESSED:6386case MouseEvent.MOUSE_RELEASED:6387case MouseEvent.MOUSE_CLICKED:6388case MouseEvent.MOUSE_ENTERED:6389case MouseEvent.MOUSE_EXITED:6390processMouseEvent((MouseEvent)e);6391break;6392case MouseEvent.MOUSE_MOVED:6393case MouseEvent.MOUSE_DRAGGED:6394processMouseMotionEvent((MouseEvent)e);6395break;6396case MouseEvent.MOUSE_WHEEL:6397processMouseWheelEvent((MouseWheelEvent)e);6398break;6399}64006401} else if (e instanceof KeyEvent) {6402processKeyEvent((KeyEvent)e);64036404} else if (e instanceof ComponentEvent) {6405processComponentEvent((ComponentEvent)e);6406} else if (e instanceof InputMethodEvent) {6407processInputMethodEvent((InputMethodEvent)e);6408} else if (e instanceof HierarchyEvent) {6409switch (e.getID()) {6410case HierarchyEvent.HIERARCHY_CHANGED:6411processHierarchyEvent((HierarchyEvent)e);6412break;6413case HierarchyEvent.ANCESTOR_MOVED:6414case HierarchyEvent.ANCESTOR_RESIZED:6415processHierarchyBoundsEvent((HierarchyEvent)e);6416break;6417}6418}6419}64206421/**6422* Processes component events occurring on this component by6423* dispatching them to any registered6424* {@code ComponentListener} objects.6425* <p>6426* This method is not called unless component events are6427* enabled for this component. Component events are enabled6428* when one of the following occurs:6429* <ul>6430* <li>A {@code ComponentListener} object is registered6431* via {@code addComponentListener}.6432* <li>Component events are enabled via {@code enableEvents}.6433* </ul>6434* <p>Note that if the event parameter is {@code null}6435* the behavior is unspecified and may result in an6436* exception.6437*6438* @param e the component event6439* @see java.awt.event.ComponentEvent6440* @see java.awt.event.ComponentListener6441* @see #addComponentListener6442* @see #enableEvents6443* @since 1.16444*/6445protected void processComponentEvent(ComponentEvent e) {6446ComponentListener listener = componentListener;6447if (listener != null) {6448int id = e.getID();6449switch(id) {6450case ComponentEvent.COMPONENT_RESIZED:6451listener.componentResized(e);6452break;6453case ComponentEvent.COMPONENT_MOVED:6454listener.componentMoved(e);6455break;6456case ComponentEvent.COMPONENT_SHOWN:6457listener.componentShown(e);6458break;6459case ComponentEvent.COMPONENT_HIDDEN:6460listener.componentHidden(e);6461break;6462}6463}6464}64656466/**6467* Processes focus events occurring on this component by6468* dispatching them to any registered6469* {@code FocusListener} objects.6470* <p>6471* This method is not called unless focus events are6472* enabled for this component. Focus events are enabled6473* when one of the following occurs:6474* <ul>6475* <li>A {@code FocusListener} object is registered6476* via {@code addFocusListener}.6477* <li>Focus events are enabled via {@code enableEvents}.6478* </ul>6479* <p>6480* If focus events are enabled for a {@code Component},6481* the current {@code KeyboardFocusManager} determines6482* whether or not a focus event should be dispatched to6483* registered {@code FocusListener} objects. If the6484* events are to be dispatched, the {@code KeyboardFocusManager}6485* calls the {@code Component}'s {@code dispatchEvent}6486* method, which results in a call to the {@code Component}'s6487* {@code processFocusEvent} method.6488* <p>6489* If focus events are enabled for a {@code Component}, calling6490* the {@code Component}'s {@code dispatchEvent} method6491* with a {@code FocusEvent} as the argument will result in a6492* call to the {@code Component}'s {@code processFocusEvent}6493* method regardless of the current {@code KeyboardFocusManager}.6494*6495* <p>Note that if the event parameter is {@code null}6496* the behavior is unspecified and may result in an6497* exception.6498*6499* @param e the focus event6500* @see java.awt.event.FocusEvent6501* @see java.awt.event.FocusListener6502* @see java.awt.KeyboardFocusManager6503* @see #addFocusListener6504* @see #enableEvents6505* @see #dispatchEvent6506* @since 1.16507*/6508protected void processFocusEvent(FocusEvent e) {6509FocusListener listener = focusListener;6510if (listener != null) {6511int id = e.getID();6512switch(id) {6513case FocusEvent.FOCUS_GAINED:6514listener.focusGained(e);6515break;6516case FocusEvent.FOCUS_LOST:6517listener.focusLost(e);6518break;6519}6520}6521}65226523/**6524* Processes key events occurring on this component by6525* dispatching them to any registered6526* {@code KeyListener} objects.6527* <p>6528* This method is not called unless key events are6529* enabled for this component. Key events are enabled6530* when one of the following occurs:6531* <ul>6532* <li>A {@code KeyListener} object is registered6533* via {@code addKeyListener}.6534* <li>Key events are enabled via {@code enableEvents}.6535* </ul>6536*6537* <p>6538* If key events are enabled for a {@code Component},6539* the current {@code KeyboardFocusManager} determines6540* whether or not a key event should be dispatched to6541* registered {@code KeyListener} objects. The6542* {@code DefaultKeyboardFocusManager} will not dispatch6543* key events to a {@code Component} that is not the focus6544* owner or is not showing.6545* <p>6546* As of J2SE 1.4, {@code KeyEvent}s are redirected to6547* the focus owner. Please see the6548* <a href="doc-files/FocusSpec.html">Focus Specification</a>6549* for further information.6550* <p>6551* Calling a {@code Component}'s {@code dispatchEvent}6552* method with a {@code KeyEvent} as the argument will6553* result in a call to the {@code Component}'s6554* {@code processKeyEvent} method regardless of the6555* current {@code KeyboardFocusManager} as long as the6556* component is showing, focused, and enabled, and key events6557* are enabled on it.6558* <p>If the event parameter is {@code null}6559* the behavior is unspecified and may result in an6560* exception.6561*6562* @param e the key event6563* @see java.awt.event.KeyEvent6564* @see java.awt.event.KeyListener6565* @see java.awt.KeyboardFocusManager6566* @see java.awt.DefaultKeyboardFocusManager6567* @see #processEvent6568* @see #dispatchEvent6569* @see #addKeyListener6570* @see #enableEvents6571* @see #isShowing6572* @since 1.16573*/6574protected void processKeyEvent(KeyEvent e) {6575KeyListener listener = keyListener;6576if (listener != null) {6577int id = e.getID();6578switch(id) {6579case KeyEvent.KEY_TYPED:6580listener.keyTyped(e);6581break;6582case KeyEvent.KEY_PRESSED:6583listener.keyPressed(e);6584break;6585case KeyEvent.KEY_RELEASED:6586listener.keyReleased(e);6587break;6588}6589}6590}65916592/**6593* Processes mouse events occurring on this component by6594* dispatching them to any registered6595* {@code MouseListener} objects.6596* <p>6597* This method is not called unless mouse events are6598* enabled for this component. Mouse events are enabled6599* when one of the following occurs:6600* <ul>6601* <li>A {@code MouseListener} object is registered6602* via {@code addMouseListener}.6603* <li>Mouse events are enabled via {@code enableEvents}.6604* </ul>6605* <p>Note that if the event parameter is {@code null}6606* the behavior is unspecified and may result in an6607* exception.6608*6609* @param e the mouse event6610* @see java.awt.event.MouseEvent6611* @see java.awt.event.MouseListener6612* @see #addMouseListener6613* @see #enableEvents6614* @since 1.16615*/6616protected void processMouseEvent(MouseEvent e) {6617MouseListener listener = mouseListener;6618if (listener != null) {6619int id = e.getID();6620switch(id) {6621case MouseEvent.MOUSE_PRESSED:6622listener.mousePressed(e);6623break;6624case MouseEvent.MOUSE_RELEASED:6625listener.mouseReleased(e);6626break;6627case MouseEvent.MOUSE_CLICKED:6628listener.mouseClicked(e);6629break;6630case MouseEvent.MOUSE_EXITED:6631listener.mouseExited(e);6632break;6633case MouseEvent.MOUSE_ENTERED:6634listener.mouseEntered(e);6635break;6636}6637}6638}66396640/**6641* Processes mouse motion events occurring on this component by6642* dispatching them to any registered6643* {@code MouseMotionListener} objects.6644* <p>6645* This method is not called unless mouse motion events are6646* enabled for this component. Mouse motion events are enabled6647* when one of the following occurs:6648* <ul>6649* <li>A {@code MouseMotionListener} object is registered6650* via {@code addMouseMotionListener}.6651* <li>Mouse motion events are enabled via {@code enableEvents}.6652* </ul>6653* <p>Note that if the event parameter is {@code null}6654* the behavior is unspecified and may result in an6655* exception.6656*6657* @param e the mouse motion event6658* @see java.awt.event.MouseEvent6659* @see java.awt.event.MouseMotionListener6660* @see #addMouseMotionListener6661* @see #enableEvents6662* @since 1.16663*/6664protected void processMouseMotionEvent(MouseEvent e) {6665MouseMotionListener listener = mouseMotionListener;6666if (listener != null) {6667int id = e.getID();6668switch(id) {6669case MouseEvent.MOUSE_MOVED:6670listener.mouseMoved(e);6671break;6672case MouseEvent.MOUSE_DRAGGED:6673listener.mouseDragged(e);6674break;6675}6676}6677}66786679/**6680* Processes mouse wheel events occurring on this component by6681* dispatching them to any registered6682* {@code MouseWheelListener} objects.6683* <p>6684* This method is not called unless mouse wheel events are6685* enabled for this component. Mouse wheel events are enabled6686* when one of the following occurs:6687* <ul>6688* <li>A {@code MouseWheelListener} object is registered6689* via {@code addMouseWheelListener}.6690* <li>Mouse wheel events are enabled via {@code enableEvents}.6691* </ul>6692* <p>6693* For information on how mouse wheel events are dispatched, see6694* the class description for {@link MouseWheelEvent}.6695* <p>6696* Note that if the event parameter is {@code null}6697* the behavior is unspecified and may result in an6698* exception.6699*6700* @param e the mouse wheel event6701* @see java.awt.event.MouseWheelEvent6702* @see java.awt.event.MouseWheelListener6703* @see #addMouseWheelListener6704* @see #enableEvents6705* @since 1.46706*/6707protected void processMouseWheelEvent(MouseWheelEvent e) {6708MouseWheelListener listener = mouseWheelListener;6709if (listener != null) {6710int id = e.getID();6711switch(id) {6712case MouseEvent.MOUSE_WHEEL:6713listener.mouseWheelMoved(e);6714break;6715}6716}6717}67186719boolean postsOldMouseEvents() {6720return false;6721}67226723/**6724* Processes input method events occurring on this component by6725* dispatching them to any registered6726* {@code InputMethodListener} objects.6727* <p>6728* This method is not called unless input method events6729* are enabled for this component. Input method events are enabled6730* when one of the following occurs:6731* <ul>6732* <li>An {@code InputMethodListener} object is registered6733* via {@code addInputMethodListener}.6734* <li>Input method events are enabled via {@code enableEvents}.6735* </ul>6736* <p>Note that if the event parameter is {@code null}6737* the behavior is unspecified and may result in an6738* exception.6739*6740* @param e the input method event6741* @see java.awt.event.InputMethodEvent6742* @see java.awt.event.InputMethodListener6743* @see #addInputMethodListener6744* @see #enableEvents6745* @since 1.26746*/6747protected void processInputMethodEvent(InputMethodEvent e) {6748InputMethodListener listener = inputMethodListener;6749if (listener != null) {6750int id = e.getID();6751switch (id) {6752case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:6753listener.inputMethodTextChanged(e);6754break;6755case InputMethodEvent.CARET_POSITION_CHANGED:6756listener.caretPositionChanged(e);6757break;6758}6759}6760}67616762/**6763* Processes hierarchy events occurring on this component by6764* dispatching them to any registered6765* {@code HierarchyListener} objects.6766* <p>6767* This method is not called unless hierarchy events6768* are enabled for this component. Hierarchy events are enabled6769* when one of the following occurs:6770* <ul>6771* <li>An {@code HierarchyListener} object is registered6772* via {@code addHierarchyListener}.6773* <li>Hierarchy events are enabled via {@code enableEvents}.6774* </ul>6775* <p>Note that if the event parameter is {@code null}6776* the behavior is unspecified and may result in an6777* exception.6778*6779* @param e the hierarchy event6780* @see java.awt.event.HierarchyEvent6781* @see java.awt.event.HierarchyListener6782* @see #addHierarchyListener6783* @see #enableEvents6784* @since 1.36785*/6786protected void processHierarchyEvent(HierarchyEvent e) {6787HierarchyListener listener = hierarchyListener;6788if (listener != null) {6789int id = e.getID();6790switch (id) {6791case HierarchyEvent.HIERARCHY_CHANGED:6792listener.hierarchyChanged(e);6793break;6794}6795}6796}67976798/**6799* Processes hierarchy bounds events occurring on this component by6800* dispatching them to any registered6801* {@code HierarchyBoundsListener} objects.6802* <p>6803* This method is not called unless hierarchy bounds events6804* are enabled for this component. Hierarchy bounds events are enabled6805* when one of the following occurs:6806* <ul>6807* <li>An {@code HierarchyBoundsListener} object is registered6808* via {@code addHierarchyBoundsListener}.6809* <li>Hierarchy bounds events are enabled via {@code enableEvents}.6810* </ul>6811* <p>Note that if the event parameter is {@code null}6812* the behavior is unspecified and may result in an6813* exception.6814*6815* @param e the hierarchy event6816* @see java.awt.event.HierarchyEvent6817* @see java.awt.event.HierarchyBoundsListener6818* @see #addHierarchyBoundsListener6819* @see #enableEvents6820* @since 1.36821*/6822protected void processHierarchyBoundsEvent(HierarchyEvent e) {6823HierarchyBoundsListener listener = hierarchyBoundsListener;6824if (listener != null) {6825int id = e.getID();6826switch (id) {6827case HierarchyEvent.ANCESTOR_MOVED:6828listener.ancestorMoved(e);6829break;6830case HierarchyEvent.ANCESTOR_RESIZED:6831listener.ancestorResized(e);6832break;6833}6834}6835}68366837/**6838* @param evt the event to handle6839* @return {@code true} if the event was handled, {@code false} otherwise6840* @deprecated As of JDK version 1.16841* replaced by processEvent(AWTEvent).6842*/6843@Deprecated6844public boolean handleEvent(Event evt) {6845switch (evt.id) {6846case Event.MOUSE_ENTER:6847return mouseEnter(evt, evt.x, evt.y);68486849case Event.MOUSE_EXIT:6850return mouseExit(evt, evt.x, evt.y);68516852case Event.MOUSE_MOVE:6853return mouseMove(evt, evt.x, evt.y);68546855case Event.MOUSE_DOWN:6856return mouseDown(evt, evt.x, evt.y);68576858case Event.MOUSE_DRAG:6859return mouseDrag(evt, evt.x, evt.y);68606861case Event.MOUSE_UP:6862return mouseUp(evt, evt.x, evt.y);68636864case Event.KEY_PRESS:6865case Event.KEY_ACTION:6866return keyDown(evt, evt.key);68676868case Event.KEY_RELEASE:6869case Event.KEY_ACTION_RELEASE:6870return keyUp(evt, evt.key);68716872case Event.ACTION_EVENT:6873return action(evt, evt.arg);6874case Event.GOT_FOCUS:6875return gotFocus(evt, evt.arg);6876case Event.LOST_FOCUS:6877return lostFocus(evt, evt.arg);6878}6879return false;6880}68816882/**6883* @param evt the event to handle6884* @param x the x coordinate6885* @param y the y coordinate6886* @return {@code false}6887* @deprecated As of JDK version 1.1,6888* replaced by processMouseEvent(MouseEvent).6889*/6890@Deprecated6891public boolean mouseDown(Event evt, int x, int y) {6892return false;6893}68946895/**6896* @param evt the event to handle6897* @param x the x coordinate6898* @param y the y coordinate6899* @return {@code false}6900* @deprecated As of JDK version 1.1,6901* replaced by processMouseMotionEvent(MouseEvent).6902*/6903@Deprecated6904public boolean mouseDrag(Event evt, int x, int y) {6905return false;6906}69076908/**6909* @param evt the event to handle6910* @param x the x coordinate6911* @param y the y coordinate6912* @return {@code false}6913* @deprecated As of JDK version 1.1,6914* replaced by processMouseEvent(MouseEvent).6915*/6916@Deprecated6917public boolean mouseUp(Event evt, int x, int y) {6918return false;6919}69206921/**6922* @param evt the event to handle6923* @param x the x coordinate6924* @param y the y coordinate6925* @return {@code false}6926* @deprecated As of JDK version 1.1,6927* replaced by processMouseMotionEvent(MouseEvent).6928*/6929@Deprecated6930public boolean mouseMove(Event evt, int x, int y) {6931return false;6932}69336934/**6935* @param evt the event to handle6936* @param x the x coordinate6937* @param y the y coordinate6938* @return {@code false}6939* @deprecated As of JDK version 1.1,6940* replaced by processMouseEvent(MouseEvent).6941*/6942@Deprecated6943public boolean mouseEnter(Event evt, int x, int y) {6944return false;6945}69466947/**6948* @param evt the event to handle6949* @param x the x coordinate6950* @param y the y coordinate6951* @return {@code false}6952* @deprecated As of JDK version 1.1,6953* replaced by processMouseEvent(MouseEvent).6954*/6955@Deprecated6956public boolean mouseExit(Event evt, int x, int y) {6957return false;6958}69596960/**6961* @param evt the event to handle6962* @param key the key pressed6963* @return {@code false}6964* @deprecated As of JDK version 1.1,6965* replaced by processKeyEvent(KeyEvent).6966*/6967@Deprecated6968public boolean keyDown(Event evt, int key) {6969return false;6970}69716972/**6973* @param evt the event to handle6974* @param key the key pressed6975* @return {@code false}6976* @deprecated As of JDK version 1.1,6977* replaced by processKeyEvent(KeyEvent).6978*/6979@Deprecated6980public boolean keyUp(Event evt, int key) {6981return false;6982}69836984/**6985* @param evt the event to handle6986* @param what the object acted on6987* @return {@code false}6988* @deprecated As of JDK version 1.1,6989* should register this component as ActionListener on component6990* which fires action events.6991*/6992@Deprecated6993public boolean action(Event evt, Object what) {6994return false;6995}69966997/**6998* Makes this {@code Component} displayable by connecting it to a6999* native screen resource.7000* This method is called internally by the toolkit and should7001* not be called directly by programs.7002* <p>7003* This method changes layout-related information, and therefore,7004* invalidates the component hierarchy.7005*7006* @see #isDisplayable7007* @see #removeNotify7008* @see #invalidate7009* @since 1.07010*/7011public void addNotify() {7012synchronized (getTreeLock()) {7013ComponentPeer peer = this.peer;7014if (peer == null || peer instanceof LightweightPeer){7015if (peer == null) {7016// Update both the Component's peer variable and the local7017// variable we use for thread safety.7018this.peer = peer = getComponentFactory().createComponent(this);7019}70207021// This is a lightweight component which means it won't be7022// able to get window-related events by itself. If any7023// have been enabled, then the nearest native container must7024// be enabled.7025if (parent != null) {7026long mask = 0;7027if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {7028mask |= AWTEvent.MOUSE_EVENT_MASK;7029}7030if ((mouseMotionListener != null) ||7031((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {7032mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;7033}7034if ((mouseWheelListener != null ) ||7035((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {7036mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;7037}7038if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {7039mask |= AWTEvent.FOCUS_EVENT_MASK;7040}7041if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {7042mask |= AWTEvent.KEY_EVENT_MASK;7043}7044if (mask != 0) {7045parent.proxyEnableEvents(mask);7046}7047}7048} else {7049// It's native. If the parent is lightweight it will need some7050// help.7051Container parent = getContainer();7052if (parent != null && parent.isLightweight()) {7053relocateComponent();7054if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())7055{7056peer.setVisible(false);7057}7058}7059}7060invalidate();70617062int npopups = (popups != null? popups.size() : 0);7063for (int i = 0 ; i < npopups ; i++) {7064PopupMenu popup = popups.elementAt(i);7065popup.addNotify();7066}70677068if (dropTarget != null) dropTarget.addNotify();70697070peerFont = getFont();70717072if (getContainer() != null && !isAddNotifyComplete) {7073getContainer().increaseComponentCount(this);7074}707570767077// Update stacking order7078updateZOrder();70797080if (!isAddNotifyComplete) {7081mixOnShowing();7082}70837084isAddNotifyComplete = true;70857086if (hierarchyListener != null ||7087(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||7088Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {7089HierarchyEvent e =7090new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,7091this, parent,7092HierarchyEvent.DISPLAYABILITY_CHANGED |7093((isRecursivelyVisible())7094? HierarchyEvent.SHOWING_CHANGED7095: 0));7096dispatchEvent(e);7097}7098}7099}71007101/**7102* Makes this {@code Component} undisplayable by destroying it native7103* screen resource.7104* <p>7105* This method is called by the toolkit internally and should7106* not be called directly by programs. Code overriding7107* this method should call {@code super.removeNotify} as7108* the first line of the overriding method.7109*7110* @see #isDisplayable7111* @see #addNotify7112* @since 1.07113*/7114public void removeNotify() {7115KeyboardFocusManager.clearMostRecentFocusOwner(this);7116if (KeyboardFocusManager.getCurrentKeyboardFocusManager().7117getPermanentFocusOwner() == this)7118{7119KeyboardFocusManager.getCurrentKeyboardFocusManager().7120setGlobalPermanentFocusOwner(null);7121}71227123synchronized (getTreeLock()) {7124if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {7125transferFocus(true);7126}71277128if (getContainer() != null && isAddNotifyComplete) {7129getContainer().decreaseComponentCount(this);7130}71317132int npopups = (popups != null? popups.size() : 0);7133for (int i = 0 ; i < npopups ; i++) {7134PopupMenu popup = popups.elementAt(i);7135popup.removeNotify();7136}7137// If there is any input context for this component, notify7138// that this component is being removed. (This has to be done7139// before hiding peer.)7140if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {7141InputContext inputContext = getInputContext();7142if (inputContext != null) {7143inputContext.removeNotify(this);7144}7145}71467147ComponentPeer p = peer;7148if (p != null) {7149boolean isLightweight = isLightweight();71507151if (bufferStrategy instanceof FlipBufferStrategy) {7152((FlipBufferStrategy)bufferStrategy).invalidate();7153}71547155if (dropTarget != null) dropTarget.removeNotify();71567157// Hide peer first to stop system events such as cursor moves.7158if (visible) {7159p.setVisible(false);7160}71617162peer = null; // Stop peer updates.7163peerFont = null;71647165Toolkit.getEventQueue().removeSourceEvents(this, false);7166KeyboardFocusManager.getCurrentKeyboardFocusManager().7167discardKeyEvents(this);71687169p.dispose();71707171mixOnHiding(isLightweight);71727173isAddNotifyComplete = false;7174// Nullifying compoundShape means that the component has normal shape7175// (or has no shape at all).7176this.compoundShape = null;7177}71787179if (hierarchyListener != null ||7180(eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||7181Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {7182HierarchyEvent e =7183new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,7184this, parent,7185HierarchyEvent.DISPLAYABILITY_CHANGED |7186((isRecursivelyVisible())7187? HierarchyEvent.SHOWING_CHANGED7188: 0));7189dispatchEvent(e);7190}7191}7192}71937194/**7195* @param evt the event to handle7196* @param what the object focused7197* @return {@code false}7198* @deprecated As of JDK version 1.1,7199* replaced by processFocusEvent(FocusEvent).7200*/7201@Deprecated7202public boolean gotFocus(Event evt, Object what) {7203return false;7204}72057206/**7207* @param evt the event to handle7208* @param what the object focused7209* @return {@code false}7210* @deprecated As of JDK version 1.1,7211* replaced by processFocusEvent(FocusEvent).7212*/7213@Deprecated7214public boolean lostFocus(Event evt, Object what) {7215return false;7216}72177218/**7219* Returns whether this {@code Component} can become the focus7220* owner.7221*7222* @return {@code true} if this {@code Component} is7223* focusable; {@code false} otherwise7224* @see #setFocusable7225* @since 1.17226* @deprecated As of 1.4, replaced by {@code isFocusable()}.7227*/7228@Deprecated7229public boolean isFocusTraversable() {7230if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {7231isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;7232}7233return focusable;7234}72357236/**7237* Returns whether this Component can be focused.7238*7239* @return {@code true} if this Component is focusable;7240* {@code false} otherwise.7241* @see #setFocusable7242* @since 1.47243*/7244public boolean isFocusable() {7245return isFocusTraversable();7246}72477248/**7249* Sets the focusable state of this Component to the specified value. This7250* value overrides the Component's default focusability.7251*7252* @param focusable indicates whether this Component is focusable7253* @see #isFocusable7254* @since 1.47255*/7256public void setFocusable(boolean focusable) {7257boolean oldFocusable;7258synchronized (this) {7259oldFocusable = this.focusable;7260this.focusable = focusable;7261}7262isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;72637264firePropertyChange("focusable", oldFocusable, focusable);7265if (oldFocusable && !focusable) {7266if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabled()) {7267transferFocus(true);7268}7269KeyboardFocusManager.clearMostRecentFocusOwner(this);7270}7271}72727273final boolean isFocusTraversableOverridden() {7274return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);7275}72767277/**7278* Sets the focus traversal keys for a given traversal operation for this7279* Component.7280* <p>7281* The default values for a Component's focus traversal keys are7282* implementation-dependent. Sun recommends that all implementations for a7283* particular native platform use the same default values. The7284* recommendations for Windows and Unix are listed below. These7285* recommendations are used in the Sun AWT implementations.7286*7287* <table class="striped">7288* <caption>Recommended default values for a Component's focus traversal7289* keys</caption>7290* <thead>7291* <tr>7292* <th scope="col">Identifier7293* <th scope="col">Meaning7294* <th scope="col">Default7295* </thead>7296* <tbody>7297* <tr>7298* <th scope="row">KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS7299* <td>Normal forward keyboard traversal7300* <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED7301* <tr>7302* <th scope="row">KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS7303* <td>Normal reverse keyboard traversal7304* <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED7305* <tr>7306* <th scope="row">KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7307* <td>Go up one focus traversal cycle7308* <td>none7309* </tbody>7310* </table>7311*7312* To disable a traversal key, use an empty Set; Collections.EMPTY_SET is7313* recommended.7314* <p>7315* Using the AWTKeyStroke API, client code can specify on which of two7316* specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal7317* operation will occur. Regardless of which KeyEvent is specified,7318* however, all KeyEvents related to the focus traversal key, including the7319* associated KEY_TYPED event, will be consumed, and will not be dispatched7320* to any Component. It is a runtime error to specify a KEY_TYPED event as7321* mapping to a focus traversal operation, or to map the same event to7322* multiple default focus traversal operations.7323* <p>7324* If a value of null is specified for the Set, this Component inherits the7325* Set from its parent. If all ancestors of this Component have null7326* specified for the Set, then the current KeyboardFocusManager's default7327* Set is used.7328* <p>7329* This method may throw a {@code ClassCastException} if any {@code Object}7330* in {@code keystrokes} is not an {@code AWTKeyStroke}.7331*7332* @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7333* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7334* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7335* @param keystrokes the Set of AWTKeyStroke for the specified operation7336* @see #getFocusTraversalKeys7337* @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS7338* @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS7339* @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS7340* @throws IllegalArgumentException if id is not one of7341* KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7342* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7343* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes7344* contains null, or if any keystroke represents a KEY_TYPED event,7345* or if any keystroke already maps to another focus traversal7346* operation for this Component7347* @since 1.47348*/7349public void setFocusTraversalKeys(int id,7350Set<? extends AWTKeyStroke> keystrokes)7351{7352if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {7353throw new IllegalArgumentException("invalid focus traversal key identifier");7354}73557356setFocusTraversalKeys_NoIDCheck(id, keystrokes);7357}73587359/**7360* Returns the Set of focus traversal keys for a given traversal operation7361* for this Component. (See7362* {@code setFocusTraversalKeys} for a full description of each key.)7363* <p>7364* If a Set of traversal keys has not been explicitly defined for this7365* Component, then this Component's parent's Set is returned. If no Set7366* has been explicitly defined for any of this Component's ancestors, then7367* the current KeyboardFocusManager's default Set is returned.7368*7369* @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7370* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7371* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7372* @return the Set of AWTKeyStrokes for the specified operation. The Set7373* will be unmodifiable, and may be empty. null will never be7374* returned.7375* @see #setFocusTraversalKeys7376* @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS7377* @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS7378* @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS7379* @throws IllegalArgumentException if id is not one of7380* KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7381* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7382* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7383* @since 1.47384*/7385public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {7386if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {7387throw new IllegalArgumentException("invalid focus traversal key identifier");7388}73897390return getFocusTraversalKeys_NoIDCheck(id);7391}73927393// We define these methods so that Container does not need to repeat this7394// code. Container cannot call super.<method> because Container allows7395// DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method7396// would erroneously generate an IllegalArgumentException for7397// DOWN_CYCLE_TRAVERSAL_KEY.7398final void setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> keystrokes) {7399Set<AWTKeyStroke> oldKeys;74007401synchronized (this) {7402if (focusTraversalKeys == null) {7403initializeFocusTraversalKeys();7404}74057406if (keystrokes != null) {7407for (AWTKeyStroke keystroke : keystrokes ) {74087409if (keystroke == null) {7410throw new IllegalArgumentException("cannot set null focus traversal key");7411}74127413if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {7414throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");7415}74167417for (int i = 0; i < focusTraversalKeys.length; i++) {7418if (i == id) {7419continue;7420}74217422if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke))7423{7424throw new IllegalArgumentException("focus traversal keys must be unique for a Component");7425}7426}7427}7428}74297430oldKeys = focusTraversalKeys[id];7431focusTraversalKeys[id] = (keystrokes != null)7432? Collections.unmodifiableSet(new HashSet<AWTKeyStroke>(keystrokes))7433: null;7434}74357436firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,7437keystrokes);7438}7439final Set<AWTKeyStroke> getFocusTraversalKeys_NoIDCheck(int id) {7440// Okay to return Set directly because it is an unmodifiable view7441@SuppressWarnings("unchecked")7442Set<AWTKeyStroke> keystrokes = (focusTraversalKeys != null)7443? focusTraversalKeys[id]7444: null;74457446if (keystrokes != null) {7447return keystrokes;7448} else {7449Container parent = this.parent;7450if (parent != null) {7451return parent.getFocusTraversalKeys(id);7452} else {7453return KeyboardFocusManager.getCurrentKeyboardFocusManager().7454getDefaultFocusTraversalKeys(id);7455}7456}7457}74587459/**7460* Returns whether the Set of focus traversal keys for the given focus7461* traversal operation has been explicitly defined for this Component. If7462* this method returns {@code false}, this Component is inheriting the7463* Set from an ancestor, or from the current KeyboardFocusManager.7464*7465* @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7466* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7467* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7468* @return {@code true} if the Set of focus traversal keys for the7469* given focus traversal operation has been explicitly defined for7470* this Component; {@code false} otherwise.7471* @throws IllegalArgumentException if id is not one of7472* KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,7473* KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or7474* KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS7475* @since 1.47476*/7477public boolean areFocusTraversalKeysSet(int id) {7478if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {7479throw new IllegalArgumentException("invalid focus traversal key identifier");7480}74817482return (focusTraversalKeys != null && focusTraversalKeys[id] != null);7483}74847485/**7486* Sets whether focus traversal keys are enabled for this Component.7487* Components for which focus traversal keys are disabled receive key7488* events for focus traversal keys. Components for which focus traversal7489* keys are enabled do not see these events; instead, the events are7490* automatically converted to traversal operations.7491*7492* @param focusTraversalKeysEnabled whether focus traversal keys are7493* enabled for this Component7494* @see #getFocusTraversalKeysEnabled7495* @see #setFocusTraversalKeys7496* @see #getFocusTraversalKeys7497* @since 1.47498*/7499public void setFocusTraversalKeysEnabled(boolean7500focusTraversalKeysEnabled) {7501boolean oldFocusTraversalKeysEnabled;7502synchronized (this) {7503oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled;7504this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;7505}7506firePropertyChange("focusTraversalKeysEnabled",7507oldFocusTraversalKeysEnabled,7508focusTraversalKeysEnabled);7509}75107511/**7512* Returns whether focus traversal keys are enabled for this Component.7513* Components for which focus traversal keys are disabled receive key7514* events for focus traversal keys. Components for which focus traversal7515* keys are enabled do not see these events; instead, the events are7516* automatically converted to traversal operations.7517*7518* @return whether focus traversal keys are enabled for this Component7519* @see #setFocusTraversalKeysEnabled7520* @see #setFocusTraversalKeys7521* @see #getFocusTraversalKeys7522* @since 1.47523*/7524public boolean getFocusTraversalKeysEnabled() {7525return focusTraversalKeysEnabled;7526}75277528/**7529* Requests that this Component get the input focus, and that this7530* Component's top-level ancestor become the focused Window. This7531* component must be displayable, focusable, visible and all of7532* its ancestors (with the exception of the top-level Window) must7533* be visible for the request to be granted. Every effort will be7534* made to honor the request; however, in some cases it may be7535* impossible to do so. Developers must never assume that this7536* Component is the focus owner until this Component receives a7537* FOCUS_GAINED event. If this request is denied because this7538* Component's top-level Window cannot become the focused Window,7539* the request will be remembered and will be granted when the7540* Window is later focused by the user.7541* <p>7542* This method cannot be used to set the focus owner to no Component at7543* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}7544* instead.7545* <p>7546* Because the focus behavior of this method is platform-dependent,7547* developers are strongly encouraged to use7548* {@code requestFocusInWindow} when possible.7549*7550* <p>Note: Not all focus transfers result from invoking this method. As7551* such, a component may receive focus without this or any of the other7552* {@code requestFocus} methods of {@code Component} being invoked.7553*7554* @see #requestFocusInWindow7555* @see java.awt.event.FocusEvent7556* @see #addFocusListener7557* @see #isFocusable7558* @see #isDisplayable7559* @see KeyboardFocusManager#clearGlobalFocusOwner7560* @since 1.07561*/7562public void requestFocus() {7563requestFocusHelper(false, true);7564}756575667567/**7568* Requests by the reason of {@code cause} that this Component get the input7569* focus, and that this Component's top-level ancestor become the7570* focused Window. This component must be displayable, focusable, visible7571* and all of its ancestors (with the exception of the top-level Window)7572* must be visible for the request to be granted. Every effort will be7573* made to honor the request; however, in some cases it may be7574* impossible to do so. Developers must never assume that this7575* Component is the focus owner until this Component receives a7576* FOCUS_GAINED event.7577* <p>7578* The focus request effect may also depend on the provided7579* cause value. If this request is succeed the {@code FocusEvent}7580* generated in the result will receive the cause value specified as the7581* argument of method. If this request is denied because this Component's7582* top-level Window cannot become the focused Window, the request will be7583* remembered and will be granted when the Window is later focused by the7584* user.7585* <p>7586* This method cannot be used to set the focus owner to no Component at7587* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}7588* instead.7589* <p>7590* Because the focus behavior of this method is platform-dependent,7591* developers are strongly encouraged to use7592* {@code requestFocusInWindow(FocusEvent.Cause)} when possible.7593*7594* <p>Note: Not all focus transfers result from invoking this method. As7595* such, a component may receive focus without this or any of the other7596* {@code requestFocus} methods of {@code Component} being invoked.7597*7598* @param cause the cause why the focus is requested7599* @see FocusEvent7600* @see FocusEvent.Cause7601* @see #requestFocusInWindow(FocusEvent.Cause)7602* @see java.awt.event.FocusEvent7603* @see #addFocusListener7604* @see #isFocusable7605* @see #isDisplayable7606* @see KeyboardFocusManager#clearGlobalFocusOwner7607* @since 97608*/7609public void requestFocus(FocusEvent.Cause cause) {7610requestFocusHelper(false, true, cause);7611}76127613/**7614* Requests that this {@code Component} get the input focus,7615* and that this {@code Component}'s top-level ancestor7616* become the focused {@code Window}. This component must be7617* displayable, focusable, visible and all of its ancestors (with7618* the exception of the top-level Window) must be visible for the7619* request to be granted. Every effort will be made to honor the7620* request; however, in some cases it may be impossible to do7621* so. Developers must never assume that this component is the7622* focus owner until this component receives a FOCUS_GAINED7623* event. If this request is denied because this component's7624* top-level window cannot become the focused window, the request7625* will be remembered and will be granted when the window is later7626* focused by the user.7627* <p>7628* This method returns a boolean value. If {@code false} is returned,7629* the request is <b>guaranteed to fail</b>. If {@code true} is7630* returned, the request will succeed <b>unless</b> it is vetoed, or an7631* extraordinary event, such as disposal of the component's peer, occurs7632* before the request can be granted by the native windowing system. Again,7633* while a return value of {@code true} indicates that the request is7634* likely to succeed, developers must never assume that this component is7635* the focus owner until this component receives a FOCUS_GAINED event.7636* <p>7637* This method cannot be used to set the focus owner to no component at7638* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}7639* instead.7640* <p>7641* Because the focus behavior of this method is platform-dependent,7642* developers are strongly encouraged to use7643* {@code requestFocusInWindow} when possible.7644* <p>7645* Every effort will be made to ensure that {@code FocusEvent}s7646* generated as a7647* result of this request will have the specified temporary value. However,7648* because specifying an arbitrary temporary state may not be implementable7649* on all native windowing systems, correct behavior for this method can be7650* guaranteed only for lightweight {@code Component}s.7651* This method is not intended7652* for general use, but exists instead as a hook for lightweight component7653* libraries, such as Swing.7654*7655* <p>Note: Not all focus transfers result from invoking this method. As7656* such, a component may receive focus without this or any of the other7657* {@code requestFocus} methods of {@code Component} being invoked.7658*7659* @param temporary true if the focus change is temporary,7660* such as when the window loses the focus; for7661* more information on temporary focus changes see the7662*<a href="doc-files/FocusSpec.html">Focus Specification</a>7663* @return {@code false} if the focus change request is guaranteed to7664* fail; {@code true} if it is likely to succeed7665* @see java.awt.event.FocusEvent7666* @see #addFocusListener7667* @see #isFocusable7668* @see #isDisplayable7669* @see KeyboardFocusManager#clearGlobalFocusOwner7670* @since 1.47671*/7672protected boolean requestFocus(boolean temporary) {7673return requestFocusHelper(temporary, true);7674}76757676/**7677* Requests by the reason of {@code cause} that this {@code Component} get7678* the input focus, and that this {@code Component}'s top-level ancestor7679* become the focused {@code Window}. This component must be7680* displayable, focusable, visible and all of its ancestors (with7681* the exception of the top-level Window) must be visible for the7682* request to be granted. Every effort will be made to honor the7683* request; however, in some cases it may be impossible to do7684* so. Developers must never assume that this component is the7685* focus owner until this component receives a FOCUS_GAINED7686* event. If this request is denied because this component's7687* top-level window cannot become the focused window, the request7688* will be remembered and will be granted when the window is later7689* focused by the user.7690* <p>7691* This method returns a boolean value. If {@code false} is returned,7692* the request is <b>guaranteed to fail</b>. If {@code true} is7693* returned, the request will succeed <b>unless</b> it is vetoed, or an7694* extraordinary event, such as disposal of the component's peer, occurs7695* before the request can be granted by the native windowing system. Again,7696* while a return value of {@code true} indicates that the request is7697* likely to succeed, developers must never assume that this component is7698* the focus owner until this component receives a FOCUS_GAINED event.7699* <p>7700* The focus request effect may also depend on the provided7701* cause value. If this request is succeed the {FocusEvent}7702* generated in the result will receive the cause value specified as the7703* argument of the method.7704* <p>7705* This method cannot be used to set the focus owner to no component at7706* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}7707* instead.7708* <p>7709* Because the focus behavior of this method is platform-dependent,7710* developers are strongly encouraged to use7711* {@code requestFocusInWindow} when possible.7712* <p>7713* Every effort will be made to ensure that {@code FocusEvent}s7714* generated as a7715* result of this request will have the specified temporary value. However,7716* because specifying an arbitrary temporary state may not be implementable7717* on all native windowing systems, correct behavior for this method can be7718* guaranteed only for lightweight {@code Component}s.7719* This method is not intended7720* for general use, but exists instead as a hook for lightweight component7721* libraries, such as Swing.7722* <p>7723* Note: Not all focus transfers result from invoking this method. As7724* such, a component may receive focus without this or any of the other7725* {@code requestFocus} methods of {@code Component} being invoked.7726*7727* @param temporary true if the focus change is temporary,7728* such as when the window loses the focus; for7729* more information on temporary focus changes see the7730*<a href="doc-files/FocusSpec.html">Focus Specification</a>7731*7732* @param cause the cause why the focus is requested7733* @return {@code false} if the focus change request is guaranteed to7734* fail; {@code true} if it is likely to succeed7735* @see FocusEvent7736* @see FocusEvent.Cause7737* @see #addFocusListener7738* @see #isFocusable7739* @see #isDisplayable7740* @see KeyboardFocusManager#clearGlobalFocusOwner7741* @since 97742*/7743protected boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {7744return requestFocusHelper(temporary, true, cause);7745}77467747/**7748* Requests that this Component get the input focus, if this7749* Component's top-level ancestor is already the focused7750* Window. This component must be displayable, focusable, visible7751* and all of its ancestors (with the exception of the top-level7752* Window) must be visible for the request to be granted. Every7753* effort will be made to honor the request; however, in some7754* cases it may be impossible to do so. Developers must never7755* assume that this Component is the focus owner until this7756* Component receives a FOCUS_GAINED event.7757* <p>7758* This method returns a boolean value. If {@code false} is returned,7759* the request is <b>guaranteed to fail</b>. If {@code true} is7760* returned, the request will succeed <b>unless</b> it is vetoed, or an7761* extraordinary event, such as disposal of the Component's peer, occurs7762* before the request can be granted by the native windowing system. Again,7763* while a return value of {@code true} indicates that the request is7764* likely to succeed, developers must never assume that this Component is7765* the focus owner until this Component receives a FOCUS_GAINED event.7766* <p>7767* This method cannot be used to set the focus owner to no Component at7768* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}7769* instead.7770* <p>7771* The focus behavior of this method can be implemented uniformly across7772* platforms, and thus developers are strongly encouraged to use this7773* method over {@code requestFocus} when possible. Code which relies7774* on {@code requestFocus} may exhibit different focus behavior on7775* different platforms.7776*7777* <p>Note: Not all focus transfers result from invoking this method. As7778* such, a component may receive focus without this or any of the other7779* {@code requestFocus} methods of {@code Component} being invoked.7780*7781* @return {@code false} if the focus change request is guaranteed to7782* fail; {@code true} if it is likely to succeed7783* @see #requestFocus7784* @see java.awt.event.FocusEvent7785* @see #addFocusListener7786* @see #isFocusable7787* @see #isDisplayable7788* @see KeyboardFocusManager#clearGlobalFocusOwner7789* @since 1.47790*/7791public boolean requestFocusInWindow() {7792return requestFocusHelper(false, false);7793}77947795/**7796* Requests by the reason of {@code cause} that this Component get the input7797* focus, if this Component's top-level ancestor is already the focused7798* Window. This component must be displayable, focusable, visible7799* and all of its ancestors (with the exception of the top-level7800* Window) must be visible for the request to be granted. Every7801* effort will be made to honor the request; however, in some7802* cases it may be impossible to do so. Developers must never7803* assume that this Component is the focus owner until this7804* Component receives a FOCUS_GAINED event.7805* <p>7806* This method returns a boolean value. If {@code false} is returned,7807* the request is <b>guaranteed to fail</b>. If {@code true} is7808* returned, the request will succeed <b>unless</b> it is vetoed, or an7809* extraordinary event, such as disposal of the Component's peer, occurs7810* before the request can be granted by the native windowing system. Again,7811* while a return value of {@code true} indicates that the request is7812* likely to succeed, developers must never assume that this Component is7813* the focus owner until this Component receives a FOCUS_GAINED event.7814* <p>7815* The focus request effect may also depend on the provided7816* cause value. If this request is succeed the {@code FocusEvent}7817* generated in the result will receive the cause value specified as the7818* argument of the method.7819* <p>7820* This method cannot be used to set the focus owner to no Component at7821* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}7822* instead.7823* <p>7824* The focus behavior of this method can be implemented uniformly across7825* platforms, and thus developers are strongly encouraged to use this7826* method over {@code requestFocus(FocusEvent.Cause)} when possible.7827* Code which relies on {@code requestFocus(FocusEvent.Cause)} may exhibit7828* different focus behavior on different platforms.7829*7830* <p>Note: Not all focus transfers result from invoking this method. As7831* such, a component may receive focus without this or any of the other7832* {@code requestFocus} methods of {@code Component} being invoked.7833*7834* @param cause the cause why the focus is requested7835* @return {@code false} if the focus change request is guaranteed to7836* fail; {@code true} if it is likely to succeed7837* @see #requestFocus(FocusEvent.Cause)7838* @see FocusEvent7839* @see FocusEvent.Cause7840* @see java.awt.event.FocusEvent7841* @see #addFocusListener7842* @see #isFocusable7843* @see #isDisplayable7844* @see KeyboardFocusManager#clearGlobalFocusOwner7845* @since 97846*/7847public boolean requestFocusInWindow(FocusEvent.Cause cause) {7848return requestFocusHelper(false, false, cause);7849}78507851/**7852* Requests that this {@code Component} get the input focus,7853* if this {@code Component}'s top-level ancestor is already7854* the focused {@code Window}. This component must be7855* displayable, focusable, visible and all of its ancestors (with7856* the exception of the top-level Window) must be visible for the7857* request to be granted. Every effort will be made to honor the7858* request; however, in some cases it may be impossible to do7859* so. Developers must never assume that this component is the7860* focus owner until this component receives a FOCUS_GAINED event.7861* <p>7862* This method returns a boolean value. If {@code false} is returned,7863* the request is <b>guaranteed to fail</b>. If {@code true} is7864* returned, the request will succeed <b>unless</b> it is vetoed, or an7865* extraordinary event, such as disposal of the component's peer, occurs7866* before the request can be granted by the native windowing system. Again,7867* while a return value of {@code true} indicates that the request is7868* likely to succeed, developers must never assume that this component is7869* the focus owner until this component receives a FOCUS_GAINED event.7870* <p>7871* This method cannot be used to set the focus owner to no component at7872* all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}7873* instead.7874* <p>7875* The focus behavior of this method can be implemented uniformly across7876* platforms, and thus developers are strongly encouraged to use this7877* method over {@code requestFocus} when possible. Code which relies7878* on {@code requestFocus} may exhibit different focus behavior on7879* different platforms.7880* <p>7881* Every effort will be made to ensure that {@code FocusEvent}s7882* generated as a7883* result of this request will have the specified temporary value. However,7884* because specifying an arbitrary temporary state may not be implementable7885* on all native windowing systems, correct behavior for this method can be7886* guaranteed only for lightweight components. This method is not intended7887* for general use, but exists instead as a hook for lightweight component7888* libraries, such as Swing.7889*7890* <p>Note: Not all focus transfers result from invoking this method. As7891* such, a component may receive focus without this or any of the other7892* {@code requestFocus} methods of {@code Component} being invoked.7893*7894* @param temporary true if the focus change is temporary,7895* such as when the window loses the focus; for7896* more information on temporary focus changes see the7897*<a href="doc-files/FocusSpec.html">Focus Specification</a>7898* @return {@code false} if the focus change request is guaranteed to7899* fail; {@code true} if it is likely to succeed7900* @see #requestFocus7901* @see java.awt.event.FocusEvent7902* @see #addFocusListener7903* @see #isFocusable7904* @see #isDisplayable7905* @see KeyboardFocusManager#clearGlobalFocusOwner7906* @since 1.47907*/7908protected boolean requestFocusInWindow(boolean temporary) {7909return requestFocusHelper(temporary, false);7910}79117912boolean requestFocusInWindow(boolean temporary, FocusEvent.Cause cause) {7913return requestFocusHelper(temporary, false, cause);7914}79157916final boolean requestFocusHelper(boolean temporary,7917boolean focusedWindowChangeAllowed) {7918return requestFocusHelper(temporary, focusedWindowChangeAllowed, FocusEvent.Cause.UNKNOWN);7919}79207921final boolean requestFocusHelper(boolean temporary,7922boolean focusedWindowChangeAllowed,7923FocusEvent.Cause cause)7924{7925// 1) Check if the event being dispatched is a system-generated mouse event.7926AWTEvent currentEvent = EventQueue.getCurrentEvent();7927if (currentEvent instanceof MouseEvent &&7928SunToolkit.isSystemGenerated(currentEvent))7929{7930// 2) Sanity check: if the mouse event component source belongs to the same containing window.7931Component source = ((MouseEvent)currentEvent).getComponent();7932if (source == null || source.getContainingWindow() == getContainingWindow()) {7933focusLog.finest("requesting focus by mouse event \"in window\"");79347935// If both the conditions are fulfilled the focus request should be strictly7936// bounded by the toplevel window. It's assumed that the mouse event activates7937// the window (if it wasn't active) and this makes it possible for a focus7938// request with a strong in-window requirement to change focus in the bounds7939// of the toplevel. If, by any means, due to asynchronous nature of the event7940// dispatching mechanism, the window happens to be natively inactive by the time7941// this focus request is eventually handled, it should not re-activate the7942// toplevel. Otherwise the result may not meet user expectations. See 6981400.7943focusedWindowChangeAllowed = false;7944}7945}7946if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {7947if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {7948focusLog.finest("requestFocus is not accepted");7949}7950return false;7951}7952// Update most-recent map7953KeyboardFocusManager.setMostRecentFocusOwner(this);79547955Component window = this;7956while ( (window != null) && !(window instanceof Window)) {7957if (!window.isVisible()) {7958if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {7959focusLog.finest("component is recursively invisible");7960}7961return false;7962}7963window = window.parent;7964}79657966ComponentPeer peer = this.peer;7967Component heavyweight = (peer instanceof LightweightPeer)7968? getNativeContainer() : this;7969if (heavyweight == null || !heavyweight.isVisible()) {7970if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {7971focusLog.finest("Component is not a part of visible hierarchy");7972}7973return false;7974}7975peer = heavyweight.peer;7976if (peer == null) {7977if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {7978focusLog.finest("Peer is null");7979}7980return false;7981}79827983// Focus this Component7984long time = 0;7985if (EventQueue.isDispatchThread()) {7986time = Toolkit.getEventQueue().getMostRecentKeyEventTime();7987} else {7988// A focus request made from outside EDT should not be associated with any event7989// and so its time stamp is simply set to the current time.7990time = System.currentTimeMillis();7991}79927993boolean success = peer.requestFocus7994(this, temporary, focusedWindowChangeAllowed, time, cause);7995if (!success) {7996KeyboardFocusManager.getCurrentKeyboardFocusManager7997(appContext).dequeueKeyEvents(time, this);7998if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {7999focusLog.finest("Peer request failed");8000}8001} else {8002if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8003focusLog.finest("Pass for " + this);8004}8005}8006return success;8007}80088009private boolean isRequestFocusAccepted(boolean temporary,8010boolean focusedWindowChangeAllowed,8011FocusEvent.Cause cause)8012{8013if (!isFocusable() || !isVisible()) {8014if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8015focusLog.finest("Not focusable or not visible");8016}8017return false;8018}80198020ComponentPeer peer = this.peer;8021if (peer == null) {8022if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8023focusLog.finest("peer is null");8024}8025return false;8026}80278028Window window = getContainingWindow();8029if (window == null || !window.isFocusableWindow()) {8030if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8031focusLog.finest("Component doesn't have toplevel");8032}8033return false;8034}80358036// We have passed all regular checks for focus request,8037// now let's call RequestFocusController and see what it says.8038Component focusOwner = KeyboardFocusManager.getMostRecentFocusOwner(window);8039if (focusOwner == null) {8040// sometimes most recent focus owner may be null, but focus owner is not8041// e.g. we reset most recent focus owner if user removes focus owner8042focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();8043if (focusOwner != null && focusOwner.getContainingWindow() != window) {8044focusOwner = null;8045}8046}80478048if (focusOwner == this || focusOwner == null) {8049// Controller is supposed to verify focus transfers and for this it8050// should know both from and to components. And it shouldn't verify8051// transfers from when these components are equal.8052if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8053focusLog.finest("focus owner is null or this");8054}8055return true;8056}80578058if (FocusEvent.Cause.ACTIVATION == cause) {8059// we shouldn't call RequestFocusController in case we are8060// in activation. We do request focus on component which8061// has got temporary focus lost and then on component which is8062// most recent focus owner. But most recent focus owner can be8063// changed by requestFocusXXX() call only, so this transfer has8064// been already approved.8065if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8066focusLog.finest("cause is activation");8067}8068return true;8069}80708071boolean ret = Component.requestFocusController.acceptRequestFocus(focusOwner,8072this,8073temporary,8074focusedWindowChangeAllowed,8075cause);8076if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {8077focusLog.finest("RequestFocusController returns {0}", ret);8078}80798080return ret;8081}80828083private static RequestFocusController requestFocusController = new DummyRequestFocusController();80848085// Swing access this method through reflection to implement InputVerifier's functionality.8086// Perhaps, we should make this method public (later ;)8087private static class DummyRequestFocusController implements RequestFocusController {8088public boolean acceptRequestFocus(Component from, Component to,8089boolean temporary, boolean focusedWindowChangeAllowed,8090FocusEvent.Cause cause)8091{8092return true;8093}8094};80958096static synchronized void setRequestFocusController(RequestFocusController requestController)8097{8098if (requestController == null) {8099requestFocusController = new DummyRequestFocusController();8100} else {8101requestFocusController = requestController;8102}8103}81048105/**8106* Returns the Container which is the focus cycle root of this Component's8107* focus traversal cycle. Each focus traversal cycle has only a single8108* focus cycle root and each Component which is not a Container belongs to8109* only a single focus traversal cycle. Containers which are focus cycle8110* roots belong to two cycles: one rooted at the Container itself, and one8111* rooted at the Container's nearest focus-cycle-root ancestor. For such8112* Containers, this method will return the Container's nearest focus-cycle-8113* root ancestor.8114*8115* @return this Component's nearest focus-cycle-root ancestor8116* @see Container#isFocusCycleRoot()8117* @since 1.48118*/8119public Container getFocusCycleRootAncestor() {8120Container rootAncestor = this.parent;8121while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {8122rootAncestor = rootAncestor.parent;8123}8124return rootAncestor;8125}81268127/**8128* Returns whether the specified Container is the focus cycle root of this8129* Component's focus traversal cycle. Each focus traversal cycle has only8130* a single focus cycle root and each Component which is not a Container8131* belongs to only a single focus traversal cycle.8132*8133* @param container the Container to be tested8134* @return {@code true} if the specified Container is a focus-cycle-8135* root of this Component; {@code false} otherwise8136* @see Container#isFocusCycleRoot()8137* @since 1.48138*/8139public boolean isFocusCycleRoot(Container container) {8140Container rootAncestor = getFocusCycleRootAncestor();8141return (rootAncestor == container);8142}81438144Container getTraversalRoot() {8145return getFocusCycleRootAncestor();8146}81478148/**8149* Transfers the focus to the next component, as though this Component were8150* the focus owner.8151* @see #requestFocus()8152* @since 1.18153*/8154public void transferFocus() {8155nextFocus();8156}81578158/**8159* @deprecated As of JDK version 1.1,8160* replaced by transferFocus().8161*/8162@Deprecated8163public void nextFocus() {8164transferFocus(false);8165}81668167boolean transferFocus(boolean clearOnFailure) {8168if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8169focusLog.finer("clearOnFailure = " + clearOnFailure);8170}8171Component toFocus = getNextFocusCandidate();8172boolean res = false;8173if (toFocus != null && !toFocus.isFocusOwner() && toFocus != this) {8174res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_FORWARD);8175}8176if (clearOnFailure && !res) {8177if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8178focusLog.finer("clear global focus owner");8179}8180KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();8181}8182if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8183focusLog.finer("returning result: " + res);8184}8185return res;8186}81878188@SuppressWarnings("removal")8189final Component getNextFocusCandidate() {8190Container rootAncestor = getTraversalRoot();8191Component comp = this;8192while (rootAncestor != null &&8193!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))8194{8195comp = rootAncestor;8196rootAncestor = comp.getFocusCycleRootAncestor();8197}8198if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8199focusLog.finer("comp = " + comp + ", root = " + rootAncestor);8200}8201Component candidate = null;8202if (rootAncestor != null) {8203FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();8204Component toFocus = policy.getComponentAfter(rootAncestor, comp);8205if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8206focusLog.finer("component after is " + toFocus);8207}8208if (toFocus == null) {8209toFocus = policy.getDefaultComponent(rootAncestor);8210if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8211focusLog.finer("default component is " + toFocus);8212}8213}8214if (toFocus == null) {8215Applet applet = EmbeddedFrame.getAppletIfAncestorOf(this);8216if (applet != null) {8217toFocus = applet;8218}8219}8220candidate = toFocus;8221}8222if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8223focusLog.finer("Focus transfer candidate: " + candidate);8224}8225return candidate;8226}82278228/**8229* Transfers the focus to the previous component, as though this Component8230* were the focus owner.8231* @see #requestFocus()8232* @since 1.48233*/8234public void transferFocusBackward() {8235transferFocusBackward(false);8236}82378238boolean transferFocusBackward(boolean clearOnFailure) {8239Container rootAncestor = getTraversalRoot();8240Component comp = this;8241while (rootAncestor != null &&8242!(rootAncestor.isShowing() && rootAncestor.canBeFocusOwner()))8243{8244comp = rootAncestor;8245rootAncestor = comp.getFocusCycleRootAncestor();8246}8247boolean res = false;8248if (rootAncestor != null) {8249FocusTraversalPolicy policy = rootAncestor.getFocusTraversalPolicy();8250Component toFocus = policy.getComponentBefore(rootAncestor, comp);8251if (toFocus == null) {8252toFocus = policy.getDefaultComponent(rootAncestor);8253}8254if (toFocus != null) {8255res = toFocus.requestFocusInWindow(FocusEvent.Cause.TRAVERSAL_BACKWARD);8256}8257}8258if (clearOnFailure && !res) {8259if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8260focusLog.finer("clear global focus owner");8261}8262KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwnerPriv();8263}8264if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {8265focusLog.finer("returning result: " + res);8266}8267return res;8268}82698270/**8271* Transfers the focus up one focus traversal cycle. Typically, the focus8272* owner is set to this Component's focus cycle root, and the current focus8273* cycle root is set to the new focus owner's focus cycle root. If,8274* however, this Component's focus cycle root is a Window, then the focus8275* owner is set to the focus cycle root's default Component to focus, and8276* the current focus cycle root is unchanged.8277*8278* @see #requestFocus()8279* @see Container#isFocusCycleRoot()8280* @see Container#setFocusCycleRoot(boolean)8281* @since 1.48282*/8283public void transferFocusUpCycle() {8284Container rootAncestor;8285for (rootAncestor = getFocusCycleRootAncestor();8286rootAncestor != null && !(rootAncestor.isShowing() &&8287rootAncestor.isFocusable() &&8288rootAncestor.isEnabled());8289rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {8290}82918292if (rootAncestor != null) {8293Container rootAncestorRootAncestor =8294rootAncestor.getFocusCycleRootAncestor();8295Container fcr = (rootAncestorRootAncestor != null) ?8296rootAncestorRootAncestor : rootAncestor;82978298KeyboardFocusManager.getCurrentKeyboardFocusManager().8299setGlobalCurrentFocusCycleRootPriv(fcr);8300rootAncestor.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);8301} else {8302Window window = getContainingWindow();83038304if (window != null) {8305Component toFocus = window.getFocusTraversalPolicy().8306getDefaultComponent(window);8307if (toFocus != null) {8308KeyboardFocusManager.getCurrentKeyboardFocusManager().8309setGlobalCurrentFocusCycleRootPriv(window);8310toFocus.requestFocus(FocusEvent.Cause.TRAVERSAL_UP);8311}8312}8313}8314}83158316/**8317* Returns {@code true} if this {@code Component} is the8318* focus owner. This method is obsolete, and has been replaced by8319* {@code isFocusOwner()}.8320*8321* @return {@code true} if this {@code Component} is the8322* focus owner; {@code false} otherwise8323* @since 1.28324*/8325public boolean hasFocus() {8326return (KeyboardFocusManager.getCurrentKeyboardFocusManager().8327getFocusOwner() == this);8328}83298330/**8331* Returns {@code true} if this {@code Component} is the8332* focus owner.8333*8334* @return {@code true} if this {@code Component} is the8335* focus owner; {@code false} otherwise8336* @since 1.48337*/8338public boolean isFocusOwner() {8339return hasFocus();8340}83418342/**8343* Used to disallow auto-focus-transfer on disposal of the focus owner8344* in the process of disposing its parent container.8345*/8346private boolean autoFocusTransferOnDisposal = true;83478348void setAutoFocusTransferOnDisposal(boolean value) {8349autoFocusTransferOnDisposal = value;8350}83518352boolean isAutoFocusTransferOnDisposal() {8353return autoFocusTransferOnDisposal;8354}83558356/**8357* Adds the specified popup menu to the component.8358* @param popup the popup menu to be added to the component.8359* @see #remove(MenuComponent)8360* @exception NullPointerException if {@code popup} is {@code null}8361* @since 1.18362*/8363public void add(PopupMenu popup) {8364synchronized (getTreeLock()) {8365if (popup.parent != null) {8366popup.parent.remove(popup);8367}8368if (popups == null) {8369popups = new Vector<PopupMenu>();8370}8371popups.addElement(popup);8372popup.parent = this;83738374if (peer != null) {8375if (popup.peer == null) {8376popup.addNotify();8377}8378}8379}8380}83818382/**8383* Removes the specified popup menu from the component.8384* @param popup the popup menu to be removed8385* @see #add(PopupMenu)8386* @since 1.18387*/8388@SuppressWarnings("unchecked")8389public void remove(MenuComponent popup) {8390synchronized (getTreeLock()) {8391if (popups == null) {8392return;8393}8394int index = popups.indexOf(popup);8395if (index >= 0) {8396PopupMenu pmenu = (PopupMenu)popup;8397if (pmenu.peer != null) {8398pmenu.removeNotify();8399}8400pmenu.parent = null;8401popups.removeElementAt(index);8402if (popups.size() == 0) {8403popups = null;8404}8405}8406}8407}84088409/**8410* Returns a string representing the state of this component. This8411* method is intended to be used only for debugging purposes, and the8412* content and format of the returned string may vary between8413* implementations. The returned string may be empty but may not be8414* {@code null}.8415*8416* @return a string representation of this component's state8417* @since 1.08418*/8419protected String paramString() {8420final String thisName = Objects.toString(getName(), "");8421final String invalid = isValid() ? "" : ",invalid";8422final String hidden = visible ? "" : ",hidden";8423final String disabled = enabled ? "" : ",disabled";8424return thisName + ',' + x + ',' + y + ',' + width + 'x' + height8425+ invalid + hidden + disabled;8426}84278428/**8429* Returns a string representation of this component and its values.8430* @return a string representation of this component8431* @since 1.08432*/8433public String toString() {8434return getClass().getName() + '[' + paramString() + ']';8435}84368437/**8438* Prints a listing of this component to the standard system output8439* stream {@code System.out}.8440* @see java.lang.System#out8441* @since 1.08442*/8443public void list() {8444list(System.out, 0);8445}84468447/**8448* Prints a listing of this component to the specified output8449* stream.8450* @param out a print stream8451* @throws NullPointerException if {@code out} is {@code null}8452* @since 1.08453*/8454public void list(PrintStream out) {8455list(out, 0);8456}84578458/**8459* Prints out a list, starting at the specified indentation, to the8460* specified print stream.8461* @param out a print stream8462* @param indent number of spaces to indent8463* @see java.io.PrintStream#println(java.lang.Object)8464* @throws NullPointerException if {@code out} is {@code null}8465* @since 1.08466*/8467public void list(PrintStream out, int indent) {8468for (int i = 0 ; i < indent ; i++) {8469out.print(" ");8470}8471out.println(this);8472}84738474/**8475* Prints a listing to the specified print writer.8476* @param out the print writer to print to8477* @throws NullPointerException if {@code out} is {@code null}8478* @since 1.18479*/8480public void list(PrintWriter out) {8481list(out, 0);8482}84838484/**8485* Prints out a list, starting at the specified indentation, to8486* the specified print writer.8487* @param out the print writer to print to8488* @param indent the number of spaces to indent8489* @throws NullPointerException if {@code out} is {@code null}8490* @see java.io.PrintStream#println(java.lang.Object)8491* @since 1.18492*/8493public void list(PrintWriter out, int indent) {8494for (int i = 0 ; i < indent ; i++) {8495out.print(" ");8496}8497out.println(this);8498}84998500/*8501* Fetches the native container somewhere higher up in the component8502* tree that contains this component.8503*/8504final Container getNativeContainer() {8505Container p = getContainer();8506while (p != null && p.peer instanceof LightweightPeer) {8507p = p.getContainer();8508}8509return p;8510}85118512/**8513* Adds a PropertyChangeListener to the listener list. The listener is8514* registered for all bound properties of this class, including the8515* following:8516* <ul>8517* <li>this Component's font ("font")</li>8518* <li>this Component's background color ("background")</li>8519* <li>this Component's foreground color ("foreground")</li>8520* <li>this Component's focusability ("focusable")</li>8521* <li>this Component's focus traversal keys enabled state8522* ("focusTraversalKeysEnabled")</li>8523* <li>this Component's Set of FORWARD_TRAVERSAL_KEYS8524* ("forwardFocusTraversalKeys")</li>8525* <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS8526* ("backwardFocusTraversalKeys")</li>8527* <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS8528* ("upCycleFocusTraversalKeys")</li>8529* <li>this Component's preferred size ("preferredSize")</li>8530* <li>this Component's minimum size ("minimumSize")</li>8531* <li>this Component's maximum size ("maximumSize")</li>8532* <li>this Component's name ("name")</li>8533* </ul>8534* Note that if this {@code Component} is inheriting a bound property, then no8535* event will be fired in response to a change in the inherited property.8536* <p>8537* If {@code listener} is {@code null},8538* no exception is thrown and no action is performed.8539*8540* @param listener the property change listener to be added8541*8542* @see #removePropertyChangeListener8543* @see #getPropertyChangeListeners8544* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8545*/8546public void addPropertyChangeListener(8547PropertyChangeListener listener) {8548synchronized (getObjectLock()) {8549if (listener == null) {8550return;8551}8552if (changeSupport == null) {8553changeSupport = new PropertyChangeSupport(this);8554}8555changeSupport.addPropertyChangeListener(listener);8556}8557}85588559/**8560* Removes a PropertyChangeListener from the listener list. This method8561* should be used to remove PropertyChangeListeners that were registered8562* for all bound properties of this class.8563* <p>8564* If listener is null, no exception is thrown and no action is performed.8565*8566* @param listener the PropertyChangeListener to be removed8567*8568* @see #addPropertyChangeListener8569* @see #getPropertyChangeListeners8570* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)8571*/8572public void removePropertyChangeListener(8573PropertyChangeListener listener) {8574synchronized (getObjectLock()) {8575if (listener == null || changeSupport == null) {8576return;8577}8578changeSupport.removePropertyChangeListener(listener);8579}8580}85818582/**8583* Returns an array of all the property change listeners8584* registered on this component.8585*8586* @return all of this component's {@code PropertyChangeListener}s8587* or an empty array if no property change8588* listeners are currently registered8589*8590* @see #addPropertyChangeListener8591* @see #removePropertyChangeListener8592* @see #getPropertyChangeListeners(java.lang.String)8593* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners8594* @since 1.48595*/8596public PropertyChangeListener[] getPropertyChangeListeners() {8597synchronized (getObjectLock()) {8598if (changeSupport == null) {8599return new PropertyChangeListener[0];8600}8601return changeSupport.getPropertyChangeListeners();8602}8603}86048605/**8606* Adds a PropertyChangeListener to the listener list for a specific8607* property. The specified property may be user-defined, or one of the8608* following:8609* <ul>8610* <li>this Component's font ("font")</li>8611* <li>this Component's background color ("background")</li>8612* <li>this Component's foreground color ("foreground")</li>8613* <li>this Component's focusability ("focusable")</li>8614* <li>this Component's focus traversal keys enabled state8615* ("focusTraversalKeysEnabled")</li>8616* <li>this Component's Set of FORWARD_TRAVERSAL_KEYS8617* ("forwardFocusTraversalKeys")</li>8618* <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS8619* ("backwardFocusTraversalKeys")</li>8620* <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS8621* ("upCycleFocusTraversalKeys")</li>8622* </ul>8623* Note that if this {@code Component} is inheriting a bound property, then no8624* event will be fired in response to a change in the inherited property.8625* <p>8626* If {@code propertyName} or {@code listener} is {@code null},8627* no exception is thrown and no action is taken.8628*8629* @param propertyName one of the property names listed above8630* @param listener the property change listener to be added8631*8632* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8633* @see #getPropertyChangeListeners(java.lang.String)8634* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8635*/8636public void addPropertyChangeListener(8637String propertyName,8638PropertyChangeListener listener) {8639synchronized (getObjectLock()) {8640if (listener == null) {8641return;8642}8643if (changeSupport == null) {8644changeSupport = new PropertyChangeSupport(this);8645}8646changeSupport.addPropertyChangeListener(propertyName, listener);8647}8648}86498650/**8651* Removes a {@code PropertyChangeListener} from the listener8652* list for a specific property. This method should be used to remove8653* {@code PropertyChangeListener}s8654* that were registered for a specific bound property.8655* <p>8656* If {@code propertyName} or {@code listener} is {@code null},8657* no exception is thrown and no action is taken.8658*8659* @param propertyName a valid property name8660* @param listener the PropertyChangeListener to be removed8661*8662* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8663* @see #getPropertyChangeListeners(java.lang.String)8664* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)8665*/8666public void removePropertyChangeListener(8667String propertyName,8668PropertyChangeListener listener) {8669synchronized (getObjectLock()) {8670if (listener == null || changeSupport == null) {8671return;8672}8673changeSupport.removePropertyChangeListener(propertyName, listener);8674}8675}86768677/**8678* Returns an array of all the listeners which have been associated8679* with the named property.8680*8681* @param propertyName the property name8682* @return all of the {@code PropertyChangeListener}s associated with8683* the named property; if no such listeners have been added or8684* if {@code propertyName} is {@code null}, an empty8685* array is returned8686*8687* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8688* @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)8689* @see #getPropertyChangeListeners8690* @since 1.48691*/8692public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {8693synchronized (getObjectLock()) {8694if (changeSupport == null) {8695return new PropertyChangeListener[0];8696}8697return changeSupport.getPropertyChangeListeners(propertyName);8698}8699}87008701/**8702* Support for reporting bound property changes for Object properties.8703* This method can be called when a bound property has changed and it will8704* send the appropriate PropertyChangeEvent to any registered8705* PropertyChangeListeners.8706*8707* @param propertyName the property whose value has changed8708* @param oldValue the property's previous value8709* @param newValue the property's new value8710*/8711protected void firePropertyChange(String propertyName,8712Object oldValue, Object newValue) {8713PropertyChangeSupport changeSupport;8714synchronized (getObjectLock()) {8715changeSupport = this.changeSupport;8716}8717if (changeSupport == null ||8718(oldValue != null && newValue != null && oldValue.equals(newValue))) {8719return;8720}8721changeSupport.firePropertyChange(propertyName, oldValue, newValue);8722}87238724/**8725* Support for reporting bound property changes for boolean properties.8726* This method can be called when a bound property has changed and it will8727* send the appropriate PropertyChangeEvent to any registered8728* PropertyChangeListeners.8729*8730* @param propertyName the property whose value has changed8731* @param oldValue the property's previous value8732* @param newValue the property's new value8733* @since 1.48734*/8735protected void firePropertyChange(String propertyName,8736boolean oldValue, boolean newValue) {8737PropertyChangeSupport changeSupport = this.changeSupport;8738if (changeSupport == null || oldValue == newValue) {8739return;8740}8741changeSupport.firePropertyChange(propertyName, oldValue, newValue);8742}87438744/**8745* Support for reporting bound property changes for integer properties.8746* This method can be called when a bound property has changed and it will8747* send the appropriate PropertyChangeEvent to any registered8748* PropertyChangeListeners.8749*8750* @param propertyName the property whose value has changed8751* @param oldValue the property's previous value8752* @param newValue the property's new value8753* @since 1.48754*/8755protected void firePropertyChange(String propertyName,8756int oldValue, int newValue) {8757PropertyChangeSupport changeSupport = this.changeSupport;8758if (changeSupport == null || oldValue == newValue) {8759return;8760}8761changeSupport.firePropertyChange(propertyName, oldValue, newValue);8762}87638764/**8765* Reports a bound property change.8766*8767* @param propertyName the programmatic name of the property8768* that was changed8769* @param oldValue the old value of the property (as a byte)8770* @param newValue the new value of the property (as a byte)8771* @see #firePropertyChange(java.lang.String, java.lang.Object,8772* java.lang.Object)8773* @since 1.58774*/8775public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {8776if (changeSupport == null || oldValue == newValue) {8777return;8778}8779firePropertyChange(propertyName, Byte.valueOf(oldValue), Byte.valueOf(newValue));8780}87818782/**8783* Reports a bound property change.8784*8785* @param propertyName the programmatic name of the property8786* that was changed8787* @param oldValue the old value of the property (as a char)8788* @param newValue the new value of the property (as a char)8789* @see #firePropertyChange(java.lang.String, java.lang.Object,8790* java.lang.Object)8791* @since 1.58792*/8793public void firePropertyChange(String propertyName, char oldValue, char newValue) {8794if (changeSupport == null || oldValue == newValue) {8795return;8796}8797firePropertyChange(propertyName, Character.valueOf(oldValue), Character.valueOf(newValue));8798}87998800/**8801* Reports a bound property change.8802*8803* @param propertyName the programmatic name of the property8804* that was changed8805* @param oldValue the old value of the property (as a short)8806* @param newValue the new value of the property (as a short)8807* @see #firePropertyChange(java.lang.String, java.lang.Object,8808* java.lang.Object)8809* @since 1.58810*/8811public void firePropertyChange(String propertyName, short oldValue, short newValue) {8812if (changeSupport == null || oldValue == newValue) {8813return;8814}8815firePropertyChange(propertyName, Short.valueOf(oldValue), Short.valueOf(newValue));8816}881788188819/**8820* Reports a bound property change.8821*8822* @param propertyName the programmatic name of the property8823* that was changed8824* @param oldValue the old value of the property (as a long)8825* @param newValue the new value of the property (as a long)8826* @see #firePropertyChange(java.lang.String, java.lang.Object,8827* java.lang.Object)8828* @since 1.58829*/8830public void firePropertyChange(String propertyName, long oldValue, long newValue) {8831if (changeSupport == null || oldValue == newValue) {8832return;8833}8834firePropertyChange(propertyName, Long.valueOf(oldValue), Long.valueOf(newValue));8835}88368837/**8838* Reports a bound property change.8839*8840* @param propertyName the programmatic name of the property8841* that was changed8842* @param oldValue the old value of the property (as a float)8843* @param newValue the new value of the property (as a float)8844* @see #firePropertyChange(java.lang.String, java.lang.Object,8845* java.lang.Object)8846* @since 1.58847*/8848public void firePropertyChange(String propertyName, float oldValue, float newValue) {8849if (changeSupport == null || oldValue == newValue) {8850return;8851}8852firePropertyChange(propertyName, Float.valueOf(oldValue), Float.valueOf(newValue));8853}88548855/**8856* Reports a bound property change.8857*8858* @param propertyName the programmatic name of the property8859* that was changed8860* @param oldValue the old value of the property (as a double)8861* @param newValue the new value of the property (as a double)8862* @see #firePropertyChange(java.lang.String, java.lang.Object,8863* java.lang.Object)8864* @since 1.58865*/8866public void firePropertyChange(String propertyName, double oldValue, double newValue) {8867if (changeSupport == null || oldValue == newValue) {8868return;8869}8870firePropertyChange(propertyName, Double.valueOf(oldValue), Double.valueOf(newValue));8871}887288738874// Serialization support.88758876/**8877* Component Serialized Data Version.8878*8879* @serial8880*/8881private int componentSerializedDataVersion = 4;88828883/**8884* This hack is for Swing serialization. It will invoke8885* the Swing package private method {@code compWriteObjectNotify}.8886*/8887private void doSwingSerialization() {8888if (!(this instanceof JComponent)) {8889return;8890}8891@SuppressWarnings("deprecation")8892Package swingPackage = Package.getPackage("javax.swing");8893// For Swing serialization to correctly work Swing needs to8894// be notified before Component does it's serialization. This8895// hack accommodates this.8896//8897// Swing classes MUST be loaded by the bootstrap class loader,8898// otherwise we don't consider them.8899for (Class<?> klass = Component.this.getClass(); klass != null;8900klass = klass.getSuperclass()) {8901if (klass.getPackage() == swingPackage &&8902klass.getClassLoader() == null) {89038904SwingAccessor.getJComponentAccessor()8905.compWriteObjectNotify((JComponent) this);8906return;8907}8908}8909}89108911/**8912* Writes default serializable fields to stream. Writes8913* a variety of serializable listeners as optional data.8914* The non-serializable listeners are detected and8915* no attempt is made to serialize them.8916*8917* @param s the {@code ObjectOutputStream} to write8918* @throws IOException if an I/O error occurs8919* @serialData {@code null} terminated sequence of8920* 0 or more pairs; the pair consists of a {@code String}8921* and an {@code Object}; the {@code String} indicates8922* the type of object and is one of the following (as of 1.4):8923* {@code componentListenerK} indicating an8924* {@code ComponentListener} object;8925* {@code focusListenerK} indicating an8926* {@code FocusListener} object;8927* {@code keyListenerK} indicating an8928* {@code KeyListener} object;8929* {@code mouseListenerK} indicating an8930* {@code MouseListener} object;8931* {@code mouseMotionListenerK} indicating an8932* {@code MouseMotionListener} object;8933* {@code inputMethodListenerK} indicating an8934* {@code InputMethodListener} object;8935* {@code hierarchyListenerK} indicating an8936* {@code HierarchyListener} object;8937* {@code hierarchyBoundsListenerK} indicating an8938* {@code HierarchyBoundsListener} object;8939* {@code mouseWheelListenerK} indicating an8940* {@code MouseWheelListener} object8941* @serialData an optional {@code ComponentOrientation}8942* (after {@code inputMethodListener}, as of 1.2)8943*8944* @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)8945* @see #componentListenerK8946* @see #focusListenerK8947* @see #keyListenerK8948* @see #mouseListenerK8949* @see #mouseMotionListenerK8950* @see #inputMethodListenerK8951* @see #hierarchyListenerK8952* @see #hierarchyBoundsListenerK8953* @see #mouseWheelListenerK8954* @see #readObject(ObjectInputStream)8955*/8956@Serial8957private void writeObject(ObjectOutputStream s)8958throws IOException8959{8960doSwingSerialization();89618962s.defaultWriteObject();89638964AWTEventMulticaster.save(s, componentListenerK, componentListener);8965AWTEventMulticaster.save(s, focusListenerK, focusListener);8966AWTEventMulticaster.save(s, keyListenerK, keyListener);8967AWTEventMulticaster.save(s, mouseListenerK, mouseListener);8968AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener);8969AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener);89708971s.writeObject(null);8972s.writeObject(componentOrientation);89738974AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener);8975AWTEventMulticaster.save(s, hierarchyBoundsListenerK,8976hierarchyBoundsListener);8977s.writeObject(null);89788979AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener);8980s.writeObject(null);89818982}89838984/**8985* Reads the {@code ObjectInputStream} and if it isn't8986* {@code null} adds a listener to receive a variety8987* of events fired by the component.8988* Unrecognized keys or values will be ignored.8989*8990* @param s the {@code ObjectInputStream} to read8991* @throws ClassNotFoundException if the class of a serialized object could8992* not be found8993* @throws IOException if an I/O error occurs8994* @see #writeObject(ObjectOutputStream)8995*/8996@SuppressWarnings("removal")8997@Serial8998private void readObject(ObjectInputStream s)8999throws ClassNotFoundException, IOException9000{9001objectLock = new Object();90029003acc = AccessController.getContext();90049005s.defaultReadObject();90069007appContext = AppContext.getAppContext();9008coalescingEnabled = checkCoalescing();9009if (componentSerializedDataVersion < 4) {9010// These fields are non-transient and rely on default9011// serialization. However, the default values are insufficient,9012// so we need to set them explicitly for object data streams prior9013// to 1.4.9014focusable = true;9015isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;9016initializeFocusTraversalKeys();9017focusTraversalKeysEnabled = true;9018}90199020Object keyOrNull;9021while(null != (keyOrNull = s.readObject())) {9022String key = ((String)keyOrNull).intern();90239024if (componentListenerK == key)9025addComponentListener((ComponentListener)(s.readObject()));90269027else if (focusListenerK == key)9028addFocusListener((FocusListener)(s.readObject()));90299030else if (keyListenerK == key)9031addKeyListener((KeyListener)(s.readObject()));90329033else if (mouseListenerK == key)9034addMouseListener((MouseListener)(s.readObject()));90359036else if (mouseMotionListenerK == key)9037addMouseMotionListener((MouseMotionListener)(s.readObject()));90389039else if (inputMethodListenerK == key)9040addInputMethodListener((InputMethodListener)(s.readObject()));90419042else // skip value for unrecognized key9043s.readObject();90449045}90469047// Read the component's orientation if it's present9048Object orient = null;90499050try {9051orient = s.readObject();9052} catch (java.io.OptionalDataException e) {9053// JDK 1.1 instances will not have this optional data.9054// e.eof will be true to indicate that there is no more9055// data available for this object.9056// If e.eof is not true, throw the exception as it9057// might have been caused by reasons unrelated to9058// componentOrientation.90599060if (!e.eof) {9061throw (e);9062}9063}90649065if (orient != null) {9066componentOrientation = (ComponentOrientation)orient;9067} else {9068componentOrientation = ComponentOrientation.UNKNOWN;9069}90709071try {9072while(null != (keyOrNull = s.readObject())) {9073String key = ((String)keyOrNull).intern();90749075if (hierarchyListenerK == key) {9076addHierarchyListener((HierarchyListener)(s.readObject()));9077}9078else if (hierarchyBoundsListenerK == key) {9079addHierarchyBoundsListener((HierarchyBoundsListener)9080(s.readObject()));9081}9082else {9083// skip value for unrecognized key9084s.readObject();9085}9086}9087} catch (java.io.OptionalDataException e) {9088// JDK 1.1/1.2 instances will not have this optional data.9089// e.eof will be true to indicate that there is no more9090// data available for this object.9091// If e.eof is not true, throw the exception as it9092// might have been caused by reasons unrelated to9093// hierarchy and hierarchyBounds listeners.90949095if (!e.eof) {9096throw (e);9097}9098}90999100try {9101while (null != (keyOrNull = s.readObject())) {9102String key = ((String)keyOrNull).intern();91039104if (mouseWheelListenerK == key) {9105addMouseWheelListener((MouseWheelListener)(s.readObject()));9106}9107else {9108// skip value for unrecognized key9109s.readObject();9110}9111}9112} catch (java.io.OptionalDataException e) {9113// pre-1.3 instances will not have this optional data.9114// e.eof will be true to indicate that there is no more9115// data available for this object.9116// If e.eof is not true, throw the exception as it9117// might have been caused by reasons unrelated to9118// mouse wheel listeners91199120if (!e.eof) {9121throw (e);9122}9123}91249125if (popups != null) {9126int npopups = popups.size();9127for (int i = 0 ; i < npopups ; i++) {9128PopupMenu popup = popups.elementAt(i);9129popup.parent = this;9130}9131}9132}91339134/**9135* Sets the language-sensitive orientation that is to be used to order9136* the elements or text within this component. Language-sensitive9137* {@code LayoutManager} and {@code Component}9138* subclasses will use this property to9139* determine how to lay out and draw components.9140* <p>9141* At construction time, a component's orientation is set to9142* {@code ComponentOrientation.UNKNOWN},9143* indicating that it has not been specified9144* explicitly. The UNKNOWN orientation behaves the same as9145* {@code ComponentOrientation.LEFT_TO_RIGHT}.9146* <p>9147* To set the orientation of a single component, use this method.9148* To set the orientation of an entire component9149* hierarchy, use9150* {@link #applyComponentOrientation applyComponentOrientation}.9151* <p>9152* This method changes layout-related information, and therefore,9153* invalidates the component hierarchy.9154*9155* @param o the orientation to be set9156*9157* @see ComponentOrientation9158* @see #invalidate9159*9160* @author Laura Werner, IBM9161*/9162public void setComponentOrientation(ComponentOrientation o) {9163ComponentOrientation oldValue = componentOrientation;9164componentOrientation = o;91659166// This is a bound property, so report the change to9167// any registered listeners. (Cheap if there are none.)9168firePropertyChange("componentOrientation", oldValue, o);91699170// This could change the preferred size of the Component.9171invalidateIfValid();9172}91739174/**9175* Retrieves the language-sensitive orientation that is to be used to order9176* the elements or text within this component. {@code LayoutManager}9177* and {@code Component}9178* subclasses that wish to respect orientation should call this method to9179* get the component's orientation before performing layout or drawing.9180*9181* @return the orientation to order the elements or text9182* @see ComponentOrientation9183*9184* @author Laura Werner, IBM9185*/9186public ComponentOrientation getComponentOrientation() {9187return componentOrientation;9188}91899190/**9191* Sets the {@code ComponentOrientation} property of this component9192* and all components contained within it.9193* <p>9194* This method changes layout-related information, and therefore,9195* invalidates the component hierarchy.9196*9197*9198* @param orientation the new component orientation of this component and9199* the components contained within it.9200* @exception NullPointerException if {@code orientation} is null.9201* @see #setComponentOrientation9202* @see #getComponentOrientation9203* @see #invalidate9204* @since 1.49205*/9206public void applyComponentOrientation(ComponentOrientation orientation) {9207if (orientation == null) {9208throw new NullPointerException();9209}9210setComponentOrientation(orientation);9211}92129213final boolean canBeFocusOwner() {9214// It is enabled, visible, focusable.9215if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {9216return true;9217}9218return false;9219}92209221/**9222* Checks that this component meets the prerequisites to be focus owner:9223* - it is enabled, visible, focusable9224* - it's parents are all enabled and showing9225* - top-level window is focusable9226* - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts9227* this component as focus owner9228* @since 1.59229*/9230final boolean canBeFocusOwnerRecursively() {9231// - it is enabled, visible, focusable9232if (!canBeFocusOwner()) {9233return false;9234}92359236// - it's parents are all enabled and showing9237synchronized(getTreeLock()) {9238if (parent != null) {9239return parent.canContainFocusOwner(this);9240}9241}9242return true;9243}92449245/**9246* Fix the location of the HW component in a LW container hierarchy.9247*/9248final void relocateComponent() {9249synchronized (getTreeLock()) {9250if (peer == null) {9251return;9252}9253int nativeX = x;9254int nativeY = y;9255for (Component cont = getContainer();9256cont != null && cont.isLightweight();9257cont = cont.getContainer())9258{9259nativeX += cont.x;9260nativeY += cont.y;9261}9262peer.setBounds(nativeX, nativeY, width, height,9263ComponentPeer.SET_LOCATION);9264}9265}92669267/**9268* Returns the {@code Window} ancestor of the component.9269* @return Window ancestor of the component or component by itself if it is Window;9270* null, if component is not a part of window hierarchy9271*/9272Window getContainingWindow() {9273return SunToolkit.getContainingWindow(this);9274}92759276/**9277* Initialize JNI field and method IDs9278*/9279private static native void initIDs();92809281/*9282* --- Accessibility Support ---9283*9284* Component will contain all of the methods in interface Accessible,9285* though it won't actually implement the interface - that will be up9286* to the individual objects which extend Component.9287*/92889289/**9290* The {@code AccessibleContext} associated with this {@code Component}.9291*/9292@SuppressWarnings("serial") // Not statically typed as Serializable9293protected AccessibleContext accessibleContext = null;92949295/**9296* Gets the {@code AccessibleContext} associated9297* with this {@code Component}.9298* The method implemented by this base9299* class returns null. Classes that extend {@code Component}9300* should implement this method to return the9301* {@code AccessibleContext} associated with the subclass.9302*9303*9304* @return the {@code AccessibleContext} of this9305* {@code Component}9306* @since 1.39307*/9308public AccessibleContext getAccessibleContext() {9309return accessibleContext;9310}93119312/**9313* Inner class of Component used to provide default support for9314* accessibility. This class is not meant to be used directly by9315* application developers, but is instead meant only to be9316* subclassed by component developers.9317* <p>9318* The class used to obtain the accessible role for this object.9319* @since 1.39320*/9321protected abstract class AccessibleAWTComponent extends AccessibleContext9322implements Serializable, AccessibleComponent {93239324/**9325* Use serialVersionUID from JDK 1.3 for interoperability.9326*/9327@Serial9328private static final long serialVersionUID = 642321655757800191L;93299330/**9331* Though the class is abstract, this should be called by9332* all sub-classes.9333*/9334protected AccessibleAWTComponent() {9335}93369337/**9338* Number of PropertyChangeListener objects registered. It's used9339* to add/remove ComponentListener and FocusListener to track9340* target Component's state.9341*/9342private transient volatile int propertyListenersCount = 0;93439344/**9345* A component listener to track show/hide/resize events9346* and convert them to PropertyChange events.9347*/9348@SuppressWarnings("serial") // Not statically typed as Serializable9349protected ComponentListener accessibleAWTComponentHandler = null;93509351/**9352* A listener to track focus events9353* and convert them to PropertyChange events.9354*/9355@SuppressWarnings("serial") // Not statically typed as Serializable9356protected FocusListener accessibleAWTFocusHandler = null;93579358/**9359* Fire PropertyChange listener, if one is registered,9360* when shown/hidden..9361* @since 1.39362*/9363protected class AccessibleAWTComponentHandler implements ComponentListener, Serializable {93649365/**9366* Use serialVersionUID from JDK 1.3 for interoperability.9367*/9368@Serial9369private static final long serialVersionUID = -1009684107426231869L;93709371/**9372* Constructs an {@code AccessibleAWTComponentHandler}.9373*/9374protected AccessibleAWTComponentHandler() {}93759376public void componentHidden(ComponentEvent e) {9377if (accessibleContext != null) {9378accessibleContext.firePropertyChange(9379AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9380AccessibleState.VISIBLE, null);9381}9382}93839384public void componentShown(ComponentEvent e) {9385if (accessibleContext != null) {9386accessibleContext.firePropertyChange(9387AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9388null, AccessibleState.VISIBLE);9389}9390}93919392public void componentMoved(ComponentEvent e) {9393}93949395public void componentResized(ComponentEvent e) {9396}9397} // inner class AccessibleAWTComponentHandler939893999400/**9401* Fire PropertyChange listener, if one is registered,9402* when focus events happen9403* @since 1.39404*/9405protected class AccessibleAWTFocusHandler implements FocusListener, Serializable {94069407/**9408* Use serialVersionUID from JDK 1.3 for interoperability.9409*/9410@Serial9411private static final long serialVersionUID = 3150908257351582233L;94129413/**9414* Constructs an {@code AccessibleAWTFocusHandler}.9415*/9416protected AccessibleAWTFocusHandler() {}94179418public void focusGained(FocusEvent event) {9419if (accessibleContext != null) {9420accessibleContext.firePropertyChange(9421AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9422null, AccessibleState.FOCUSED);9423}9424}9425public void focusLost(FocusEvent event) {9426if (accessibleContext != null) {9427accessibleContext.firePropertyChange(9428AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9429AccessibleState.FOCUSED, null);9430}9431}9432} // inner class AccessibleAWTFocusHandler943394349435/**9436* Adds a {@code PropertyChangeListener} to the listener list.9437*9438* @param listener the property change listener to be added9439*/9440public void addPropertyChangeListener(PropertyChangeListener listener) {9441if (accessibleAWTComponentHandler == null) {9442accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();9443}9444if (accessibleAWTFocusHandler == null) {9445accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();9446}9447if (propertyListenersCount++ == 0) {9448Component.this.addComponentListener(accessibleAWTComponentHandler);9449Component.this.addFocusListener(accessibleAWTFocusHandler);9450}9451super.addPropertyChangeListener(listener);9452}94539454/**9455* Remove a PropertyChangeListener from the listener list.9456* This removes a PropertyChangeListener that was registered9457* for all properties.9458*9459* @param listener The PropertyChangeListener to be removed9460*/9461public void removePropertyChangeListener(PropertyChangeListener listener) {9462if (--propertyListenersCount == 0) {9463Component.this.removeComponentListener(accessibleAWTComponentHandler);9464Component.this.removeFocusListener(accessibleAWTFocusHandler);9465}9466super.removePropertyChangeListener(listener);9467}94689469// AccessibleContext methods9470//9471/**9472* Gets the accessible name of this object. This should almost never9473* return {@code java.awt.Component.getName()},9474* as that generally isn't a localized name,9475* and doesn't have meaning for the user. If the9476* object is fundamentally a text object (e.g. a menu item), the9477* accessible name should be the text of the object (e.g. "save").9478* If the object has a tooltip, the tooltip text may also be an9479* appropriate String to return.9480*9481* @return the localized name of the object -- can be9482* {@code null} if this9483* object does not have a name9484* @see javax.accessibility.AccessibleContext#setAccessibleName9485*/9486public String getAccessibleName() {9487return accessibleName;9488}94899490/**9491* Gets the accessible description of this object. This should be9492* a concise, localized description of what this object is - what9493* is its meaning to the user. If the object has a tooltip, the9494* tooltip text may be an appropriate string to return, assuming9495* it contains a concise description of the object (instead of just9496* the name of the object - e.g. a "Save" icon on a toolbar that9497* had "save" as the tooltip text shouldn't return the tooltip9498* text as the description, but something like "Saves the current9499* text document" instead).9500*9501* @return the localized description of the object -- can be9502* {@code null} if this object does not have a description9503* @see javax.accessibility.AccessibleContext#setAccessibleDescription9504*/9505public String getAccessibleDescription() {9506return accessibleDescription;9507}95089509/**9510* Gets the role of this object.9511*9512* @return an instance of {@code AccessibleRole}9513* describing the role of the object9514* @see javax.accessibility.AccessibleRole9515*/9516public AccessibleRole getAccessibleRole() {9517return AccessibleRole.AWT_COMPONENT;9518}95199520/**9521* Gets the state of this object.9522*9523* @return an instance of {@code AccessibleStateSet}9524* containing the current state set of the object9525* @see javax.accessibility.AccessibleState9526*/9527public AccessibleStateSet getAccessibleStateSet() {9528return Component.this.getAccessibleStateSet();9529}95309531/**9532* Gets the {@code Accessible} parent of this object.9533* If the parent of this object implements {@code Accessible},9534* this method should simply return {@code getParent}.9535*9536* @return the {@code Accessible} parent of this9537* object -- can be {@code null} if this9538* object does not have an {@code Accessible} parent9539*/9540public Accessible getAccessibleParent() {9541if (accessibleParent != null) {9542return accessibleParent;9543} else {9544Container parent = getParent();9545if (parent instanceof Accessible) {9546return (Accessible) parent;9547}9548}9549return null;9550}95519552/**9553* Gets the index of this object in its accessible parent.9554*9555* @return the index of this object in its parent; or -1 if this9556* object does not have an accessible parent9557* @see #getAccessibleParent9558*/9559public int getAccessibleIndexInParent() {9560return Component.this.getAccessibleIndexInParent();9561}95629563/**9564* Returns the number of accessible children in the object. If all9565* of the children of this object implement {@code Accessible},9566* then this method should return the number of children of this object.9567*9568* @return the number of accessible children in the object9569*/9570public int getAccessibleChildrenCount() {9571return 0; // Components don't have children9572}95739574/**9575* Returns the nth {@code Accessible} child of the object.9576*9577* @param i zero-based index of child9578* @return the nth {@code Accessible} child of the object9579*/9580public Accessible getAccessibleChild(int i) {9581return null; // Components don't have children9582}95839584/**9585* Returns the locale of this object.9586*9587* @return the locale of this object9588*/9589public Locale getLocale() {9590return Component.this.getLocale();9591}95929593/**9594* Gets the {@code AccessibleComponent} associated9595* with this object if one exists.9596* Otherwise return {@code null}.9597*9598* @return the component9599*/9600public AccessibleComponent getAccessibleComponent() {9601return this;9602}960396049605// AccessibleComponent methods9606//9607/**9608* Gets the background color of this object.9609*9610* @return the background color, if supported, of the object;9611* otherwise, {@code null}9612*/9613public Color getBackground() {9614return Component.this.getBackground();9615}96169617/**9618* Sets the background color of this object.9619* (For transparency, see {@code isOpaque}.)9620*9621* @param c the new {@code Color} for the background9622* @see Component#isOpaque9623*/9624public void setBackground(Color c) {9625Component.this.setBackground(c);9626}96279628/**9629* Gets the foreground color of this object.9630*9631* @return the foreground color, if supported, of the object;9632* otherwise, {@code null}9633*/9634public Color getForeground() {9635return Component.this.getForeground();9636}96379638/**9639* Sets the foreground color of this object.9640*9641* @param c the new {@code Color} for the foreground9642*/9643public void setForeground(Color c) {9644Component.this.setForeground(c);9645}96469647/**9648* Gets the {@code Cursor} of this object.9649*9650* @return the {@code Cursor}, if supported,9651* of the object; otherwise, {@code null}9652*/9653public Cursor getCursor() {9654return Component.this.getCursor();9655}96569657/**9658* Sets the {@code Cursor} of this object.9659* <p>9660* The method may have no visual effect if the Java platform9661* implementation and/or the native system do not support9662* changing the mouse cursor shape.9663* @param cursor the new {@code Cursor} for the object9664*/9665public void setCursor(Cursor cursor) {9666Component.this.setCursor(cursor);9667}96689669/**9670* Gets the {@code Font} of this object.9671*9672* @return the {@code Font}, if supported,9673* for the object; otherwise, {@code null}9674*/9675public Font getFont() {9676return Component.this.getFont();9677}96789679/**9680* Sets the {@code Font} of this object.9681*9682* @param f the new {@code Font} for the object9683*/9684public void setFont(Font f) {9685Component.this.setFont(f);9686}96879688/**9689* Gets the {@code FontMetrics} of this object.9690*9691* @param f the {@code Font}9692* @return the {@code FontMetrics}, if supported,9693* the object; otherwise, {@code null}9694* @see #getFont9695*/9696public FontMetrics getFontMetrics(Font f) {9697if (f == null) {9698return null;9699} else {9700return Component.this.getFontMetrics(f);9701}9702}97039704/**9705* Determines if the object is enabled.9706*9707* @return true if object is enabled; otherwise, false9708*/9709public boolean isEnabled() {9710return Component.this.isEnabled();9711}97129713/**9714* Sets the enabled state of the object.9715*9716* @param b if true, enables this object; otherwise, disables it9717*/9718public void setEnabled(boolean b) {9719boolean old = Component.this.isEnabled();9720Component.this.setEnabled(b);9721if (b != old) {9722if (accessibleContext != null) {9723if (b) {9724accessibleContext.firePropertyChange(9725AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9726null, AccessibleState.ENABLED);9727} else {9728accessibleContext.firePropertyChange(9729AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9730AccessibleState.ENABLED, null);9731}9732}9733}9734}97359736/**9737* Determines if the object is visible. Note: this means that the9738* object intends to be visible; however, it may not in fact be9739* showing on the screen because one of the objects that this object9740* is contained by is not visible. To determine if an object is9741* showing on the screen, use {@code isShowing}.9742*9743* @return true if object is visible; otherwise, false9744*/9745public boolean isVisible() {9746return Component.this.isVisible();9747}97489749/**9750* Sets the visible state of the object.9751*9752* @param b if true, shows this object; otherwise, hides it9753*/9754public void setVisible(boolean b) {9755boolean old = Component.this.isVisible();9756Component.this.setVisible(b);9757if (b != old) {9758if (accessibleContext != null) {9759if (b) {9760accessibleContext.firePropertyChange(9761AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9762null, AccessibleState.VISIBLE);9763} else {9764accessibleContext.firePropertyChange(9765AccessibleContext.ACCESSIBLE_STATE_PROPERTY,9766AccessibleState.VISIBLE, null);9767}9768}9769}9770}97719772/**9773* Determines if the object is showing. This is determined by checking9774* the visibility of the object and ancestors of the object. Note:9775* this will return true even if the object is obscured by another9776* (for example, it happens to be underneath a menu that was pulled9777* down).9778*9779* @return true if object is showing; otherwise, false9780*/9781public boolean isShowing() {9782return Component.this.isShowing();9783}97849785/**9786* Checks whether the specified point is within this object's bounds,9787* where the point's x and y coordinates are defined to be relative to9788* the coordinate system of the object.9789*9790* @param p the {@code Point} relative to the9791* coordinate system of the object9792* @return true if object contains {@code Point}; otherwise false9793*/9794public boolean contains(Point p) {9795return Component.this.contains(p);9796}97979798/**9799* Returns the location of the object on the screen.9800*9801* @return location of object on screen -- can be9802* {@code null} if this object is not on the screen9803*/9804public Point getLocationOnScreen() {9805synchronized (Component.this.getTreeLock()) {9806if (Component.this.isShowing()) {9807return Component.this.getLocationOnScreen();9808} else {9809return null;9810}9811}9812}98139814/**9815* Gets the location of the object relative to the parent in the form9816* of a point specifying the object's top-left corner in the screen's9817* coordinate space.9818*9819* @return an instance of Point representing the top-left corner of9820* the object's bounds in the coordinate space of the screen;9821* {@code null} if this object or its parent are not on the screen9822*/9823public Point getLocation() {9824return Component.this.getLocation();9825}98269827/**9828* Sets the location of the object relative to the parent.9829* @param p the coordinates of the object9830*/9831public void setLocation(Point p) {9832Component.this.setLocation(p);9833}98349835/**9836* Gets the bounds of this object in the form of a Rectangle object.9837* The bounds specify this object's width, height, and location9838* relative to its parent.9839*9840* @return a rectangle indicating this component's bounds;9841* {@code null} if this object is not on the screen9842*/9843public Rectangle getBounds() {9844return Component.this.getBounds();9845}98469847/**9848* Sets the bounds of this object in the form of a9849* {@code Rectangle} object.9850* The bounds specify this object's width, height, and location9851* relative to its parent.9852*9853* @param r a rectangle indicating this component's bounds9854*/9855public void setBounds(Rectangle r) {9856Component.this.setBounds(r);9857}98589859/**9860* Returns the size of this object in the form of a9861* {@code Dimension} object. The height field of the9862* {@code Dimension} object contains this object's9863* height, and the width field of the {@code Dimension}9864* object contains this object's width.9865*9866* @return a {@code Dimension} object that indicates9867* the size of this component; {@code null} if9868* this object is not on the screen9869*/9870public Dimension getSize() {9871return Component.this.getSize();9872}98739874/**9875* Resizes this object so that it has width and height.9876*9877* @param d the dimension specifying the new size of the object9878*/9879public void setSize(Dimension d) {9880Component.this.setSize(d);9881}98829883/**9884* Returns the {@code Accessible} child,9885* if one exists, contained at the local9886* coordinate {@code Point}. Otherwise returns9887* {@code null}.9888*9889* @param p the point defining the top-left corner of9890* the {@code Accessible}, given in the9891* coordinate space of the object's parent9892* @return the {@code Accessible}, if it exists,9893* at the specified location; else {@code null}9894*/9895public Accessible getAccessibleAt(Point p) {9896return null; // Components don't have children9897}98989899/**9900* Returns whether this object can accept focus or not.9901*9902* @return true if object can accept focus; otherwise false9903*/9904public boolean isFocusTraversable() {9905return Component.this.isFocusTraversable();9906}99079908/**9909* Requests focus for this object.9910*/9911public void requestFocus() {9912Component.this.requestFocus();9913}99149915/**9916* Adds the specified focus listener to receive focus events from this9917* component.9918*9919* @param l the focus listener9920*/9921public void addFocusListener(FocusListener l) {9922Component.this.addFocusListener(l);9923}99249925/**9926* Removes the specified focus listener so it no longer receives focus9927* events from this component.9928*9929* @param l the focus listener9930*/9931public void removeFocusListener(FocusListener l) {9932Component.this.removeFocusListener(l);9933}99349935} // inner class AccessibleAWTComponent993699379938/**9939* Gets the index of this object in its accessible parent.9940* If this object does not have an accessible parent, returns9941* -1.9942*9943* @return the index of this object in its accessible parent9944*/9945int getAccessibleIndexInParent() {9946synchronized (getTreeLock()) {99479948AccessibleContext accContext = getAccessibleContext();9949if (accContext == null) {9950return -1;9951}99529953Accessible parent = accContext.getAccessibleParent();9954if (parent == null) {9955return -1;9956}99579958accContext = parent.getAccessibleContext();9959for (int i = 0; i < accContext.getAccessibleChildrenCount(); i++) {9960if (this.equals(accContext.getAccessibleChild(i))) {9961return i;9962}9963}99649965return -1;9966}9967}99689969/**9970* Gets the current state set of this object.9971*9972* @return an instance of {@code AccessibleStateSet}9973* containing the current state set of the object9974* @see AccessibleState9975*/9976AccessibleStateSet getAccessibleStateSet() {9977synchronized (getTreeLock()) {9978AccessibleStateSet states = new AccessibleStateSet();9979if (this.isEnabled()) {9980states.add(AccessibleState.ENABLED);9981}9982if (this.isFocusTraversable()) {9983states.add(AccessibleState.FOCUSABLE);9984}9985if (this.isVisible()) {9986states.add(AccessibleState.VISIBLE);9987}9988if (this.isShowing()) {9989states.add(AccessibleState.SHOWING);9990}9991if (this.isFocusOwner()) {9992states.add(AccessibleState.FOCUSED);9993}9994if (this instanceof Accessible) {9995AccessibleContext ac = ((Accessible) this).getAccessibleContext();9996if (ac != null) {9997Accessible ap = ac.getAccessibleParent();9998if (ap != null) {9999AccessibleContext pac = ap.getAccessibleContext();10000if (pac != null) {10001AccessibleSelection as = pac.getAccessibleSelection();10002if (as != null) {10003states.add(AccessibleState.SELECTABLE);10004int i = ac.getAccessibleIndexInParent();10005if (i >= 0) {10006if (as.isAccessibleChildSelected(i)) {10007states.add(AccessibleState.SELECTED);10008}10009}10010}10011}10012}10013}10014}10015if (Component.isInstanceOf(this, "javax.swing.JComponent")) {10016if (((javax.swing.JComponent) this).isOpaque()) {10017states.add(AccessibleState.OPAQUE);10018}10019}10020return states;10021}10022}1002310024/**10025* Checks that the given object is instance of the given class.10026* @param obj Object to be checked10027* @param className The name of the class. Must be fully-qualified class name.10028* @return true, if this object is instanceof given class,10029* false, otherwise, or if obj or className is null10030*/10031static boolean isInstanceOf(Object obj, String className) {10032if (obj == null) return false;10033if (className == null) return false;1003410035Class<?> cls = obj.getClass();10036while (cls != null) {10037if (cls.getName().equals(className)) {10038return true;10039}10040cls = cls.getSuperclass();10041}10042return false;10043}100441004510046// ************************** MIXING CODE *******************************1004710048/**10049* Check whether we can trust the current bounds of the component.10050* The return value of false indicates that the container of the10051* component is invalid, and therefore needs to be laid out, which would10052* probably mean changing the bounds of its children.10053* Null-layout of the container or absence of the container mean10054* the bounds of the component are final and can be trusted.10055*/10056final boolean areBoundsValid() {10057Container cont = getContainer();10058return cont == null || cont.isValid() || cont.getLayout() == null;10059}1006010061/**10062* Applies the shape to the component10063* @param shape Shape to be applied to the component10064*/10065void applyCompoundShape(Region shape) {10066checkTreeLock();1006710068if (!areBoundsValid()) {10069if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10070mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());10071}10072return;10073}1007410075if (!isLightweight()) {10076ComponentPeer peer = this.peer;10077if (peer != null) {10078// The Region class has some optimizations. That's why10079// we should manually check whether it's empty and10080// substitute the object ourselves. Otherwise we end up10081// with some incorrect Region object with loX being10082// greater than the hiX for instance.10083if (shape.isEmpty()) {10084shape = Region.EMPTY_REGION;10085}100861008710088// Note: the shape is not really copied/cloned. We create10089// the Region object ourselves, so there's no any possibility10090// to modify the object outside of the mixing code.10091// Nullifying compoundShape means that the component has normal shape10092// (or has no shape at all).10093if (shape.equals(getNormalShape())) {10094if (this.compoundShape == null) {10095return;10096}10097this.compoundShape = null;10098peer.applyShape(null);10099} else {10100if (shape.equals(getAppliedShape())) {10101return;10102}10103this.compoundShape = shape;10104Point compAbsolute = getLocationOnWindow();10105if (mixingLog.isLoggable(PlatformLogger.Level.FINER)) {10106mixingLog.fine("this = " + this +10107"; compAbsolute=" + compAbsolute + "; shape=" + shape);10108}10109peer.applyShape(shape.getTranslatedRegion(-compAbsolute.x, -compAbsolute.y));10110}10111}10112}10113}1011410115/**10116* Returns the shape previously set with applyCompoundShape().10117* If the component is LW or no shape was applied yet,10118* the method returns the normal shape.10119*/10120private Region getAppliedShape() {10121checkTreeLock();10122//XXX: if we allow LW components to have a shape, this must be changed10123return (this.compoundShape == null || isLightweight()) ? getNormalShape() : this.compoundShape;10124}1012510126Point getLocationOnWindow() {10127checkTreeLock();10128Point curLocation = getLocation();1012910130for (Container parent = getContainer();10131parent != null && !(parent instanceof Window);10132parent = parent.getContainer())10133{10134curLocation.x += parent.getX();10135curLocation.y += parent.getY();10136}1013710138return curLocation;10139}1014010141/**10142* Returns the full shape of the component located in window coordinates10143*/10144final Region getNormalShape() {10145checkTreeLock();10146//XXX: we may take into account a user-specified shape for this component10147Point compAbsolute = getLocationOnWindow();10148return10149Region.getInstanceXYWH(10150compAbsolute.x,10151compAbsolute.y,10152getWidth(),10153getHeight()10154);10155}1015610157/**10158* Returns the "opaque shape" of the component.10159*10160* The opaque shape of a lightweight components is the actual shape that10161* needs to be cut off of the heavyweight components in order to mix this10162* lightweight component correctly with them.10163*10164* The method is overriden in the java.awt.Container to handle non-opaque10165* containers containing opaque children.10166*10167* See 6637655 for details.10168*/10169Region getOpaqueShape() {10170checkTreeLock();10171if (mixingCutoutRegion != null) {10172return mixingCutoutRegion;10173} else {10174return getNormalShape();10175}10176}1017710178final int getSiblingIndexAbove() {10179checkTreeLock();10180Container parent = getContainer();10181if (parent == null) {10182return -1;10183}1018410185int nextAbove = parent.getComponentZOrder(this) - 1;1018610187return nextAbove < 0 ? -1 : nextAbove;10188}1018910190final ComponentPeer getHWPeerAboveMe() {10191checkTreeLock();1019210193Container cont = getContainer();10194int indexAbove = getSiblingIndexAbove();1019510196while (cont != null) {10197for (int i = indexAbove; i > -1; i--) {10198Component comp = cont.getComponent(i);10199if (comp != null && comp.isDisplayable() && !comp.isLightweight()) {10200return comp.peer;10201}10202}10203// traversing the hierarchy up to the closest HW container;10204// further traversing may return a component that is not actually10205// a native sibling of this component and this kind of z-order10206// request may not be allowed by the underlying system (6852051).10207if (!cont.isLightweight()) {10208break;10209}1021010211indexAbove = cont.getSiblingIndexAbove();10212cont = cont.getContainer();10213}1021410215return null;10216}1021710218final int getSiblingIndexBelow() {10219checkTreeLock();10220Container parent = getContainer();10221if (parent == null) {10222return -1;10223}1022410225int nextBelow = parent.getComponentZOrder(this) + 1;1022610227return nextBelow >= parent.getComponentCount() ? -1 : nextBelow;10228}1022910230final boolean isNonOpaqueForMixing() {10231return mixingCutoutRegion != null &&10232mixingCutoutRegion.isEmpty();10233}1023410235private Region calculateCurrentShape() {10236checkTreeLock();10237Region s = getNormalShape();1023810239if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10240mixingLog.fine("this = " + this + "; normalShape=" + s);10241}1024210243if (getContainer() != null) {10244Component comp = this;10245Container cont = comp.getContainer();1024610247while (cont != null) {10248for (int index = comp.getSiblingIndexAbove(); index != -1; --index) {10249/* It is assumed that:10250*10251* getComponent(getContainer().getComponentZOrder(comp)) == comp10252*10253* The assumption has been made according to the current10254* implementation of the Container class.10255*/10256Component c = cont.getComponent(index);10257if (c.isLightweight() && c.isShowing()) {10258s = s.getDifference(c.getOpaqueShape());10259}10260}1026110262if (cont.isLightweight()) {10263s = s.getIntersection(cont.getNormalShape());10264} else {10265break;10266}1026710268comp = cont;10269cont = cont.getContainer();10270}10271}1027210273if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10274mixingLog.fine("currentShape=" + s);10275}1027610277return s;10278}1027910280void applyCurrentShape() {10281checkTreeLock();10282if (!areBoundsValid()) {10283if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10284mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());10285}10286return; // Because applyCompoundShape() ignores such components anyway10287}10288if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10289mixingLog.fine("this = " + this);10290}10291applyCompoundShape(calculateCurrentShape());10292}1029310294final void subtractAndApplyShape(Region s) {10295checkTreeLock();1029610297if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10298mixingLog.fine("this = " + this + "; s=" + s);10299}1030010301applyCompoundShape(getAppliedShape().getDifference(s));10302}1030310304private void applyCurrentShapeBelowMe() {10305checkTreeLock();10306Container parent = getContainer();10307if (parent != null && parent.isShowing()) {10308// First, reapply shapes of my siblings10309parent.recursiveApplyCurrentShape(getSiblingIndexBelow());1031010311// Second, if my container is non-opaque, reapply shapes of siblings of my container10312Container parent2 = parent.getContainer();10313while (!parent.isOpaque() && parent2 != null) {10314parent2.recursiveApplyCurrentShape(parent.getSiblingIndexBelow());1031510316parent = parent2;10317parent2 = parent.getContainer();10318}10319}10320}1032110322final void subtractAndApplyShapeBelowMe() {10323checkTreeLock();10324Container parent = getContainer();10325if (parent != null && isShowing()) {10326Region opaqueShape = getOpaqueShape();1032710328// First, cut my siblings10329parent.recursiveSubtractAndApplyShape(opaqueShape, getSiblingIndexBelow());1033010331// Second, if my container is non-opaque, cut siblings of my container10332Container parent2 = parent.getContainer();10333while (!parent.isOpaque() && parent2 != null) {10334parent2.recursiveSubtractAndApplyShape(opaqueShape, parent.getSiblingIndexBelow());1033510336parent = parent2;10337parent2 = parent.getContainer();10338}10339}10340}1034110342void mixOnShowing() {10343synchronized (getTreeLock()) {10344if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10345mixingLog.fine("this = " + this);10346}10347if (!isMixingNeeded()) {10348return;10349}10350if (isLightweight()) {10351subtractAndApplyShapeBelowMe();10352} else {10353applyCurrentShape();10354}10355}10356}1035710358void mixOnHiding(boolean isLightweight) {10359// We cannot be sure that the peer exists at this point, so we need the argument10360// to find out whether the hiding component is (well, actually was) a LW or a HW.10361synchronized (getTreeLock()) {10362if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10363mixingLog.fine("this = " + this + "; isLightweight = " + isLightweight);10364}10365if (!isMixingNeeded()) {10366return;10367}10368if (isLightweight) {10369applyCurrentShapeBelowMe();10370}10371}10372}1037310374void mixOnReshaping() {10375synchronized (getTreeLock()) {10376if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10377mixingLog.fine("this = " + this);10378}10379if (!isMixingNeeded()) {10380return;10381}10382if (isLightweight()) {10383applyCurrentShapeBelowMe();10384} else {10385applyCurrentShape();10386}10387}10388}1038910390void mixOnZOrderChanging(int oldZorder, int newZorder) {10391synchronized (getTreeLock()) {10392boolean becameHigher = newZorder < oldZorder;10393Container parent = getContainer();1039410395if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10396mixingLog.fine("this = " + this +10397"; oldZorder=" + oldZorder + "; newZorder=" + newZorder + "; parent=" + parent);10398}10399if (!isMixingNeeded()) {10400return;10401}10402if (isLightweight()) {10403if (becameHigher) {10404if (parent != null && isShowing()) {10405parent.recursiveSubtractAndApplyShape(getOpaqueShape(), getSiblingIndexBelow(), oldZorder);10406}10407} else {10408if (parent != null) {10409parent.recursiveApplyCurrentShape(oldZorder, newZorder);10410}10411}10412} else {10413if (becameHigher) {10414applyCurrentShape();10415} else {10416if (parent != null) {10417Region shape = getAppliedShape();1041810419for (int index = oldZorder; index < newZorder; index++) {10420Component c = parent.getComponent(index);10421if (c.isLightweight() && c.isShowing()) {10422shape = shape.getDifference(c.getOpaqueShape());10423}10424}10425applyCompoundShape(shape);10426}10427}10428}10429}10430}1043110432void mixOnValidating() {10433// This method gets overriden in the Container. Obviously, a plain10434// non-container components don't need to handle validation.10435}1043610437final boolean isMixingNeeded() {10438if (SunToolkit.getSunAwtDisableMixing()) {10439if (mixingLog.isLoggable(PlatformLogger.Level.FINEST)) {10440mixingLog.finest("this = " + this + "; Mixing disabled via sun.awt.disableMixing");10441}10442return false;10443}10444if (!areBoundsValid()) {10445if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10446mixingLog.fine("this = " + this + "; areBoundsValid = " + areBoundsValid());10447}10448return false;10449}10450Window window = getContainingWindow();10451if (window != null) {10452if (!window.hasHeavyweightDescendants() || !window.hasLightweightDescendants() || window.isDisposing()) {10453if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10454mixingLog.fine("containing window = " + window +10455"; has h/w descendants = " + window.hasHeavyweightDescendants() +10456"; has l/w descendants = " + window.hasLightweightDescendants() +10457"; disposing = " + window.isDisposing());10458}10459return false;10460}10461} else {10462if (mixingLog.isLoggable(PlatformLogger.Level.FINE)) {10463mixingLog.fine("this = " + this + "; containing window is null");10464}10465return false;10466}10467return true;10468}1046910470/**10471* Sets a 'mixing-cutout' shape for this lightweight component.10472*10473* This method is used exclusively for the purposes of the10474* Heavyweight/Lightweight Components Mixing feature and will10475* have no effect if applied to a heavyweight component.10476*10477* By default a lightweight component is treated as an opaque rectangle for10478* the purposes of the Heavyweight/Lightweight Components Mixing feature.10479* This method enables developers to set an arbitrary shape to be cut out10480* from heavyweight components positioned underneath the lightweight10481* component in the z-order.10482* <p>10483* The {@code shape} argument may have the following values:10484* <ul>10485* <li>{@code null} - reverts the default cutout shape (the rectangle equal10486* to the component's {@code getBounds()})10487* <li><i>empty-shape</i> - does not cut out anything from heavyweight10488* components. This makes this lightweight component effectively10489* transparent. Note that descendants of the lightweight component still10490* affect the shapes of heavyweight components. An example of an10491* <i>empty-shape</i> is {@code new Rectangle()}.10492* <li><i>non-empty-shape</i> - the given shape will be cut out from10493* heavyweight components.10494* </ul>10495* <p>10496* The most common example when the 'mixing-cutout' shape is needed is a10497* glass pane component. The {@link JRootPane#setGlassPane} method10498* automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape10499* for the given glass pane component. If a developer needs some other10500* 'mixing-cutout' shape for the glass pane (which is rare), this must be10501* changed manually after installing the glass pane to the root pane.10502*10503* @param shape the new 'mixing-cutout' shape10504* @since 910505*/10506public void setMixingCutoutShape(Shape shape) {10507Region region = shape == null ? null : Region.getInstance(shape, null);1050810509synchronized (getTreeLock()) {10510boolean needShowing = false;10511boolean needHiding = false;1051210513if (!isNonOpaqueForMixing()) {10514needHiding = true;10515}1051610517mixingCutoutRegion = region;1051810519if (!isNonOpaqueForMixing()) {10520needShowing = true;10521}1052210523if (isMixingNeeded()) {10524if (needHiding) {10525mixOnHiding(isLightweight());10526}10527if (needShowing) {10528mixOnShowing();10529}10530}10531}10532}1053310534// ****************** END OF MIXING CODE ********************************1053510536// Note that the method is overriden in the Window class,10537// a window doesn't need to be updated in the Z-order.10538void updateZOrder() {10539peer.setZOrder(getHWPeerAboveMe());10540}1054110542}105431054410545