1 /* Component.java -- a graphics component
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006
3 Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
42 //import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer;
44 import gnu.java.awt.ComponentReshapeEvent;
46 import gnu.java.lang.CPStringBuilder;
48 import java.awt.dnd.DropTarget;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.AdjustmentEvent;
51 import java.awt.event.ComponentEvent;
52 import java.awt.event.ComponentListener;
53 import java.awt.event.FocusEvent;
54 import java.awt.event.FocusListener;
55 import java.awt.event.HierarchyBoundsListener;
56 import java.awt.event.HierarchyEvent;
57 import java.awt.event.HierarchyListener;
58 import java.awt.event.InputEvent;
59 import java.awt.event.InputMethodEvent;
60 import java.awt.event.InputMethodListener;
61 import java.awt.event.KeyEvent;
62 import java.awt.event.KeyListener;
63 import java.awt.event.MouseEvent;
64 import java.awt.event.MouseListener;
65 import java.awt.event.MouseMotionListener;
66 import java.awt.event.MouseWheelEvent;
67 import java.awt.event.MouseWheelListener;
68 import java.awt.event.PaintEvent;
69 import java.awt.event.WindowEvent;
70 import java.awt.im.InputContext;
71 import java.awt.im.InputMethodRequests;
72 import java.awt.image.BufferStrategy;
73 import java.awt.image.ColorModel;
74 import java.awt.image.ImageObserver;
75 import java.awt.image.ImageProducer;
76 import java.awt.image.VolatileImage;
77 import java.awt.peer.ComponentPeer;
78 import java.awt.peer.LightweightPeer;
79 import java.beans.PropertyChangeEvent;
80 import java.beans.PropertyChangeListener;
81 import java.beans.PropertyChangeSupport;
82 import java.io.IOException;
83 import java.io.ObjectInputStream;
84 import java.io.ObjectOutputStream;
85 import java.io.PrintStream;
86 import java.io.PrintWriter;
87 import java.io.Serializable;
88 import java.lang.reflect.Array;
89 import java.util.Collections;
90 import java.util.EventListener;
91 import java.util.HashSet;
92 import java.util.Iterator;
93 import java.util.Locale;
95 import java.util.Vector;
97 import javax.accessibility.Accessible;
98 import javax.accessibility.AccessibleComponent;
99 import javax.accessibility.AccessibleContext;
100 import javax.accessibility.AccessibleRole;
101 import javax.accessibility.AccessibleState;
102 import javax.accessibility.AccessibleStateSet;
105 * The root of all evil. All graphical representations are subclasses of this
106 * giant class, which is designed for screen display and user interaction.
107 * This class can be extended directly to build a lightweight component (one
108 * not associated with a native window); lightweight components must reside
109 * inside a heavyweight window.
111 * <p>This class is Serializable, which has some big implications. A user can
112 * save the state of all graphical components in one VM, and reload them in
113 * another. Note that this class will only save Serializable listeners, and
114 * ignore the rest, without causing any serialization exceptions. However, by
115 * making a listener serializable, and adding it to another element, you link
116 * in that entire element to the state of this component. To get around this,
117 * use the idiom shown in the example below - make listeners non-serializable
118 * in inner classes, rather than using this object itself as the listener, if
119 * external objects do not need to save the state of this object.
123 * import java.awt.event.*;
124 * import java.io.Serializable;
125 * class MyApp implements Serializable
127 * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
128 * // Serializing aButton will not suck in an instance of MyApp, with its
129 * // accompanying field bigOne.
130 * Button aButton = new Button();
131 * class MyActionListener implements ActionListener
133 * public void actionPerformed(ActionEvent e)
135 * System.out.println("Hello There");
140 * aButton.addActionListener(new MyActionListener());
145 * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
146 * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
147 * incomplete or only stubs; except for methods relating to the Drag and
148 * Drop, Input Method, and Accessibility frameworks: These methods are
149 * present but commented out.
151 * @author original author unknown
152 * @author Eric Blake (ebb9@email.byu.edu)
154 * @status still missing 1.4 support
156 public abstract class Component
157 implements ImageObserver, MenuContainer, Serializable
159 // Word to the wise - this file is huge. Search for '\f' (^L) for logical
160 // sectioning by fields, public API, private API, and nested classes.
164 * Compatible with JDK 1.0+.
166 private static final long serialVersionUID = -7644114512714619750L;
169 * Constant returned by the <code>getAlignmentY</code> method to indicate
170 * that the component wishes to be aligned to the top relative to
173 * @see #getAlignmentY()
175 public static final float TOP_ALIGNMENT = 0;
178 * Constant returned by the <code>getAlignmentY</code> and
179 * <code>getAlignmentX</code> methods to indicate
180 * that the component wishes to be aligned to the centdisper relative to
183 * @see #getAlignmentX()
184 * @see #getAlignmentY()
186 public static final float CENTER_ALIGNMENT = 0.5f;
189 * Constant returned by the <code>getAlignmentY</code> method to indicate
190 * that the component wishes to be aligned to the bottom relative to
193 * @see #getAlignmentY()
195 public static final float BOTTOM_ALIGNMENT = 1;
198 * Constant returned by the <code>getAlignmentX</code> method to indicate
199 * that the component wishes to be aligned to the right relative to
202 * @see #getAlignmentX()
204 public static final float RIGHT_ALIGNMENT = 1;
207 * Constant returned by the <code>getAlignmentX</code> method to indicate
208 * that the component wishes to be aligned to the left relative to
211 * @see #getAlignmentX()
213 public static final float LEFT_ALIGNMENT = 0;
216 * Make the treelock a String so that it can easily be identified
217 * in debug dumps. We clone the String in order to avoid a conflict in
218 * the unlikely event that some other package uses exactly the same string
221 static final Object treeLock = new String("AWT_TREE_LOCK");
224 * The default maximum size.
226 private static final Dimension DEFAULT_MAX_SIZE
227 = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
229 // Serialized fields from the serialization spec.
232 * The x position of the component in the parent's coordinate system.
234 * @see #getLocation()
235 * @serial the x position
240 * The y position of the component in the parent's coordinate system.
242 * @see #getLocation()
243 * @serial the y position
248 * The component width.
256 * The component height.
264 * The foreground color for the component. This may be null.
266 * @see #getForeground()
267 * @see #setForeground(Color)
268 * @serial the foreground color
273 * The background color for the component. This may be null.
275 * @see #getBackground()
276 * @see #setBackground(Color)
277 * @serial the background color
282 * The default font used in the component. This may be null.
285 * @see #setFont(Font)
291 * The font in use by the peer, or null if there is no peer.
293 * @serial the peer's font
298 * The cursor displayed when the pointer is over this component. This may
302 * @see #setCursor(Cursor)
307 * The locale for the component.
310 * @see #setLocale(Locale)
312 Locale locale = Locale.getDefault ();
315 * True if the object should ignore repaint events (usually because it is
318 * @see #getIgnoreRepaint()
319 * @see #setIgnoreRepaint(boolean)
320 * @serial true to ignore repaints
323 boolean ignoreRepaint;
326 * True when the object is visible (although it is only showing if all
327 * ancestors are likewise visible). For component, this defaults to true.
330 * @see #setVisible(boolean)
331 * @serial true if visible
333 boolean visible = true;
336 * True if the object is enabled, meaning it can interact with the user.
337 * For component, this defaults to true.
340 * @see #setEnabled(boolean)
341 * @serial true if enabled
343 boolean enabled = true;
346 * True if the object is valid. This is set to false any time a size
347 * adjustment means the component need to be layed out again.
352 * @serial true if layout is valid
357 * The DropTarget for drag-and-drop operations.
359 * @see #getDropTarget()
360 * @see #setDropTarget(DropTarget)
361 * @serial the drop target, or null
364 DropTarget dropTarget;
367 * The list of popup menus for this component.
369 * @see #add(PopupMenu)
370 * @serial the list of popups
375 * The component's name. May be null, in which case a default name is
376 * generated on the first use.
379 * @see #setName(String)
385 * True once the user has set the name. Note that the user may set the name
390 * @see #setName(String)
391 * @serial true if the name has been explicitly set
393 boolean nameExplicitlySet;
396 * Indicates if the object can be focused. Defaults to true for components.
398 * @see #isFocusable()
399 * @see #setFocusable(boolean)
402 boolean focusable = true;
405 * Tracks whether this component's {@link #isFocusTraversable}
406 * method has been overridden.
410 int isFocusTraversableOverridden;
413 * The focus traversal keys, if not inherited from the parent or
414 * default keyboard focus manager. These sets will contain only
415 * AWTKeyStrokes that represent press and release events to use as
418 * @see #getFocusTraversalKeys(int)
419 * @see #setFocusTraversalKeys(int, Set)
422 Set[] focusTraversalKeys;
425 * True if focus traversal keys are enabled. This defaults to true for
426 * Component. If this is true, keystrokes in focusTraversalKeys are trapped
427 * and processed automatically rather than being passed on to the component.
429 * @see #getFocusTraversalKeysEnabled()
430 * @see #setFocusTraversalKeysEnabled(boolean)
433 boolean focusTraversalKeysEnabled = true;
436 * Cached information on the minimum size. Should have been transient.
443 * Flag indicating whether the minimum size for the component has been set
444 * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
449 * The maximum size for the component.
450 * @see #setMaximumSize(Dimension)
455 * A flag indicating whether the maximum size for the component has been set
456 * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
461 * Cached information on the preferred size. Should have been transient.
468 * Flag indicating whether the preferred size for the component has been set
469 * by a call to {@link #setPreferredSize(Dimension)} with a non-null value.
474 * Set to true if an event is to be handled by this component, false if
475 * it is to be passed up the hierarcy.
477 * @see #dispatchEvent(AWTEvent)
478 * @serial true to process event locally
480 boolean newEventsOnly;
483 * Set by subclasses to enable event handling of particular events, and
484 * left alone when modifying listeners. For component, this defaults to
485 * enabling only input methods.
487 * @see #enableInputMethods(boolean)
489 * @serial the mask of events to process
491 long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
494 * Describes all registered PropertyChangeListeners.
496 * @see #addPropertyChangeListener(PropertyChangeListener)
497 * @see #removePropertyChangeListener(PropertyChangeListener)
498 * @see #firePropertyChange(String, Object, Object)
499 * @serial the property change listeners
502 PropertyChangeSupport changeSupport;
505 * True if the component has been packed (layed out).
507 * @serial true if this is packed
512 * The serialization version for this class. Currently at version 4.
514 * XXX How do we handle prior versions?
516 * @serial the serialization version
518 int componentSerializedDataVersion = 4;
521 * The accessible context associated with this component. This is only set
524 * @see #getAccessibleContext()
525 * @serial the accessibility context
528 AccessibleContext accessibleContext;
531 // Guess what - listeners are special cased in serialization. See
532 // readObject and writeObject.
534 /** Component listener chain. */
535 transient ComponentListener componentListener;
537 /** Focus listener chain. */
538 transient FocusListener focusListener;
540 /** Key listener chain. */
541 transient KeyListener keyListener;
543 /** Mouse listener chain. */
544 transient MouseListener mouseListener;
546 /** Mouse motion listener chain. */
547 transient MouseMotionListener mouseMotionListener;
550 * Mouse wheel listener chain.
554 transient MouseWheelListener mouseWheelListener;
557 * Input method listener chain.
561 transient InputMethodListener inputMethodListener;
564 * Hierarcy listener chain.
568 transient HierarchyListener hierarchyListener;
571 * Hierarcy bounds listener chain.
575 transient HierarchyBoundsListener hierarchyBoundsListener;
577 // Anything else is non-serializable, and should be declared "transient".
580 transient Container parent;
582 /** The associated native peer. */
583 transient ComponentPeer peer;
585 /** The preferred component orientation. */
586 transient ComponentOrientation componentOrientation = ComponentOrientation.UNKNOWN;
589 * The associated graphics configuration.
593 transient GraphicsConfiguration graphicsConfig;
596 * The buffer strategy for repainting.
600 transient BufferStrategy bufferStrategy;
603 * The number of hierarchy listeners of this container plus all of its
604 * children. This is needed for efficient handling of HierarchyEvents.
605 * These must be propagated to all child components with HierarchyListeners
606 * attached. To avoid traversal of the whole subtree, we keep track of
607 * the number of HierarchyListeners here and only walk the paths that
608 * actually have listeners.
610 int numHierarchyListeners;
611 int numHierarchyBoundsListeners;
614 * true if requestFocus was called on this component when its
615 * top-level ancestor was not focusable.
617 private transient FocusEvent pendingFocusRequest = null;
620 * The system properties that affect image updating.
622 private static transient boolean incrementalDraw;
623 private static transient Long redrawRate;
627 incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
628 redrawRate = Long.getLong ("awt.image.redrawrate");
631 // Public and protected API.
634 * Default constructor for subclasses. When Component is extended directly,
635 * it forms a lightweight component that must be hosted in an opaque native
636 * container higher in the tree.
638 protected Component()
640 // Nothing to do here.
644 * Returns the name of this component.
646 * @return the name of this component
647 * @see #setName(String)
650 public String getName()
652 if (name == null && ! nameExplicitlySet)
653 name = generateName();
658 * Sets the name of this component to the specified name (this is a bound
659 * property with the name 'name').
661 * @param name the new name (<code>null</code> permitted).
665 public void setName(String name)
667 nameExplicitlySet = true;
668 String old = this.name;
670 firePropertyChange("name", old, name);
674 * Returns the parent of this component.
676 * @return the parent of this component
678 public Container getParent()
684 * Returns the native windowing system peer for this component. Only the
685 * platform specific implementation code should call this method.
687 * @return the peer for this component
688 * @deprecated user programs should not directly manipulate peers; use
689 * {@link #isDisplayable()} instead
691 // Classpath's Gtk peers rely on this.
692 public ComponentPeer getPeer()
698 * Set the associated drag-and-drop target, which receives events when this
701 * @param dt the new drop target
704 public void setDropTarget(DropTarget dt)
706 this.dropTarget = dt;
709 dropTarget.addNotify(peer);
713 * Gets the associated drag-and-drop target, if there is one.
715 * @return the drop target
717 public DropTarget getDropTarget()
723 * Returns the graphics configuration of this component, if there is one.
724 * If it has not been set, it is inherited from the parent.
726 * @return the graphics configuration, or null
729 public GraphicsConfiguration getGraphicsConfiguration()
731 GraphicsConfiguration conf = null;
732 synchronized (getTreeLock())
734 if (graphicsConfig != null)
736 conf = graphicsConfig;
740 Component par = getParent();
743 conf = parent.getGraphicsConfiguration();
751 * Returns the object used for synchronization locks on this component
752 * when performing tree and layout functions.
754 * @return the synchronization lock for this component
756 public final Object getTreeLock()
762 * Returns the toolkit in use for this component. The toolkit is associated
763 * with the frame this component belongs to.
765 * @return the toolkit for this component
767 public Toolkit getToolkit()
769 // Only heavyweight peers can handle this.
770 ComponentPeer p = peer;
771 Component comp = this;
772 while (p instanceof LightweightPeer)
775 p = comp == null ? null : comp.peer;
781 tk = peer.getToolkit();
784 tk = Toolkit.getDefaultToolkit();
789 * Tests whether or not this component is valid. A invalid component needs
790 * to have its layout redone.
792 * @return true if this component is valid
796 public boolean isValid()
798 // Tests show that components are invalid as long as they are not showing, even after validate()
799 // has been called on them.
800 return peer != null && valid;
804 * Tests if the component is displayable. It must be connected to a native
805 * screen resource. This reduces to checking that peer is not null. A
806 * containment hierarchy is made displayable when a window is packed or
809 * @return true if the component is displayable
810 * @see Container#add(Component)
811 * @see Container#remove(Component)
814 * @see Window#dispose()
817 public boolean isDisplayable()
823 * Tests whether or not this component is visible. Except for top-level
824 * frames, components are initially visible.
826 * @return true if the component is visible
827 * @see #setVisible(boolean)
829 public boolean isVisible()
835 * Tests whether or not this component is actually being shown on
836 * the screen. This will be true if and only if it this component is
837 * visible and its parent components are all visible.
839 * @return true if the component is showing on the screen
840 * @see #setVisible(boolean)
842 public boolean isShowing()
844 Component par = parent;
845 return visible && peer != null && (par == null || par.isShowing());
849 * Tests whether or not this component is enabled. Components are enabled
850 * by default, and must be enabled to receive user input or generate events.
852 * @return true if the component is enabled
853 * @see #setEnabled(boolean)
855 public boolean isEnabled()
861 * Enables or disables this component. The component must be enabled to
862 * receive events (except that lightweight components always receive mouse
865 * @param enabled true to enable this component
868 * @see #isLightweight()
872 public void setEnabled(boolean enabled)
878 * Enables this component.
880 * @deprecated use {@link #setEnabled(boolean)} instead
886 // Need to lock the tree here, because the peers are involved.
887 synchronized (getTreeLock())
890 ComponentPeer p = peer;
898 * Enables or disables this component.
900 * @param enabled true to enable this component
902 * @deprecated use {@link #setEnabled(boolean)} instead
904 public void enable(boolean enabled)
913 * Disables this component.
915 * @deprecated use {@link #setEnabled(boolean)} instead
917 public void disable()
921 // Need to lock the tree here, because the peers are involved.
922 synchronized (getTreeLock())
925 ComponentPeer p = peer;
933 * Checks if this image is painted to an offscreen image buffer that is
934 * later copied to screen (double buffering reduces flicker). This version
935 * returns false, so subclasses must override it if they provide double
938 * @return true if this is double buffered; defaults to false
940 public boolean isDoubleBuffered()
946 * Enables or disables input method support for this component. By default,
947 * components have this enabled. Input methods are given the opportunity
948 * to process key events before this component and its listeners.
950 * @param enable true to enable input method processing
951 * @see #processKeyEvent(KeyEvent)
954 public void enableInputMethods(boolean enable)
957 eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
959 eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
963 * Makes this component visible or invisible. Note that it wtill might
964 * not show the component, if a parent is invisible.
966 * @param visible true to make this component visible
972 public void setVisible(boolean visible)
974 // Inspection by subclassing shows that Sun's implementation calls
975 // show(boolean) which then calls show() or hide(). It is the show()
976 // method that is overriden in subclasses like Window.
981 * Makes this component visible on the screen.
983 * @deprecated use {@link #setVisible(boolean)} instead
987 // We must set visible before showing the peer. Otherwise the
988 // peer could post paint events before visible is true, in which
989 // case lightweight components are not initially painted --
990 // Container.paint first calls isShowing () before painting itself
994 // Need to lock the tree here to avoid races and inconsistencies.
995 synchronized (getTreeLock())
998 // Avoid NullPointerExceptions by creating a local reference.
999 ComponentPeer currentPeer = peer;
1000 if (currentPeer != null)
1004 // Fire HierarchyEvent.
1005 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1007 HierarchyEvent.SHOWING_CHANGED);
1009 // The JDK repaints the component before invalidating the parent.
1011 if (peer instanceof LightweightPeer)
1015 // Only post an event if this component actually has a listener
1016 // or has this event explicitly enabled.
1017 if (componentListener != null
1018 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1021 new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
1022 getToolkit().getSystemEventQueue().postEvent(ce);
1026 // Invalidate the parent if we have one. The component itself must
1027 // not be invalidated. We also avoid NullPointerException with
1028 // a local reference here.
1029 Container currentParent = parent;
1030 if (currentParent != null)
1031 currentParent.invalidate();
1037 * Makes this component visible or invisible.
1039 * @param visible true to make this component visible
1041 * @deprecated use {@link #setVisible(boolean)} instead
1043 public void show(boolean visible)
1052 * Hides this component so that it is no longer shown on the screen.
1054 * @deprecated use {@link #setVisible(boolean)} instead
1060 // Need to lock the tree here to avoid races and inconsistencies.
1061 synchronized (getTreeLock())
1065 // Avoid NullPointerExceptions by creating a local reference.
1066 ComponentPeer currentPeer = peer;
1067 if (currentPeer != null)
1071 // Fire hierarchy event.
1072 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1074 HierarchyEvent.SHOWING_CHANGED);
1075 // The JDK repaints the component before invalidating the
1076 // parent. So do we. This only applies for lightweights.
1077 if (peer instanceof LightweightPeer)
1081 // Only post an event if this component actually has a listener
1082 // or has this event explicitly enabled.
1083 if (componentListener != null
1084 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1087 new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
1088 getToolkit().getSystemEventQueue().postEvent(ce);
1092 // Invalidate the parent if we have one. The component itself need
1093 // not be invalidated. We also avoid NullPointerException with
1094 // a local reference here.
1095 Container currentParent = parent;
1096 if (currentParent != null)
1097 currentParent.invalidate();
1103 * Returns this component's foreground color. If not set, this is inherited
1106 * @return this component's foreground color, or null
1107 * @see #setForeground(Color)
1109 public Color getForeground()
1111 if (foreground != null)
1113 return parent == null ? null : parent.getForeground();
1117 * Sets this component's foreground color to the specified color. This is a
1120 * @param c the new foreground color
1121 * @see #getForeground()
1123 public void setForeground(Color c)
1126 peer.setForeground(c);
1128 Color previous = foreground;
1130 firePropertyChange("foreground", previous, c);
1134 * Tests if the foreground was explicitly set, or just inherited from the
1137 * @return true if the foreground has been set
1140 public boolean isForegroundSet()
1142 return foreground != null;
1146 * Returns this component's background color. If not set, this is inherited
1149 * @return the background color of the component, or null
1150 * @see #setBackground(Color)
1152 public Color getBackground()
1154 if (background != null)
1156 return parent == null ? null : parent.getBackground();
1160 * Sets this component's background color to the specified color. The parts
1161 * of the component affected by the background color may by system dependent.
1162 * This is a bound property.
1164 * @param c the new background color
1165 * @see #getBackground()
1167 public void setBackground(Color c)
1169 // return if the background is already set to that color.
1170 if ((c != null) && c.equals(background))
1173 Color previous = background;
1175 if (peer != null && c != null)
1176 peer.setBackground(c);
1177 firePropertyChange("background", previous, c);
1181 * Tests if the background was explicitly set, or just inherited from the
1184 * @return true if the background has been set
1187 public boolean isBackgroundSet()
1189 return background != null;
1193 * Returns the font in use for this component. If not set, this is inherited
1196 * @return the font for this component
1197 * @see #setFont(Font)
1199 public Font getFont()
1201 return getFontImpl();
1205 * Implementation of getFont(). This is pulled out of getFont() to prevent
1206 * client programs from overriding this.
1208 * @return the font of this component
1210 private final Font getFontImpl()
1215 Component p = parent;
1217 f = p.getFontImpl();
1220 // It is important to return null here and not some kind of default
1221 // font, otherwise the Swing UI would not install its fonts because
1222 // it keeps non-UIResource fonts.
1230 * Sets the font for this component to the specified font. This is a bound
1233 * @param f the new font for this component
1237 public void setFont(Font f)
1241 // Synchronize on the tree because getFontImpl() relies on the hierarchy
1242 // not beeing changed.
1243 synchronized (getTreeLock())
1245 // Synchronize on this here to guarantee thread safety wrt to the
1253 // Create local variable here for thread safety.
1254 ComponentPeer p = peer;
1257 // The peer receives the real font setting, which can depend on
1258 // the parent font when this component's font has been set to null.
1268 // Fire property change event.
1269 firePropertyChange("font", oldFont, newFont);
1271 // Invalidate when necessary as font changes can change the size of the
1278 * Tests if the font was explicitly set, or just inherited from the parent.
1280 * @return true if the font has been set
1283 public boolean isFontSet()
1285 return font != null;
1289 * Returns the locale for this component. If this component does not
1290 * have a locale, the locale of the parent component is returned.
1292 * @return the locale for this component
1293 * @throws IllegalComponentStateException if it has no locale or parent
1294 * @see #setLocale(Locale)
1297 public Locale getLocale()
1302 throw new IllegalComponentStateException
1303 ("Component has no parent: can't determine Locale");
1304 return parent.getLocale();
1308 * Sets the locale for this component to the specified locale. This is a
1311 * @param newLocale the new locale for this component
1313 public void setLocale(Locale newLocale)
1315 if (locale == newLocale)
1318 Locale oldLocale = locale;
1320 firePropertyChange("locale", oldLocale, newLocale);
1321 // New writing/layout direction or more/less room for localized labels.
1326 * Returns the color model of the device this componet is displayed on.
1328 * @return this object's color model
1329 * @see Toolkit#getColorModel()
1331 public ColorModel getColorModel()
1333 GraphicsConfiguration config = getGraphicsConfiguration();
1334 return config != null ? config.getColorModel()
1335 : getToolkit().getColorModel();
1339 * Returns the location of this component's top left corner relative to
1340 * its parent component. This may be outdated, so for synchronous behavior,
1341 * you should use a component listner.
1343 * @return the location of this component
1344 * @see #setLocation(int, int)
1345 * @see #getLocationOnScreen()
1348 public Point getLocation()
1354 * Returns the location of this component's top left corner in screen
1357 * @return the location of this component in screen coordinates
1358 * @throws IllegalComponentStateException if the component is not showing
1360 public Point getLocationOnScreen()
1363 throw new IllegalComponentStateException("component "
1364 + getClass().getName()
1367 // Need to lock the tree here. We get crazy races and explosions when
1368 // the tree changes while we are trying to find the location of this
1370 synchronized (getTreeLock())
1372 // Only a heavyweight peer can answer the question for the screen
1373 // location. So we are going through the hierarchy until we find
1374 // one and add up the offsets while doing so.
1377 ComponentPeer p = peer;
1378 Component comp = this;
1379 while (p instanceof LightweightPeer)
1384 p = comp == null ? null: comp.peer;
1386 // Now we have a heavyweight component.
1387 assert ! (p instanceof LightweightPeer);
1388 Point loc = p.getLocationOnScreen();
1396 * Returns the location of this component's top left corner relative to
1397 * its parent component.
1399 * @return the location of this component
1400 * @deprecated use {@link #getLocation()} instead
1402 public Point location()
1404 return new Point (x, y);
1408 * Moves this component to the specified location, relative to the parent's
1409 * coordinates. The coordinates are the new upper left corner of this
1412 * @param x the new X coordinate of this component
1413 * @param y the new Y coordinate of this component
1414 * @see #getLocation()
1415 * @see #setBounds(int, int, int, int)
1417 public void setLocation(int x, int y)
1423 * Moves this component to the specified location, relative to the parent's
1424 * coordinates. The coordinates are the new upper left corner of this
1427 * @param x the new X coordinate of this component
1428 * @param y the new Y coordinate of this component
1429 * @deprecated use {@link #setLocation(int, int)} instead
1431 public void move(int x, int y)
1433 setBounds(x, y, this.width, this.height);
1437 * Moves this component to the specified location, relative to the parent's
1438 * coordinates. The coordinates are the new upper left corner of this
1441 * @param p new coordinates for this component
1442 * @throws NullPointerException if p is null
1443 * @see #getLocation()
1444 * @see #setBounds(int, int, int, int)
1447 public void setLocation(Point p)
1449 setLocation(p.x, p.y);
1453 * Returns the size of this object.
1455 * @return the size of this object
1456 * @see #setSize(int, int)
1459 public Dimension getSize()
1465 * Returns the size of this object.
1467 * @return the size of this object
1468 * @deprecated use {@link #getSize()} instead
1470 public Dimension size()
1472 return new Dimension (width, height);
1476 * Sets the size of this component to the specified width and height.
1478 * @param width the new width of this component
1479 * @param height the new height of this component
1481 * @see #setBounds(int, int, int, int)
1483 public void setSize(int width, int height)
1485 resize (width, height);
1489 * Sets the size of this component to the specified value.
1491 * @param width the new width of the component
1492 * @param height the new height of the component
1493 * @deprecated use {@link #setSize(int, int)} instead
1495 public void resize(int width, int height)
1497 setBounds(this.x, this.y, width, height);
1501 * Sets the size of this component to the specified value.
1503 * @param d the new size of this component
1504 * @throws NullPointerException if d is null
1505 * @see #setSize(int, int)
1506 * @see #setBounds(int, int, int, int)
1509 public void setSize(Dimension d)
1515 * Sets the size of this component to the specified value.
1517 * @param d the new size of this component
1518 * @throws NullPointerException if d is null
1519 * @deprecated use {@link #setSize(Dimension)} instead
1521 public void resize(Dimension d)
1523 resize (d.width, d.height);
1527 * Returns a bounding rectangle for this component. Note that the
1528 * returned rectange is relative to this component's parent, not to
1531 * @return the bounding rectangle for this component
1532 * @see #setBounds(int, int, int, int)
1533 * @see #getLocation()
1536 public Rectangle getBounds()
1542 * Returns a bounding rectangle for this component. Note that the
1543 * returned rectange is relative to this component's parent, not to
1546 * @return the bounding rectangle for this component
1547 * @deprecated use {@link #getBounds()} instead
1549 public Rectangle bounds()
1551 return new Rectangle (x, y, width, height);
1555 * Sets the bounding rectangle for this component to the specified values.
1556 * Note that these coordinates are relative to the parent, not to the screen.
1558 * @param x the X coordinate of the upper left corner of the rectangle
1559 * @param y the Y coordinate of the upper left corner of the rectangle
1560 * @param w the width of the rectangle
1561 * @param h the height of the rectangle
1563 * @see #setLocation(int, int)
1564 * @see #setLocation(Point)
1565 * @see #setSize(int, int)
1566 * @see #setSize(Dimension)
1569 public void setBounds(int x, int y, int w, int h)
1571 reshape (x, y, w, h);
1575 * Sets the bounding rectangle for this component to the specified values.
1576 * Note that these coordinates are relative to the parent, not to the screen.
1578 * @param x the X coordinate of the upper left corner of the rectangle
1579 * @param y the Y coordinate of the upper left corner of the rectangle
1580 * @param width the width of the rectangle
1581 * @param height the height of the rectangle
1582 * @deprecated use {@link #setBounds(int, int, int, int)} instead
1584 public void reshape(int x, int y, int width, int height)
1586 // We need to lock the tree here, otherwise we risk races and
1588 synchronized (getTreeLock())
1592 int oldwidth = this.width;
1593 int oldheight = this.height;
1595 boolean resized = oldwidth != width || oldheight != height;
1596 boolean moved = oldx != x || oldy != y;
1598 if (resized || moved)
1600 // Update the fields.
1604 this.height = height;
1608 peer.setBounds (x, y, width, height);
1611 if (parent != null && parent.valid)
1612 parent.invalidate();
1615 // Send some events to interested listeners.
1616 notifyReshape(resized, moved);
1618 // Repaint this component and the parent if appropriate.
1619 if (parent != null && peer instanceof LightweightPeer
1622 // The parent repaints the area that we occupied before.
1623 parent.repaint(oldx, oldy, oldwidth, oldheight);
1624 // This component repaints the area that we occupy now.
1632 * Sends notification to interested listeners about resizing and/or moving
1633 * the component. If this component has interested
1634 * component listeners or the corresponding event mask enabled, then
1635 * COMPONENT_MOVED and/or COMPONENT_RESIZED events are posted to the event
1638 * @param resized true if the component has been resized, false otherwise
1639 * @param moved true if the component has been moved, false otherwise
1641 void notifyReshape(boolean resized, boolean moved)
1643 // Only post an event if this component actually has a listener
1644 // or has this event explicitly enabled.
1645 if (componentListener != null
1646 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1648 // Fire component event on this component.
1651 ComponentEvent ce = new ComponentEvent(this,
1652 ComponentEvent.COMPONENT_MOVED);
1653 getToolkit().getSystemEventQueue().postEvent(ce);
1657 ComponentEvent ce = new ComponentEvent(this,
1658 ComponentEvent.COMPONENT_RESIZED);
1659 getToolkit().getSystemEventQueue().postEvent(ce);
1665 * Sets the bounding rectangle for this component to the specified
1666 * rectangle. Note that these coordinates are relative to the parent, not
1669 * @param r the new bounding rectangle
1670 * @throws NullPointerException if r is null
1672 * @see #setLocation(Point)
1673 * @see #setSize(Dimension)
1676 public void setBounds(Rectangle r)
1678 setBounds (r.x, r.y, r.width, r.height);
1682 * Gets the x coordinate of the upper left corner. This is more efficient
1683 * than getBounds().x or getLocation().x.
1685 * @return the current x coordinate
1694 * Gets the y coordinate of the upper left corner. This is more efficient
1695 * than getBounds().y or getLocation().y.
1697 * @return the current y coordinate
1706 * Gets the width of the component. This is more efficient than
1707 * getBounds().width or getSize().width.
1709 * @return the current width
1712 public int getWidth()
1718 * Gets the height of the component. This is more efficient than
1719 * getBounds().height or getSize().height.
1721 * @return the current width
1724 public int getHeight()
1730 * Returns the bounds of this component. This allows reuse of an existing
1731 * rectangle, if r is non-null.
1733 * @param r the rectangle to use, or null
1734 * @return the bounds
1736 public Rectangle getBounds(Rectangle r)
1739 r = new Rectangle();
1748 * Returns the size of this component. This allows reuse of an existing
1749 * dimension, if d is non-null.
1751 * @param d the dimension to use, or null
1754 public Dimension getSize(Dimension d)
1757 d = new Dimension();
1764 * Returns the location of this component. This allows reuse of an existing
1765 * point, if p is non-null.
1767 * @param p the point to use, or null
1768 * @return the location
1770 public Point getLocation(Point p)
1780 * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1781 * components are opaque. A component is opaque if it draws all pixels in
1782 * the bounds; a lightweight component is partially transparent if it lets
1783 * pixels underneath show through. Subclasses that guarantee that all pixels
1784 * will be drawn should override this.
1786 * @return true if this is opaque
1787 * @see #isLightweight()
1790 public boolean isOpaque()
1792 return ! isLightweight();
1796 * Return whether the component is lightweight. That means the component has
1797 * no native peer, but is displayable. This applies to subclasses of
1798 * Component not in this package, such as javax.swing.
1800 * @return true if the component has a lightweight peer
1801 * @see #isDisplayable()
1804 public boolean isLightweight()
1806 return peer instanceof LightweightPeer;
1810 * Returns the component's preferred size.
1812 * @return the component's preferred size
1813 * @see #getMinimumSize()
1814 * @see #setPreferredSize(Dimension)
1815 * @see LayoutManager
1817 public Dimension getPreferredSize()
1819 return preferredSize();
1823 * Sets the preferred size that will be returned by
1824 * {@link #getPreferredSize()} always, and sends a
1825 * {@link PropertyChangeEvent} (with the property name 'preferredSize') to
1826 * all registered listeners.
1828 * @param size the preferred size (<code>null</code> permitted).
1832 * @see #getPreferredSize()
1834 public void setPreferredSize(Dimension size)
1836 Dimension old = prefSizeSet ? prefSize : null;
1838 prefSizeSet = (size != null);
1839 firePropertyChange("preferredSize", old, size);
1843 * Returns <code>true</code> if the current preferred size is not
1844 * <code>null</code> and was set by a call to
1845 * {@link #setPreferredSize(Dimension)}, otherwise returns <code>false</code>.
1847 * @return A boolean.
1851 public boolean isPreferredSizeSet()
1857 * Returns the component's preferred size.
1859 * @return the component's preferred size
1860 * @deprecated use {@link #getPreferredSize()} instead
1862 public Dimension preferredSize()
1864 // Create a new Dimension object, so that the application doesn't mess
1865 // with the actual values.
1866 return new Dimension(preferredSizeImpl());
1870 * The actual calculation is pulled out of preferredSize() so that
1871 * we can call it from Container.preferredSize() and avoid creating a
1872 * new intermediate Dimension object.
1874 * @return the preferredSize of the component
1876 Dimension preferredSizeImpl()
1878 Dimension size = prefSize;
1879 // Try to use a cached value.
1880 if (size == null || !(valid || prefSizeSet))
1882 // We need to lock here, because the calculation depends on the
1883 // component structure not changing.
1884 synchronized (getTreeLock())
1886 ComponentPeer p = peer;
1888 size = peer.preferredSize();
1890 size = minimumSizeImpl();
1897 * Returns the component's minimum size.
1899 * @return the component's minimum size
1900 * @see #getPreferredSize()
1901 * @see #setMinimumSize(Dimension)
1902 * @see LayoutManager
1904 public Dimension getMinimumSize()
1906 return minimumSize();
1910 * Sets the minimum size that will be returned by {@link #getMinimumSize()}
1911 * always, and sends a {@link PropertyChangeEvent} (with the property name
1912 * 'minimumSize') to all registered listeners.
1914 * @param size the minimum size (<code>null</code> permitted).
1918 * @see #getMinimumSize()
1920 public void setMinimumSize(Dimension size)
1922 Dimension old = minSizeSet ? minSize : null;
1924 minSizeSet = (size != null);
1925 firePropertyChange("minimumSize", old, size);
1929 * Returns <code>true</code> if the current minimum size is not
1930 * <code>null</code> and was set by a call to
1931 * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
1933 * @return A boolean.
1937 public boolean isMinimumSizeSet()
1943 * Returns the component's minimum size.
1945 * @return the component's minimum size
1946 * @deprecated use {@link #getMinimumSize()} instead
1948 public Dimension minimumSize()
1950 // Create a new Dimension object, so that the application doesn't mess
1951 // with the actual values.
1952 return new Dimension(minimumSizeImpl());
1956 * The actual calculation is pulled out of minimumSize() so that
1957 * we can call it from Container.preferredSize() and
1958 * Component.preferredSizeImpl and avoid creating a
1959 * new intermediate Dimension object.
1961 * @return the minimum size of the component
1963 Dimension minimumSizeImpl()
1965 Dimension size = minSize;
1966 if (size == null || !(valid || minSizeSet))
1968 // We need to lock here, because the calculation depends on the
1969 // component structure not changing.
1970 synchronized (getTreeLock())
1972 ComponentPeer p = peer;
1974 size = peer.minimumSize();
1983 * Returns the component's maximum size.
1985 * @return the component's maximum size
1986 * @see #getMinimumSize()
1987 * @see #setMaximumSize(Dimension)
1988 * @see #getPreferredSize()
1989 * @see LayoutManager
1991 public Dimension getMaximumSize()
1993 return new Dimension(maximumSizeImpl());
1997 * This is pulled out from getMaximumSize(), so that we can access it
1998 * from Container.getMaximumSize() without creating an additional
1999 * intermediate Dimension object.
2001 * @return the maximum size of the component
2003 Dimension maximumSizeImpl()
2009 size = DEFAULT_MAX_SIZE;
2014 * Sets the maximum size that will be returned by {@link #getMaximumSize()}
2015 * always, and sends a {@link PropertyChangeEvent} (with the property name
2016 * 'maximumSize') to all registered listeners.
2018 * @param size the maximum size (<code>null</code> permitted).
2022 * @see #getMaximumSize()
2024 public void setMaximumSize(Dimension size)
2026 Dimension old = maxSizeSet ? maxSize : null;
2028 maxSizeSet = (size != null);
2029 firePropertyChange("maximumSize", old, size);
2033 * Returns <code>true</code> if the current maximum size is not
2034 * <code>null</code> and was set by a call to
2035 * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
2037 * @return A boolean.
2041 public boolean isMaximumSizeSet()
2047 * Returns the preferred horizontal alignment of this component. The value
2048 * returned will be between {@link #LEFT_ALIGNMENT} and
2049 * {@link #RIGHT_ALIGNMENT}, inclusive.
2051 * @return the preferred horizontal alignment of this component
2053 public float getAlignmentX()
2055 return CENTER_ALIGNMENT;
2059 * Returns the preferred vertical alignment of this component. The value
2060 * returned will be between {@link #TOP_ALIGNMENT} and
2061 * {@link #BOTTOM_ALIGNMENT}, inclusive.
2063 * @return the preferred vertical alignment of this component
2065 public float getAlignmentY()
2067 return CENTER_ALIGNMENT;
2071 * Calls the layout manager to re-layout the component. This is called
2072 * during validation of a container in most cases.
2075 * @see LayoutManager
2077 public void doLayout()
2083 * Calls the layout manager to re-layout the component. This is called
2084 * during validation of a container in most cases.
2086 * @deprecated use {@link #doLayout()} instead
2088 public void layout()
2090 // Nothing to do unless we're a container.
2094 * Called to ensure that the layout for this component is valid. This is
2095 * usually called on containers.
2097 * @see #invalidate()
2099 * @see LayoutManager
2100 * @see Container#validate()
2102 public void validate()
2106 // Synchronize on the tree here as this might change the layout
2107 // of the hierarchy.
2108 synchronized (getTreeLock())
2110 // Create local variables for thread safety.
2111 ComponentPeer p = peer;
2114 // Possibly update the peer's font.
2115 Font newFont = getFont();
2116 Font oldFont = peerFont;
2117 // Only update when the font really changed.
2118 if (newFont != oldFont
2119 && (oldFont == null || ! oldFont.equals(newFont)))
2124 // Let the peer perform any layout.
2133 * Invalidates this component and all of its parent components. This will
2134 * cause them to have their layout redone. This is called frequently, so
2137 public void invalidate()
2139 // Need to lock here, to avoid races and other ugly stuff when doing
2140 // layout or structure changes in other threads.
2141 synchronized (getTreeLock())
2146 // Throw away cached layout information.
2154 // Also invalidate the parent, if it hasn't already been invalidated.
2155 if (parent != null && parent.isValid())
2156 parent.invalidate();
2161 * Returns a graphics object for this component. Returns <code>null</code>
2162 * if this component is not currently displayed on the screen.
2164 * @return a graphics object for this component
2165 * @see #paint(Graphics)
2167 public Graphics getGraphics()
2169 // Only heavyweight peers can handle this.
2170 ComponentPeer p = peer;
2172 if (p instanceof LightweightPeer)
2176 g = parent.getGraphics();
2180 g.setClip(0, 0, width, height);
2181 g.setFont(getFont());
2188 g = p.getGraphics();
2194 * Returns the font metrics for the specified font in this component.
2196 * @param font the font to retrieve metrics for
2197 * @return the font metrics for the specified font
2198 * @throws NullPointerException if font is null
2200 * @see Toolkit#getFontMetrics(Font)
2202 public FontMetrics getFontMetrics(Font font)
2204 ComponentPeer p = peer;
2205 Component comp = this;
2206 while (p instanceof LightweightPeer)
2209 p = comp == null ? null : comp.peer;
2212 return p == null ? getToolkit().getFontMetrics(font)
2213 : p.getFontMetrics(font);
2217 * Sets the cursor for this component to the specified cursor. The cursor
2218 * is displayed when the point is contained by the component, and the
2219 * component is visible, displayable, and enabled. This is inherited by
2220 * subcomponents unless they set their own cursor.
2222 * @param cursor the new cursor for this component
2226 * @see #contains(int, int)
2227 * @see Toolkit#createCustomCursor(Image, Point, String)
2229 public void setCursor(Cursor cursor)
2231 this.cursor = cursor;
2233 // Only heavyweight peers handle this.
2234 ComponentPeer p = peer;
2235 Component comp = this;
2236 while (p instanceof LightweightPeer)
2239 p = comp == null ? null : comp.peer;
2243 p.setCursor(cursor);
2247 * Returns the cursor for this component. If not set, this is inherited
2248 * from the parent, or from Cursor.getDefaultCursor().
2250 * @return the cursor for this component
2252 public Cursor getCursor()
2256 return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
2260 * Tests if the cursor was explicitly set, or just inherited from the parent.
2262 * @return true if the cursor has been set
2265 public boolean isCursorSet()
2267 return cursor != null;
2271 * Paints this component on the screen. The clipping region in the graphics
2272 * context will indicate the region that requires painting. This is called
2273 * whenever the component first shows, or needs to be repaired because
2274 * something was temporarily drawn on top. It is not necessary for
2275 * subclasses to call <code>super.paint(g)</code>. Components with no area
2278 * @param g the graphics context for this paint job
2279 * @see #update(Graphics)
2281 public void paint(Graphics g)
2283 // This is a callback method and is meant to be overridden by subclasses
2284 // that want to perform custom painting.
2288 * Updates this component. This is called for heavyweight components in
2289 * response to {@link #repaint()}. The default implementation simply forwards
2290 * to {@link #paint(Graphics)}. The coordinates of the graphics are
2291 * relative to this component. Subclasses should call either
2292 * <code>super.update(g)</code> or <code>paint(g)</code>.
2294 * @param g the graphics context for this update
2296 * @see #paint(Graphics)
2299 public void update(Graphics g)
2301 // Note 1: We used to clear the background here for lightweights and
2302 // toplevel components. Tests show that this is not what the JDK does
2303 // here. Note that there is some special handling and background
2304 // clearing code in Container.update(Graphics).
2306 // Note 2 (for peer implementors): The JDK doesn't seem call update() for
2307 // toplevel components, even when an UPDATE event is sent (as a result
2313 * Paints this entire component, including any sub-components.
2315 * @param g the graphics context for this paint job
2317 * @see #paint(Graphics)
2319 public void paintAll(Graphics g)
2324 if (peer instanceof LightweightPeer)
2332 * Repaint this entire component. The <code>update()</code> method
2333 * on this component will be called as soon as possible.
2335 * @see #update(Graphics)
2336 * @see #repaint(long, int, int, int, int)
2338 public void repaint()
2340 repaint(0, 0, 0, width, height);
2344 * Repaint this entire component. The <code>update()</code> method on this
2345 * component will be called in approximate the specified number of
2348 * @param tm milliseconds before this component should be repainted
2349 * @see #paint(Graphics)
2350 * @see #repaint(long, int, int, int, int)
2352 public void repaint(long tm)
2354 repaint(tm, 0, 0, width, height);
2358 * Repaints the specified rectangular region within this component. The
2359 * <code>update</code> method on this component will be called as soon as
2360 * possible. The coordinates are relative to this component.
2362 * @param x the X coordinate of the upper left of the region to repaint
2363 * @param y the Y coordinate of the upper left of the region to repaint
2364 * @param w the width of the region to repaint
2365 * @param h the height of the region to repaint
2366 * @see #update(Graphics)
2367 * @see #repaint(long, int, int, int, int)
2369 public void repaint(int x, int y, int w, int h)
2371 repaint(0, x, y, w, h);
2375 * Repaints the specified rectangular region within this component. The
2376 * <code>update</code> method on this component will be called in
2377 * approximately the specified number of milliseconds. The coordinates
2378 * are relative to this component.
2380 * @param tm milliseconds before this component should be repainted
2381 * @param x the X coordinate of the upper left of the region to repaint
2382 * @param y the Y coordinate of the upper left of the region to repaint
2383 * @param width the width of the region to repaint
2384 * @param height the height of the region to repaint
2385 * @see #update(Graphics)
2387 public void repaint(long tm, int x, int y, int width, int height)
2389 // The repaint() call has previously been delegated to
2390 // {@link ComponentPeer.repaint()}. Testing on the JDK using some
2391 // dummy peers show that this methods is never called. I think it makes
2392 // sense to actually perform the tasks below here, since it's pretty
2393 // much peer independent anyway, and makes sure only heavyweights are
2394 // bothered by this.
2395 ComponentPeer p = peer;
2397 // Let the nearest heavyweight parent handle repainting for lightweight
2399 // We need to recursivly call repaint() on the parent here, since
2400 // a (lightweight) parent component might have overridden repaint()
2401 // to perform additional custom tasks.
2403 if (p instanceof LightweightPeer)
2405 // We perform some boundary checking to restrict the paint
2406 // region to this component.
2409 int px = this.x + Math.max(0, x);
2410 int py = this.y + Math.max(0, y);
2411 int pw = Math.min(this.width, width);
2412 int ph = Math.min(this.height, height);
2413 parent.repaint(tm, px, py, pw, ph);
2418 // Now send an UPDATE event to the heavyweight component that we've found.
2419 if (isVisible() && p != null && width > 0 && height > 0)
2421 PaintEvent pe = new PaintEvent(this, PaintEvent.UPDATE,
2422 new Rectangle(x, y, width, height));
2423 getToolkit().getSystemEventQueue().postEvent(pe);
2429 * Prints this component. This method is provided so that printing can be
2430 * done in a different manner from painting. However, the implementation
2431 * in this class simply calls the <code>paint()</code> method.
2433 * @param g the graphics context of the print device
2435 * @see #paint(Graphics)
2437 public void print(Graphics g)
2443 * Prints this component, including all sub-components.
2445 * @param g the graphics context of the print device
2447 * @see #paintAll(Graphics)
2449 public void printAll(Graphics g)
2457 * Called when an image has changed so that this component is repainted.
2458 * This incrementally draws an image as more bits are available, when
2459 * possible. Incremental drawing is enabled if the system property
2460 * <code>awt.image.incrementalDraw</code> is not present or is true, in which
2461 * case the redraw rate is set to 100ms or the value of the system property
2462 * <code>awt.image.redrawrate</code>.
2464 * <p>The coordinate system used depends on the particular flags.
2466 * @param img the image that has been updated
2467 * @param flags tlags as specified in <code>ImageObserver</code>
2468 * @param x the X coordinate
2469 * @param y the Y coordinate
2470 * @param w the width
2471 * @param h the height
2472 * @return false if the image is completely loaded, loading has been
2473 * aborted, or an error has occurred. true if more updates are
2475 * @see ImageObserver
2476 * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
2477 * @see Graphics#drawImage(Image, int, int, ImageObserver)
2478 * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
2479 * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
2480 * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2482 public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2484 if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2486 else if ((flags & SOMEBITS) != 0)
2488 if (incrementalDraw)
2490 if (redrawRate != null)
2492 long tm = redrawRate.longValue();
2501 return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2505 * Creates an image from the specified producer.
2507 * @param producer the image procedure to create the image from
2508 * @return the resulting image
2510 public Image createImage(ImageProducer producer)
2512 // Only heavyweight peers can handle this.
2513 ComponentPeer p = peer;
2514 Component comp = this;
2515 while (p instanceof LightweightPeer)
2518 p = comp == null ? null : comp.peer;
2521 // Sun allows producer to be null.
2524 im = p.createImage(producer);
2526 im = getToolkit().createImage(producer);
2531 * Creates an image with the specified width and height for use in
2532 * double buffering. Headless environments do not support images.
2534 * @param width the width of the image
2535 * @param height the height of the image
2536 * @return the requested image, or null if it is not supported
2538 public Image createImage (int width, int height)
2540 Image returnValue = null;
2541 if (!GraphicsEnvironment.isHeadless ())
2543 // Only heavyweight peers can handle this.
2544 ComponentPeer p = peer;
2545 Component comp = this;
2546 while (p instanceof LightweightPeer)
2549 p = comp == null ? null : comp.peer;
2553 returnValue = p.createImage(width, height);
2559 * Creates an image with the specified width and height for use in
2560 * double buffering. Headless environments do not support images.
2562 * @param width the width of the image
2563 * @param height the height of the image
2564 * @return the requested image, or null if it is not supported
2567 public VolatileImage createVolatileImage(int width, int height)
2569 // Only heavyweight peers can handle this.
2570 ComponentPeer p = peer;
2571 Component comp = this;
2572 while (p instanceof LightweightPeer)
2575 p = comp == null ? null : comp.peer;
2578 VolatileImage im = null;
2580 im = p.createVolatileImage(width, height);
2585 * Creates an image with the specified width and height for use in
2586 * double buffering. Headless environments do not support images. The image
2587 * will support the specified capabilities.
2589 * @param width the width of the image
2590 * @param height the height of the image
2591 * @param caps the requested capabilities
2592 * @return the requested image, or null if it is not supported
2593 * @throws AWTException if a buffer with the capabilities cannot be created
2596 public VolatileImage createVolatileImage(int width, int height,
2597 ImageCapabilities caps)
2600 // Only heavyweight peers can handle this.
2601 ComponentPeer p = peer;
2602 Component comp = this;
2603 while (p instanceof LightweightPeer)
2606 p = comp == null ? null : comp.peer;
2609 VolatileImage im = null;
2611 im = peer.createVolatileImage(width, height);
2616 * Prepares the specified image for rendering on this component.
2618 * @param image the image to prepare for rendering
2619 * @param observer the observer to notify of image preparation status
2620 * @return true if the image is already fully prepared
2621 * @throws NullPointerException if image is null
2623 public boolean prepareImage(Image image, ImageObserver observer)
2625 return prepareImage(image, image.getWidth(observer),
2626 image.getHeight(observer), observer);
2630 * Prepares the specified image for rendering on this component at the
2631 * specified scaled width and height
2633 * @param image the image to prepare for rendering
2634 * @param width the scaled width of the image
2635 * @param height the scaled height of the image
2636 * @param observer the observer to notify of image preparation status
2637 * @return true if the image is already fully prepared
2639 public boolean prepareImage(Image image, int width, int height,
2640 ImageObserver observer)
2642 // Only heavyweight peers handle this.
2643 ComponentPeer p = peer;
2644 Component comp = this;
2645 while (p instanceof LightweightPeer)
2648 p = comp == null ? null : comp.peer;
2653 retval = p.prepareImage(image, width, height, observer);
2655 retval = getToolkit().prepareImage(image, width, height, observer);
2660 * Returns the status of the loading of the specified image. The value
2661 * returned will be those flags defined in <code>ImageObserver</code>.
2663 * @param image the image to check on
2664 * @param observer the observer to notify of image loading progress
2665 * @return the image observer flags indicating the status of the load
2666 * @see #prepareImage(Image, int, int, ImageObserver)
2667 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2668 * @throws NullPointerException if image is null
2670 public int checkImage(Image image, ImageObserver observer)
2672 return checkImage(image, -1, -1, observer);
2676 * Returns the status of the loading of the specified image. The value
2677 * returned will be those flags defined in <code>ImageObserver</code>.
2679 * @param image the image to check on
2680 * @param width the scaled image width
2681 * @param height the scaled image height
2682 * @param observer the observer to notify of image loading progress
2683 * @return the image observer flags indicating the status of the load
2684 * @see #prepareImage(Image, int, int, ImageObserver)
2685 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2687 public int checkImage(Image image, int width, int height,
2688 ImageObserver observer)
2690 // Only heavyweight peers handle this.
2691 ComponentPeer p = peer;
2692 Component comp = this;
2693 while (p instanceof LightweightPeer)
2696 p = comp == null ? null : comp.peer;
2701 retval = p.checkImage(image, width, height, observer);
2703 retval = getToolkit().checkImage(image, width, height, observer);
2708 * Sets whether paint messages delivered by the operating system should be
2709 * ignored. This does not affect messages from AWT, except for those
2710 * triggered by OS messages. Setting this to true can allow faster
2711 * performance in full-screen mode or page-flipping.
2713 * @param ignoreRepaint the new setting for ignoring repaint events
2714 * @see #getIgnoreRepaint()
2715 * @see BufferStrategy
2716 * @see GraphicsDevice#setFullScreenWindow(Window)
2719 public void setIgnoreRepaint(boolean ignoreRepaint)
2721 this.ignoreRepaint = ignoreRepaint;
2725 * Test whether paint events from the operating system are ignored.
2727 * @return the status of ignoring paint events
2728 * @see #setIgnoreRepaint(boolean)
2731 public boolean getIgnoreRepaint()
2733 return ignoreRepaint;
2737 * Tests whether or not the specified point is contained within this
2738 * component. Coordinates are relative to this component.
2740 * @param x the X coordinate of the point to test
2741 * @param y the Y coordinate of the point to test
2742 * @return true if the point is within this component
2743 * @see #getComponentAt(int, int)
2745 public boolean contains(int x, int y)
2747 return inside (x, y);
2751 * Tests whether or not the specified point is contained within this
2752 * component. Coordinates are relative to this component.
2754 * @param x the X coordinate of the point to test
2755 * @param y the Y coordinate of the point to test
2756 * @return true if the point is within this component
2757 * @deprecated use {@link #contains(int, int)} instead
2759 public boolean inside(int x, int y)
2761 return x >= 0 && y >= 0 && x < width && y < height;
2765 * Tests whether or not the specified point is contained within this
2766 * component. Coordinates are relative to this component.
2768 * @param p the point to test
2769 * @return true if the point is within this component
2770 * @throws NullPointerException if p is null
2771 * @see #getComponentAt(Point)
2774 public boolean contains(Point p)
2776 return contains (p.x, p.y);
2780 * Returns the component occupying the position (x,y). This will either
2781 * be this component, an immediate child component, or <code>null</code>
2782 * if neither of the first two occupies the specified location.
2784 * @param x the X coordinate to search for components at
2785 * @param y the Y coordinate to search for components at
2786 * @return the component at the specified location, or null
2787 * @see #contains(int, int)
2789 public Component getComponentAt(int x, int y)
2791 return locate (x, y);
2795 * Returns the component occupying the position (x,y). This will either
2796 * be this component, an immediate child component, or <code>null</code>
2797 * if neither of the first two occupies the specified location.
2799 * @param x the X coordinate to search for components at
2800 * @param y the Y coordinate to search for components at
2801 * @return the component at the specified location, or null
2802 * @deprecated use {@link #getComponentAt(int, int)} instead
2804 public Component locate(int x, int y)
2806 return contains (x, y) ? this : null;
2810 * Returns the component occupying the position (x,y). This will either
2811 * be this component, an immediate child component, or <code>null</code>
2812 * if neither of the first two occupies the specified location.
2814 * @param p the point to search for components at
2815 * @return the component at the specified location, or null
2816 * @throws NullPointerException if p is null
2817 * @see #contains(Point)
2820 public Component getComponentAt(Point p)
2822 return getComponentAt (p.x, p.y);
2826 * AWT 1.0 event delivery.
2828 * Deliver an AWT 1.0 event to this Component. This method simply
2829 * calls {@link #postEvent}.
2831 * @param e the event to deliver
2832 * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2834 public void deliverEvent (Event e)
2840 * Forwards AWT events to processEvent() if:<ul>
2841 * <li>Events have been enabled for this type of event via
2842 * <code>enableEvents()</code></li>,
2843 * <li>There is at least one registered listener for this type of event</li>
2846 * @param e the event to dispatch
2848 public final void dispatchEvent(AWTEvent e)
2850 // Some subclasses in the AWT package need to override this behavior,
2851 // hence the use of dispatchEventImpl().
2852 dispatchEventImpl(e);
2856 * By default, no old mouse events should be ignored.
2857 * This can be overridden by subclasses.
2859 * @return false, no mouse events are ignored.
2861 static boolean ignoreOldMouseEvents()
2867 * AWT 1.0 event handler.
2869 * This method simply calls handleEvent and returns the result.
2871 * @param e the event to handle
2872 * @return true if the event was handled, false otherwise
2873 * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2875 public boolean postEvent (Event e)
2877 boolean handled = handleEvent (e);
2879 if (!handled && getParent() != null)
2880 // FIXME: need to translate event coordinates to parent's
2881 // coordinate space.
2882 handled = getParent ().postEvent (e);
2888 * Adds the specified listener to this component. This is harmless if the
2889 * listener is null, but if the listener has already been registered, it
2890 * will now be registered twice.
2892 * @param listener the new listener to add
2893 * @see ComponentEvent
2894 * @see #removeComponentListener(ComponentListener)
2895 * @see #getComponentListeners()
2898 public synchronized void addComponentListener(ComponentListener listener)
2900 if (listener != null)
2902 componentListener = AWTEventMulticaster.add(componentListener,
2904 newEventsOnly = true;
2909 * Removes the specified listener from the component. This is harmless if
2910 * the listener was not previously registered.
2912 * @param listener the listener to remove
2913 * @see ComponentEvent
2914 * @see #addComponentListener(ComponentListener)
2915 * @see #getComponentListeners()
2918 public synchronized void removeComponentListener(ComponentListener listener)
2920 componentListener = AWTEventMulticaster.remove(componentListener, listener);
2924 * Returns an array of all specified listeners registered on this component.
2926 * @return an array of listeners
2927 * @see #addComponentListener(ComponentListener)
2928 * @see #removeComponentListener(ComponentListener)
2931 public synchronized ComponentListener[] getComponentListeners()
2933 return (ComponentListener[])
2934 AWTEventMulticaster.getListeners(componentListener,
2935 ComponentListener.class);
2939 * Adds the specified listener to this component. This is harmless if the
2940 * listener is null, but if the listener has already been registered, it
2941 * will now be registered twice.
2943 * @param listener the new listener to add
2945 * @see #removeFocusListener(FocusListener)
2946 * @see #getFocusListeners()
2949 public synchronized void addFocusListener(FocusListener listener)
2951 if (listener != null)
2953 focusListener = AWTEventMulticaster.add(focusListener, listener);
2954 newEventsOnly = true;
2959 * Removes the specified listener from the component. This is harmless if
2960 * the listener was not previously registered.
2962 * @param listener the listener to remove
2964 * @see #addFocusListener(FocusListener)
2965 * @see #getFocusListeners()
2968 public synchronized void removeFocusListener(FocusListener listener)
2970 focusListener = AWTEventMulticaster.remove(focusListener, listener);
2974 * Returns an array of all specified listeners registered on this component.
2976 * @return an array of listeners
2977 * @see #addFocusListener(FocusListener)
2978 * @see #removeFocusListener(FocusListener)
2981 public synchronized FocusListener[] getFocusListeners()
2983 return (FocusListener[])
2984 AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2988 * Adds the specified listener to this component. This is harmless if the
2989 * listener is null, but if the listener has already been registered, it
2990 * will now be registered twice.
2992 * @param listener the new listener to add
2993 * @see HierarchyEvent
2994 * @see #removeHierarchyListener(HierarchyListener)
2995 * @see #getHierarchyListeners()
2998 public synchronized void addHierarchyListener(HierarchyListener listener)
3000 if (listener != null)
3002 hierarchyListener = AWTEventMulticaster.add(hierarchyListener,
3004 newEventsOnly = true;
3005 // Need to lock the tree, otherwise we might end up inconsistent.
3006 synchronized (getTreeLock())
3008 numHierarchyListeners++;
3010 parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3017 * Removes the specified listener from the component. This is harmless if
3018 * the listener was not previously registered.
3020 * @param listener the listener to remove
3021 * @see HierarchyEvent
3022 * @see #addHierarchyListener(HierarchyListener)
3023 * @see #getHierarchyListeners()
3026 public synchronized void removeHierarchyListener(HierarchyListener listener)
3028 hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
3030 // Need to lock the tree, otherwise we might end up inconsistent.
3031 synchronized (getTreeLock())
3033 numHierarchyListeners--;
3035 parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3041 * Returns an array of all specified listeners registered on this component.
3043 * @return an array of listeners
3044 * @see #addHierarchyListener(HierarchyListener)
3045 * @see #removeHierarchyListener(HierarchyListener)
3048 public synchronized HierarchyListener[] getHierarchyListeners()
3050 return (HierarchyListener[])
3051 AWTEventMulticaster.getListeners(hierarchyListener,
3052 HierarchyListener.class);
3056 * Adds the specified listener to this component. This is harmless if the
3057 * listener is null, but if the listener has already been registered, it
3058 * will now be registered twice.
3060 * @param listener the new listener to add
3061 * @see HierarchyEvent
3062 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3063 * @see #getHierarchyBoundsListeners()
3066 public synchronized void
3067 addHierarchyBoundsListener(HierarchyBoundsListener listener)
3069 if (listener != null)
3071 hierarchyBoundsListener =
3072 AWTEventMulticaster.add(hierarchyBoundsListener, listener);
3073 newEventsOnly = true;
3075 // Need to lock the tree, otherwise we might end up inconsistent.
3076 synchronized (getTreeLock())
3078 numHierarchyBoundsListeners++;
3080 parent.updateHierarchyListenerCount
3081 (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
3087 * Removes the specified listener from the component. This is harmless if
3088 * the listener was not previously registered.
3090 * @param listener the listener to remove
3091 * @see HierarchyEvent
3092 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3093 * @see #getHierarchyBoundsListeners()
3096 public synchronized void
3097 removeHierarchyBoundsListener(HierarchyBoundsListener listener)
3099 hierarchyBoundsListener =
3100 AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
3102 // Need to lock the tree, otherwise we might end up inconsistent.
3103 synchronized (getTreeLock())
3105 numHierarchyBoundsListeners--;
3107 parent.updateHierarchyListenerCount
3108 (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3114 * Returns an array of all specified listeners registered on this component.
3116 * @return an array of listeners
3117 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3118 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3121 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
3123 return (HierarchyBoundsListener[])
3124 AWTEventMulticaster.getListeners(hierarchyBoundsListener,
3125 HierarchyBoundsListener.class);
3129 * Fires a HierarchyEvent or HierarchyChangeEvent on this component.
3131 * @param id the event id
3132 * @param changed the changed component
3133 * @param parent the parent
3134 * @param flags the event flags
3136 void fireHierarchyEvent(int id, Component changed, Container parent,
3139 boolean enabled = false;
3142 case HierarchyEvent.HIERARCHY_CHANGED:
3143 enabled = hierarchyListener != null
3144 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0;
3146 case HierarchyEvent.ANCESTOR_MOVED:
3147 case HierarchyEvent.ANCESTOR_RESIZED:
3148 enabled = hierarchyBoundsListener != null
3149 || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0;
3152 assert false : "Should not reach here";
3156 HierarchyEvent ev = new HierarchyEvent(this, id, changed, parent,
3163 * Adds the specified listener to this component. This is harmless if the
3164 * listener is null, but if the listener has already been registered, it
3165 * will now be registered twice.
3167 * @param listener the new listener to add
3169 * @see #removeKeyListener(KeyListener)
3170 * @see #getKeyListeners()
3173 public synchronized void addKeyListener(KeyListener listener)
3175 if (listener != null)
3177 keyListener = AWTEventMulticaster.add(keyListener, listener);
3178 newEventsOnly = true;
3183 * Removes the specified listener from the component. This is harmless if
3184 * the listener was not previously registered.
3186 * @param listener the listener to remove
3188 * @see #addKeyListener(KeyListener)
3189 * @see #getKeyListeners()
3192 public synchronized void removeKeyListener(KeyListener listener)
3194 keyListener = AWTEventMulticaster.remove(keyListener, listener);
3198 * Returns an array of all specified listeners registered on this component.
3200 * @return an array of listeners
3201 * @see #addKeyListener(KeyListener)
3202 * @see #removeKeyListener(KeyListener)
3205 public synchronized KeyListener[] getKeyListeners()
3207 return (KeyListener[])
3208 AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
3212 * Adds the specified listener to this component. This is harmless if the
3213 * listener is null, but if the listener has already been registered, it
3214 * will now be registered twice.
3216 * @param listener the new listener to add
3218 * @see #removeMouseListener(MouseListener)
3219 * @see #getMouseListeners()
3222 public synchronized void addMouseListener(MouseListener listener)
3224 if (listener != null)
3226 mouseListener = AWTEventMulticaster.add(mouseListener, listener);
3227 newEventsOnly = true;
3232 * Removes the specified listener from the component. This is harmless if
3233 * the listener was not previously registered.
3235 * @param listener the listener to remove
3237 * @see #addMouseListener(MouseListener)
3238 * @see #getMouseListeners()
3241 public synchronized void removeMouseListener(MouseListener listener)
3243 mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
3247 * Returns an array of all specified listeners registered on this component.
3249 * @return an array of listeners
3250 * @see #addMouseListener(MouseListener)
3251 * @see #removeMouseListener(MouseListener)
3254 public synchronized MouseListener[] getMouseListeners()
3256 return (MouseListener[])
3257 AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
3261 * Adds the specified listener to this component. This is harmless if the
3262 * listener is null, but if the listener has already been registered, it
3263 * will now be registered twice.
3265 * @param listener the new listener to add
3267 * @see #removeMouseMotionListener(MouseMotionListener)
3268 * @see #getMouseMotionListeners()
3271 public synchronized void addMouseMotionListener(MouseMotionListener listener)
3273 if (listener != null)
3275 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,
3277 newEventsOnly = true;
3282 * Removes the specified listener from the component. This is harmless if
3283 * the listener was not previously registered.
3285 * @param listener the listener to remove
3287 * @see #addMouseMotionListener(MouseMotionListener)
3288 * @see #getMouseMotionListeners()
3291 public synchronized void removeMouseMotionListener(MouseMotionListener listener)
3293 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
3297 * Returns an array of all specified listeners registered on this component.
3299 * @return an array of listeners
3300 * @see #addMouseMotionListener(MouseMotionListener)
3301 * @see #removeMouseMotionListener(MouseMotionListener)
3304 public synchronized MouseMotionListener[] getMouseMotionListeners()
3306 return (MouseMotionListener[])
3307 AWTEventMulticaster.getListeners(mouseMotionListener,
3308 MouseMotionListener.class);
3312 * Adds the specified listener to this component. This is harmless if the
3313 * listener is null, but if the listener has already been registered, it
3314 * will now be registered twice.
3316 * @param listener the new listener to add
3318 * @see MouseWheelEvent
3319 * @see #removeMouseWheelListener(MouseWheelListener)
3320 * @see #getMouseWheelListeners()
3323 public synchronized void addMouseWheelListener(MouseWheelListener listener)
3325 if (listener != null)
3327 mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,
3329 newEventsOnly = true;
3334 * Removes the specified listener from the component. This is harmless if
3335 * the listener was not previously registered.
3337 * @param listener the listener to remove
3339 * @see MouseWheelEvent
3340 * @see #addMouseWheelListener(MouseWheelListener)
3341 * @see #getMouseWheelListeners()
3344 public synchronized void removeMouseWheelListener(MouseWheelListener listener)
3346 mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
3350 * Returns an array of all specified listeners registered on this component.
3352 * @return an array of listeners
3353 * @see #addMouseWheelListener(MouseWheelListener)
3354 * @see #removeMouseWheelListener(MouseWheelListener)
3357 public synchronized MouseWheelListener[] getMouseWheelListeners()
3359 return (MouseWheelListener[])
3360 AWTEventMulticaster.getListeners(mouseWheelListener,
3361 MouseWheelListener.class);
3365 * Adds the specified listener to this component. This is harmless if the
3366 * listener is null, but if the listener has already been registered, it
3367 * will now be registered twice.
3369 * @param listener the new listener to add
3370 * @see InputMethodEvent
3371 * @see #removeInputMethodListener(InputMethodListener)
3372 * @see #getInputMethodListeners()
3373 * @see #getInputMethodRequests()
3376 public synchronized void addInputMethodListener(InputMethodListener listener)
3378 if (listener != null)
3380 inputMethodListener = AWTEventMulticaster.add(inputMethodListener,
3382 newEventsOnly = true;
3387 * Removes the specified listener from the component. This is harmless if
3388 * the listener was not previously registered.
3390 * @param listener the listener to remove
3391 * @see InputMethodEvent
3392 * @see #addInputMethodListener(InputMethodListener)
3393 * @see #getInputMethodRequests()
3396 public synchronized void removeInputMethodListener(InputMethodListener listener)
3398 inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
3402 * Returns an array of all specified listeners registered on this component.
3404 * @return an array of listeners
3405 * @see #addInputMethodListener(InputMethodListener)
3406 * @see #removeInputMethodListener(InputMethodListener)
3409 public synchronized InputMethodListener[] getInputMethodListeners()
3411 return (InputMethodListener[])
3412 AWTEventMulticaster.getListeners(inputMethodListener,
3413 InputMethodListener.class);
3417 * Returns all registered {@link EventListener}s of the given
3418 * <code>listenerType</code>.
3420 * @param listenerType the class of listeners to filter (<code>null</code>
3423 * @return An array of registered listeners.
3425 * @throws ClassCastException if <code>listenerType</code> does not implement
3426 * the {@link EventListener} interface.
3427 * @throws NullPointerException if <code>listenerType</code> is
3428 * <code>null</code>.
3430 * @see #getComponentListeners()
3431 * @see #getFocusListeners()
3432 * @see #getHierarchyListeners()
3433 * @see #getHierarchyBoundsListeners()
3434 * @see #getKeyListeners()
3435 * @see #getMouseListeners()
3436 * @see #getMouseMotionListeners()
3437 * @see #getMouseWheelListeners()
3438 * @see #getInputMethodListeners()
3439 * @see #getPropertyChangeListeners()
3442 public <T extends EventListener> T[] getListeners(Class<T> listenerType)
3444 if (listenerType == ComponentListener.class)
3445 return (T[]) getComponentListeners();
3446 if (listenerType == FocusListener.class)
3447 return (T[]) getFocusListeners();
3448 if (listenerType == HierarchyListener.class)
3449 return (T[]) getHierarchyListeners();
3450 if (listenerType == HierarchyBoundsListener.class)
3451 return (T[]) getHierarchyBoundsListeners();
3452 if (listenerType == KeyListener.class)
3453 return (T[]) getKeyListeners();
3454 if (listenerType == MouseListener.class)
3455 return (T[]) getMouseListeners();
3456 if (listenerType == MouseMotionListener.class)
3457 return (T[]) getMouseMotionListeners();
3458 if (listenerType == MouseWheelListener.class)
3459 return (T[]) getMouseWheelListeners();
3460 if (listenerType == InputMethodListener.class)
3461 return (T[]) getInputMethodListeners();
3462 if (listenerType == PropertyChangeListener.class)
3463 return (T[]) getPropertyChangeListeners();
3464 return (T[]) Array.newInstance(listenerType, 0);
3468 * Returns the input method request handler, for subclasses which support
3469 * on-the-spot text input. By default, input methods are handled by AWT,
3470 * and this returns null.
3472 * @return the input method handler, null by default
3475 public InputMethodRequests getInputMethodRequests()
3481 * Gets the input context of this component, which is inherited from the
3482 * parent unless this is overridden.
3484 * @return the text input context
3487 public InputContext getInputContext()
3489 return parent == null ? null : parent.getInputContext();
3493 * Enables the specified events. The events to enable are specified
3494 * by OR-ing together the desired masks from <code>AWTEvent</code>.
3496 * <p>Events are enabled by default when a listener is attached to the
3497 * component for that event type. This method can be used by subclasses
3498 * to ensure the delivery of a specified event regardless of whether
3499 * or not a listener is attached.
3501 * @param eventsToEnable the desired events to enable
3502 * @see #processEvent(AWTEvent)
3503 * @see #disableEvents(long)
3507 protected final void enableEvents(long eventsToEnable)
3509 // Update the counter for hierarchy (bounds) listeners.
3510 if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3511 && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0)
3513 // Need to lock the tree, otherwise we might end up inconsistent.
3514 synchronized (getTreeLock())
3516 numHierarchyListeners++;
3518 parent.updateHierarchyListenerCount
3519 (AWTEvent.HIERARCHY_EVENT_MASK,
3523 if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3524 && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0)
3526 // Need to lock the tree, otherwise we might end up inconsistent.
3527 synchronized (getTreeLock())
3529 numHierarchyBoundsListeners++;
3531 parent.updateHierarchyListenerCount
3532 (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3537 eventMask |= eventsToEnable;
3538 newEventsOnly = true;
3540 // Only heavyweight peers handle this.
3541 ComponentPeer p = peer;
3542 Component comp = this;
3543 while (p instanceof LightweightPeer)
3546 p = comp == null ? null : comp.peer;
3550 p.setEventMask(eventMask);
3555 * Disables the specified events. The events to disable are specified
3556 * by OR-ing together the desired masks from <code>AWTEvent</code>.
3558 * @param eventsToDisable the desired events to disable
3559 * @see #enableEvents(long)
3562 protected final void disableEvents(long eventsToDisable)
3564 // Update the counter for hierarchy (bounds) listeners.
3565 if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3566 && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)
3568 // Need to lock the tree, otherwise we might end up inconsistent.
3569 synchronized (getTreeLock())
3571 numHierarchyListeners--;
3573 parent.updateHierarchyListenerCount
3574 (AWTEvent.HIERARCHY_EVENT_MASK,
3578 if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3579 && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0)
3581 // Need to lock the tree, otherwise we might end up inconsistent.
3582 synchronized (getTreeLock())
3584 numHierarchyBoundsListeners--;
3586 parent.updateHierarchyListenerCount
3587 (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3592 eventMask &= ~eventsToDisable;
3594 // Only heavyweight peers handle this.
3595 ComponentPeer p = peer;
3596 Component comp = this;
3597 while (p instanceof LightweightPeer)
3600 p = comp == null ? null : comp.peer;
3604 p.setEventMask(eventMask);
3609 * This is called by the EventQueue if two events with the same event id
3610 * and owner component are queued. Returns a new combined event, or null if
3611 * no combining is done. The coelesced events are currently mouse moves
3612 * (intermediate ones are discarded) and paint events (a merged paint is
3613 * created in place of the two events).
3615 * @param existingEvent the event on the queue
3616 * @param newEvent the new event that might be entered on the queue
3617 * @return null if both events are kept, or the replacement coelesced event
3619 protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
3621 AWTEvent coalesced = null;
3622 switch (existingEvent.id)
3624 case MouseEvent.MOUSE_MOVED:
3625 case MouseEvent.MOUSE_DRAGGED:
3626 // Just drop the old (intermediate) event and return the new one.
3627 MouseEvent me1 = (MouseEvent) existingEvent;
3628 MouseEvent me2 = (MouseEvent) newEvent;
3629 if (me1.getModifiers() == me2.getModifiers())
3630 coalesced = newEvent;
3632 case PaintEvent.PAINT:
3633 case PaintEvent.UPDATE:
3634 // For heavyweights the EventQueue should ask the peer.
3635 if (peer == null || peer instanceof LightweightPeer)
3637 PaintEvent pe1 = (PaintEvent) existingEvent;
3638 PaintEvent pe2 = (PaintEvent) newEvent;
3639 Rectangle r1 = pe1.getUpdateRect();
3640 Rectangle r2 = pe2.getUpdateRect();
3641 if (r1.contains(r2))
3642 coalesced = existingEvent;
3643 else if (r2.contains(r1))
3644 coalesced = newEvent;
3648 // Replace the event and let the heavyweight figure out the expanding
3649 // of the repaint area.
3650 coalesced = newEvent;
3660 * Processes the specified event. In this class, this method simply
3661 * calls one of the more specific event handlers.
3663 * @param e the event to process
3664 * @throws NullPointerException if e is null
3665 * @see #processComponentEvent(ComponentEvent)
3666 * @see #processFocusEvent(FocusEvent)
3667 * @see #processKeyEvent(KeyEvent)
3668 * @see #processMouseEvent(MouseEvent)
3669 * @see #processMouseMotionEvent(MouseEvent)
3670 * @see #processInputMethodEvent(InputMethodEvent)
3671 * @see #processHierarchyEvent(HierarchyEvent)
3672 * @see #processMouseWheelEvent(MouseWheelEvent)
3675 protected void processEvent(AWTEvent e)
3677 /* Note: the order of these if statements are
3678 important. Subclasses must be checked first. Eg. MouseEvent
3679 must be checked before ComponentEvent, since a MouseEvent
3680 object is also an instance of a ComponentEvent. */
3682 if (e instanceof FocusEvent)
3683 processFocusEvent((FocusEvent) e);
3684 else if (e instanceof MouseWheelEvent)
3685 processMouseWheelEvent((MouseWheelEvent) e);
3686 else if (e instanceof MouseEvent)
3688 if (e.id == MouseEvent.MOUSE_MOVED
3689 || e.id == MouseEvent.MOUSE_DRAGGED)
3690 processMouseMotionEvent((MouseEvent) e);
3692 processMouseEvent((MouseEvent) e);
3694 else if (e instanceof KeyEvent)
3695 processKeyEvent((KeyEvent) e);
3696 else if (e instanceof InputMethodEvent)
3697 processInputMethodEvent((InputMethodEvent) e);
3698 else if (e instanceof ComponentEvent)
3699 processComponentEvent((ComponentEvent) e);
3700 else if (e instanceof HierarchyEvent)
3702 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3703 processHierarchyEvent((HierarchyEvent) e);
3705 processHierarchyBoundsEvent((HierarchyEvent) e);
3710 * Called when a component event is dispatched and component events are
3711 * enabled. This method passes the event along to any listeners
3712 * that are attached.
3714 * @param e the <code>ComponentEvent</code> to process
3715 * @throws NullPointerException if e is null
3716 * @see ComponentListener
3717 * @see #addComponentListener(ComponentListener)
3718 * @see #enableEvents(long)
3721 protected void processComponentEvent(ComponentEvent e)
3723 if (componentListener == null)
3727 case ComponentEvent.COMPONENT_HIDDEN:
3728 componentListener.componentHidden(e);
3730 case ComponentEvent.COMPONENT_MOVED:
3731 componentListener.componentMoved(e);
3733 case ComponentEvent.COMPONENT_RESIZED:
3734 componentListener.componentResized(e);
3736 case ComponentEvent.COMPONENT_SHOWN:
3737 componentListener.componentShown(e);
3743 * Called when a focus event is dispatched and component events are
3744 * enabled. This method passes the event along to any listeners
3745 * that are attached.
3747 * @param e the <code>FocusEvent</code> to process
3748 * @throws NullPointerException if e is null
3749 * @see FocusListener
3750 * @see #addFocusListener(FocusListener)
3751 * @see #enableEvents(long)
3754 protected void processFocusEvent(FocusEvent e)
3756 if (focusListener == null)
3761 case FocusEvent.FOCUS_GAINED:
3762 focusListener.focusGained(e);
3764 case FocusEvent.FOCUS_LOST:
3765 focusListener.focusLost(e);
3771 * Called when a key event is dispatched and component events are
3772 * enabled. This method passes the event along to any listeners
3773 * that are attached.
3775 * @param e the <code>KeyEvent</code> to process
3776 * @throws NullPointerException if e is null
3778 * @see #addKeyListener(KeyListener)
3779 * @see #enableEvents(long)
3782 protected void processKeyEvent(KeyEvent e)
3784 if (keyListener == null)
3788 case KeyEvent.KEY_PRESSED:
3789 keyListener.keyPressed(e);
3791 case KeyEvent.KEY_RELEASED:
3792 keyListener.keyReleased(e);
3794 case KeyEvent.KEY_TYPED:
3795 keyListener.keyTyped(e);
3801 * Called when a regular mouse event is dispatched and component events are
3802 * enabled. This method passes the event along to any listeners
3803 * that are attached.
3805 * @param e the <code>MouseEvent</code> to process
3806 * @throws NullPointerException if e is null
3807 * @see MouseListener
3808 * @see #addMouseListener(MouseListener)
3809 * @see #enableEvents(long)
3812 protected void processMouseEvent(MouseEvent e)
3814 if (mouseListener == null)
3818 case MouseEvent.MOUSE_CLICKED:
3819 mouseListener.mouseClicked(e);
3821 case MouseEvent.MOUSE_ENTERED:
3822 if( isLightweight() )
3823 setCursor( getCursor() );
3824 mouseListener.mouseEntered(e);
3826 case MouseEvent.MOUSE_EXITED:
3827 mouseListener.mouseExited(e);
3829 case MouseEvent.MOUSE_PRESSED:
3830 mouseListener.mousePressed(e);
3832 case MouseEvent.MOUSE_RELEASED:
3833 mouseListener.mouseReleased(e);
3839 * Called when a mouse motion event is dispatched and component events are
3840 * enabled. This method passes the event along to any listeners
3841 * that are attached.
3843 * @param e the <code>MouseMotionEvent</code> to process
3844 * @throws NullPointerException if e is null
3845 * @see MouseMotionListener
3846 * @see #addMouseMotionListener(MouseMotionListener)
3847 * @see #enableEvents(long)
3850 protected void processMouseMotionEvent(MouseEvent e)
3852 if (mouseMotionListener == null)
3856 case MouseEvent.MOUSE_DRAGGED:
3857 mouseMotionListener.mouseDragged(e);
3859 case MouseEvent.MOUSE_MOVED:
3860 mouseMotionListener.mouseMoved(e);
3867 * Called when a mouse wheel event is dispatched and component events are
3868 * enabled. This method passes the event along to any listeners that are
3871 * @param e the <code>MouseWheelEvent</code> to process
3872 * @throws NullPointerException if e is null
3873 * @see MouseWheelListener
3874 * @see #addMouseWheelListener(MouseWheelListener)
3875 * @see #enableEvents(long)
3878 protected void processMouseWheelEvent(MouseWheelEvent e)
3880 if (mouseWheelListener != null
3881 && e.id == MouseEvent.MOUSE_WHEEL)
3883 mouseWheelListener.mouseWheelMoved(e);
3889 * Called when an input method event is dispatched and component events are
3890 * enabled. This method passes the event along to any listeners that are
3893 * @param e the <code>InputMethodEvent</code> to process
3894 * @throws NullPointerException if e is null
3895 * @see InputMethodListener
3896 * @see #addInputMethodListener(InputMethodListener)
3897 * @see #enableEvents(long)
3900 protected void processInputMethodEvent(InputMethodEvent e)
3902 if (inputMethodListener == null)
3906 case InputMethodEvent.CARET_POSITION_CHANGED:
3907 inputMethodListener.caretPositionChanged(e);
3909 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3910 inputMethodListener.inputMethodTextChanged(e);
3916 * Called when a hierarchy change event is dispatched and component events
3917 * are enabled. This method passes the event along to any listeners that are
3920 * @param e the <code>HierarchyEvent</code> to process
3921 * @throws NullPointerException if e is null
3922 * @see HierarchyListener
3923 * @see #addHierarchyListener(HierarchyListener)
3924 * @see #enableEvents(long)
3927 protected void processHierarchyEvent(HierarchyEvent e)
3929 if (hierarchyListener == null)
3931 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3932 hierarchyListener.hierarchyChanged(e);
3936 * Called when a hierarchy bounds event is dispatched and component events
3937 * are enabled. This method passes the event along to any listeners that are
3940 * @param e the <code>HierarchyEvent</code> to process
3941 * @throws NullPointerException if e is null
3942 * @see HierarchyBoundsListener
3943 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3944 * @see #enableEvents(long)
3947 protected void processHierarchyBoundsEvent(HierarchyEvent e)
3949 if (hierarchyBoundsListener == null)
3953 case HierarchyEvent.ANCESTOR_MOVED:
3954 hierarchyBoundsListener.ancestorMoved(e);
3956 case HierarchyEvent.ANCESTOR_RESIZED:
3957 hierarchyBoundsListener.ancestorResized(e);
3963 * AWT 1.0 event handler.
3965 * This method calls one of the event-specific handler methods. For
3966 * example for key events, either {@link #keyDown(Event,int)}
3967 * or {@link #keyUp(Event,int)} is called. A derived
3968 * component can override one of these event-specific methods if it
3969 * only needs to handle certain event types. Otherwise it can
3970 * override handleEvent itself and handle any event.
3972 * @param evt the event to handle
3973 * @return true if the event was handled, false otherwise
3974 * @deprecated use {@link #processEvent(AWTEvent)} instead
3976 public boolean handleEvent (Event evt)
3980 // Handle key events.
3981 case Event.KEY_ACTION:
3982 case Event.KEY_PRESS:
3983 return keyDown (evt, evt.key);
3984 case Event.KEY_ACTION_RELEASE:
3985 case Event.KEY_RELEASE:
3986 return keyUp (evt, evt.key);
3988 // Handle mouse events.
3989 case Event.MOUSE_DOWN:
3990 return mouseDown (evt, evt.x, evt.y);
3991 case Event.MOUSE_UP:
3992 return mouseUp (evt, evt.x, evt.y);
3993 case Event.MOUSE_MOVE:
3994 return mouseMove (evt, evt.x, evt.y);
3995 case Event.MOUSE_DRAG:
3996 return mouseDrag (evt, evt.x, evt.y);
3997 case Event.MOUSE_ENTER:
3998 return mouseEnter (evt, evt.x, evt.y);
3999 case Event.MOUSE_EXIT:
4000 return mouseExit (evt, evt.x, evt.y);
4002 // Handle focus events.
4003 case Event.GOT_FOCUS:
4004 return gotFocus (evt, evt.arg);
4005 case Event.LOST_FOCUS:
4006 return lostFocus (evt, evt.arg);
4008 // Handle action event.
4009 case Event.ACTION_EVENT:
4010 return action (evt, evt.arg);
4017 * AWT 1.0 MOUSE_DOWN event handler. This method is meant to be
4018 * overridden by components providing their own MOUSE_DOWN handler.
4019 * The default implementation simply returns false.
4021 * @param evt the event to handle
4022 * @param x the x coordinate, ignored
4023 * @param y the y coordinate, ignored
4025 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4027 public boolean mouseDown(Event evt, int x, int y)
4033 * AWT 1.0 MOUSE_DRAG event handler. This method is meant to be
4034 * overridden by components providing their own MOUSE_DRAG handler.
4035 * The default implementation simply returns false.
4037 * @param evt the event to handle
4038 * @param x the x coordinate, ignored
4039 * @param y the y coordinate, ignored
4041 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4043 public boolean mouseDrag(Event evt, int x, int y)
4049 * AWT 1.0 MOUSE_UP event handler. This method is meant to be
4050 * overridden by components providing their own MOUSE_UP handler.
4051 * The default implementation simply returns false.
4053 * @param evt the event to handle
4054 * @param x the x coordinate, ignored
4055 * @param y the y coordinate, ignored
4057 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4059 public boolean mouseUp(Event evt, int x, int y)
4065 * AWT 1.0 MOUSE_MOVE event handler. This method is meant to be
4066 * overridden by components providing their own MOUSE_MOVE handler.
4067 * The default implementation simply returns false.
4069 * @param evt the event to handle
4070 * @param x the x coordinate, ignored
4071 * @param y the y coordinate, ignored
4073 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4075 public boolean mouseMove(Event evt, int x, int y)
4081 * AWT 1.0 MOUSE_ENTER event handler. This method is meant to be
4082 * overridden by components providing their own MOUSE_ENTER handler.
4083 * The default implementation simply returns false.
4085 * @param evt the event to handle
4086 * @param x the x coordinate, ignored
4087 * @param y the y coordinate, ignored
4089 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4091 public boolean mouseEnter(Event evt, int x, int y)
4097 * AWT 1.0 MOUSE_EXIT event handler. This method is meant to be
4098 * overridden by components providing their own MOUSE_EXIT handler.
4099 * The default implementation simply returns false.
4101 * @param evt the event to handle
4102 * @param x the x coordinate, ignored
4103 * @param y the y coordinate, ignored
4105 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4107 public boolean mouseExit(Event evt, int x, int y)
4113 * AWT 1.0 KEY_PRESS and KEY_ACTION event handler. This method is
4114 * meant to be overridden by components providing their own key
4115 * press handler. The default implementation simply returns false.
4117 * @param evt the event to handle
4118 * @param key the key pressed, ignored
4120 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4122 public boolean keyDown(Event evt, int key)
4128 * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler. This
4129 * method is meant to be overridden by components providing their
4130 * own key release handler. The default implementation simply
4133 * @param evt the event to handle
4134 * @param key the key pressed, ignored
4136 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4138 public boolean keyUp(Event evt, int key)
4144 * AWT 1.0 ACTION_EVENT event handler. This method is meant to be
4145 * overridden by components providing their own action event
4146 * handler. The default implementation simply returns false.
4148 * @param evt the event to handle
4149 * @param what the object acted on, ignored
4151 * @deprecated in classes which support actions, use
4152 * <code>processActionEvent(ActionEvent)</code> instead
4154 public boolean action(Event evt, Object what)
4160 * Called when the parent of this Component is made visible or when
4161 * the Component is added to an already visible Container and needs
4162 * to be shown. A native peer - if any - is created at this
4163 * time. This method is called automatically by the AWT system and
4164 * should not be called by user level code.
4166 * @see #isDisplayable()
4167 * @see #removeNotify()
4169 public void addNotify()
4171 // We need to lock the tree here to avoid races and inconsistencies.
4172 synchronized (getTreeLock())
4175 peer = getToolkit().createComponent(this);
4176 else if (parent != null && parent.isLightweight())
4177 new HeavyweightInLightweightListener(parent);
4178 // Now that all the children has gotten their peers, we should
4179 // have the event mask needed for this component and its
4180 //lightweight subcomponents.
4181 peer.setEventMask(eventMask);
4183 // We used to leave the invalidate() to the peer. However, I put it
4184 // back here for 2 reasons: 1) The RI does call invalidate() from
4185 // addNotify(); 2) The peer shouldn't be bother with validation too
4189 if (dropTarget != null)
4190 dropTarget.addNotify(peer);
4192 // Fetch the peerFont for later installation in validate().
4193 peerFont = getFont();
4195 // Notify hierarchy listeners.
4196 long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4197 if (isHierarchyVisible())
4198 flags |= HierarchyEvent.SHOWING_CHANGED;
4199 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4205 * Called to inform this component is has been removed from its
4206 * container. Its native peer - if any - is destroyed at this time.
4207 * This method is called automatically by the AWT system and should
4208 * not be called by user level code.
4210 * @see #isDisplayable()
4213 public void removeNotify()
4215 // We need to lock the tree here to avoid races and inconsistencies.
4216 synchronized (getTreeLock())
4218 // We null our peer field before disposing of it, such that if we're
4219 // not the event dispatch thread and the dispatch thread is awoken by
4220 // the dispose call, there will be no race checking the peer's null
4223 ComponentPeer tmp = peer;
4232 // Notify hierarchy listeners.
4233 long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4234 if (isHierarchyVisible())
4235 flags |= HierarchyEvent.SHOWING_CHANGED;
4236 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4242 * AWT 1.0 GOT_FOCUS event handler. This method is meant to be
4243 * overridden by components providing their own GOT_FOCUS handler.
4244 * The default implementation simply returns false.
4246 * @param evt the event to handle
4247 * @param what the Object focused, ignored
4249 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4251 public boolean gotFocus(Event evt, Object what)
4257 * AWT 1.0 LOST_FOCUS event handler. This method is meant to be
4258 * overridden by components providing their own LOST_FOCUS handler.
4259 * The default implementation simply returns false.
4261 * @param evt the event to handle
4262 * @param what the Object focused, ignored
4264 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4266 public boolean lostFocus(Event evt, Object what)
4272 * Tests whether or not this component is in the group that can be
4273 * traversed using the keyboard traversal mechanism (such as the TAB key).
4275 * @return true if the component is traversed via the TAB key
4276 * @see #setFocusable(boolean)
4278 * @deprecated use {@link #isFocusable()} instead
4280 public boolean isFocusTraversable()
4282 return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
4286 * Tests if this component can receive focus.
4288 * @return true if this component can receive focus
4291 public boolean isFocusable()
4297 * Specify whether this component can receive focus. This method also
4298 * sets the {@link #isFocusTraversableOverridden} field to 1, which
4299 * appears to be the undocumented way {@link
4300 * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
4301 * respect the {@link #isFocusable()} method of the component.
4303 * @param focusable the new focusable status
4306 public void setFocusable(boolean focusable)
4308 firePropertyChange("focusable", this.focusable, focusable);
4309 this.focusable = focusable;
4310 this.isFocusTraversableOverridden = 1;
4314 * Sets the focus traversal keys for one of the three focus
4315 * traversal directions supported by Components:
4316 * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
4317 * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
4318 * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
4319 * default values should match the operating system's native
4320 * choices. To disable a given traversal, use
4321 * <code>Collections.EMPTY_SET</code>. The event dispatcher will
4322 * consume PRESSED, RELEASED, and TYPED events for the specified
4323 * key, although focus can only transfer on PRESSED or RELEASED.
4325 * <p>The defaults are:
4327 * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
4328 * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
4329 * <td>Normal forward traversal</td>
4330 * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
4331 * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
4332 * <td>Normal backward traversal</td>
4333 * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
4334 * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
4335 * <td>Go up a traversal cycle</td><td>None</td></tr>
4338 * If keystrokes is null, this component's focus traversal key set
4339 * is inherited from one of its ancestors. If none of its ancestors
4340 * has its own set of focus traversal keys, the focus traversal keys
4341 * are set to the defaults retrieved from the current
4342 * KeyboardFocusManager. If not null, the set must contain only
4343 * AWTKeyStrokes that are not already focus keys and are not
4346 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
4347 * UP_CYCLE_TRAVERSAL_KEYS
4348 * @param keystrokes a set of keys, or null
4349 * @throws IllegalArgumentException if id or keystrokes is invalid
4350 * @see #getFocusTraversalKeys(int)
4351 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4352 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4353 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4356 public void setFocusTraversalKeys(int id,
4357 Set<? extends AWTKeyStroke> keystrokes)
4359 if (keystrokes == null)
4361 Container parent = getParent ();
4363 while (parent != null)
4365 if (parent.areFocusTraversalKeysSet (id))
4367 keystrokes = parent.getFocusTraversalKeys (id);
4370 parent = parent.getParent ();
4373 if (keystrokes == null)
4374 keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
4375 getDefaultFocusTraversalKeys (id);
4383 case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
4384 sa = getFocusTraversalKeys
4385 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4386 sb = getFocusTraversalKeys
4387 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4388 name = "forwardFocusTraversalKeys";
4390 case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
4391 sa = getFocusTraversalKeys
4392 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4393 sb = getFocusTraversalKeys
4394 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4395 name = "backwardFocusTraversalKeys";
4397 case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
4398 sa = getFocusTraversalKeys
4399 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4400 sb = getFocusTraversalKeys
4401 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4402 name = "upCycleFocusTraversalKeys";
4405 throw new IllegalArgumentException ();
4408 int i = keystrokes.size ();
4409 Iterator iter = keystrokes.iterator ();
4413 Object o = iter.next ();
4414 if (!(o instanceof AWTKeyStroke)
4415 || sa.contains (o) || sb.contains (o)
4416 || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
4417 throw new IllegalArgumentException ();
4420 if (focusTraversalKeys == null)
4421 focusTraversalKeys = new Set[3];
4423 keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
4424 firePropertyChange (name, focusTraversalKeys[id], keystrokes);
4426 focusTraversalKeys[id] = keystrokes;
4430 * Returns the set of keys for a given focus traversal action, as
4431 * defined in <code>setFocusTraversalKeys</code>. If not set, this
4432 * is inherited from the parent component, which may have gotten it
4433 * from the KeyboardFocusManager.
4435 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4436 * or UP_CYCLE_TRAVERSAL_KEYS
4438 * @return set of traversal keys
4440 * @throws IllegalArgumentException if id is invalid
4442 * @see #setFocusTraversalKeys (int, Set)
4443 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4444 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4445 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4449 public Set<AWTKeyStroke> getFocusTraversalKeys (int id)
4451 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4452 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4453 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4454 throw new IllegalArgumentException();
4456 Set<AWTKeyStroke> s = null;
4458 if (focusTraversalKeys != null)
4459 s = focusTraversalKeys[id];
4461 if (s == null && parent != null)
4462 s = parent.getFocusTraversalKeys (id);
4464 return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
4465 .getDefaultFocusTraversalKeys(id)) : s;
4469 * Tests whether the focus traversal keys for a given action are explicitly
4472 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4473 * or UP_CYCLE_TRAVERSAL_KEYS
4474 * @return true if that set is explicitly specified
4475 * @throws IllegalArgumentException if id is invalid
4476 * @see #getFocusTraversalKeys (int)
4477 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4478 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4479 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4482 public boolean areFocusTraversalKeysSet (int id)
4484 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4485 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4486 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4487 throw new IllegalArgumentException ();
4489 return focusTraversalKeys != null && focusTraversalKeys[id] != null;
4493 * Enable or disable focus traversal keys on this Component. If
4494 * they are, then the keyboard focus manager consumes and acts on
4495 * key press and release events that trigger focus traversal, and
4496 * discards the corresponding key typed events. If focus traversal
4497 * keys are disabled, then all key events that would otherwise
4498 * trigger focus traversal are sent to this Component.
4500 * @param focusTraversalKeysEnabled the new value of the flag
4501 * @see #getFocusTraversalKeysEnabled ()
4502 * @see #setFocusTraversalKeys (int, Set)
4503 * @see #getFocusTraversalKeys (int)
4506 public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
4508 firePropertyChange ("focusTraversalKeysEnabled",
4509 this.focusTraversalKeysEnabled,
4510 focusTraversalKeysEnabled);
4511 this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
4515 * Check whether or not focus traversal keys are enabled on this
4516 * Component. If they are, then the keyboard focus manager consumes
4517 * and acts on key press and release events that trigger focus
4518 * traversal, and discards the corresponding key typed events. If
4519 * focus traversal keys are disabled, then all key events that would
4520 * otherwise trigger focus traversal are sent to this Component.
4522 * @return true if focus traversal keys are enabled
4523 * @see #setFocusTraversalKeysEnabled (boolean)
4524 * @see #setFocusTraversalKeys (int, Set)
4525 * @see #getFocusTraversalKeys (int)
4528 public boolean getFocusTraversalKeysEnabled ()
4530 return focusTraversalKeysEnabled;
4534 * Request that this Component be given the keyboard input focus and
4535 * that its top-level ancestor become the focused Window.
4537 * For the request to be granted, the Component must be focusable,
4538 * displayable and showing and the top-level Window to which it
4539 * belongs must be focusable. If the request is initially denied on
4540 * the basis that the top-level Window is not focusable, the request
4541 * will be remembered and granted when the Window does become
4544 * Never assume that this Component is the focus owner until it
4545 * receives a FOCUS_GAINED event.
4547 * The behaviour of this method is platform-dependent.
4548 * {@link #requestFocusInWindow()} should be used instead.
4550 * @see #requestFocusInWindow ()
4552 * @see #addFocusListener (FocusListener)
4553 * @see #isFocusable ()
4554 * @see #isDisplayable ()
4555 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4557 public void requestFocus ()
4559 requestFocusImpl(false, true);
4563 * Request that this Component be given the keyboard input focus and
4564 * that its top-level ancestor become the focused Window.
4566 * For the request to be granted, the Component must be focusable,
4567 * displayable and showing and the top-level Window to which it
4568 * belongs must be focusable. If the request is initially denied on
4569 * the basis that the top-level Window is not focusable, the request
4570 * will be remembered and granted when the Window does become
4573 * Never assume that this Component is the focus owner until it
4574 * receives a FOCUS_GAINED event.
4576 * The behaviour of this method is platform-dependent.
4577 * {@link #requestFocusInWindow()} should be used instead.
4579 * If the return value is false, the request is guaranteed to fail.
4580 * If the return value is true, the request will succeed unless it
4581 * is vetoed or something in the native windowing system intervenes,
4582 * preventing this Component's top-level ancestor from becoming
4583 * focused. This method is meant to be called by derived
4584 * lightweight Components that want to avoid unnecessary repainting
4585 * when they know a given focus transfer need only be temporary.
4587 * @param temporary true if the focus request is temporary
4588 * @return true if the request has a chance of success
4589 * @see #requestFocusInWindow ()
4591 * @see #addFocusListener (FocusListener)
4592 * @see #isFocusable ()
4593 * @see #isDisplayable ()
4594 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4597 protected boolean requestFocus (boolean temporary)
4599 return requestFocusImpl(temporary, true);
4603 * Request that this component be given the keyboard input focus, if
4604 * its top-level ancestor is the currently focused Window. A
4605 * <code>FOCUS_GAINED</code> event will be fired if and only if this
4606 * request is successful. To be successful, the component must be
4607 * displayable, showing, and focusable, and its ancestor top-level
4608 * Window must be focused.
4610 * If the return value is false, the request is guaranteed to fail.
4611 * If the return value is true, the request will succeed unless it
4612 * is vetoed or something in the native windowing system intervenes,
4613 * preventing this Component's top-level ancestor from becoming
4616 * @return true if the request has a chance of success
4617 * @see #requestFocus ()
4619 * @see #addFocusListener (FocusListener)
4620 * @see #isFocusable ()
4621 * @see #isDisplayable ()
4622 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4625 public boolean requestFocusInWindow ()
4627 return requestFocusImpl(false, false);
4631 * Request that this component be given the keyboard input focus, if
4632 * its top-level ancestor is the currently focused Window. A
4633 * <code>FOCUS_GAINED</code> event will be fired if and only if this
4634 * request is successful. To be successful, the component must be
4635 * displayable, showing, and focusable, and its ancestor top-level
4636 * Window must be focused.
4638 * If the return value is false, the request is guaranteed to fail.
4639 * If the return value is true, the request will succeed unless it
4640 * is vetoed or something in the native windowing system intervenes,
4641 * preventing this Component's top-level ancestor from becoming
4642 * focused. This method is meant to be called by derived
4643 * lightweight Components that want to avoid unnecessary repainting
4644 * when they know a given focus transfer need only be temporary.
4646 * @param temporary true if the focus request is temporary
4647 * @return true if the request has a chance of success
4648 * @see #requestFocus ()
4650 * @see #addFocusListener (FocusListener)
4651 * @see #isFocusable ()
4652 * @see #isDisplayable ()
4653 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4656 protected boolean requestFocusInWindow (boolean temporary)
4658 return requestFocusImpl(temporary, false);
4662 * Helper method for all 4 requestFocus variants.
4664 * @param temporary indicates if the focus change is temporary
4665 * @param focusWindow indicates if the window focus may be changed
4667 * @return <code>false</code> if the request has been definitely denied,
4668 * <code>true</code> otherwise
4670 private boolean requestFocusImpl(boolean temporary, boolean focusWindow)
4672 boolean retval = false;
4674 // Don't try to focus non-focusable and non-visible components.
4675 if (isFocusable() && isVisible())
4677 ComponentPeer myPeer = peer;
4680 // Find Window ancestor and find out if we're showing while
4682 boolean showing = true;
4683 Component window = this;
4684 while (! (window instanceof Window))
4686 if (! window.isVisible())
4688 window = window.parent;
4690 // Don't allow focus when there is no window or the window
4691 // is not focusable.
4692 if (window != null && ((Window) window).isFocusableWindow()
4695 // Search for nearest heavy ancestor (including this
4697 Component heavyweightParent = this;
4698 while (heavyweightParent.peer instanceof LightweightPeer)
4699 heavyweightParent = heavyweightParent.parent;
4701 // Don't allow focus on lightweight components without
4702 // visible heavyweight ancestor
4703 if (heavyweightParent != null && heavyweightParent.isVisible())
4705 // Don't allow focus when heavyweightParent has no peer.
4706 myPeer = heavyweightParent.peer;
4709 // Register lightweight focus request.
4710 if (heavyweightParent != this)
4712 KeyboardFocusManager
4713 .addLightweightFocusRequest(heavyweightParent,
4717 // Try to focus the component.
4718 long time = EventQueue.getMostRecentEventTime();
4719 boolean success = myPeer.requestFocus(this, temporary,
4724 // Dequeue key events if focus request failed.
4725 KeyboardFocusManager kfm =
4726 KeyboardFocusManager.getCurrentKeyboardFocusManager();
4727 kfm.dequeueKeyEvents(time, this);
4739 * Transfers focus to the next component in the focus traversal
4740 * order, as though this were the current focus owner.
4742 * @see #requestFocus()
4745 public void transferFocus ()
4751 * Returns the root container that owns the focus cycle where this
4752 * component resides. A focus cycle root is in two cycles, one as
4753 * the ancestor, and one as the focusable element; this call always
4754 * returns the ancestor.
4756 * @return the ancestor container that owns the focus cycle
4759 public Container getFocusCycleRootAncestor ()
4761 Container parent = getParent ();
4763 while (parent != null && !parent.isFocusCycleRoot())
4764 parent = parent.getParent ();
4770 * Tests if the container is the ancestor of the focus cycle that
4771 * this component belongs to.
4773 * @param c the container to test
4774 * @return true if c is the focus cycle root
4777 public boolean isFocusCycleRoot (Container c)
4779 return c == getFocusCycleRootAncestor ();
4783 * AWT 1.0 focus event processor. Transfers focus to the next
4784 * component in the focus traversal order, as though this were the
4785 * current focus owner.
4787 * @deprecated use {@link #transferFocus ()} instead
4789 public void nextFocus ()
4791 // Find the nearest valid (== showing && focusable && enabled) focus
4792 // cycle root ancestor and the focused component in it.
4793 Container focusRoot = getFocusCycleRootAncestor();
4794 Component focusComp = this;
4795 while (focusRoot != null
4796 && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4797 && focusRoot.isEnabled()))
4799 focusComp = focusRoot;
4800 focusRoot = focusComp.getFocusCycleRootAncestor();
4803 if (focusRoot != null)
4805 // First try to get the componentBefore from the policy.
4806 FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4807 Component nextFocus = policy.getComponentAfter(focusRoot, focusComp);
4809 // If this fails, then ask for the defaultComponent.
4810 if (nextFocus == null)
4811 nextFocus = policy.getDefaultComponent(focusRoot);
4813 // Request focus on this component, if not null.
4814 if (nextFocus != null)
4815 nextFocus.requestFocus();
4820 * Transfers focus to the previous component in the focus traversal
4821 * order, as though this were the current focus owner.
4823 * @see #requestFocus ()
4826 public void transferFocusBackward ()
4828 // Find the nearest valid (== showing && focusable && enabled) focus
4829 // cycle root ancestor and the focused component in it.
4830 Container focusRoot = getFocusCycleRootAncestor();
4831 Component focusComp = this;
4832 while (focusRoot != null
4833 && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4834 && focusRoot.isEnabled()))
4836 focusComp = focusRoot;
4837 focusRoot = focusComp.getFocusCycleRootAncestor();
4840 if (focusRoot != null)
4842 // First try to get the componentBefore from the policy.
4843 FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4844 Component nextFocus = policy.getComponentBefore(focusRoot, focusComp);
4846 // If this fails, then ask for the defaultComponent.
4847 if (nextFocus == null)
4848 nextFocus = policy.getDefaultComponent(focusRoot);
4850 // Request focus on this component, if not null.
4851 if (nextFocus != null)
4852 nextFocus.requestFocus();
4857 * Transfers focus to the focus cycle root of this component.
4858 * However, if this is a Window, the default focus owner in the
4859 * window in the current focus cycle is focused instead.
4861 * @see #requestFocus()
4862 * @see #isFocusCycleRoot(Container)
4865 public void transferFocusUpCycle ()
4867 // Find the nearest focus cycle root ancestor that is itself
4868 // focusable, showing and enabled.
4869 Container focusCycleRoot = getFocusCycleRootAncestor();
4870 while (focusCycleRoot != null &&
4871 ! (focusCycleRoot.isShowing() && focusCycleRoot.isFocusable()
4872 && focusCycleRoot.isEnabled()))
4874 focusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor();
4877 KeyboardFocusManager fm =
4878 KeyboardFocusManager.getCurrentKeyboardFocusManager();
4880 if (focusCycleRoot != null)
4882 // If we found a focus cycle root, then we make this the new
4883 // focused component, and make it's focus cycle root the new
4884 // global focus cycle root. If the found root has no focus cycle
4885 // root ancestor itself, then the component will be both the focused
4886 // component and the new global focus cycle root.
4887 Container focusCycleAncestor =
4888 focusCycleRoot.getFocusCycleRootAncestor();
4889 Container globalFocusCycleRoot;
4890 if (focusCycleAncestor == null)
4891 globalFocusCycleRoot = focusCycleRoot;
4893 globalFocusCycleRoot = focusCycleAncestor;
4895 fm.setGlobalCurrentFocusCycleRoot(globalFocusCycleRoot);
4896 focusCycleRoot.requestFocus();
4900 // If this component has no applicable focus cycle root, we try
4901 // find the nearest window and set this as the new global focus cycle
4902 // root and the default focus component of this window the new focused
4905 if (this instanceof Container)
4906 cont = (Container) this;
4910 while (cont != null && !(cont instanceof Window))
4911 cont = cont.getParent();
4915 FocusTraversalPolicy policy = cont.getFocusTraversalPolicy();
4916 Component focusComp = policy.getDefaultComponent(cont);
4917 if (focusComp != null)
4919 fm.setGlobalCurrentFocusCycleRoot(cont);
4920 focusComp.requestFocus();
4927 * Tests if this component is the focus owner. Use {@link
4928 * #isFocusOwner ()} instead.
4930 * @return true if this component owns focus
4933 public boolean hasFocus ()
4935 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4937 Component focusOwner = manager.getFocusOwner ();
4939 return this == focusOwner;
4943 * Tests if this component is the focus owner.
4945 * @return true if this component owns focus
4948 public boolean isFocusOwner()
4954 * Adds the specified popup menu to this component.
4956 * @param popup the popup menu to be added
4958 * @see #remove(MenuComponent)
4962 public synchronized void add(PopupMenu popup)
4965 popups = new Vector();
4968 if (popup.parent != null)
4969 popup.parent.remove(popup);
4970 popup.parent = this;
4976 * Removes the specified popup menu from this component.
4978 * @param popup the popup menu to remove
4979 * @see #add(PopupMenu)
4982 public synchronized void remove(MenuComponent popup)
4985 popups.remove(popup);
4989 * Returns a debugging string representing this component. The string may
4990 * be empty but not null.
4992 * @return a string representing this component
4994 protected String paramString()
4996 CPStringBuilder param = new CPStringBuilder();
4997 String name = getName();
4999 param.append(name).append(",");
5000 param.append(x).append(",").append(y).append(",").append(width)
5001 .append("x").append(height);
5003 param.append(",invalid");
5005 param.append(",invisible");
5007 param.append(",disabled");
5009 param.append(",translucent");
5010 if (isDoubleBuffered())
5011 param.append(",doublebuffered");
5013 param.append(",parent=null");
5015 param.append(",parent=").append(parent.getName());
5016 return param.toString();
5020 * Returns a string representation of this component. This is implemented
5021 * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
5023 * @return a string representation of this component
5025 public String toString()
5027 return getClass().getName() + '[' + paramString() + ']';
5031 * Prints a listing of this component to <code>System.out</code>.
5033 * @see #list(PrintStream)
5037 list(System.out, 0);
5041 * Prints a listing of this component to the specified print stream.
5043 * @param out the <code>PrintStream</code> to print to
5045 public void list(PrintStream out)
5051 * Prints a listing of this component to the specified print stream,
5052 * starting at the specified indentation point.
5054 * @param out the <code>PrintStream</code> to print to
5055 * @param indent the indentation point
5057 public void list(PrintStream out, int indent)
5059 for (int i = 0; i < indent; ++i)
5061 out.println(toString());
5065 * Prints a listing of this component to the specified print writer.
5067 * @param out the <code>PrintWrinter</code> to print to
5070 public void list(PrintWriter out)
5076 * Prints a listing of this component to the specified print writer,
5077 * starting at the specified indentation point.
5079 * @param out the <code>PrintWriter</code> to print to
5080 * @param indent the indentation point
5083 public void list(PrintWriter out, int indent)
5085 for (int i = 0; i < indent; ++i)
5087 out.println(toString());
5091 * Adds the specified property listener to this component. This is harmless
5092 * if the listener is null, but if the listener has already been registered,
5093 * it will now be registered twice. The property listener ignores inherited
5094 * properties. Recognized properties include:<br>
5096 * <li>the font (<code>"font"</code>)</li>
5097 * <li>the background color (<code>"background"</code>)</li>
5098 * <li>the foreground color (<code>"foreground"</code>)</li>
5099 * <li>the focusability (<code>"focusable"</code>)</li>
5100 * <li>the focus key traversal enabled state
5101 * (<code>"focusTraversalKeysEnabled"</code>)</li>
5102 * <li>the set of forward traversal keys
5103 * (<code>"forwardFocusTraversalKeys"</code>)</li>
5104 * <li>the set of backward traversal keys
5105 * (<code>"backwardFocusTraversalKeys"</code>)</li>
5106 * <li>the set of up-cycle traversal keys
5107 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
5110 * @param listener the new listener to add
5111 * @see #removePropertyChangeListener(PropertyChangeListener)
5112 * @see #getPropertyChangeListeners()
5113 * @see #addPropertyChangeListener(String, PropertyChangeListener)
5116 public void addPropertyChangeListener(PropertyChangeListener listener)
5118 if (changeSupport == null)
5119 changeSupport = new PropertyChangeSupport(this);
5120 changeSupport.addPropertyChangeListener(listener);
5124 * Removes the specified property listener from the component. This is
5125 * harmless if the listener was not previously registered.
5127 * @param listener the listener to remove
5128 * @see #addPropertyChangeListener(PropertyChangeListener)
5129 * @see #getPropertyChangeListeners()
5130 * @see #removePropertyChangeListener(String, PropertyChangeListener)
5133 public void removePropertyChangeListener(PropertyChangeListener listener)
5135 if (changeSupport != null)
5136 changeSupport.removePropertyChangeListener(listener);
5140 * Returns an array of all specified listeners registered on this component.
5142 * @return an array of listeners
5143 * @see #addPropertyChangeListener(PropertyChangeListener)
5144 * @see #removePropertyChangeListener(PropertyChangeListener)
5145 * @see #getPropertyChangeListeners(String)
5148 public PropertyChangeListener[] getPropertyChangeListeners()
5150 return changeSupport == null ? new PropertyChangeListener[0]
5151 : changeSupport.getPropertyChangeListeners();
5155 * Adds the specified property listener to this component. This is harmless
5156 * if the listener is null, but if the listener has already been registered,
5157 * it will now be registered twice. The property listener ignores inherited
5158 * properties. The listener is keyed to a single property. Recognized
5159 * properties include:<br>
5161 * <li>the font (<code>"font"</code>)</li>
5162 * <li>the background color (<code>"background"</code>)</li>
5163 * <li>the foreground color (<code>"foreground"</code>)</li>
5164 * <li>the focusability (<code>"focusable"</code>)</li>
5165 * <li>the focus key traversal enabled state
5166 * (<code>"focusTraversalKeysEnabled"</code>)</li>
5167 * <li>the set of forward traversal keys
5168 * (<code>"forwardFocusTraversalKeys"</code>)</li>
5169 p * <li>the set of backward traversal keys
5170 * (<code>"backwardFocusTraversalKeys"</code>)</li>
5171 * <li>the set of up-cycle traversal keys
5172 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
5175 * @param propertyName the property name to filter on
5176 * @param listener the new listener to add
5177 * @see #removePropertyChangeListener(String, PropertyChangeListener)
5178 * @see #getPropertyChangeListeners(String)
5179 * @see #addPropertyChangeListener(PropertyChangeListener)
5182 public void addPropertyChangeListener(String propertyName,
5183 PropertyChangeListener listener)
5185 if (changeSupport == null)
5186 changeSupport = new PropertyChangeSupport(this);
5187 changeSupport.addPropertyChangeListener(propertyName, listener);
5191 * Removes the specified property listener on a particular property from
5192 * the component. This is harmless if the listener was not previously
5195 * @param propertyName the property name to filter on
5196 * @param listener the listener to remove
5197 * @see #addPropertyChangeListener(String, PropertyChangeListener)
5198 * @see #getPropertyChangeListeners(String)
5199 * @see #removePropertyChangeListener(PropertyChangeListener)
5202 public void removePropertyChangeListener(String propertyName,
5203 PropertyChangeListener listener)
5205 if (changeSupport != null)
5206 changeSupport.removePropertyChangeListener(propertyName, listener);
5210 * Returns an array of all specified listeners on the named property that
5211 * are registered on this component.
5213 * @return an array of listeners
5214 * @see #addPropertyChangeListener(String, PropertyChangeListener)
5215 * @see #removePropertyChangeListener(String, PropertyChangeListener)
5216 * @see #getPropertyChangeListeners()
5219 public PropertyChangeListener[] getPropertyChangeListeners(String property)
5221 return changeSupport == null ? new PropertyChangeListener[0]
5222 : changeSupport.getPropertyChangeListeners(property);
5226 * Report a change in a bound property to any registered property listeners.
5228 * @param propertyName the property that changed
5229 * @param oldValue the old property value
5230 * @param newValue the new property value
5232 protected void firePropertyChange(String propertyName, Object oldValue,
5235 if (changeSupport != null)
5236 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5240 * Report a change in a bound property to any registered property listeners.
5242 * @param propertyName the property that changed
5243 * @param oldValue the old property value
5244 * @param newValue the new property value
5246 protected void firePropertyChange(String propertyName, boolean oldValue,
5249 if (changeSupport != null)
5250 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5254 * Report a change in a bound property to any registered property listeners.
5256 * @param propertyName the property that changed
5257 * @param oldValue the old property value
5258 * @param newValue the new property value
5260 protected void firePropertyChange(String propertyName, int oldValue,
5263 if (changeSupport != null)
5264 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5268 * Report a change in a bound property to any registered property listeners.
5270 * @param propertyName the property that changed
5271 * @param oldValue the old property value
5272 * @param newValue the new property value
5276 public void firePropertyChange(String propertyName, byte oldValue,
5279 if (changeSupport != null)
5280 changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
5281 new Byte(newValue));
5285 * Report a change in a bound property to any registered property listeners.
5287 * @param propertyName the property that changed
5288 * @param oldValue the old property value
5289 * @param newValue the new property value
5293 public void firePropertyChange(String propertyName, char oldValue,
5296 if (changeSupport != null)
5297 changeSupport.firePropertyChange(propertyName, new Character(oldValue),
5298 new Character(newValue));
5302 * Report a change in a bound property to any registered property listeners.
5304 * @param propertyName the property that changed
5305 * @param oldValue the old property value
5306 * @param newValue the new property value
5310 public void firePropertyChange(String propertyName, short oldValue,
5313 if (changeSupport != null)
5314 changeSupport.firePropertyChange(propertyName, new Short(oldValue),
5315 new Short(newValue));
5319 * Report a change in a bound property to any registered property listeners.
5321 * @param propertyName the property that changed
5322 * @param oldValue the old property value
5323 * @param newValue the new property value
5327 public void firePropertyChange(String propertyName, long oldValue,
5330 if (changeSupport != null)
5331 changeSupport.firePropertyChange(propertyName, new Long(oldValue),
5332 new Long(newValue));
5336 * Report a change in a bound property to any registered property listeners.
5338 * @param propertyName the property that changed
5339 * @param oldValue the old property value
5340 * @param newValue the new property value
5344 public void firePropertyChange(String propertyName, float oldValue,
5347 if (changeSupport != null)
5348 changeSupport.firePropertyChange(propertyName, new Float(oldValue),
5349 new Float(newValue));
5354 * Report a change in a bound property to any registered property listeners.
5356 * @param propertyName the property that changed
5357 * @param oldValue the old property value
5358 * @param newValue the new property value
5362 public void firePropertyChange(String propertyName, double oldValue,
5365 if (changeSupport != null)
5366 changeSupport.firePropertyChange(propertyName, new Double(oldValue),
5367 new Double(newValue));
5371 * Sets the text layout orientation of this component. New components default
5372 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
5373 * the current component, while
5374 * {@link #applyComponentOrientation(ComponentOrientation)} affects the
5377 * @param o the new orientation (<code>null</code> is accepted)
5378 * @see #getComponentOrientation()
5380 public void setComponentOrientation(ComponentOrientation o)
5383 ComponentOrientation oldOrientation = componentOrientation;
5384 componentOrientation = o;
5385 firePropertyChange("componentOrientation", oldOrientation, o);
5389 * Determines the text layout orientation used by this component.
5391 * @return the component orientation (this can be <code>null</code>)
5392 * @see #setComponentOrientation(ComponentOrientation)
5394 public ComponentOrientation getComponentOrientation()
5396 return componentOrientation;
5400 * Sets the text layout orientation of this component. New components default
5401 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
5402 * entire hierarchy, while
5403 * {@link #setComponentOrientation(ComponentOrientation)} affects only the
5404 * current component.
5406 * @param o the new orientation
5407 * @throws NullPointerException if o is null
5408 * @see #getComponentOrientation()
5411 public void applyComponentOrientation(ComponentOrientation o)
5413 setComponentOrientation(o);
5417 * Returns the accessibility framework context of this class. Component is
5418 * not accessible, so the default implementation returns null. Subclasses
5419 * must override this behavior, and return an appropriate subclass of
5420 * {@link AccessibleAWTComponent}.
5422 * @return the accessibility context
5424 public AccessibleContext getAccessibleContext()
5430 // Helper methods; some are package visible for use by subclasses.
5433 * Subclasses should override this to return unique component names like
5436 * @return the generated name for this component
5438 String generateName()
5440 // Component is abstract.
5445 * Sets the peer for this component.
5447 * @param peer the new peer
5449 final void setPeer(ComponentPeer peer)
5455 * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
5456 * event ({@link Event}).
5458 * @param e an AWT 1.1 event to translate
5460 * @return an AWT 1.0 event representing e
5462 static Event translateEvent (AWTEvent e)
5464 Object target = e.getSource ();
5465 Event translated = null;
5467 if (e instanceof WindowEvent)
5469 WindowEvent we = (WindowEvent) e;
5475 case WindowEvent.WINDOW_DEICONIFIED:
5476 newId = Event.WINDOW_DEICONIFY;
5478 case WindowEvent.WINDOW_CLOSED:
5479 case WindowEvent.WINDOW_CLOSING:
5480 newId = Event.WINDOW_DESTROY;
5482 case WindowEvent.WINDOW_ICONIFIED:
5483 newId = Event.WINDOW_ICONIFY;
5485 case WindowEvent.WINDOW_GAINED_FOCUS:
5486 newId = Event.GOT_FOCUS;
5488 case WindowEvent.WINDOW_LOST_FOCUS:
5489 newId = Event.LOST_FOCUS;
5495 translated = new Event(target, 0, newId, 0, 0, 0, 0);
5497 else if (e instanceof InputEvent)
5499 InputEvent ie = (InputEvent) e;
5500 long when = ie.getWhen ();
5503 int id = e.getID ();
5506 int mods = ie.getModifiersEx ();
5508 if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
5509 oldMods |= Event.META_MASK;
5510 else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
5511 oldMods |= Event.ALT_MASK;
5513 if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
5514 oldMods |= Event.SHIFT_MASK;
5516 if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
5517 oldMods |= Event.CTRL_MASK;
5519 if ((mods & InputEvent.META_DOWN_MASK) != 0)
5520 oldMods |= Event.META_MASK;
5522 if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
5523 oldMods |= Event.ALT_MASK;
5525 if (e instanceof MouseEvent && !ignoreOldMouseEvents())
5527 if (id == MouseEvent.MOUSE_PRESSED)
5528 oldID = Event.MOUSE_DOWN;
5529 else if (id == MouseEvent.MOUSE_RELEASED)
5530 oldID = Event.MOUSE_UP;
5531 else if (id == MouseEvent.MOUSE_MOVED)
5532 oldID = Event.MOUSE_MOVE;
5533 else if (id == MouseEvent.MOUSE_DRAGGED)
5534 oldID = Event.MOUSE_DRAG;
5535 else if (id == MouseEvent.MOUSE_ENTERED)
5536 oldID = Event.MOUSE_ENTER;
5537 else if (id == MouseEvent.MOUSE_EXITED)
5538 oldID = Event.MOUSE_EXIT;
5540 // No analogous AWT 1.0 mouse event.
5543 MouseEvent me = (MouseEvent) e;
5545 translated = new Event (target, when, oldID,
5546 me.getX (), me.getY (), 0, oldMods);
5548 else if (e instanceof KeyEvent)
5550 if (id == KeyEvent.KEY_PRESSED)
5551 oldID = Event.KEY_PRESS;
5552 else if (e.getID () == KeyEvent.KEY_RELEASED)
5553 oldID = Event.KEY_RELEASE;
5555 // No analogous AWT 1.0 key event.
5559 int newKey = ((KeyEvent) e).getKeyCode ();
5562 case KeyEvent.VK_BACK_SPACE:
5563 oldKey = Event.BACK_SPACE;
5565 case KeyEvent.VK_CAPS_LOCK:
5566 oldKey = Event.CAPS_LOCK;
5568 case KeyEvent.VK_DELETE:
5569 oldKey = Event.DELETE;
5571 case KeyEvent.VK_DOWN:
5572 case KeyEvent.VK_KP_DOWN:
5573 oldKey = Event.DOWN;
5575 case KeyEvent.VK_END:
5578 case KeyEvent.VK_ENTER:
5579 oldKey = Event.ENTER;
5581 case KeyEvent.VK_ESCAPE:
5582 oldKey = Event.ESCAPE;
5584 case KeyEvent.VK_F1:
5587 case KeyEvent.VK_F10:
5590 case KeyEvent.VK_F11:
5593 case KeyEvent.VK_F12:
5596 case KeyEvent.VK_F2:
5599 case KeyEvent.VK_F3:
5602 case KeyEvent.VK_F4:
5605 case KeyEvent.VK_F5:
5608 case KeyEvent.VK_F6:
5611 case KeyEvent.VK_F7:
5614 case KeyEvent.VK_F8:
5617 case KeyEvent.VK_F9:
5620 case KeyEvent.VK_HOME:
5621 oldKey = Event.HOME;
5623 case KeyEvent.VK_INSERT:
5624 oldKey = Event.INSERT;
5626 case KeyEvent.VK_LEFT:
5627 case KeyEvent.VK_KP_LEFT:
5628 oldKey = Event.LEFT;
5630 case KeyEvent.VK_NUM_LOCK:
5631 oldKey = Event.NUM_LOCK;
5633 case KeyEvent.VK_PAUSE:
5634 oldKey = Event.PAUSE;
5636 case KeyEvent.VK_PAGE_DOWN:
5637 oldKey = Event.PGDN;
5639 case KeyEvent.VK_PAGE_UP:
5640 oldKey = Event.PGUP;
5642 case KeyEvent.VK_PRINTSCREEN:
5643 oldKey = Event.PRINT_SCREEN;
5645 case KeyEvent.VK_RIGHT:
5646 case KeyEvent.VK_KP_RIGHT:
5647 oldKey = Event.RIGHT;
5649 case KeyEvent.VK_SCROLL_LOCK:
5650 oldKey = Event.SCROLL_LOCK;
5652 case KeyEvent.VK_TAB:
5655 case KeyEvent.VK_UP:
5656 case KeyEvent.VK_KP_UP:
5660 oldKey = ((KeyEvent) e).getKeyChar();
5663 translated = new Event (target, when, oldID,
5664 0, 0, oldKey, oldMods);
5667 else if (e instanceof AdjustmentEvent)
5669 AdjustmentEvent ae = (AdjustmentEvent) e;
5670 int type = ae.getAdjustmentType();
5672 if (type == AdjustmentEvent.BLOCK_DECREMENT)
5673 oldType = Event.SCROLL_PAGE_UP;
5674 else if (type == AdjustmentEvent.BLOCK_INCREMENT)
5675 oldType = Event.SCROLL_PAGE_DOWN;
5676 else if (type == AdjustmentEvent.TRACK)
5677 oldType = Event.SCROLL_ABSOLUTE;
5678 else if (type == AdjustmentEvent.UNIT_DECREMENT)
5679 oldType = Event.SCROLL_LINE_UP;
5680 else if (type == AdjustmentEvent.UNIT_INCREMENT)
5681 oldType = Event.SCROLL_LINE_DOWN;
5684 translated = new Event(target, oldType, new Integer(ae.getValue()));
5686 else if (e instanceof ActionEvent)
5687 translated = new Event (target, Event.ACTION_EVENT,
5688 ((ActionEvent) e).getActionCommand ());
5694 * Implementation of dispatchEvent. Allows trusted package classes
5695 * to dispatch additional events first. This implementation first
5696 * translates <code>e</code> to an AWT 1.0 event and sends the
5697 * result to {@link #postEvent}. If the AWT 1.0 event is not
5698 * handled, and events of type <code>e</code> are enabled for this
5699 * component, e is passed on to {@link #processEvent}.
5701 * @param e the event to dispatch
5703 void dispatchEventImpl(AWTEvent e)
5705 // Update the component's knowledge about the size.
5706 // Important: Please look at the big comment in ComponentReshapeEvent
5707 // to learn why we did it this way. If you change this code, make
5708 // sure that the peer->AWT bounds update still works.
5709 // (for instance: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29448 )
5710 if (e instanceof ComponentReshapeEvent)
5712 ComponentReshapeEvent reshape = (ComponentReshapeEvent) e;
5715 width = reshape.width;
5716 height = reshape.height;
5720 // Retarget focus events before dispatching it to the KeyboardFocusManager
5721 // in order to handle lightweight components properly.
5722 boolean dispatched = false;
5723 if (! e.isFocusManagerEvent)
5725 e = KeyboardFocusManager.retargetFocusEvent(e);
5726 dispatched = KeyboardFocusManager.getCurrentKeyboardFocusManager()
5732 // Give toolkit a chance to dispatch the event
5733 // to globally registered listeners.
5734 Toolkit.getDefaultToolkit().globalDispatchEvent(e);
5738 if (eventTypeEnabled(e.id))
5743 Event oldEvent = translateEvent(e);
5744 if (oldEvent != null)
5745 postEvent (oldEvent);
5748 peer.handleEvent(e);
5753 * Tells whether or not an event type is enabled.
5755 boolean eventTypeEnabled (int type)
5757 if (type > AWTEvent.RESERVED_ID_MAX)
5762 case HierarchyEvent.HIERARCHY_CHANGED:
5763 return (hierarchyListener != null
5764 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0);
5766 case HierarchyEvent.ANCESTOR_MOVED:
5767 case HierarchyEvent.ANCESTOR_RESIZED:
5768 return (hierarchyBoundsListener != null
5769 || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0);
5771 case ComponentEvent.COMPONENT_HIDDEN:
5772 case ComponentEvent.COMPONENT_MOVED:
5773 case ComponentEvent.COMPONENT_RESIZED:
5774 case ComponentEvent.COMPONENT_SHOWN:
5775 return (componentListener != null
5776 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
5778 case KeyEvent.KEY_PRESSED:
5779 case KeyEvent.KEY_RELEASED:
5780 case KeyEvent.KEY_TYPED:
5781 return (keyListener != null
5782 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
5784 case MouseEvent.MOUSE_CLICKED:
5785 case MouseEvent.MOUSE_ENTERED:
5786 case MouseEvent.MOUSE_EXITED:
5787 case MouseEvent.MOUSE_PRESSED:
5788 case MouseEvent.MOUSE_RELEASED:
5789 return (mouseListener != null
5790 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
5791 case MouseEvent.MOUSE_MOVED:
5792 case MouseEvent.MOUSE_DRAGGED:
5793 return (mouseMotionListener != null
5794 || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
5795 case MouseEvent.MOUSE_WHEEL:
5796 return (mouseWheelListener != null
5797 || (eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0);
5799 case FocusEvent.FOCUS_GAINED:
5800 case FocusEvent.FOCUS_LOST:
5801 return (focusListener != null
5802 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
5804 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5805 case InputMethodEvent.CARET_POSITION_CHANGED:
5806 return (inputMethodListener != null
5807 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
5809 case PaintEvent.PAINT:
5810 case PaintEvent.UPDATE:
5811 return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
5819 * Returns <code>true</code> when this component and all of its ancestors
5820 * are visible, <code>false</code> otherwise.
5822 * @return <code>true</code> when this component and all of its ancestors
5823 * are visible, <code>false</code> otherwise
5825 boolean isHierarchyVisible()
5827 boolean visible = isVisible();
5828 Component comp = parent;
5829 while (comp != null && visible)
5833 visible = visible && comp.isVisible();
5839 * Returns the mouse pointer position relative to this Component's
5842 * @return relative mouse pointer position
5844 * @throws HeadlessException if in a headless environment
5846 public Point getMousePosition() throws HeadlessException
5848 return getMousePositionHelper(true);
5851 Point getMousePositionHelper(boolean allowChildren) throws HeadlessException
5853 if (GraphicsEnvironment.isHeadless())
5854 throw new HeadlessException("can't get mouse position"
5855 + " in headless environment");
5859 Component parent = this;
5860 int windowRelativeXOffset = 0;
5861 int windowRelativeYOffset = 0;
5862 while (parent != null && !(parent instanceof Window))
5864 windowRelativeXOffset += parent.getX();
5865 windowRelativeYOffset += parent.getY();
5866 parent = parent.getParent();
5871 Window window = (Window) parent;
5872 if (!Toolkit.getDefaultToolkit()
5873 .getMouseInfoPeer().isWindowUnderMouse(window))
5876 PointerInfo info = MouseInfo.getPointerInfo();
5877 Point mouseLocation = info.getLocation();
5878 Point windowLocation = window.getLocationOnScreen();
5880 int x = mouseLocation.x - windowLocation.x;
5881 int y = mouseLocation.y - windowLocation.y;
5883 if (!mouseOverComponent(window.getComponentAt(x, y), allowChildren))
5886 return new Point(x - windowRelativeXOffset, y - windowRelativeYOffset);
5889 boolean mouseOverComponent(Component component, boolean allowChildren)
5891 return component == this;
5895 * This method is used to implement transferFocus(). CHILD is the child
5896 * making the request. This is overridden by Container; when called for an
5897 * ordinary component there is no child and so we always return null.
5899 * FIXME: is this still needed, in light of focus traversal policies?
5901 * @param child the component making the request
5902 * @return the next component to focus on
5904 Component findNextFocusComponent(Component child)
5910 * Deserializes this component. This regenerates all serializable listeners
5911 * which were registered originally.
5913 * @param s the stream to read from
5914 * @throws ClassNotFoundException if deserialization fails
5915 * @throws IOException if the stream fails
5917 private void readObject(ObjectInputStream s)
5918 throws ClassNotFoundException, IOException
5920 s.defaultReadObject();
5921 String key = (String) s.readObject();
5924 Object listener = s.readObject();
5925 if ("componentL".equals(key))
5926 addComponentListener((ComponentListener) listener);
5927 else if ("focusL".equals(key))
5928 addFocusListener((FocusListener) listener);
5929 else if ("keyL".equals(key))
5930 addKeyListener((KeyListener) listener);
5931 else if ("mouseL".equals(key))
5932 addMouseListener((MouseListener) listener);
5933 else if ("mouseMotionL".equals(key))
5934 addMouseMotionListener((MouseMotionListener) listener);
5935 else if ("inputMethodL".equals(key))
5936 addInputMethodListener((InputMethodListener) listener);
5937 else if ("hierarchyL".equals(key))
5938 addHierarchyListener((HierarchyListener) listener);
5939 else if ("hierarchyBoundsL".equals(key))
5940 addHierarchyBoundsListener((HierarchyBoundsListener) listener);
5941 else if ("mouseWheelL".equals(key))
5942 addMouseWheelListener((MouseWheelListener) listener);
5943 key = (String) s.readObject();
5948 * Serializes this component. This ignores all listeners which do not
5949 * implement Serializable, but includes those that do.
5951 * @param s the stream to write to
5952 * @throws IOException if the stream fails
5954 private void writeObject(ObjectOutputStream s) throws IOException
5956 s.defaultWriteObject();
5957 AWTEventMulticaster.save(s, "componentL", componentListener);
5958 AWTEventMulticaster.save(s, "focusL", focusListener);
5959 AWTEventMulticaster.save(s, "keyL", keyListener);
5960 AWTEventMulticaster.save(s, "mouseL", mouseListener);
5961 AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5962 AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5963 AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5964 AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5965 AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5966 s.writeObject(null);
5973 * This class fixes the bounds for a Heavyweight component that
5974 * is placed inside a Lightweight container. When the lightweight is
5975 * moved or resized, setBounds for the lightweight peer does nothing.
5976 * Therefore, it was never moved on the screen. This class is
5977 * attached to the lightweight, and it adjusts the position and size
5978 * of the peer when notified.
5979 * This is the same for show and hide.
5981 class HeavyweightInLightweightListener
5982 implements ComponentListener
5986 * Constructor. Adds component listener to lightweight parent.
5988 * @param parent - the lightweight container.
5990 public HeavyweightInLightweightListener(Container parent)
5992 parent.addComponentListener(this);
5996 * This method is called when the component is resized.
5998 * @param event the <code>ComponentEvent</code> indicating the resize
6000 public void componentResized(ComponentEvent event)
6002 // Nothing to do here, componentMoved will be called.
6006 * This method is called when the component is moved.
6008 * @param event the <code>ComponentEvent</code> indicating the move
6010 public void componentMoved(ComponentEvent event)
6013 peer.setBounds(x, y, width, height);
6017 * This method is called when the component is made visible.
6019 * @param event the <code>ComponentEvent</code> indicating the visibility
6021 public void componentShown(ComponentEvent event)
6028 * This method is called when the component is hidden.
6030 * @param event the <code>ComponentEvent</code> indicating the visibility
6032 public void componentHidden(ComponentEvent event)
6040 * This class provides accessibility support for subclasses of container.
6042 * @author Eric Blake (ebb9@email.byu.edu)
6044 * @status updated to 1.4
6046 protected abstract class AccessibleAWTComponent extends AccessibleContext
6047 implements Serializable, AccessibleComponent
6050 * Compatible with JDK 1.3+.
6052 private static final long serialVersionUID = 642321655757800191L;
6055 * Converts show/hide events to PropertyChange events, and is registered
6056 * as a component listener on this component.
6058 * @serial the component handler
6060 protected ComponentListener accessibleAWTComponentHandler
6061 = new AccessibleAWTComponentHandler();
6064 * Converts focus events to PropertyChange events, and is registered
6065 * as a focus listener on this component.
6067 * @serial the focus handler
6069 protected FocusListener accessibleAWTFocusHandler
6070 = new AccessibleAWTFocusHandler();
6073 * The default constructor.
6075 protected AccessibleAWTComponent()
6077 Component.this.addComponentListener(accessibleAWTComponentHandler);
6078 Component.this.addFocusListener(accessibleAWTFocusHandler);
6082 * Adds a global property change listener to the accessible component.
6084 * @param l the listener to add
6085 * @see #ACCESSIBLE_NAME_PROPERTY
6086 * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
6087 * @see #ACCESSIBLE_STATE_PROPERTY
6088 * @see #ACCESSIBLE_VALUE_PROPERTY
6089 * @see #ACCESSIBLE_SELECTION_PROPERTY
6090 * @see #ACCESSIBLE_TEXT_PROPERTY
6091 * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
6093 public void addPropertyChangeListener(PropertyChangeListener l)
6095 Component.this.addPropertyChangeListener(l);
6096 super.addPropertyChangeListener(l);
6100 * Removes a global property change listener from this accessible
6103 * @param l the listener to remove
6105 public void removePropertyChangeListener(PropertyChangeListener l)
6107 Component.this.removePropertyChangeListener(l);
6108 super.removePropertyChangeListener(l);
6112 * Returns the accessible name of this component. It is almost always
6113 * wrong to return getName(), since it is not localized. In fact, for
6114 * things like buttons, this should be the text of the button, not the
6115 * name of the object. The tooltip text might also be appropriate.
6118 * @see #setAccessibleName(String)
6120 public String getAccessibleName()
6122 return accessibleName;
6126 * Returns a brief description of this accessible context. This should
6129 * @return a description of this component
6130 * @see #setAccessibleDescription(String)
6132 public String getAccessibleDescription()
6134 return accessibleDescription;
6138 * Returns the role of this component.
6140 * @return the accessible role
6142 public AccessibleRole getAccessibleRole()
6144 return AccessibleRole.AWT_COMPONENT;
6148 * Returns a state set describing this component's state.
6150 * @return a new state set
6151 * @see AccessibleState
6153 public AccessibleStateSet getAccessibleStateSet()
6155 AccessibleStateSet s = new AccessibleStateSet();
6156 if (Component.this.isEnabled())
6157 s.add(AccessibleState.ENABLED);
6159 s.add(AccessibleState.FOCUSABLE);
6161 s.add(AccessibleState.FOCUSED);
6162 // Note: While the java.awt.Component has an 'opaque' property, it
6163 // seems that it is not added to the accessible state set here, even
6164 // if this property is true. However, it is handled for
6165 // javax.swing.JComponent, so we add it there.
6166 if (Component.this.isShowing())
6167 s.add(AccessibleState.SHOWING);
6168 if (Component.this.isVisible())
6169 s.add(AccessibleState.VISIBLE);
6174 * Returns the parent of this component, if it is accessible.
6176 * @return the accessible parent
6178 public Accessible getAccessibleParent()
6180 if (accessibleParent == null)
6182 Container parent = getParent();
6183 accessibleParent = parent instanceof Accessible
6184 ? (Accessible) parent : null;
6186 return accessibleParent;
6190 * Returns the index of this component in its accessible parent.
6192 * @return the index, or -1 if the parent is not accessible
6193 * @see #getAccessibleParent()
6195 public int getAccessibleIndexInParent()
6197 if (getAccessibleParent() == null)
6199 AccessibleContext context
6200 = ((Component) accessibleParent).getAccessibleContext();
6201 if (context == null)
6203 for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
6204 if (context.getAccessibleChild(i) == Component.this)
6210 * Returns the number of children of this component which implement
6211 * Accessible. Subclasses must override this if they can have children.
6213 * @return the number of accessible children, default 0
6215 public int getAccessibleChildrenCount()
6221 * Returns the ith accessible child. Subclasses must override this if
6222 * they can have children.
6224 * @return the ith accessible child, or null
6225 * @see #getAccessibleChildrenCount()
6227 public Accessible getAccessibleChild(int i)
6233 * Returns the locale of this component.
6235 * @return the locale
6236 * @throws IllegalComponentStateException if the locale is unknown
6238 public Locale getLocale()
6240 return Component.this.getLocale();
6244 * Returns this, since it is an accessible component.
6246 * @return the accessible component
6248 public AccessibleComponent getAccessibleComponent()
6254 * Gets the background color.
6256 * @return the background color
6257 * @see #setBackground(Color)
6259 public Color getBackground()
6261 return Component.this.getBackground();
6265 * Sets the background color.
6267 * @param c the background color
6268 * @see #getBackground()
6271 public void setBackground(Color c)
6273 Component.this.setBackground(c);
6277 * Gets the foreground color.
6279 * @return the foreground color
6280 * @see #setForeground(Color)
6282 public Color getForeground()
6284 return Component.this.getForeground();
6288 * Sets the foreground color.
6290 * @param c the foreground color
6291 * @see #getForeground()
6293 public void setForeground(Color c)
6295 Component.this.setForeground(c);
6301 * @return the cursor
6302 * @see #setCursor(Cursor)
6304 public Cursor getCursor()
6306 return Component.this.getCursor();
6312 * @param cursor the cursor
6315 public void setCursor(Cursor cursor)
6317 Component.this.setCursor(cursor);
6324 * @see #setFont(Font)
6326 public Font getFont()
6328 return Component.this.getFont();
6337 public void setFont(Font f)
6339 Component.this.setFont(f);
6343 * Gets the font metrics for a font.
6345 * @param f the font to look up
6346 * @return its metrics
6347 * @throws NullPointerException if f is null
6350 public FontMetrics getFontMetrics(Font f)
6352 return Component.this.getFontMetrics(f);
6356 * Tests if the component is enabled.
6358 * @return true if the component is enabled
6359 * @see #setEnabled(boolean)
6360 * @see #getAccessibleStateSet()
6361 * @see AccessibleState#ENABLED
6363 public boolean isEnabled()
6365 return Component.this.isEnabled();
6369 * Set whether the component is enabled.
6371 * @param b the new enabled status
6374 public void setEnabled(boolean b)
6376 Component.this.setEnabled(b);
6380 * Test whether the component is visible (not necesarily showing).
6382 * @return true if it is visible
6383 * @see #setVisible(boolean)
6384 * @see #getAccessibleStateSet()
6385 * @see AccessibleState#VISIBLE
6387 public boolean isVisible()
6389 return Component.this.isVisible();
6393 * Sets the visibility of this component.
6395 * @param b the desired visibility
6398 public void setVisible(boolean b)
6400 Component.this.setVisible(b);
6404 * Tests if the component is showing.
6406 * @return true if this is showing
6408 public boolean isShowing()
6410 return Component.this.isShowing();
6414 * Tests if the point is contained in this component.
6416 * @param p the point to check
6417 * @return true if it is contained
6418 * @throws NullPointerException if p is null
6420 public boolean contains(Point p)
6422 return Component.this.contains(p.x, p.y);
6426 * Returns the location of this object on the screen, or null if it is
6429 * @return the location relative to screen coordinates, if showing
6431 * @see #getLocation()
6433 public Point getLocationOnScreen()
6435 return Component.this.isShowing() ? Component.this.getLocationOnScreen()
6440 * Returns the location of this object relative to its parent's coordinate
6441 * system, or null if it is not showing.
6443 * @return the location
6445 * @see #getLocationOnScreen()
6447 public Point getLocation()
6449 return Component.this.getLocation();
6453 * Sets the location of this relative to its parent's coordinate system.
6455 * @param p the location
6456 * @throws NullPointerException if p is null
6457 * @see #getLocation()
6459 public void setLocation(Point p)
6461 Component.this.setLocation(p.x, p.y);
6465 * Gets the bounds of this component, or null if it is not on screen.
6467 * @return the bounds
6468 * @see #contains(Point)
6469 * @see #setBounds(Rectangle)
6471 public Rectangle getBounds()
6473 return Component.this.getBounds();
6477 * Sets the bounds of this component.
6479 * @param r the bounds
6480 * @throws NullPointerException if r is null
6483 public void setBounds(Rectangle r)
6485 Component.this.setBounds(r.x, r.y, r.width, r.height);
6489 * Gets the size of this component, or null if it is not showing.
6492 * @see #setSize(Dimension)
6494 public Dimension getSize()
6496 return Component.this.getSize();
6500 * Sets the size of this component.
6503 * @throws NullPointerException if d is null
6506 public void setSize(Dimension d)
6508 Component.this.setSize(d.width, d.height);
6512 * Returns the Accessible child at a point relative to the coordinate
6513 * system of this component, if one exists, or null. Since components
6514 * have no children, subclasses must override this to get anything besides
6517 * @param p the point to check
6518 * @return the accessible child at that point
6519 * @throws NullPointerException if p is null
6521 public Accessible getAccessibleAt(Point p)
6527 * Tests whether this component can accept focus.
6529 * @return true if this is focus traversable
6530 * @see #getAccessibleStateSet ()
6531 * @see AccessibleState#FOCUSABLE
6532 * @see AccessibleState#FOCUSED
6534 public boolean isFocusTraversable ()
6536 return Component.this.isFocusTraversable ();
6540 * Requests focus for this component.
6542 * @see #isFocusTraversable ()
6544 public void requestFocus ()
6546 Component.this.requestFocus ();
6550 * Adds a focus listener.
6552 * @param l the listener to add
6554 public void addFocusListener(FocusListener l)
6556 Component.this.addFocusListener(l);
6560 * Removes a focus listener.
6562 * @param l the listener to remove
6564 public void removeFocusListener(FocusListener l)
6566 Component.this.removeFocusListener(l);
6570 * Converts component changes into property changes.
6572 * @author Eric Blake (ebb9@email.byu.edu)
6574 * @status updated to 1.4
6576 protected class AccessibleAWTComponentHandler implements ComponentListener
6579 * Default constructor.
6581 protected AccessibleAWTComponentHandler()
6583 // Nothing to do here.
6587 * Convert a component hidden to a property change.
6589 * @param e the event to convert
6591 public void componentHidden(ComponentEvent e)
6593 AccessibleAWTComponent.this.firePropertyChange
6594 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
6598 * Convert a component shown to a property change.
6600 * @param e the event to convert
6602 public void componentShown(ComponentEvent e)
6604 AccessibleAWTComponent.this.firePropertyChange
6605 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
6609 * Moving a component does not affect properties.
6613 public void componentMoved(ComponentEvent e)
6615 // Nothing to do here.
6619 * Resizing a component does not affect properties.
6623 public void componentResized(ComponentEvent e)
6625 // Nothing to do here.
6627 } // class AccessibleAWTComponentHandler
6630 * Converts focus changes into property changes.
6632 * @author Eric Blake (ebb9@email.byu.edu)
6634 * @status updated to 1.4
6636 protected class AccessibleAWTFocusHandler implements FocusListener
6639 * Default constructor.
6641 protected AccessibleAWTFocusHandler()
6643 // Nothing to do here.
6647 * Convert a focus gained to a property change.
6649 * @param e the event to convert
6651 public void focusGained(FocusEvent e)
6653 AccessibleAWTComponent.this.firePropertyChange
6654 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
6658 * Convert a focus lost to a property change.
6660 * @param e the event to convert
6662 public void focusLost(FocusEvent e)
6664 AccessibleAWTComponent.this.firePropertyChange
6665 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
6667 } // class AccessibleAWTComponentHandler
6668 } // class AccessibleAWTComponent
6671 * This class provides support for blitting offscreen surfaces to a
6674 * @see BufferStrategy
6678 protected class BltBufferStrategy extends BufferStrategy
6681 * The capabilities of the image buffer.
6683 protected BufferCapabilities caps;
6686 * The back buffers used in this strategy.
6688 protected VolatileImage[] backBuffers;
6691 * Whether or not the image buffer resources are allocated and
6692 * ready to be drawn into.
6694 protected boolean validatedContents;
6697 * The width of the back buffers.
6699 protected int width;
6702 * The height of the back buffers.
6704 protected int height;
6709 private VolatileImage frontBuffer;
6712 * Creates a blitting buffer strategy.
6714 * @param numBuffers the number of buffers, including the front
6716 * @param caps the capabilities of this strategy
6718 protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
6721 createBackBuffers(numBuffers - 1);
6723 height = getHeight();
6727 * Initializes the backBuffers field with an array of numBuffers
6730 * @param numBuffers the number of backbuffers to create
6732 protected void createBackBuffers(int numBuffers)
6734 GraphicsConfiguration c =
6735 GraphicsEnvironment.getLocalGraphicsEnvironment()
6736 .getDefaultScreenDevice().getDefaultConfiguration();
6738 backBuffers = new VolatileImage[numBuffers];
6740 for (int i = 0; i < numBuffers; i++)
6741 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6745 * Retrieves the capabilities of this buffer strategy.
6747 * @return the capabilities of this buffer strategy
6749 public BufferCapabilities getCapabilities()
6755 * Retrieves a graphics object that can be used to draw into this
6756 * strategy's image buffer.
6758 * @return a graphics object
6760 public Graphics getDrawGraphics()
6762 // Return the backmost buffer's graphics.
6763 return backBuffers[0].getGraphics();
6767 * Bring the contents of the back buffer to the front buffer.
6771 GraphicsConfiguration c =
6772 GraphicsEnvironment.getLocalGraphicsEnvironment()
6773 .getDefaultScreenDevice().getDefaultConfiguration();
6775 // draw the front buffer.
6776 getGraphics().drawImage(backBuffers[backBuffers.length - 1],
6777 width, height, null);
6779 BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
6781 // blit the back buffers.
6782 for (int i = backBuffers.length - 1; i > 0 ; i--)
6783 backBuffers[i] = backBuffers[i - 1];
6785 // create new backmost buffer.
6786 if (f == BufferCapabilities.FlipContents.UNDEFINED)
6787 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6789 // create new backmost buffer and clear it to the background
6791 if (f == BufferCapabilities.FlipContents.BACKGROUND)
6793 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6794 backBuffers[0].getGraphics().clearRect(0, 0, width, height);
6797 // FIXME: set the backmost buffer to the prior contents of the
6798 // front buffer. How do we retrieve the contents of the front
6801 // if (f == BufferCapabilities.FlipContents.PRIOR)
6803 // set the backmost buffer to a copy of the new front buffer.
6804 if (f == BufferCapabilities.FlipContents.COPIED)
6805 backBuffers[0] = backBuffers[backBuffers.length - 1];
6809 * Re-create the image buffer resources if they've been lost.
6811 protected void revalidate()
6813 GraphicsConfiguration c =
6814 GraphicsEnvironment.getLocalGraphicsEnvironment()
6815 .getDefaultScreenDevice().getDefaultConfiguration();
6817 for (int i = 0; i < backBuffers.length; i++)
6819 int result = backBuffers[i].validate(c);
6820 if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6821 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6823 validatedContents = true;
6827 * Returns whether or not the image buffer resources have been
6830 * @return true if the resources have been lost, false otherwise
6832 public boolean contentsLost()
6834 for (int i = 0; i < backBuffers.length; i++)
6836 if (backBuffers[i].contentsLost())
6838 validatedContents = false;
6842 // we know that the buffer resources are valid now because we
6843 // just checked them
6844 validatedContents = true;
6849 * Returns whether or not the image buffer resources have been
6852 * @return true if the resources have been restored, false
6855 public boolean contentsRestored()
6857 GraphicsConfiguration c =
6858 GraphicsEnvironment.getLocalGraphicsEnvironment()
6859 .getDefaultScreenDevice().getDefaultConfiguration();
6861 boolean imageRestored = false;
6863 for (int i = 0; i < backBuffers.length; i++)
6865 int result = backBuffers[i].validate(c);
6866 if (result == VolatileImage.IMAGE_RESTORED)
6867 imageRestored = true;
6868 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6871 // we know that the buffer resources are valid now because we
6872 // just checked them
6873 validatedContents = true;
6874 return imageRestored;
6879 * This class provides support for flipping component buffers. It
6880 * can only be used on Canvases and Windows.
6884 protected class FlipBufferStrategy extends BufferStrategy
6887 * The number of buffers.
6889 protected int numBuffers;
6892 * The capabilities of this buffering strategy.
6894 protected BufferCapabilities caps;
6897 * An Image reference to the drawing buffer.
6899 protected Image drawBuffer;
6902 * A VolatileImage reference to the drawing buffer.
6904 protected VolatileImage drawVBuffer;
6907 * Whether or not the image buffer resources are allocated and
6908 * ready to be drawn into.
6910 protected boolean validatedContents;
6913 * The width of the back buffer.
6918 * The height of the back buffer.
6923 * Creates a flipping buffer strategy. The only supported
6924 * strategy for FlipBufferStrategy itself is a double-buffer page
6925 * flipping strategy. It forms the basis for more complex derived
6928 * @param numBuffers the number of buffers
6929 * @param caps the capabilities of this buffering strategy
6931 * @throws AWTException if the requested
6932 * number-of-buffers/capabilities combination is not supported
6934 protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
6939 height = getHeight();
6942 createBuffers(numBuffers, caps);
6945 drawVBuffer = peer.createVolatileImage(width, height);
6946 drawBuffer = drawVBuffer;
6951 * Creates a multi-buffer flipping strategy. The number of
6952 * buffers must be greater than one and the buffer capabilities
6953 * must specify page flipping.
6955 * @param numBuffers the number of flipping buffers; must be
6957 * @param caps the buffering capabilities; caps.isPageFlipping()
6960 * @throws IllegalArgumentException if numBuffers is not greater
6961 * than one or if the page flipping capability is not requested
6963 * @throws AWTException if the requested flipping strategy is not
6966 protected void createBuffers(int numBuffers, BufferCapabilities caps)
6969 if (numBuffers <= 1)
6970 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6971 + " numBuffers must be greater than"
6974 if (!caps.isPageFlipping())
6975 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6976 + " flipping must be a specified"
6979 peer.createBuffers(numBuffers, caps);
6983 * Return a direct reference to the back buffer image.
6985 * @return a direct reference to the back buffer image.
6987 protected Image getBackBuffer()
6989 return peer.getBackBuffer();
6993 * Perform a flip operation to transfer the contents of the back
6994 * buffer to the front buffer.
6996 protected void flip(BufferCapabilities.FlipContents flipAction)
6998 peer.flip(flipAction);
7002 * Release the back buffer's resources.
7004 protected void destroyBuffers()
7006 peer.destroyBuffers();
7010 * Retrieves the capabilities of this buffer strategy.
7012 * @return the capabilities of this buffer strategy
7014 public BufferCapabilities getCapabilities()
7020 * Retrieves a graphics object that can be used to draw into this
7021 * strategy's image buffer.
7023 * @return a graphics object
7025 public Graphics getDrawGraphics()
7027 return drawVBuffer.getGraphics();
7031 * Re-create the image buffer resources if they've been lost.
7033 protected void revalidate()
7035 GraphicsConfiguration c =
7036 GraphicsEnvironment.getLocalGraphicsEnvironment()
7037 .getDefaultScreenDevice().getDefaultConfiguration();
7039 if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
7040 drawVBuffer = peer.createVolatileImage(width, height);
7041 validatedContents = true;
7045 * Returns whether or not the image buffer resources have been
7048 * @return true if the resources have been lost, false otherwise
7050 public boolean contentsLost()
7052 if (drawVBuffer.contentsLost())
7054 validatedContents = false;
7057 // we know that the buffer resources are valid now because we
7058 // just checked them
7059 validatedContents = true;
7064 * Returns whether or not the image buffer resources have been
7067 * @return true if the resources have been restored, false
7070 public boolean contentsRestored()
7072 GraphicsConfiguration c =
7073 GraphicsEnvironment.getLocalGraphicsEnvironment()
7074 .getDefaultScreenDevice().getDefaultConfiguration();
7076 int result = drawVBuffer.validate(c);
7078 boolean imageRestored = false;
7080 if (result == VolatileImage.IMAGE_RESTORED)
7081 imageRestored = true;
7082 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
7085 // we know that the buffer resources are valid now because we
7086 // just checked them
7087 validatedContents = true;
7088 return imageRestored;
7092 * Bring the contents of the back buffer to the front buffer.
7096 flip(caps.getFlipContents());