1 /* Component.java -- a graphics component
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java.awt.dnd.DropTarget;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ComponentEvent;
44 import java.awt.event.ComponentListener;
45 import java.awt.event.FocusEvent;
46 import java.awt.event.FocusListener;
47 import java.awt.event.HierarchyBoundsListener;
48 import java.awt.event.HierarchyEvent;
49 import java.awt.event.HierarchyListener;
50 import java.awt.event.InputEvent;
51 import java.awt.event.InputMethodEvent;
52 import java.awt.event.InputMethodListener;
53 import java.awt.event.KeyEvent;
54 import java.awt.event.KeyListener;
55 import java.awt.event.MouseEvent;
56 import java.awt.event.MouseListener;
57 import java.awt.event.MouseMotionListener;
58 import java.awt.event.MouseWheelEvent;
59 import java.awt.event.MouseWheelListener;
60 import java.awt.event.PaintEvent;
61 import java.awt.event.WindowEvent;
62 import java.awt.im.InputContext;
63 import java.awt.im.InputMethodRequests;
64 import java.awt.image.BufferStrategy;
65 import java.awt.image.ColorModel;
66 import java.awt.image.ImageObserver;
67 import java.awt.image.ImageProducer;
68 import java.awt.image.VolatileImage;
69 import java.awt.peer.ComponentPeer;
70 import java.awt.peer.LightweightPeer;
71 import java.beans.PropertyChangeListener;
72 import java.beans.PropertyChangeSupport;
73 import java.io.IOException;
74 import java.io.ObjectInputStream;
75 import java.io.ObjectOutputStream;
76 import java.io.PrintStream;
77 import java.io.PrintWriter;
78 import java.io.Serializable;
79 import java.lang.reflect.Array;
80 import java.util.Collections;
81 import java.util.EventListener;
82 import java.util.HashSet;
83 import java.util.Iterator;
84 import java.util.Locale;
86 import java.util.Vector;
88 import javax.accessibility.Accessible;
89 import javax.accessibility.AccessibleComponent;
90 import javax.accessibility.AccessibleContext;
91 import javax.accessibility.AccessibleRole;
92 import javax.accessibility.AccessibleState;
93 import javax.accessibility.AccessibleStateSet;
96 * The root of all evil. All graphical representations are subclasses of this
97 * giant class, which is designed for screen display and user interaction.
98 * This class can be extended directly to build a lightweight component (one
99 * not associated with a native window); lightweight components must reside
100 * inside a heavyweight window.
102 * <p>This class is Serializable, which has some big implications. A user can
103 * save the state of all graphical components in one VM, and reload them in
104 * another. Note that this class will only save Serializable listeners, and
105 * ignore the rest, without causing any serialization exceptions. However, by
106 * making a listener serializable, and adding it to another element, you link
107 * in that entire element to the state of this component. To get around this,
108 * use the idiom shown in the example below - make listeners non-serializable
109 * in inner classes, rather than using this object itself as the listener, if
110 * external objects do not need to save the state of this object.
114 * import java.awt.event.*;
115 * import java.io.Serializable;
116 * class MyApp implements Serializable
118 * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
119 * // Serializing aButton will not suck in an instance of MyApp, with its
120 * // accompanying field bigOne.
121 * Button aButton = new Button();
122 * class MyActionListener implements ActionListener
124 * public void actionPerformed(ActionEvent e)
126 * System.out.println("Hello There");
131 * aButton.addActionListener(new MyActionListener());
136 * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
137 * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
138 * incomplete or only stubs; except for methods relating to the Drag and
139 * Drop, Input Method, and Accessibility frameworks: These methods are
140 * present but commented out.
142 * @author original author unknown
143 * @author Eric Blake (ebb9@email.byu.edu)
145 * @status still missing 1.4 support
147 public abstract class Component
148 implements ImageObserver, MenuContainer, Serializable
150 // Word to the wise - this file is huge. Search for '\f' (^L) for logical
151 // sectioning by fields, public API, private API, and nested classes.
155 * Compatible with JDK 1.0+.
157 private static final long serialVersionUID = -7644114512714619750L;
160 * Constant returned by the <code>getAlignmentY</code> method to indicate
161 * that the component wishes to be aligned to the top relative to
164 * @see #getAlignmentY()
166 public static final float TOP_ALIGNMENT = 0;
169 * Constant returned by the <code>getAlignmentY</code> and
170 * <code>getAlignmentX</code> methods to indicate
171 * that the component wishes to be aligned to the center relative to
174 * @see #getAlignmentX()
175 * @see #getAlignmentY()
177 public static final float CENTER_ALIGNMENT = 0.5f;
180 * Constant returned by the <code>getAlignmentY</code> method to indicate
181 * that the component wishes to be aligned to the bottom relative to
184 * @see #getAlignmentY()
186 public static final float BOTTOM_ALIGNMENT = 1;
189 * Constant returned by the <code>getAlignmentX</code> method to indicate
190 * that the component wishes to be aligned to the right relative to
193 * @see #getAlignmentX()
195 public static final float RIGHT_ALIGNMENT = 1;
198 * Constant returned by the <code>getAlignmentX</code> method to indicate
199 * that the component wishes to be aligned to the left relative to
202 * @see #getAlignmentX()
204 public static final float LEFT_ALIGNMENT = 0;
207 * Make the treelock a String so that it can easily be identified
208 * in debug dumps. We clone the String in order to avoid a conflict in
209 * the unlikely event that some other package uses exactly the same string
212 static final Object treeLock = new String("AWT_TREE_LOCK");
214 // Serialized fields from the serialization spec.
217 * The x position of the component in the parent's coordinate system.
219 * @see #getLocation()
220 * @serial the x position
225 * The y position of the component in the parent's coordinate system.
227 * @see #getLocation()
228 * @serial the y position
233 * The component width.
241 * The component height.
249 * The foreground color for the component. This may be null.
251 * @see #getForeground()
252 * @see #setForeground(Color)
253 * @serial the foreground color
258 * The background color for the component. This may be null.
260 * @see #getBackground()
261 * @see #setBackground(Color)
262 * @serial the background color
267 * The default font used in the component. This may be null.
270 * @see #setFont(Font)
276 * The font in use by the peer, or null if there is no peer.
278 * @serial the peer's font
283 * The cursor displayed when the pointer is over this component. This may
287 * @see #setCursor(Cursor)
292 * The locale for the component.
295 * @see #setLocale(Locale)
297 Locale locale = Locale.getDefault ();
300 * True if the object should ignore repaint events (usually because it is
303 * @see #getIgnoreRepaint()
304 * @see #setIgnoreRepaint(boolean)
305 * @serial true to ignore repaints
308 boolean ignoreRepaint;
311 * True when the object is visible (although it is only showing if all
312 * ancestors are likewise visible). For component, this defaults to true.
315 * @see #setVisible(boolean)
316 * @serial true if visible
318 boolean visible = true;
321 * True if the object is enabled, meaning it can interact with the user.
322 * For component, this defaults to true.
325 * @see #setEnabled(boolean)
326 * @serial true if enabled
328 boolean enabled = true;
331 * True if the object is valid. This is set to false any time a size
332 * adjustment means the component need to be layed out again.
337 * @serial true if layout is valid
342 * The DropTarget for drag-and-drop operations.
344 * @see #getDropTarget()
345 * @see #setDropTarget(DropTarget)
346 * @serial the drop target, or null
349 DropTarget dropTarget;
352 * The list of popup menus for this component.
354 * @see #add(PopupMenu)
355 * @serial the list of popups
360 * The component's name. May be null, in which case a default name is
361 * generated on the first use.
364 * @see #setName(String)
370 * True once the user has set the name. Note that the user may set the name
375 * @see #setName(String)
376 * @serial true if the name has been explicitly set
378 boolean nameExplicitlySet;
381 * Indicates if the object can be focused. Defaults to true for components.
383 * @see #isFocusable()
384 * @see #setFocusable(boolean)
387 boolean focusable = true;
390 * Tracks whether this component's {@link #isFocusTraversable}
391 * method has been overridden.
395 int isFocusTraversableOverridden;
398 * The focus traversal keys, if not inherited from the parent or
399 * default keyboard focus manager. These sets will contain only
400 * AWTKeyStrokes that represent press and release events to use as
403 * @see #getFocusTraversalKeys(int)
404 * @see #setFocusTraversalKeys(int, Set)
407 Set[] focusTraversalKeys;
410 * True if focus traversal keys are enabled. This defaults to true for
411 * Component. If this is true, keystrokes in focusTraversalKeys are trapped
412 * and processed automatically rather than being passed on to the component.
414 * @see #getFocusTraversalKeysEnabled()
415 * @see #setFocusTraversalKeysEnabled(boolean)
418 boolean focusTraversalKeysEnabled = true;
421 * Cached information on the minimum size. Should have been transient.
428 * Cached information on the preferred size. Should have been transient.
435 * Set to true if an event is to be handled by this component, false if
436 * it is to be passed up the hierarcy.
438 * @see #dispatchEvent(AWTEvent)
439 * @serial true to process event locally
441 boolean newEventsOnly;
444 * Set by subclasses to enable event handling of particular events, and
445 * left alone when modifying listeners. For component, this defaults to
446 * enabling only input methods.
448 * @see #enableInputMethods(boolean)
450 * @serial the mask of events to process
452 long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
455 * Describes all registered PropertyChangeListeners.
457 * @see #addPropertyChangeListener(PropertyChangeListener)
458 * @see #removePropertyChangeListener(PropertyChangeListener)
459 * @see #firePropertyChange(String, Object, Object)
460 * @serial the property change listeners
463 PropertyChangeSupport changeSupport;
466 * True if the component has been packed (layed out).
468 * @serial true if this is packed
473 * The serialization version for this class. Currently at version 4.
475 * XXX How do we handle prior versions?
477 * @serial the serialization version
479 int componentSerializedDataVersion = 4;
482 * The accessible context associated with this component. This is only set
485 * @see #getAccessibleContext()
486 * @serial the accessibility context
489 AccessibleContext accessibleContext;
492 // Guess what - listeners are special cased in serialization. See
493 // readObject and writeObject.
495 /** Component listener chain. */
496 transient ComponentListener componentListener;
498 /** Focus listener chain. */
499 transient FocusListener focusListener;
501 /** Key listener chain. */
502 transient KeyListener keyListener;
504 /** Mouse listener chain. */
505 transient MouseListener mouseListener;
507 /** Mouse motion listener chain. */
508 transient MouseMotionListener mouseMotionListener;
511 * Mouse wheel listener chain.
515 transient MouseWheelListener mouseWheelListener;
518 * Input method listener chain.
522 transient InputMethodListener inputMethodListener;
525 * Hierarcy listener chain.
529 transient HierarchyListener hierarchyListener;
532 * Hierarcy bounds listener chain.
536 transient HierarchyBoundsListener hierarchyBoundsListener;
538 // Anything else is non-serializable, and should be declared "transient".
541 transient Container parent;
543 /** The associated native peer. */
544 transient ComponentPeer peer;
546 /** The preferred component orientation. */
547 transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
550 * The associated graphics configuration.
554 transient GraphicsConfiguration graphicsConfig;
557 * The buffer strategy for repainting.
561 transient BufferStrategy bufferStrategy;
564 * true if requestFocus was called on this component when its
565 * top-level ancestor was not focusable.
567 private transient FocusEvent pendingFocusRequest = null;
570 * The system properties that affect image updating.
572 private static transient boolean incrementalDraw;
573 private static transient Long redrawRate;
577 incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
578 redrawRate = Long.getLong ("awt.image.redrawrate");
581 // Public and protected API.
584 * Default constructor for subclasses. When Component is extended directly,
585 * it forms a lightweight component that must be hosted in an opaque native
586 * container higher in the tree.
588 protected Component()
593 * Returns the name of this component.
595 * @return the name of this component
596 * @see #setName(String)
599 public String getName()
601 if (name == null && ! nameExplicitlySet)
602 name = generateName();
607 * Sets the name of this component to the specified name.
609 * @param name the new name of this component
613 public void setName(String name)
615 nameExplicitlySet = true;
620 * Returns the parent of this component.
622 * @return the parent of this component
624 public Container getParent()
630 * Returns the native windowing system peer for this component. Only the
631 * platform specific implementation code should call this method.
633 * @return the peer for this component
634 * @deprecated user programs should not directly manipulate peers; use
635 * {@link #isDisplayable()} instead
637 // Classpath's Gtk peers rely on this.
638 public ComponentPeer getPeer()
644 * Set the associated drag-and-drop target, which receives events when this
647 * @param dt the new drop target
650 public void setDropTarget(DropTarget dt)
652 this.dropTarget = dt;
656 * Gets the associated drag-and-drop target, if there is one.
658 * @return the drop target
660 public DropTarget getDropTarget()
666 * Returns the graphics configuration of this component, if there is one.
667 * If it has not been set, it is inherited from the parent.
669 * @return the graphics configuration, or null
672 public GraphicsConfiguration getGraphicsConfiguration()
674 return getGraphicsConfigurationImpl();
678 * Returns the object used for synchronization locks on this component
679 * when performing tree and layout functions.
681 * @return the synchronization lock for this component
683 public final Object getTreeLock()
689 * Returns the toolkit in use for this component. The toolkit is associated
690 * with the frame this component belongs to.
692 * @return the toolkit for this component
694 public Toolkit getToolkit()
698 Toolkit tk = peer.getToolkit();
702 // Get toolkit for lightweight component.
704 return parent.getToolkit();
705 return Toolkit.getDefaultToolkit();
709 * Tests whether or not this component is valid. A invalid component needs
710 * to have its layout redone.
712 * @return true if this component is valid
716 public boolean isValid()
722 * Tests if the component is displayable. It must be connected to a native
723 * screen resource, and all its ancestors must be displayable. A containment
724 * hierarchy is made displayable when a window is packed or made visible.
726 * @return true if the component is displayable
727 * @see Container#add(Component)
728 * @see Container#remove(Component)
731 * @see Window#dispose()
734 public boolean isDisplayable()
737 return parent.isDisplayable();
742 * Tests whether or not this component is visible. Except for top-level
743 * frames, components are initially visible.
745 * @return true if the component is visible
746 * @see #setVisible(boolean)
748 public boolean isVisible()
754 * Tests whether or not this component is actually being shown on
755 * the screen. This will be true if and only if it this component is
756 * visible and its parent components are all visible.
758 * @return true if the component is showing on the screen
759 * @see #setVisible(boolean)
761 public boolean isShowing()
763 if (! visible || peer == null)
766 return parent == null ? true : parent.isShowing();
770 * Tests whether or not this component is enabled. Components are enabled
771 * by default, and must be enabled to receive user input or generate events.
773 * @return true if the component is enabled
774 * @see #setEnabled(boolean)
776 public boolean isEnabled()
782 * Enables or disables this component. The component must be enabled to
783 * receive events (except that lightweight components always receive mouse
786 * @param enabled true to enable this component
789 * @see #isLightweight()
793 public void setEnabled(boolean enabled)
799 * Enables this component.
801 * @deprecated use {@link #setEnabled(boolean)} instead
807 peer.setEnabled (true);
811 * Enables or disables this component.
813 * @param enabled true to enable this component
815 * @deprecated use {@link #setEnabled(boolean)} instead
817 public void enable(boolean enabled)
826 * Disables this component.
828 * @deprecated use {@link #setEnabled(boolean)} instead
830 public void disable()
832 this.enabled = false;
834 peer.setEnabled (false);
838 * Checks if this image is painted to an offscreen image buffer that is
839 * later copied to screen (double buffering reduces flicker). This version
840 * returns false, so subclasses must override it if they provide double
843 * @return true if this is double buffered; defaults to false
845 public boolean isDoubleBuffered()
851 * Enables or disables input method support for this component. By default,
852 * components have this enabled. Input methods are given the opportunity
853 * to process key events before this component and its listeners.
855 * @param enable true to enable input method processing
856 * @see #processKeyEvent(KeyEvent)
859 public void enableInputMethods(boolean enable)
862 eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
864 eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
868 * Makes this component visible or invisible. Note that it wtill might
869 * not show the component, if a parent is invisible.
871 * @param visible true to make this component visible
877 public void setVisible(boolean visible)
879 // Inspection by subclassing shows that Sun's implementation calls
880 // show(boolean) which then calls show() or hide(). It is the show()
881 // method that is overriden in subclasses like Window.
886 * Makes this component visible on the screen.
888 * @deprecated use {@link #setVisible(boolean)} instead
892 // We must set visible before showing the peer. Otherwise the
893 // peer could post paint events before visible is true, in which
894 // case lightweight components are not initially painted --
895 // Container.paint first calls isShowing () before painting itself
900 // Avoid NullPointerExceptions by creating a local reference.
901 ComponentPeer currentPeer=peer;
902 if (currentPeer != null)
903 currentPeer.setVisible(true);
905 // Invalidate the parent if we have one. The component itself must
906 // not be invalidated. We also avoid NullPointerException with
907 // a local reference here.
908 Container currentParent = parent;
909 if (currentParent != null)
911 currentParent.invalidate();
912 currentParent.repaint();
916 new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
917 getToolkit().getSystemEventQueue().postEvent(ce);
922 * Makes this component visible or invisible.
924 * @param visible true to make this component visible
926 * @deprecated use {@link #setVisible(boolean)} instead
928 public void show(boolean visible)
937 * Hides this component so that it is no longer shown on the screen.
939 * @deprecated use {@link #setVisible(boolean)} instead
945 // Avoid NullPointerExceptions by creating a local reference.
946 ComponentPeer currentPeer=peer;
947 if (currentPeer != null)
948 currentPeer.setVisible(false);
950 this.visible = false;
952 // Invalidate the parent if we have one. The component itself must
953 // not be invalidated. We also avoid NullPointerException with
954 // a local reference here.
955 Container currentParent = parent;
956 if (currentParent != null)
958 currentParent.invalidate();
959 currentParent.repaint();
963 new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
964 getToolkit().getSystemEventQueue().postEvent(ce);
969 * Returns this component's foreground color. If not set, this is inherited
972 * @return this component's foreground color, or null
973 * @see #setForeground(Color)
975 public Color getForeground()
977 if (foreground != null)
979 return parent == null ? SystemColor.windowText : parent.getForeground();
983 * Sets this component's foreground color to the specified color. This is a
986 * @param c the new foreground color
987 * @see #getForeground()
989 public void setForeground(Color c)
992 peer.setForeground(c);
994 Color previous = foreground;
996 firePropertyChange("foreground", previous, c);
1000 * Tests if the foreground was explicitly set, or just inherited from the
1003 * @return true if the foreground has been set
1006 public boolean isForegroundSet()
1008 return foreground != null;
1012 * Returns this component's background color. If not set, this is inherited
1015 * @return the background color of the component, or null
1016 * @see #setBackground(Color)
1018 public Color getBackground()
1020 if (background != null)
1022 return parent == null ? null : parent.getBackground();
1026 * Sets this component's background color to the specified color. The parts
1027 * of the component affected by the background color may by system dependent.
1028 * This is a bound property.
1030 * @param c the new background color
1031 * @see #getBackground()
1033 public void setBackground(Color c)
1035 // return if the background is already set to that color.
1036 if ((c != null) && c.equals(background))
1039 // If c is null, inherit from closest ancestor whose bg is set.
1040 if (c == null && parent != null)
1041 c = parent.getBackground();
1042 if (peer != null && c != null)
1043 peer.setBackground(c);
1045 Color previous = background;
1047 firePropertyChange("background", previous, c);
1051 * Tests if the background was explicitly set, or just inherited from the
1054 * @return true if the background has been set
1057 public boolean isBackgroundSet()
1059 return background != null;
1063 * Returns the font in use for this component. If not set, this is inherited
1066 * @return the font for this component
1067 * @see #setFont(Font)
1069 public Font getFont()
1075 Component p = parent;
1079 return new Font("Dialog", Font.PLAIN, 12);
1083 * Sets the font for this component to the specified font. This is a bound
1086 * @param newFont the new font for this component
1090 public void setFont(Font newFont)
1092 if((newFont != null && (font == null || !font.equals(newFont)))
1095 Font oldFont = font;
1099 firePropertyChange("font", oldFont, newFont);
1105 * Tests if the font was explicitly set, or just inherited from the parent.
1107 * @return true if the font has been set
1110 public boolean isFontSet()
1112 return font != null;
1116 * Returns the locale for this component. If this component does not
1117 * have a locale, the locale of the parent component is returned.
1119 * @return the locale for this component
1120 * @throws IllegalComponentStateException if it has no locale or parent
1121 * @see #setLocale(Locale)
1124 public Locale getLocale()
1129 throw new IllegalComponentStateException
1130 ("Component has no parent: can't determine Locale");
1131 return parent.getLocale();
1135 * Sets the locale for this component to the specified locale. This is a
1138 * @param newLocale the new locale for this component
1140 public void setLocale(Locale newLocale)
1142 if (locale == newLocale)
1145 Locale oldLocale = locale;
1147 firePropertyChange("locale", oldLocale, newLocale);
1148 // New writing/layout direction or more/less room for localized labels.
1153 * Returns the color model of the device this componet is displayed on.
1155 * @return this object's color model
1156 * @see Toolkit#getColorModel()
1158 public ColorModel getColorModel()
1160 GraphicsConfiguration config = getGraphicsConfiguration();
1161 return config != null ? config.getColorModel()
1162 : getToolkit().getColorModel();
1166 * Returns the location of this component's top left corner relative to
1167 * its parent component. This may be outdated, so for synchronous behavior,
1168 * you should use a component listner.
1170 * @return the location of this component
1171 * @see #setLocation(int, int)
1172 * @see #getLocationOnScreen()
1175 public Point getLocation()
1181 * Returns the location of this component's top left corner in screen
1184 * @return the location of this component in screen coordinates
1185 * @throws IllegalComponentStateException if the component is not showing
1187 public Point getLocationOnScreen()
1190 throw new IllegalComponentStateException("component "
1191 + getClass().getName()
1193 // We know peer != null here.
1194 return peer.getLocationOnScreen();
1198 * Returns the location of this component's top left corner relative to
1199 * its parent component.
1201 * @return the location of this component
1202 * @deprecated use {@link #getLocation()} instead
1204 public Point location()
1206 return new Point (x, y);
1210 * Moves this component to the specified location, relative to the parent's
1211 * coordinates. The coordinates are the new upper left corner of this
1214 * @param x the new X coordinate of this component
1215 * @param y the new Y coordinate of this component
1216 * @see #getLocation()
1217 * @see #setBounds(int, int, int, int)
1219 public void setLocation(int x, int y)
1225 * Moves this component to the specified location, relative to the parent's
1226 * coordinates. The coordinates are the new upper left corner of this
1229 * @param x the new X coordinate of this component
1230 * @param y the new Y coordinate of this component
1231 * @deprecated use {@link #setLocation(int, int)} instead
1233 public void move(int x, int y)
1235 setBounds(x, y, this.width, this.height);
1239 * Moves this component to the specified location, relative to the parent's
1240 * coordinates. The coordinates are the new upper left corner of this
1243 * @param p new coordinates for this component
1244 * @throws NullPointerException if p is null
1245 * @see #getLocation()
1246 * @see #setBounds(int, int, int, int)
1249 public void setLocation(Point p)
1251 setLocation(p.x, p.y);
1255 * Returns the size of this object.
1257 * @return the size of this object
1258 * @see #setSize(int, int)
1261 public Dimension getSize()
1267 * Returns the size of this object.
1269 * @return the size of this object
1270 * @deprecated use {@link #getSize()} instead
1272 public Dimension size()
1274 return new Dimension (width, height);
1278 * Sets the size of this component to the specified width and height.
1280 * @param width the new width of this component
1281 * @param height the new height of this component
1283 * @see #setBounds(int, int, int, int)
1285 public void setSize(int width, int height)
1287 resize (width, height);
1291 * Sets the size of this component to the specified value.
1293 * @param width the new width of the component
1294 * @param height the new height of the component
1295 * @deprecated use {@link #setSize(int, int)} instead
1297 public void resize(int width, int height)
1299 setBounds(this.x, this.y, width, height);
1303 * Sets the size of this component to the specified value.
1305 * @param d the new size of this component
1306 * @throws NullPointerException if d is null
1307 * @see #setSize(int, int)
1308 * @see #setBounds(int, int, int, int)
1311 public void setSize(Dimension d)
1317 * Sets the size of this component to the specified value.
1319 * @param d the new size of this component
1320 * @throws NullPointerException if d is null
1321 * @deprecated use {@link #setSize(Dimension)} instead
1323 public void resize(Dimension d)
1325 resize (d.width, d.height);
1329 * Returns a bounding rectangle for this component. Note that the
1330 * returned rectange is relative to this component's parent, not to
1333 * @return the bounding rectangle for this component
1334 * @see #setBounds(int, int, int, int)
1335 * @see #getLocation()
1338 public Rectangle getBounds()
1344 * Returns a bounding rectangle for this component. Note that the
1345 * returned rectange is relative to this component's parent, not to
1348 * @return the bounding rectangle for this component
1349 * @deprecated use {@link #getBounds()} instead
1351 public Rectangle bounds()
1353 return new Rectangle (x, y, width, height);
1357 * Sets the bounding rectangle for this component to the specified values.
1358 * Note that these coordinates are relative to the parent, not to the screen.
1360 * @param x the X coordinate of the upper left corner of the rectangle
1361 * @param y the Y coordinate of the upper left corner of the rectangle
1362 * @param w the width of the rectangle
1363 * @param h the height of the rectangle
1365 * @see #setLocation(int, int)
1366 * @see #setLocation(Point)
1367 * @see #setSize(int, int)
1368 * @see #setSize(Dimension)
1371 public void setBounds(int x, int y, int w, int h)
1373 reshape (x, y, w, h);
1377 * Sets the bounding rectangle for this component to the specified values.
1378 * Note that these coordinates are relative to the parent, not to the screen.
1380 * @param x the X coordinate of the upper left corner of the rectangle
1381 * @param y the Y coordinate of the upper left corner of the rectangle
1382 * @param width the width of the rectangle
1383 * @param height the height of the rectangle
1384 * @deprecated use {@link #setBounds(int, int, int, int)} instead
1386 public void reshape(int x, int y, int width, int height)
1390 int oldwidth = this.width;
1391 int oldheight = this.height;
1393 if (this.x == x && this.y == y
1394 && this.width == width && this.height == height)
1400 this.height = height;
1402 peer.setBounds (x, y, width, height);
1404 // Erase old bounds and repaint new bounds for lightweights.
1405 if (isLightweight() && isShowing ())
1409 Rectangle parentBounds = parent.getBounds();
1410 Rectangle oldBounds = new Rectangle(parent.getX() + oldx,
1411 parent.getY() + oldy,
1412 oldwidth, oldheight);
1413 Rectangle newBounds = new Rectangle(parent.getX() + x,
1416 Rectangle destroyed = oldBounds.union(newBounds);
1417 if (!destroyed.isEmpty())
1418 parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
1423 // Only post event if this component is visible and has changed size.
1425 && (oldx != x || oldy != y))
1427 ComponentEvent ce = new ComponentEvent(this,
1428 ComponentEvent.COMPONENT_MOVED);
1429 getToolkit().getSystemEventQueue().postEvent(ce);
1432 && (oldwidth != width || oldheight != height))
1434 ComponentEvent ce = new ComponentEvent(this,
1435 ComponentEvent.COMPONENT_RESIZED);
1436 getToolkit().getSystemEventQueue().postEvent(ce);
1441 * Sets the bounding rectangle for this component to the specified
1442 * rectangle. Note that these coordinates are relative to the parent, not
1445 * @param r the new bounding rectangle
1446 * @throws NullPointerException if r is null
1448 * @see #setLocation(Point)
1449 * @see #setSize(Dimension)
1452 public void setBounds(Rectangle r)
1454 setBounds (r.x, r.y, r.width, r.height);
1458 * Gets the x coordinate of the upper left corner. This is more efficient
1459 * than getBounds().x or getLocation().x.
1461 * @return the current x coordinate
1470 * Gets the y coordinate of the upper left corner. This is more efficient
1471 * than getBounds().y or getLocation().y.
1473 * @return the current y coordinate
1482 * Gets the width of the component. This is more efficient than
1483 * getBounds().width or getSize().width.
1485 * @return the current width
1488 public int getWidth()
1494 * Gets the height of the component. This is more efficient than
1495 * getBounds().height or getSize().height.
1497 * @return the current width
1500 public int getHeight()
1506 * Returns the bounds of this component. This allows reuse of an existing
1507 * rectangle, if r is non-null.
1509 * @param r the rectangle to use, or null
1510 * @return the bounds
1512 public Rectangle getBounds(Rectangle r)
1515 r = new Rectangle();
1524 * Returns the size of this component. This allows reuse of an existing
1525 * dimension, if d is non-null.
1527 * @param d the dimension to use, or null
1530 public Dimension getSize(Dimension d)
1533 d = new Dimension();
1540 * Returns the location of this component. This allows reuse of an existing
1541 * point, if p is non-null.
1543 * @param p the point to use, or null
1544 * @return the location
1546 public Point getLocation(Point p)
1556 * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1557 * components are opaque. A component is opaque if it draws all pixels in
1558 * the bounds; a lightweight component is partially transparent if it lets
1559 * pixels underneath show through. Subclasses that guarantee that all pixels
1560 * will be drawn should override this.
1562 * @return true if this is opaque
1563 * @see #isLightweight()
1566 public boolean isOpaque()
1568 return ! isLightweight();
1572 * Return whether the component is lightweight. That means the component has
1573 * no native peer, but is displayable. This applies to subclasses of
1574 * Component not in this package, such as javax.swing.
1576 * @return true if the component has a lightweight peer
1577 * @see #isDisplayable()
1580 public boolean isLightweight()
1582 return peer instanceof LightweightPeer;
1586 * Returns the component's preferred size.
1588 * @return the component's preferred size
1589 * @see #getMinimumSize()
1590 * @see LayoutManager
1592 public Dimension getPreferredSize()
1594 return preferredSize();
1598 * Returns the component's preferred size.
1600 * @return the component's preferred size
1601 * @deprecated use {@link #getPreferredSize()} instead
1603 public Dimension preferredSize()
1605 if (prefSize == null)
1607 return new Dimension(width, height);
1609 prefSize = peer.getPreferredSize();
1614 * Returns the component's minimum size.
1616 * @return the component's minimum size
1617 * @see #getPreferredSize()
1618 * @see LayoutManager
1620 public Dimension getMinimumSize()
1622 return minimumSize();
1626 * Returns the component's minimum size.
1628 * @return the component's minimum size
1629 * @deprecated use {@link #getMinimumSize()} instead
1631 public Dimension minimumSize()
1633 if (minSize == null)
1634 minSize = (peer != null ? peer.getMinimumSize()
1635 : new Dimension(width, height));
1640 * Returns the component's maximum size.
1642 * @return the component's maximum size
1643 * @see #getMinimumSize()
1644 * @see #getPreferredSize()
1645 * @see LayoutManager
1647 public Dimension getMaximumSize()
1649 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1653 * Returns the preferred horizontal alignment of this component. The value
1654 * returned will be between {@link #LEFT_ALIGNMENT} and
1655 * {@link #RIGHT_ALIGNMENT}, inclusive.
1657 * @return the preferred horizontal alignment of this component
1659 public float getAlignmentX()
1661 return CENTER_ALIGNMENT;
1665 * Returns the preferred vertical alignment of this component. The value
1666 * returned will be between {@link #TOP_ALIGNMENT} and
1667 * {@link #BOTTOM_ALIGNMENT}, inclusive.
1669 * @return the preferred vertical alignment of this component
1671 public float getAlignmentY()
1673 return CENTER_ALIGNMENT;
1677 * Calls the layout manager to re-layout the component. This is called
1678 * during validation of a container in most cases.
1681 * @see LayoutManager
1683 public void doLayout()
1689 * Calls the layout manager to re-layout the component. This is called
1690 * during validation of a container in most cases.
1692 * @deprecated use {@link #doLayout()} instead
1694 public void layout()
1696 // Nothing to do unless we're a container.
1700 * Called to ensure that the layout for this component is valid. This is
1701 * usually called on containers.
1703 * @see #invalidate()
1705 * @see LayoutManager
1706 * @see Container#validate()
1708 public void validate()
1714 * Invalidates this component and all of its parent components. This will
1715 * cause them to have their layout redone. This is called frequently, so
1718 public void invalidate()
1723 if (parent != null && parent.valid)
1724 parent.invalidate();
1728 * Returns a graphics object for this component. Returns <code>null</code>
1729 * if this component is not currently displayed on the screen.
1731 * @return a graphics object for this component
1732 * @see #paint(Graphics)
1734 public Graphics getGraphics()
1738 Graphics gfx = peer.getGraphics();
1741 // create graphics for lightweight:
1742 Container parent = getParent();
1745 gfx = parent.getGraphics();
1746 Rectangle bounds = getBounds();
1747 gfx.setClip(bounds);
1748 gfx.translate(bounds.x, bounds.y);
1756 * Returns the font metrics for the specified font in this component.
1758 * @param font the font to retrieve metrics for
1759 * @return the font metrics for the specified font
1760 * @throws NullPointerException if font is null
1762 * @see Toolkit#getFontMetrics(Font)
1764 public FontMetrics getFontMetrics(Font font)
1766 return peer == null ? getToolkit().getFontMetrics(font)
1767 : peer.getFontMetrics(font);
1771 * Sets the cursor for this component to the specified cursor. The cursor
1772 * is displayed when the point is contained by the component, and the
1773 * component is visible, displayable, and enabled. This is inherited by
1774 * subcomponents unless they set their own cursor.
1776 * @param cursor the new cursor for this component
1780 * @see #contains(int, int)
1781 * @see Toolkit#createCustomCursor(Image, Point, String)
1783 public void setCursor(Cursor cursor)
1785 this.cursor = cursor;
1787 peer.setCursor(cursor);
1791 * Returns the cursor for this component. If not set, this is inherited
1792 * from the parent, or from Cursor.getDefaultCursor().
1794 * @return the cursor for this component
1796 public Cursor getCursor()
1800 return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
1804 * Tests if the cursor was explicitly set, or just inherited from the parent.
1806 * @return true if the cursor has been set
1809 public boolean isCursorSet()
1811 return cursor != null;
1815 * Paints this component on the screen. The clipping region in the graphics
1816 * context will indicate the region that requires painting. This is called
1817 * whenever the component first shows, or needs to be repaired because
1818 * something was temporarily drawn on top. It is not necessary for
1819 * subclasses to call <code>super.paint(g)</code>. Components with no area
1822 * @param g the graphics context for this paint job
1823 * @see #update(Graphics)
1825 public void paint(Graphics g)
1827 // This is a callback method and is meant to be overridden by subclasses
1828 // that want to perform custom painting.
1832 * Updates this component. This is called in response to
1833 * <code>repaint</code>. This method fills the component with the
1834 * background color, then sets the foreground color of the specified
1835 * graphics context to the foreground color of this component and calls
1836 * the <code>paint()</code> method. The coordinates of the graphics are
1837 * relative to this component. Subclasses should call either
1838 * <code>super.update(g)</code> or <code>paint(g)</code>.
1840 * @param g the graphics context for this update
1842 * @see #paint(Graphics)
1845 * @specnote In contrast to what the spec says, tests show that the exact
1846 * behaviour is to clear the background on lightweight and
1847 * top-level components only. Heavyweight components are not
1848 * affected by this method and only call paint().
1850 public void update(Graphics g)
1852 // Tests show that the clearing of the background is only done in
1854 // - If the component is lightweight (yes this is in contrast to the spec).
1856 // - If the component is a toplevel container.
1857 if (isLightweight() || getParent() == null)
1859 Rectangle clip = g.getClipBounds();
1861 g.clearRect(0, 0, width, height);
1863 g.clearRect(clip.x, clip.y, clip.width, clip.height);
1869 * Paints this entire component, including any sub-components.
1871 * @param g the graphics context for this paint job
1873 * @see #paint(Graphics)
1875 public void paintAll(Graphics g)
1883 * Repaint this entire component. The <code>update()</code> method
1884 * on this component will be called as soon as possible.
1886 * @see #update(Graphics)
1887 * @see #repaint(long, int, int, int, int)
1889 public void repaint()
1893 Component p = parent;
1895 p.repaint(0, getX(), getY(), width, height);
1898 repaint(0, 0, 0, width, height);
1902 * Repaint this entire component. The <code>update()</code> method on this
1903 * component will be called in approximate the specified number of
1906 * @param tm milliseconds before this component should be repainted
1907 * @see #paint(Graphics)
1908 * @see #repaint(long, int, int, int, int)
1910 public void repaint(long tm)
1914 Component p = parent;
1916 p.repaint(tm, getX(), getY(), width, height);
1919 repaint(tm, 0, 0, width, height);
1923 * Repaints the specified rectangular region within this component. The
1924 * <code>update</code> method on this component will be called as soon as
1925 * possible. The coordinates are relative to this component.
1927 * @param x the X coordinate of the upper left of the region to repaint
1928 * @param y the Y coordinate of the upper left of the region to repaint
1929 * @param w the width of the region to repaint
1930 * @param h the height of the region to repaint
1931 * @see #update(Graphics)
1932 * @see #repaint(long, int, int, int, int)
1934 public void repaint(int x, int y, int w, int h)
1938 Component p = parent;
1940 p.repaint(0, x + getX(), y + getY(), width, height);
1943 repaint(0, x, y, w, h);
1947 * Repaints the specified rectangular region within this component. The
1948 * <code>update</code> method on this component will be called in
1949 * approximately the specified number of milliseconds. The coordinates
1950 * are relative to this component.
1952 * @param tm milliseconds before this component should be repainted
1953 * @param x the X coordinate of the upper left of the region to repaint
1954 * @param y the Y coordinate of the upper left of the region to repaint
1955 * @param width the width of the region to repaint
1956 * @param height the height of the region to repaint
1957 * @see #update(Graphics)
1959 public void repaint(long tm, int x, int y, int width, int height)
1963 Component p = parent;
1965 p.repaint(tm, x + getX(), y + getY(), width, height);
1969 ComponentPeer p = peer;
1971 p.repaint(tm, x, y, width, height);
1976 * Prints this component. This method is provided so that printing can be
1977 * done in a different manner from painting. However, the implementation
1978 * in this class simply calls the <code>paint()</code> method.
1980 * @param g the graphics context of the print device
1982 * @see #paint(Graphics)
1984 public void print(Graphics g)
1990 * Prints this component, including all sub-components. This method is
1991 * provided so that printing can be done in a different manner from
1992 * painting. However, the implementation in this class simply calls the
1993 * <code>paintAll()</code> method.
1995 * @param g the graphics context of the print device
1997 * @see #paintAll(Graphics)
1999 public void printAll(Graphics g)
2005 * Called when an image has changed so that this component is repainted.
2006 * This incrementally draws an image as more bits are available, when
2007 * possible. Incremental drawing is enabled if the system property
2008 * <code>awt.image.incrementalDraw</code> is not present or is true, in which
2009 * case the redraw rate is set to 100ms or the value of the system property
2010 * <code>awt.image.redrawrate</code>.
2012 * <p>The coordinate system used depends on the particular flags.
2014 * @param img the image that has been updated
2015 * @param flags tlags as specified in <code>ImageObserver</code>
2016 * @param x the X coordinate
2017 * @param y the Y coordinate
2018 * @param w the width
2019 * @param h the height
2020 * @return false if the image is completely loaded, loading has been
2021 * aborted, or an error has occurred. true if more updates are
2023 * @see ImageObserver
2024 * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
2025 * @see Graphics#drawImage(Image, int, int, ImageObserver)
2026 * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
2027 * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
2028 * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2030 public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2032 if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2034 else if ((flags & SOMEBITS) != 0)
2036 if (incrementalDraw)
2038 if (redrawRate != null)
2040 long tm = redrawRate.longValue();
2049 return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2053 * Creates an image from the specified producer.
2055 * @param producer the image procedure to create the image from
2056 * @return the resulting image
2058 public Image createImage(ImageProducer producer)
2060 // Sun allows producer to be null.
2062 return peer.createImage(producer);
2064 return getToolkit().createImage(producer);
2068 * Creates an image with the specified width and height for use in
2069 * double buffering. Headless environments do not support images.
2071 * @param width the width of the image
2072 * @param height the height of the image
2073 * @return the requested image, or null if it is not supported
2075 public Image createImage (int width, int height)
2077 Image returnValue = null;
2078 if (!GraphicsEnvironment.isHeadless ())
2080 if (isLightweight () && parent != null)
2081 returnValue = parent.createImage (width, height);
2082 else if (peer != null)
2083 returnValue = peer.createImage (width, height);
2089 * Creates an image with the specified width and height for use in
2090 * double buffering. Headless environments do not support images.
2092 * @param width the width of the image
2093 * @param height the height of the image
2094 * @return the requested image, or null if it is not supported
2097 public VolatileImage createVolatileImage(int width, int height)
2099 if (GraphicsEnvironment.isHeadless())
2101 GraphicsConfiguration config = getGraphicsConfiguration();
2102 return config == null ? null
2103 : config.createCompatibleVolatileImage(width, height);
2107 * Creates an image with the specified width and height for use in
2108 * double buffering. Headless environments do not support images. The image
2109 * will support the specified capabilities.
2111 * @param width the width of the image
2112 * @param height the height of the image
2113 * @param caps the requested capabilities
2114 * @return the requested image, or null if it is not supported
2115 * @throws AWTException if a buffer with the capabilities cannot be created
2118 public VolatileImage createVolatileImage(int width, int height,
2119 ImageCapabilities caps)
2122 if (GraphicsEnvironment.isHeadless())
2124 GraphicsConfiguration config = getGraphicsConfiguration();
2125 return config == null ? null
2126 : config.createCompatibleVolatileImage(width, height, caps);
2130 * Prepares the specified image for rendering on this component.
2132 * @param image the image to prepare for rendering
2133 * @param observer the observer to notify of image preparation status
2134 * @return true if the image is already fully prepared
2135 * @throws NullPointerException if image is null
2137 public boolean prepareImage(Image image, ImageObserver observer)
2139 return prepareImage(image, image.getWidth(observer),
2140 image.getHeight(observer), observer);
2144 * Prepares the specified image for rendering on this component at the
2145 * specified scaled width and height
2147 * @param image the image to prepare for rendering
2148 * @param width the scaled width of the image
2149 * @param height the scaled height of the image
2150 * @param observer the observer to notify of image preparation status
2151 * @return true if the image is already fully prepared
2153 public boolean prepareImage(Image image, int width, int height,
2154 ImageObserver observer)
2157 return peer.prepareImage(image, width, height, observer);
2159 return getToolkit().prepareImage(image, width, height, observer);
2163 * Returns the status of the loading of the specified image. The value
2164 * returned will be those flags defined in <code>ImageObserver</code>.
2166 * @param image the image to check on
2167 * @param observer the observer to notify of image loading progress
2168 * @return the image observer flags indicating the status of the load
2169 * @see #prepareImage(Image, int, int, ImageObserver)
2170 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2171 * @throws NullPointerException if image is null
2173 public int checkImage(Image image, ImageObserver observer)
2175 return checkImage(image, -1, -1, observer);
2179 * Returns the status of the loading of the specified image. The value
2180 * returned will be those flags defined in <code>ImageObserver</code>.
2182 * @param image the image to check on
2183 * @param width the scaled image width
2184 * @param height the scaled image height
2185 * @param observer the observer to notify of image loading progress
2186 * @return the image observer flags indicating the status of the load
2187 * @see #prepareImage(Image, int, int, ImageObserver)
2188 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2190 public int checkImage(Image image, int width, int height,
2191 ImageObserver observer)
2194 return peer.checkImage(image, width, height, observer);
2195 return getToolkit().checkImage(image, width, height, observer);
2199 * Sets whether paint messages delivered by the operating system should be
2200 * ignored. This does not affect messages from AWT, except for those
2201 * triggered by OS messages. Setting this to true can allow faster
2202 * performance in full-screen mode or page-flipping.
2204 * @param ignoreRepaint the new setting for ignoring repaint events
2205 * @see #getIgnoreRepaint()
2206 * @see BufferStrategy
2207 * @see GraphicsDevice#setFullScreenWindow(Window)
2210 public void setIgnoreRepaint(boolean ignoreRepaint)
2212 this.ignoreRepaint = ignoreRepaint;
2216 * Test whether paint events from the operating system are ignored.
2218 * @return the status of ignoring paint events
2219 * @see #setIgnoreRepaint(boolean)
2222 public boolean getIgnoreRepaint()
2224 return ignoreRepaint;
2228 * Tests whether or not the specified point is contained within this
2229 * component. Coordinates are relative to this component.
2231 * @param x the X coordinate of the point to test
2232 * @param y the Y coordinate of the point to test
2233 * @return true if the point is within this component
2234 * @see #getComponentAt(int, int)
2236 public boolean contains(int x, int y)
2238 return inside (x, y);
2242 * Tests whether or not the specified point is contained within this
2243 * component. Coordinates are relative to this component.
2245 * @param x the X coordinate of the point to test
2246 * @param y the Y coordinate of the point to test
2247 * @return true if the point is within this component
2248 * @deprecated use {@link #contains(int, int)} instead
2250 public boolean inside(int x, int y)
2252 return x >= 0 && y >= 0 && x < width && y < height;
2256 * Tests whether or not the specified point is contained within this
2257 * component. Coordinates are relative to this component.
2259 * @param p the point to test
2260 * @return true if the point is within this component
2261 * @throws NullPointerException if p is null
2262 * @see #getComponentAt(Point)
2265 public boolean contains(Point p)
2267 return contains (p.x, p.y);
2271 * Returns the component occupying the position (x,y). This will either
2272 * be this component, an immediate child component, or <code>null</code>
2273 * if neither of the first two occupies the specified location.
2275 * @param x the X coordinate to search for components at
2276 * @param y the Y coordinate to search for components at
2277 * @return the component at the specified location, or null
2278 * @see #contains(int, int)
2280 public Component getComponentAt(int x, int y)
2282 return locate (x, y);
2286 * Returns the component occupying the position (x,y). This will either
2287 * be this component, an immediate child component, or <code>null</code>
2288 * if neither of the first two occupies the specified location.
2290 * @param x the X coordinate to search for components at
2291 * @param y the Y coordinate to search for components at
2292 * @return the component at the specified location, or null
2293 * @deprecated use {@link #getComponentAt(int, int)} instead
2295 public Component locate(int x, int y)
2297 return contains (x, y) ? this : null;
2301 * Returns the component occupying the position (x,y). This will either
2302 * be this component, an immediate child component, or <code>null</code>
2303 * if neither of the first two occupies the specified location.
2305 * @param p the point to search for components at
2306 * @return the component at the specified location, or null
2307 * @throws NullPointerException if p is null
2308 * @see #contains(Point)
2311 public Component getComponentAt(Point p)
2313 return getComponentAt (p.x, p.y);
2317 * AWT 1.0 event delivery.
2319 * Deliver an AWT 1.0 event to this Component. This method simply
2320 * calls {@link #postEvent}.
2322 * @param e the event to deliver
2323 * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2325 public void deliverEvent (Event e)
2331 * Forwards AWT events to processEvent() if:<ul>
2332 * <li>Events have been enabled for this type of event via
2333 * <code>enableEvents()</code></li>,
2334 * <li>There is at least one registered listener for this type of event</li>
2337 * @param e the event to dispatch
2339 public final void dispatchEvent(AWTEvent e)
2341 // Some subclasses in the AWT package need to override this behavior,
2342 // hence the use of dispatchEventImpl().
2343 dispatchEventImpl(e);
2347 * AWT 1.0 event handler.
2349 * This method simply calls handleEvent and returns the result.
2351 * @param e the event to handle
2352 * @return true if the event was handled, false otherwise
2353 * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2355 public boolean postEvent (Event e)
2357 boolean handled = handleEvent (e);
2359 if (!handled && getParent() != null)
2360 // FIXME: need to translate event coordinates to parent's
2361 // coordinate space.
2362 handled = getParent ().postEvent (e);
2368 * Adds the specified listener to this component. This is harmless if the
2369 * listener is null, but if the listener has already been registered, it
2370 * will now be registered twice.
2372 * @param listener the new listener to add
2373 * @see ComponentEvent
2374 * @see #removeComponentListener(ComponentListener)
2375 * @see #getComponentListeners()
2378 public synchronized void addComponentListener(ComponentListener listener)
2380 componentListener = AWTEventMulticaster.add(componentListener, listener);
2381 if (componentListener != null)
2382 enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
2386 * Removes the specified listener from the component. This is harmless if
2387 * the listener was not previously registered.
2389 * @param listener the listener to remove
2390 * @see ComponentEvent
2391 * @see #addComponentListener(ComponentListener)
2392 * @see #getComponentListeners()
2395 public synchronized void removeComponentListener(ComponentListener listener)
2397 componentListener = AWTEventMulticaster.remove(componentListener, listener);
2401 * Returns an array of all specified listeners registered on this component.
2403 * @return an array of listeners
2404 * @see #addComponentListener(ComponentListener)
2405 * @see #removeComponentListener(ComponentListener)
2408 public synchronized ComponentListener[] getComponentListeners()
2410 return (ComponentListener[])
2411 AWTEventMulticaster.getListeners(componentListener,
2412 ComponentListener.class);
2416 * Adds the specified listener to this component. This is harmless if the
2417 * listener is null, but if the listener has already been registered, it
2418 * will now be registered twice.
2420 * @param listener the new listener to add
2422 * @see #removeFocusListener(FocusListener)
2423 * @see #getFocusListeners()
2426 public synchronized void addFocusListener(FocusListener listener)
2428 focusListener = AWTEventMulticaster.add(focusListener, listener);
2429 if (focusListener != null)
2430 enableEvents(AWTEvent.FOCUS_EVENT_MASK);
2434 * Removes the specified listener from the component. This is harmless if
2435 * the listener was not previously registered.
2437 * @param listener the listener to remove
2439 * @see #addFocusListener(FocusListener)
2440 * @see #getFocusListeners()
2443 public synchronized void removeFocusListener(FocusListener listener)
2445 focusListener = AWTEventMulticaster.remove(focusListener, listener);
2449 * Returns an array of all specified listeners registered on this component.
2451 * @return an array of listeners
2452 * @see #addFocusListener(FocusListener)
2453 * @see #removeFocusListener(FocusListener)
2456 public synchronized FocusListener[] getFocusListeners()
2458 return (FocusListener[])
2459 AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2463 * Adds the specified listener to this component. This is harmless if the
2464 * listener is null, but if the listener has already been registered, it
2465 * will now be registered twice.
2467 * @param listener the new listener to add
2468 * @see HierarchyEvent
2469 * @see #removeHierarchyListener(HierarchyListener)
2470 * @see #getHierarchyListeners()
2473 public synchronized void addHierarchyListener(HierarchyListener listener)
2475 hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
2476 if (hierarchyListener != null)
2477 enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
2481 * Removes the specified listener from the component. This is harmless if
2482 * the listener was not previously registered.
2484 * @param listener the listener to remove
2485 * @see HierarchyEvent
2486 * @see #addHierarchyListener(HierarchyListener)
2487 * @see #getHierarchyListeners()
2490 public synchronized void removeHierarchyListener(HierarchyListener listener)
2492 hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
2496 * Returns an array of all specified listeners registered on this component.
2498 * @return an array of listeners
2499 * @see #addHierarchyListener(HierarchyListener)
2500 * @see #removeHierarchyListener(HierarchyListener)
2503 public synchronized HierarchyListener[] getHierarchyListeners()
2505 return (HierarchyListener[])
2506 AWTEventMulticaster.getListeners(hierarchyListener,
2507 HierarchyListener.class);
2511 * Adds the specified listener to this component. This is harmless if the
2512 * listener is null, but if the listener has already been registered, it
2513 * will now be registered twice.
2515 * @param listener the new listener to add
2516 * @see HierarchyEvent
2517 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2518 * @see #getHierarchyBoundsListeners()
2521 public synchronized void
2522 addHierarchyBoundsListener(HierarchyBoundsListener listener)
2524 hierarchyBoundsListener =
2525 AWTEventMulticaster.add(hierarchyBoundsListener, listener);
2526 if (hierarchyBoundsListener != null)
2527 enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2531 * Removes the specified listener from the component. This is harmless if
2532 * the listener was not previously registered.
2534 * @param listener the listener to remove
2535 * @see HierarchyEvent
2536 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2537 * @see #getHierarchyBoundsListeners()
2540 public synchronized void
2541 removeHierarchyBoundsListener(HierarchyBoundsListener listener)
2543 hierarchyBoundsListener =
2544 AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
2548 * Returns an array of all specified listeners registered on this component.
2550 * @return an array of listeners
2551 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2552 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2555 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
2557 return (HierarchyBoundsListener[])
2558 AWTEventMulticaster.getListeners(hierarchyBoundsListener,
2559 HierarchyBoundsListener.class);
2563 * Adds the specified listener to this component. This is harmless if the
2564 * listener is null, but if the listener has already been registered, it
2565 * will now be registered twice.
2567 * @param listener the new listener to add
2569 * @see #removeKeyListener(KeyListener)
2570 * @see #getKeyListeners()
2573 public synchronized void addKeyListener(KeyListener listener)
2575 keyListener = AWTEventMulticaster.add(keyListener, listener);
2576 if (keyListener != null)
2577 enableEvents(AWTEvent.KEY_EVENT_MASK);
2581 * Removes the specified listener from the component. This is harmless if
2582 * the listener was not previously registered.
2584 * @param listener the listener to remove
2586 * @see #addKeyListener(KeyListener)
2587 * @see #getKeyListeners()
2590 public synchronized void removeKeyListener(KeyListener listener)
2592 keyListener = AWTEventMulticaster.remove(keyListener, listener);
2596 * Returns an array of all specified listeners registered on this component.
2598 * @return an array of listeners
2599 * @see #addKeyListener(KeyListener)
2600 * @see #removeKeyListener(KeyListener)
2603 public synchronized KeyListener[] getKeyListeners()
2605 return (KeyListener[])
2606 AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
2610 * Adds the specified listener to this component. This is harmless if the
2611 * listener is null, but if the listener has already been registered, it
2612 * will now be registered twice.
2614 * @param listener the new listener to add
2616 * @see #removeMouseListener(MouseListener)
2617 * @see #getMouseListeners()
2620 public synchronized void addMouseListener(MouseListener listener)
2622 mouseListener = AWTEventMulticaster.add(mouseListener, listener);
2623 if (mouseListener != null)
2624 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2628 * Removes the specified listener from the component. This is harmless if
2629 * the listener was not previously registered.
2631 * @param listener the listener to remove
2633 * @see #addMouseListener(MouseListener)
2634 * @see #getMouseListeners()
2637 public synchronized void removeMouseListener(MouseListener listener)
2639 mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
2643 * Returns an array of all specified listeners registered on this component.
2645 * @return an array of listeners
2646 * @see #addMouseListener(MouseListener)
2647 * @see #removeMouseListener(MouseListener)
2650 public synchronized MouseListener[] getMouseListeners()
2652 return (MouseListener[])
2653 AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
2657 * Adds the specified listener to this component. This is harmless if the
2658 * listener is null, but if the listener has already been registered, it
2659 * will now be registered twice.
2661 * @param listener the new listener to add
2663 * @see #removeMouseMotionListener(MouseMotionListener)
2664 * @see #getMouseMotionListeners()
2667 public synchronized void addMouseMotionListener(MouseMotionListener listener)
2669 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
2670 if (mouseMotionListener != null)
2671 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2675 * Removes the specified listener from the component. This is harmless if
2676 * the listener was not previously registered.
2678 * @param listener the listener to remove
2680 * @see #addMouseMotionListener(MouseMotionListener)
2681 * @see #getMouseMotionListeners()
2684 public synchronized void removeMouseMotionListener(MouseMotionListener listener)
2686 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
2690 * Returns an array of all specified listeners registered on this component.
2692 * @return an array of listeners
2693 * @see #addMouseMotionListener(MouseMotionListener)
2694 * @see #removeMouseMotionListener(MouseMotionListener)
2697 public synchronized MouseMotionListener[] getMouseMotionListeners()
2699 return (MouseMotionListener[])
2700 AWTEventMulticaster.getListeners(mouseMotionListener,
2701 MouseMotionListener.class);
2705 * Adds the specified listener to this component. This is harmless if the
2706 * listener is null, but if the listener has already been registered, it
2707 * will now be registered twice.
2709 * @param listener the new listener to add
2711 * @see MouseWheelEvent
2712 * @see #removeMouseWheelListener(MouseWheelListener)
2713 * @see #getMouseWheelListeners()
2716 public synchronized void addMouseWheelListener(MouseWheelListener listener)
2718 mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
2719 if (mouseWheelListener != null)
2720 enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
2724 * Removes the specified listener from the component. This is harmless if
2725 * the listener was not previously registered.
2727 * @param listener the listener to remove
2729 * @see MouseWheelEvent
2730 * @see #addMouseWheelListener(MouseWheelListener)
2731 * @see #getMouseWheelListeners()
2734 public synchronized void removeMouseWheelListener(MouseWheelListener listener)
2736 mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
2740 * Returns an array of all specified listeners registered on this component.
2742 * @return an array of listeners
2743 * @see #addMouseWheelListener(MouseWheelListener)
2744 * @see #removeMouseWheelListener(MouseWheelListener)
2747 public synchronized MouseWheelListener[] getMouseWheelListeners()
2749 return (MouseWheelListener[])
2750 AWTEventMulticaster.getListeners(mouseWheelListener,
2751 MouseWheelListener.class);
2755 * Adds the specified listener to this component. This is harmless if the
2756 * listener is null, but if the listener has already been registered, it
2757 * will now be registered twice.
2759 * @param listener the new listener to add
2760 * @see InputMethodEvent
2761 * @see #removeInputMethodListener(InputMethodListener)
2762 * @see #getInputMethodListeners()
2763 * @see #getInputMethodRequests()
2766 public synchronized void addInputMethodListener(InputMethodListener listener)
2768 inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
2769 if (inputMethodListener != null)
2770 enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
2774 * Removes the specified listener from the component. This is harmless if
2775 * the listener was not previously registered.
2777 * @param listener the listener to remove
2778 * @see InputMethodEvent
2779 * @see #addInputMethodListener(InputMethodListener)
2780 * @see #getInputMethodRequests()
2783 public synchronized void removeInputMethodListener(InputMethodListener listener)
2785 inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
2789 * Returns an array of all specified listeners registered on this component.
2791 * @return an array of listeners
2792 * @see #addInputMethodListener(InputMethodListener)
2793 * @see #removeInputMethodListener(InputMethodListener)
2796 public synchronized InputMethodListener[] getInputMethodListeners()
2798 return (InputMethodListener[])
2799 AWTEventMulticaster.getListeners(inputMethodListener,
2800 InputMethodListener.class);
2804 * Returns all registered EventListers of the given listenerType.
2806 * @param listenerType the class of listeners to filter
2807 * @return an array of registered listeners
2808 * @see #getComponentListeners()
2809 * @see #getFocusListeners()
2810 * @see #getHierarchyListeners()
2811 * @see #getHierarchyBoundsListeners()
2812 * @see #getKeyListeners()
2813 * @see #getMouseListeners()
2814 * @see #getMouseMotionListeners()
2815 * @see #getMouseWheelListeners()
2816 * @see #getInputMethodListeners()
2817 * @see #getPropertyChangeListeners()
2820 public EventListener[] getListeners(Class listenerType)
2822 if (listenerType == ComponentListener.class)
2823 return getComponentListeners();
2824 if (listenerType == FocusListener.class)
2825 return getFocusListeners();
2826 if (listenerType == HierarchyListener.class)
2827 return getHierarchyListeners();
2828 if (listenerType == HierarchyBoundsListener.class)
2829 return getHierarchyBoundsListeners();
2830 if (listenerType == KeyListener.class)
2831 return getKeyListeners();
2832 if (listenerType == MouseListener.class)
2833 return getMouseListeners();
2834 if (listenerType == MouseMotionListener.class)
2835 return getMouseMotionListeners();
2836 if (listenerType == MouseWheelListener.class)
2837 return getMouseWheelListeners();
2838 if (listenerType == InputMethodListener.class)
2839 return getInputMethodListeners();
2840 if (listenerType == PropertyChangeListener.class)
2841 return getPropertyChangeListeners();
2842 return (EventListener[]) Array.newInstance(listenerType, 0);
2846 * Returns the input method request handler, for subclasses which support
2847 * on-the-spot text input. By default, input methods are handled by AWT,
2848 * and this returns null.
2850 * @return the input method handler, null by default
2853 public InputMethodRequests getInputMethodRequests()
2859 * Gets the input context of this component, which is inherited from the
2860 * parent unless this is overridden.
2862 * @return the text input context
2865 public InputContext getInputContext()
2867 return parent == null ? null : parent.getInputContext();
2871 * Enables the specified events. The events to enable are specified
2872 * by OR-ing together the desired masks from <code>AWTEvent</code>.
2874 * <p>Events are enabled by default when a listener is attached to the
2875 * component for that event type. This method can be used by subclasses
2876 * to ensure the delivery of a specified event regardless of whether
2877 * or not a listener is attached.
2879 * @param eventsToEnable the desired events to enable
2880 * @see #processEvent(AWTEvent)
2881 * @see #disableEvents(long)
2885 protected final void enableEvents(long eventsToEnable)
2887 eventMask |= eventsToEnable;
2888 // TODO: Unlike Sun's implementation, I think we should try and
2889 // enable/disable events at the peer (gtk/X) level. This will avoid
2890 // clogging the event pipeline with useless mousemove events that
2891 // we arn't interested in, etc. This will involve extending the peer
2892 // interface, but thats okay because the peer interfaces have been
2893 // deprecated for a long time, and no longer feature in the
2894 // API specification at all.
2895 if (isLightweight() && parent != null)
2896 parent.enableEvents(eventsToEnable);
2897 else if (peer != null)
2898 peer.setEventMask(eventMask);
2902 * Disables the specified events. The events to disable are specified
2903 * by OR-ing together the desired masks from <code>AWTEvent</code>.
2905 * @param eventsToDisable the desired events to disable
2906 * @see #enableEvents(long)
2909 protected final void disableEvents(long eventsToDisable)
2911 eventMask &= ~eventsToDisable;
2912 // forward new event mask to peer?
2916 * This is called by the EventQueue if two events with the same event id
2917 * and owner component are queued. Returns a new combined event, or null if
2918 * no combining is done. The coelesced events are currently mouse moves
2919 * (intermediate ones are discarded) and paint events (a merged paint is
2920 * created in place of the two events).
2922 * @param existingEvent the event on the queue
2923 * @param newEvent the new event that might be entered on the queue
2924 * @return null if both events are kept, or the replacement coelesced event
2926 protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
2928 switch (existingEvent.id)
2930 case MouseEvent.MOUSE_MOVED:
2931 case MouseEvent.MOUSE_DRAGGED:
2932 // Just drop the old (intermediate) event and return the new one.
2934 case PaintEvent.PAINT:
2935 case PaintEvent.UPDATE:
2936 return coalescePaintEvents((PaintEvent) existingEvent,
2937 (PaintEvent) newEvent);
2944 * Processes the specified event. In this class, this method simply
2945 * calls one of the more specific event handlers.
2947 * @param e the event to process
2948 * @throws NullPointerException if e is null
2949 * @see #processComponentEvent(ComponentEvent)
2950 * @see #processFocusEvent(FocusEvent)
2951 * @see #processKeyEvent(KeyEvent)
2952 * @see #processMouseEvent(MouseEvent)
2953 * @see #processMouseMotionEvent(MouseEvent)
2954 * @see #processInputMethodEvent(InputMethodEvent)
2955 * @see #processHierarchyEvent(HierarchyEvent)
2956 * @see #processMouseWheelEvent(MouseWheelEvent)
2959 protected void processEvent(AWTEvent e)
2961 /* Note: the order of these if statements are
2962 important. Subclasses must be checked first. Eg. MouseEvent
2963 must be checked before ComponentEvent, since a MouseEvent
2964 object is also an instance of a ComponentEvent. */
2966 if (e instanceof FocusEvent)
2967 processFocusEvent((FocusEvent) e);
2968 else if (e instanceof MouseWheelEvent)
2969 processMouseWheelEvent((MouseWheelEvent) e);
2970 else if (e instanceof MouseEvent)
2972 if (e.id == MouseEvent.MOUSE_MOVED
2973 || e.id == MouseEvent.MOUSE_DRAGGED)
2974 processMouseMotionEvent((MouseEvent) e);
2976 processMouseEvent((MouseEvent) e);
2978 else if (e instanceof KeyEvent)
2979 processKeyEvent((KeyEvent) e);
2980 else if (e instanceof InputMethodEvent)
2981 processInputMethodEvent((InputMethodEvent) e);
2982 else if (e instanceof ComponentEvent)
2983 processComponentEvent((ComponentEvent) e);
2984 else if (e instanceof HierarchyEvent)
2986 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
2987 processHierarchyEvent((HierarchyEvent) e);
2989 processHierarchyBoundsEvent((HierarchyEvent) e);
2994 * Called when a component event is dispatched and component events are
2995 * enabled. This method passes the event along to any listeners
2996 * that are attached.
2998 * @param e the <code>ComponentEvent</code> to process
2999 * @throws NullPointerException if e is null
3000 * @see ComponentListener
3001 * @see #addComponentListener(ComponentListener)
3002 * @see #enableEvents(long)
3005 protected void processComponentEvent(ComponentEvent e)
3007 if (componentListener == null)
3011 case ComponentEvent.COMPONENT_HIDDEN:
3012 componentListener.componentHidden(e);
3014 case ComponentEvent.COMPONENT_MOVED:
3015 componentListener.componentMoved(e);
3017 case ComponentEvent.COMPONENT_RESIZED:
3018 componentListener.componentResized(e);
3020 case ComponentEvent.COMPONENT_SHOWN:
3021 componentListener.componentShown(e);
3027 * Called when a focus event is dispatched and component events are
3028 * enabled. This method passes the event along to any listeners
3029 * that are attached.
3031 * @param e the <code>FocusEvent</code> to process
3032 * @throws NullPointerException if e is null
3033 * @see FocusListener
3034 * @see #addFocusListener(FocusListener)
3035 * @see #enableEvents(long)
3038 protected void processFocusEvent(FocusEvent e)
3040 if (focusListener == null)
3045 case FocusEvent.FOCUS_GAINED:
3046 focusListener.focusGained(e);
3048 case FocusEvent.FOCUS_LOST:
3049 focusListener.focusLost(e);
3055 * Called when a key event is dispatched and component events are
3056 * enabled. This method passes the event along to any listeners
3057 * that are attached.
3059 * @param e the <code>KeyEvent</code> to process
3060 * @throws NullPointerException if e is null
3062 * @see #addKeyListener(KeyListener)
3063 * @see #enableEvents(long)
3066 protected void processKeyEvent(KeyEvent e)
3068 if (keyListener == null)
3072 case KeyEvent.KEY_PRESSED:
3073 keyListener.keyPressed(e);
3075 case KeyEvent.KEY_RELEASED:
3076 keyListener.keyReleased(e);
3078 case KeyEvent.KEY_TYPED:
3079 keyListener.keyTyped(e);
3085 * Called when a regular mouse event is dispatched and component events are
3086 * enabled. This method passes the event along to any listeners
3087 * that are attached.
3089 * @param e the <code>MouseEvent</code> to process
3090 * @throws NullPointerException if e is null
3091 * @see MouseListener
3092 * @see #addMouseListener(MouseListener)
3093 * @see #enableEvents(long)
3096 protected void processMouseEvent(MouseEvent e)
3098 if (mouseListener == null)
3102 case MouseEvent.MOUSE_CLICKED:
3103 mouseListener.mouseClicked(e);
3105 case MouseEvent.MOUSE_ENTERED:
3106 mouseListener.mouseEntered(e);
3108 case MouseEvent.MOUSE_EXITED:
3109 mouseListener.mouseExited(e);
3111 case MouseEvent.MOUSE_PRESSED:
3112 mouseListener.mousePressed(e);
3114 case MouseEvent.MOUSE_RELEASED:
3115 mouseListener.mouseReleased(e);
3122 * Called when a mouse motion event is dispatched and component events are
3123 * enabled. This method passes the event along to any listeners
3124 * that are attached.
3126 * @param e the <code>MouseMotionEvent</code> to process
3127 * @throws NullPointerException if e is null
3128 * @see MouseMotionListener
3129 * @see #addMouseMotionListener(MouseMotionListener)
3130 * @see #enableEvents(long)
3133 protected void processMouseMotionEvent(MouseEvent e)
3135 if (mouseMotionListener == null)
3139 case MouseEvent.MOUSE_DRAGGED:
3140 mouseMotionListener.mouseDragged(e);
3142 case MouseEvent.MOUSE_MOVED:
3143 mouseMotionListener.mouseMoved(e);
3150 * Called when a mouse wheel event is dispatched and component events are
3151 * enabled. This method passes the event along to any listeners that are
3154 * @param e the <code>MouseWheelEvent</code> to process
3155 * @throws NullPointerException if e is null
3156 * @see MouseWheelListener
3157 * @see #addMouseWheelListener(MouseWheelListener)
3158 * @see #enableEvents(long)
3161 protected void processMouseWheelEvent(MouseWheelEvent e)
3163 if (mouseWheelListener != null
3164 && e.id == MouseEvent.MOUSE_WHEEL)
3166 mouseWheelListener.mouseWheelMoved(e);
3172 * Called when an input method event is dispatched and component events are
3173 * enabled. This method passes the event along to any listeners that are
3176 * @param e the <code>InputMethodEvent</code> to process
3177 * @throws NullPointerException if e is null
3178 * @see InputMethodListener
3179 * @see #addInputMethodListener(InputMethodListener)
3180 * @see #enableEvents(long)
3183 protected void processInputMethodEvent(InputMethodEvent e)
3185 if (inputMethodListener == null)
3189 case InputMethodEvent.CARET_POSITION_CHANGED:
3190 inputMethodListener.caretPositionChanged(e);
3192 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3193 inputMethodListener.inputMethodTextChanged(e);
3199 * Called when a hierarchy change event is dispatched and component events
3200 * are enabled. This method passes the event along to any listeners that are
3203 * @param e the <code>HierarchyEvent</code> to process
3204 * @throws NullPointerException if e is null
3205 * @see HierarchyListener
3206 * @see #addHierarchyListener(HierarchyListener)
3207 * @see #enableEvents(long)
3210 protected void processHierarchyEvent(HierarchyEvent e)
3212 if (hierarchyListener == null)
3214 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3215 hierarchyListener.hierarchyChanged(e);
3219 * Called when a hierarchy bounds event is dispatched and component events
3220 * are enabled. This method passes the event along to any listeners that are
3223 * @param e the <code>HierarchyEvent</code> to process
3224 * @throws NullPointerException if e is null
3225 * @see HierarchyBoundsListener
3226 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3227 * @see #enableEvents(long)
3230 protected void processHierarchyBoundsEvent(HierarchyEvent e)
3232 if (hierarchyBoundsListener == null)
3236 case HierarchyEvent.ANCESTOR_MOVED:
3237 hierarchyBoundsListener.ancestorMoved(e);
3239 case HierarchyEvent.ANCESTOR_RESIZED:
3240 hierarchyBoundsListener.ancestorResized(e);
3246 * AWT 1.0 event handler.
3248 * This method calls one of the event-specific handler methods. For
3249 * example for key events, either {@link #keyDown(Event,int)}
3250 * or {@link #keyUp(Event,int)} is called. A derived
3251 * component can override one of these event-specific methods if it
3252 * only needs to handle certain event types. Otherwise it can
3253 * override handleEvent itself and handle any event.
3255 * @param evt the event to handle
3256 * @return true if the event was handled, false otherwise
3257 * @deprecated use {@link #processEvent(AWTEvent)} instead
3259 public boolean handleEvent (Event evt)
3263 // Handle key events.
3264 case Event.KEY_ACTION:
3265 case Event.KEY_PRESS:
3266 return keyDown (evt, evt.key);
3267 case Event.KEY_ACTION_RELEASE:
3268 case Event.KEY_RELEASE:
3269 return keyUp (evt, evt.key);
3271 // Handle mouse events.
3272 case Event.MOUSE_DOWN:
3273 return mouseDown (evt, evt.x, evt.y);
3274 case Event.MOUSE_UP:
3275 return mouseUp (evt, evt.x, evt.y);
3276 case Event.MOUSE_MOVE:
3277 return mouseMove (evt, evt.x, evt.y);
3278 case Event.MOUSE_DRAG:
3279 return mouseDrag (evt, evt.x, evt.y);
3280 case Event.MOUSE_ENTER:
3281 return mouseEnter (evt, evt.x, evt.y);
3282 case Event.MOUSE_EXIT:
3283 return mouseExit (evt, evt.x, evt.y);
3285 // Handle focus events.
3286 case Event.GOT_FOCUS:
3287 return gotFocus (evt, evt.arg);
3288 case Event.LOST_FOCUS:
3289 return lostFocus (evt, evt.arg);
3291 // Handle action event.
3292 case Event.ACTION_EVENT:
3293 return action (evt, evt.arg);
3300 * AWT 1.0 MOUSE_DOWN event handler. This method is meant to be
3301 * overridden by components providing their own MOUSE_DOWN handler.
3302 * The default implementation simply returns false.
3304 * @param evt the event to handle
3305 * @param x the x coordinate, ignored
3306 * @param y the y coordinate, ignored
3308 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3310 public boolean mouseDown(Event evt, int x, int y)
3316 * AWT 1.0 MOUSE_DRAG event handler. This method is meant to be
3317 * overridden by components providing their own MOUSE_DRAG handler.
3318 * The default implementation simply returns false.
3320 * @param evt the event to handle
3321 * @param x the x coordinate, ignored
3322 * @param y the y coordinate, ignored
3324 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3326 public boolean mouseDrag(Event evt, int x, int y)
3332 * AWT 1.0 MOUSE_UP event handler. This method is meant to be
3333 * overridden by components providing their own MOUSE_UP handler.
3334 * The default implementation simply returns false.
3336 * @param evt the event to handle
3337 * @param x the x coordinate, ignored
3338 * @param y the y coordinate, ignored
3340 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3342 public boolean mouseUp(Event evt, int x, int y)
3348 * AWT 1.0 MOUSE_MOVE event handler. This method is meant to be
3349 * overridden by components providing their own MOUSE_MOVE handler.
3350 * The default implementation simply returns false.
3352 * @param evt the event to handle
3353 * @param x the x coordinate, ignored
3354 * @param y the y coordinate, ignored
3356 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3358 public boolean mouseMove(Event evt, int x, int y)
3364 * AWT 1.0 MOUSE_ENTER event handler. This method is meant to be
3365 * overridden by components providing their own MOUSE_ENTER handler.
3366 * The default implementation simply returns false.
3368 * @param evt the event to handle
3369 * @param x the x coordinate, ignored
3370 * @param y the y coordinate, ignored
3372 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3374 public boolean mouseEnter(Event evt, int x, int y)
3380 * AWT 1.0 MOUSE_EXIT event handler. This method is meant to be
3381 * overridden by components providing their own MOUSE_EXIT handler.
3382 * The default implementation simply returns false.
3384 * @param evt the event to handle
3385 * @param x the x coordinate, ignored
3386 * @param y the y coordinate, ignored
3388 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3390 public boolean mouseExit(Event evt, int x, int y)
3396 * AWT 1.0 KEY_PRESS and KEY_ACTION event handler. This method is
3397 * meant to be overridden by components providing their own key
3398 * press handler. The default implementation simply returns false.
3400 * @param evt the event to handle
3401 * @param key the key pressed, ignored
3403 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3405 public boolean keyDown(Event evt, int key)
3411 * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler. This
3412 * method is meant to be overridden by components providing their
3413 * own key release handler. The default implementation simply
3416 * @param evt the event to handle
3417 * @param key the key pressed, ignored
3419 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3421 public boolean keyUp(Event evt, int key)
3427 * AWT 1.0 ACTION_EVENT event handler. This method is meant to be
3428 * overridden by components providing their own action event
3429 * handler. The default implementation simply returns false.
3431 * @param evt the event to handle
3432 * @param what the object acted on, ignored
3434 * @deprecated in classes which support actions, use
3435 * <code>processActionEvent(ActionEvent)</code> instead
3437 public boolean action(Event evt, Object what)
3443 * Called to inform this component it has been added to a container.
3444 * A native peer - if any - is created at this time. This method is
3445 * called automatically by the AWT system and should not be called by
3448 * @see #isDisplayable()
3449 * @see #removeNotify()
3451 public void addNotify()
3454 peer = getToolkit().createComponent(this);
3455 /* Now that all the children has gotten their peers, we should
3456 have the event mask needed for this component and its
3457 lightweight subcomponents. */
3458 peer.setEventMask(eventMask);
3459 /* We do not invalidate here, but rather leave that job up to
3460 the peer. For efficiency, the peer can choose not to
3461 invalidate if it is happy with the current dimensions,
3466 * Called to inform this component is has been removed from its
3467 * container. Its native peer - if any - is destroyed at this time.
3468 * This method is called automatically by the AWT system and should
3469 * not be called by user level code.
3471 * @see #isDisplayable()
3474 public void removeNotify()
3476 // We null our peer field before disposing of it, such that if we're
3477 // not the event dispatch thread and the dispatch thread is awoken by
3478 // the dispose call, there will be no race checking the peer's null
3481 ComponentPeer tmp = peer;
3488 * AWT 1.0 GOT_FOCUS event handler. This method is meant to be
3489 * overridden by components providing their own GOT_FOCUS handler.
3490 * The default implementation simply returns false.
3492 * @param evt the event to handle
3493 * @param what the Object focused, ignored
3495 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3497 public boolean gotFocus(Event evt, Object what)
3503 * AWT 1.0 LOST_FOCUS event handler. This method is meant to be
3504 * overridden by components providing their own LOST_FOCUS handler.
3505 * The default implementation simply returns false.
3507 * @param evt the event to handle
3508 * @param what the Object focused, ignored
3510 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3512 public boolean lostFocus(Event evt, Object what)
3518 * Tests whether or not this component is in the group that can be
3519 * traversed using the keyboard traversal mechanism (such as the TAB key).
3521 * @return true if the component is traversed via the TAB key
3522 * @see #setFocusable(boolean)
3524 * @deprecated use {@link #isFocusable()} instead
3526 public boolean isFocusTraversable()
3528 return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
3532 * Tests if this component can receive focus.
3534 * @return true if this component can receive focus
3537 public boolean isFocusable()
3543 * Specify whether this component can receive focus. This method also
3544 * sets the {@link #isFocusTraversableOverridden} field to 1, which
3545 * appears to be the undocumented way {@link
3546 * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
3547 * respect the {@link #isFocusable()} method of the component.
3549 * @param focusable the new focusable status
3552 public void setFocusable(boolean focusable)
3554 firePropertyChange("focusable", this.focusable, focusable);
3555 this.focusable = focusable;
3556 this.isFocusTraversableOverridden = 1;
3560 * Sets the focus traversal keys for one of the three focus
3561 * traversal directions supported by Components:
3562 * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
3563 * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
3564 * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
3565 * default values should match the operating system's native
3566 * choices. To disable a given traversal, use
3567 * <code>Collections.EMPTY_SET</code>. The event dispatcher will
3568 * consume PRESSED, RELEASED, and TYPED events for the specified
3569 * key, although focus can only transfer on PRESSED or RELEASED.
3571 * <p>The defaults are:
3573 * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
3574 * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
3575 * <td>Normal forward traversal</td>
3576 * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
3577 * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
3578 * <td>Normal backward traversal</td>
3579 * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
3580 * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
3581 * <td>Go up a traversal cycle</td><td>None</td></tr>
3584 * If keystrokes is null, this component's focus traversal key set
3585 * is inherited from one of its ancestors. If none of its ancestors
3586 * has its own set of focus traversal keys, the focus traversal keys
3587 * are set to the defaults retrieved from the current
3588 * KeyboardFocusManager. If not null, the set must contain only
3589 * AWTKeyStrokes that are not already focus keys and are not
3592 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3593 * UP_CYCLE_TRAVERSAL_KEYS
3594 * @param keystrokes a set of keys, or null
3595 * @throws IllegalArgumentException if id or keystrokes is invalid
3596 * @see #getFocusTraversalKeys(int)
3597 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3598 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3599 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3602 public void setFocusTraversalKeys(int id, Set keystrokes)
3604 if (keystrokes == null)
3606 Container parent = getParent ();
3608 while (parent != null)
3610 if (parent.areFocusTraversalKeysSet (id))
3612 keystrokes = parent.getFocusTraversalKeys (id);
3615 parent = parent.getParent ();
3618 if (keystrokes == null)
3619 keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
3620 getDefaultFocusTraversalKeys (id);
3628 case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
3629 sa = getFocusTraversalKeys
3630 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3631 sb = getFocusTraversalKeys
3632 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3633 name = "forwardFocusTraversalKeys";
3635 case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
3636 sa = getFocusTraversalKeys
3637 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3638 sb = getFocusTraversalKeys
3639 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3640 name = "backwardFocusTraversalKeys";
3642 case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
3643 sa = getFocusTraversalKeys
3644 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3645 sb = getFocusTraversalKeys
3646 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3647 name = "upCycleFocusTraversalKeys";
3650 throw new IllegalArgumentException ();
3653 int i = keystrokes.size ();
3654 Iterator iter = keystrokes.iterator ();
3658 Object o = iter.next ();
3659 if (!(o instanceof AWTKeyStroke)
3660 || sa.contains (o) || sb.contains (o)
3661 || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
3662 throw new IllegalArgumentException ();
3665 if (focusTraversalKeys == null)
3666 focusTraversalKeys = new Set[3];
3668 keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
3669 firePropertyChange (name, focusTraversalKeys[id], keystrokes);
3671 focusTraversalKeys[id] = keystrokes;
3675 * Returns the set of keys for a given focus traversal action, as
3676 * defined in <code>setFocusTraversalKeys</code>. If not set, this
3677 * is inherited from the parent component, which may have gotten it
3678 * from the KeyboardFocusManager.
3680 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3681 * or UP_CYCLE_TRAVERSAL_KEYS
3683 * @return set of traversal keys
3685 * @throws IllegalArgumentException if id is invalid
3687 * @see #setFocusTraversalKeys (int, Set)
3688 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3689 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3690 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3694 public Set getFocusTraversalKeys (int id)
3696 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3697 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3698 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3699 throw new IllegalArgumentException();
3703 if (focusTraversalKeys != null)
3704 s = focusTraversalKeys[id];
3706 if (s == null && parent != null)
3707 s = parent.getFocusTraversalKeys (id);
3709 return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
3710 .getDefaultFocusTraversalKeys(id)) : s;
3714 * Tests whether the focus traversal keys for a given action are explicitly
3717 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3718 * or UP_CYCLE_TRAVERSAL_KEYS
3719 * @return true if that set is explicitly specified
3720 * @throws IllegalArgumentException if id is invalid
3721 * @see #getFocusTraversalKeys (int)
3722 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3723 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3724 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3727 public boolean areFocusTraversalKeysSet (int id)
3729 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3730 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3731 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3732 throw new IllegalArgumentException ();
3734 return focusTraversalKeys != null && focusTraversalKeys[id] != null;
3738 * Enable or disable focus traversal keys on this Component. If
3739 * they are, then the keyboard focus manager consumes and acts on
3740 * key press and release events that trigger focus traversal, and
3741 * discards the corresponding key typed events. If focus traversal
3742 * keys are disabled, then all key events that would otherwise
3743 * trigger focus traversal are sent to this Component.
3745 * @param focusTraversalKeysEnabled the new value of the flag
3746 * @see #getFocusTraversalKeysEnabled ()
3747 * @see #setFocusTraversalKeys (int, Set)
3748 * @see #getFocusTraversalKeys (int)
3751 public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
3753 firePropertyChange ("focusTraversalKeysEnabled",
3754 this.focusTraversalKeysEnabled,
3755 focusTraversalKeysEnabled);
3756 this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
3760 * Check whether or not focus traversal keys are enabled on this
3761 * Component. If they are, then the keyboard focus manager consumes
3762 * and acts on key press and release events that trigger focus
3763 * traversal, and discards the corresponding key typed events. If
3764 * focus traversal keys are disabled, then all key events that would
3765 * otherwise trigger focus traversal are sent to this Component.
3767 * @return true if focus traversal keys are enabled
3768 * @see #setFocusTraversalKeysEnabled (boolean)
3769 * @see #setFocusTraversalKeys (int, Set)
3770 * @see #getFocusTraversalKeys (int)
3773 public boolean getFocusTraversalKeysEnabled ()
3775 return focusTraversalKeysEnabled;
3779 * Request that this Component be given the keyboard input focus and
3780 * that its top-level ancestor become the focused Window.
3782 * For the request to be granted, the Component must be focusable,
3783 * displayable and showing and the top-level Window to which it
3784 * belongs must be focusable. If the request is initially denied on
3785 * the basis that the top-level Window is not focusable, the request
3786 * will be remembered and granted when the Window does become
3789 * Never assume that this Component is the focus owner until it
3790 * receives a FOCUS_GAINED event.
3792 * The behaviour of this method is platform-dependent.
3793 * {@link #requestFocusInWindow()} should be used instead.
3795 * @see #requestFocusInWindow ()
3797 * @see #addFocusListener (FocusListener)
3798 * @see #isFocusable ()
3799 * @see #isDisplayable ()
3800 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3802 public void requestFocus ()
3804 if (isDisplayable ()
3808 synchronized (getTreeLock ())
3810 // Find this Component's top-level ancestor.
3811 Container parent = getParent ();
3813 while (parent != null
3814 && !(parent instanceof Window))
3815 parent = parent.getParent ();
3817 Window toplevel = (Window) parent;
3818 if (toplevel.isFocusableWindow ())
3820 if (peer != null && !isLightweight())
3821 // This call will cause a FOCUS_GAINED event to be
3822 // posted to the system event queue if the native
3823 // windowing system grants the focus request.
3824 peer.requestFocus ();
3827 // Either our peer hasn't been created yet or we're a
3828 // lightweight component. In either case we want to
3829 // post a FOCUS_GAINED event.
3830 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3833 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3834 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3835 if (currentFocusOwner != null)
3837 eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
3839 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
3840 currentFocusOwner));
3843 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
3848 pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
3854 * Request that this Component be given the keyboard input focus and
3855 * that its top-level ancestor become the focused Window.
3857 * For the request to be granted, the Component must be focusable,
3858 * displayable and showing and the top-level Window to which it
3859 * belongs must be focusable. If the request is initially denied on
3860 * the basis that the top-level Window is not focusable, the request
3861 * will be remembered and granted when the Window does become
3864 * Never assume that this Component is the focus owner until it
3865 * receives a FOCUS_GAINED event.
3867 * The behaviour of this method is platform-dependent.
3868 * {@link #requestFocusInWindow()} should be used instead.
3870 * If the return value is false, the request is guaranteed to fail.
3871 * If the return value is true, the request will succeed unless it
3872 * is vetoed or something in the native windowing system intervenes,
3873 * preventing this Component's top-level ancestor from becoming
3874 * focused. This method is meant to be called by derived
3875 * lightweight Components that want to avoid unnecessary repainting
3876 * when they know a given focus transfer need only be temporary.
3878 * @param temporary true if the focus request is temporary
3879 * @return true if the request has a chance of success
3880 * @see #requestFocusInWindow ()
3882 * @see #addFocusListener (FocusListener)
3883 * @see #isFocusable ()
3884 * @see #isDisplayable ()
3885 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3888 protected boolean requestFocus (boolean temporary)
3890 if (isDisplayable ()
3894 synchronized (getTreeLock ())
3896 // Find this Component's top-level ancestor.
3897 Container parent = getParent ();
3899 while (parent != null
3900 && !(parent instanceof Window))
3901 parent = parent.getParent ();
3903 Window toplevel = (Window) parent;
3904 if (toplevel.isFocusableWindow ())
3906 if (peer != null && !isLightweight())
3907 // This call will cause a FOCUS_GAINED event to be
3908 // posted to the system event queue if the native
3909 // windowing system grants the focus request.
3910 peer.requestFocus ();
3913 // Either our peer hasn't been created yet or we're a
3914 // lightweight component. In either case we want to
3915 // post a FOCUS_GAINED event.
3916 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3919 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3920 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3921 if (currentFocusOwner != null)
3923 eq.postEvent (new FocusEvent(currentFocusOwner,
3924 FocusEvent.FOCUS_LOST,
3926 eq.postEvent (new FocusEvent(this,
3927 FocusEvent.FOCUS_GAINED,
3929 currentFocusOwner));
3932 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
3937 // FIXME: need to add a focus listener to our top-level
3938 // ancestor, so that we can post this event when it becomes
3939 // the focused window.
3940 pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
3943 // Always return true.
3948 * Request that this component be given the keyboard input focus, if
3949 * its top-level ancestor is the currently focused Window. A
3950 * <code>FOCUS_GAINED</code> event will be fired if and only if this
3951 * request is successful. To be successful, the component must be
3952 * displayable, showing, and focusable, and its ancestor top-level
3953 * Window must be focused.
3955 * If the return value is false, the request is guaranteed to fail.
3956 * If the return value is true, the request will succeed unless it
3957 * is vetoed or something in the native windowing system intervenes,
3958 * preventing this Component's top-level ancestor from becoming
3961 * @return true if the request has a chance of success
3962 * @see #requestFocus ()
3964 * @see #addFocusListener (FocusListener)
3965 * @see #isFocusable ()
3966 * @see #isDisplayable ()
3967 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3970 public boolean requestFocusInWindow ()
3972 return requestFocusInWindow (false);
3976 * Request that this component be given the keyboard input focus, if
3977 * its top-level ancestor is the currently focused Window. A
3978 * <code>FOCUS_GAINED</code> event will be fired if and only if this
3979 * request is successful. To be successful, the component must be
3980 * displayable, showing, and focusable, and its ancestor top-level
3981 * Window must be focused.
3983 * If the return value is false, the request is guaranteed to fail.
3984 * If the return value is true, the request will succeed unless it
3985 * is vetoed or something in the native windowing system intervenes,
3986 * preventing this Component's top-level ancestor from becoming
3987 * focused. This method is meant to be called by derived
3988 * lightweight Components that want to avoid unnecessary repainting
3989 * when they know a given focus transfer need only be temporary.
3991 * @param temporary true if the focus request is temporary
3992 * @return true if the request has a chance of success
3993 * @see #requestFocus ()
3995 * @see #addFocusListener (FocusListener)
3996 * @see #isFocusable ()
3997 * @see #isDisplayable ()
3998 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4001 protected boolean requestFocusInWindow (boolean temporary)
4003 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4005 Window focusedWindow = manager.getFocusedWindow ();
4007 if (isDisplayable ()
4011 if (focusedWindow != null)
4013 synchronized (getTreeLock ())
4015 Container parent = getParent ();
4017 while (parent != null
4018 && !(parent instanceof Window))
4019 parent = parent.getParent ();
4021 Window toplevel = (Window) parent;
4023 // Check if top-level ancestor is currently focused window.
4024 if (focusedWindow == toplevel)
4028 && !(this instanceof Window))
4029 // This call will cause a FOCUS_GAINED event to be
4030 // posted to the system event queue if the native
4031 // windowing system grants the focus request.
4032 peer.requestFocus ();
4035 // Either our peer hasn't been created yet or we're a
4036 // lightweight component. In either case we want to
4037 // post a FOCUS_GAINED event.
4038 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
4041 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
4042 if (currentFocusOwner != null)
4044 eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
4046 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
4047 currentFocusOwner));
4050 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
4065 * Transfers focus to the next component in the focus traversal
4066 * order, as though this were the current focus owner.
4068 * @see #requestFocus()
4071 public void transferFocus ()
4077 * Returns the root container that owns the focus cycle where this
4078 * component resides. A focus cycle root is in two cycles, one as
4079 * the ancestor, and one as the focusable element; this call always
4080 * returns the ancestor.
4082 * @return the ancestor container that owns the focus cycle
4085 public Container getFocusCycleRootAncestor ()
4087 if (this instanceof Window
4088 && ((Container) this).isFocusCycleRoot ())
4089 return (Container) this;
4091 Container parent = getParent ();
4093 while (parent != null
4094 && !parent.isFocusCycleRoot ())
4095 parent = parent.getParent ();
4101 * Tests if the container is the ancestor of the focus cycle that
4102 * this component belongs to.
4104 * @param c the container to test
4105 * @return true if c is the focus cycle root
4108 public boolean isFocusCycleRoot (Container c)
4110 return c == getFocusCycleRootAncestor ();
4114 * AWT 1.0 focus event processor. Transfers focus to the next
4115 * component in the focus traversal order, as though this were the
4116 * current focus owner.
4118 * @deprecated use {@link #transferFocus ()} instead
4120 public void nextFocus ()
4122 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4124 manager.focusNextComponent (this);
4128 * Transfers focus to the previous component in the focus traversal
4129 * order, as though this were the current focus owner.
4131 * @see #requestFocus ()
4134 public void transferFocusBackward ()
4136 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4138 manager.focusPreviousComponent (this);
4142 * Transfers focus to the focus cycle root of this component.
4143 * However, if this is a Window, the default focus owner in the
4144 * window in the current focus cycle is focused instead.
4146 * @see #requestFocus()
4147 * @see #isFocusCycleRoot(Container)
4150 public void transferFocusUpCycle ()
4152 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4154 manager.upFocusCycle (this);
4158 * Tests if this component is the focus owner. Use {@link
4159 * #isFocusOwner ()} instead.
4161 * @return true if this component owns focus
4164 public boolean hasFocus ()
4166 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4168 Component focusOwner = manager.getFocusOwner ();
4170 return this == focusOwner;
4174 * Tests if this component is the focus owner.
4176 * @return true if this component owns focus
4179 public boolean isFocusOwner()
4185 * Adds the specified popup menu to this component.
4187 * @param popup the popup menu to be added
4189 * @see #remove(MenuComponent)
4193 public synchronized void add(PopupMenu popup)
4196 popups = new Vector();
4199 if (popup.parent != null)
4200 popup.parent.remove(popup);
4201 popup.parent = this;
4207 * Removes the specified popup menu from this component.
4209 * @param popup the popup menu to remove
4210 * @see #add(PopupMenu)
4213 public synchronized void remove(MenuComponent popup)
4216 popups.remove(popup);
4220 * Returns a debugging string representing this component. The string may
4221 * be empty but not null.
4223 * @return a string representing this component
4225 protected String paramString()
4227 StringBuffer param = new StringBuffer();
4228 String name = getName();
4230 param.append(name).append(",");
4231 param.append(x).append(",").append(y).append(",").append(width)
4232 .append("x").append(height);
4234 param.append(",invalid");
4236 param.append(",invisible");
4238 param.append(",disabled");
4240 param.append(",translucent");
4241 if (isDoubleBuffered())
4242 param.append(",doublebuffered");
4244 param.append(",parent==null");
4246 param.append(",parent==").append(parent.getName());
4247 return param.toString();
4251 * Returns a string representation of this component. This is implemented
4252 * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
4254 * @return a string representation of this component
4256 public String toString()
4258 return getClass().getName() + '[' + paramString() + ']';
4262 * Prints a listing of this component to <code>System.out</code>.
4264 * @see #list(PrintStream)
4268 list(System.out, 0);
4272 * Prints a listing of this component to the specified print stream.
4274 * @param out the <code>PrintStream</code> to print to
4276 public void list(PrintStream out)
4282 * Prints a listing of this component to the specified print stream,
4283 * starting at the specified indentation point.
4285 * @param out the <code>PrintStream</code> to print to
4286 * @param indent the indentation point
4288 public void list(PrintStream out, int indent)
4290 for (int i = 0; i < indent; ++i)
4292 out.println(toString());
4296 * Prints a listing of this component to the specified print writer.
4298 * @param out the <code>PrintWrinter</code> to print to
4301 public void list(PrintWriter out)
4307 * Prints a listing of this component to the specified print writer,
4308 * starting at the specified indentation point.
4310 * @param out the <code>PrintWriter</code> to print to
4311 * @param indent the indentation point
4314 public void list(PrintWriter out, int indent)
4316 for (int i = 0; i < indent; ++i)
4318 out.println(toString());
4322 * Adds the specified property listener to this component. This is harmless
4323 * if the listener is null, but if the listener has already been registered,
4324 * it will now be registered twice. The property listener ignores inherited
4325 * properties. Recognized properties include:<br>
4327 * <li>the font (<code>"font"</code>)</li>
4328 * <li>the background color (<code>"background"</code>)</li>
4329 * <li>the foreground color (<code>"foreground"</code>)</li>
4330 * <li>the focusability (<code>"focusable"</code>)</li>
4331 * <li>the focus key traversal enabled state
4332 * (<code>"focusTraversalKeysEnabled"</code>)</li>
4333 * <li>the set of forward traversal keys
4334 * (<code>"forwardFocusTraversalKeys"</code>)</li>
4335 * <li>the set of backward traversal keys
4336 * (<code>"backwardFocusTraversalKeys"</code>)</li>
4337 * <li>the set of up-cycle traversal keys
4338 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
4341 * @param listener the new listener to add
4342 * @see #removePropertyChangeListener(PropertyChangeListener)
4343 * @see #getPropertyChangeListeners()
4344 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4347 public void addPropertyChangeListener(PropertyChangeListener listener)
4349 if (changeSupport == null)
4350 changeSupport = new PropertyChangeSupport(this);
4351 changeSupport.addPropertyChangeListener(listener);
4355 * Removes the specified property listener from the component. This is
4356 * harmless if the listener was not previously registered.
4358 * @param listener the listener to remove
4359 * @see #addPropertyChangeListener(PropertyChangeListener)
4360 * @see #getPropertyChangeListeners()
4361 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4364 public void removePropertyChangeListener(PropertyChangeListener listener)
4366 if (changeSupport != null)
4367 changeSupport.removePropertyChangeListener(listener);
4371 * Returns an array of all specified listeners registered on this component.
4373 * @return an array of listeners
4374 * @see #addPropertyChangeListener(PropertyChangeListener)
4375 * @see #removePropertyChangeListener(PropertyChangeListener)
4376 * @see #getPropertyChangeListeners(String)
4379 public PropertyChangeListener[] getPropertyChangeListeners()
4381 return changeSupport == null ? new PropertyChangeListener[0]
4382 : changeSupport.getPropertyChangeListeners();
4386 * Adds the specified property listener to this component. This is harmless
4387 * if the listener is null, but if the listener has already been registered,
4388 * it will now be registered twice. The property listener ignores inherited
4389 * properties. The listener is keyed to a single property. Recognized
4390 * properties include:<br>
4392 * <li>the font (<code>"font"</code>)</li>
4393 * <li>the background color (<code>"background"</code>)</li>
4394 * <li>the foreground color (<code>"foreground"</code>)</li>
4395 * <li>the focusability (<code>"focusable"</code>)</li>
4396 * <li>the focus key traversal enabled state
4397 * (<code>"focusTraversalKeysEnabled"</code>)</li>
4398 * <li>the set of forward traversal keys
4399 * (<code>"forwardFocusTraversalKeys"</code>)</li>
4400 p * <li>the set of backward traversal keys
4401 * (<code>"backwardFocusTraversalKeys"</code>)</li>
4402 * <li>the set of up-cycle traversal keys
4403 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
4406 * @param propertyName the property name to filter on
4407 * @param listener the new listener to add
4408 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4409 * @see #getPropertyChangeListeners(String)
4410 * @see #addPropertyChangeListener(PropertyChangeListener)
4413 public void addPropertyChangeListener(String propertyName,
4414 PropertyChangeListener listener)
4416 if (changeSupport == null)
4417 changeSupport = new PropertyChangeSupport(this);
4418 changeSupport.addPropertyChangeListener(propertyName, listener);
4422 * Removes the specified property listener on a particular property from
4423 * the component. This is harmless if the listener was not previously
4426 * @param propertyName the property name to filter on
4427 * @param listener the listener to remove
4428 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4429 * @see #getPropertyChangeListeners(String)
4430 * @see #removePropertyChangeListener(PropertyChangeListener)
4433 public void removePropertyChangeListener(String propertyName,
4434 PropertyChangeListener listener)
4436 if (changeSupport != null)
4437 changeSupport.removePropertyChangeListener(propertyName, listener);
4441 * Returns an array of all specified listeners on the named property that
4442 * are registered on this component.
4444 * @return an array of listeners
4445 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4446 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4447 * @see #getPropertyChangeListeners()
4450 public PropertyChangeListener[] getPropertyChangeListeners(String property)
4452 return changeSupport == null ? new PropertyChangeListener[0]
4453 : changeSupport.getPropertyChangeListeners(property);
4457 * Report a change in a bound property to any registered property listeners.
4459 * @param propertyName the property that changed
4460 * @param oldValue the old property value
4461 * @param newValue the new property value
4463 protected void firePropertyChange(String propertyName, Object oldValue,
4466 if (changeSupport != null)
4467 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4471 * Report a change in a bound property to any registered property listeners.
4473 * @param propertyName the property that changed
4474 * @param oldValue the old property value
4475 * @param newValue the new property value
4477 protected void firePropertyChange(String propertyName, boolean oldValue,
4480 if (changeSupport != null)
4481 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4485 * Report a change in a bound property to any registered property listeners.
4487 * @param propertyName the property that changed
4488 * @param oldValue the old property value
4489 * @param newValue the new property value
4491 protected void firePropertyChange(String propertyName, int oldValue,
4494 if (changeSupport != null)
4495 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4499 * Sets the text layout orientation of this component. New components default
4500 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
4501 * the current component, while
4502 * {@link #applyComponentOrientation(ComponentOrientation)} affects the
4505 * @param o the new orientation
4506 * @throws NullPointerException if o is null
4507 * @see #getComponentOrientation()
4509 public void setComponentOrientation(ComponentOrientation o)
4512 throw new NullPointerException();
4513 ComponentOrientation oldOrientation = orientation;
4515 firePropertyChange("componentOrientation", oldOrientation, o);
4519 * Determines the text layout orientation used by this component.
4521 * @return the component orientation
4522 * @see #setComponentOrientation(ComponentOrientation)
4524 public ComponentOrientation getComponentOrientation()
4530 * Sets the text layout orientation of this component. New components default
4531 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
4532 * entire hierarchy, while
4533 * {@link #setComponentOrientation(ComponentOrientation)} affects only the
4534 * current component.
4536 * @param o the new orientation
4537 * @throws NullPointerException if o is null
4538 * @see #getComponentOrientation()
4541 public void applyComponentOrientation(ComponentOrientation o)
4543 setComponentOrientation(o);
4547 * Returns the accessibility framework context of this class. Component is
4548 * not accessible, so the default implementation returns null. Subclasses
4549 * must override this behavior, and return an appropriate subclass of
4550 * {@link AccessibleAWTComponent}.
4552 * @return the accessibility context
4554 public AccessibleContext getAccessibleContext()
4560 // Helper methods; some are package visible for use by subclasses.
4563 * Subclasses should override this to return unique component names like
4566 * @return the generated name for this component
4568 String generateName()
4570 // Component is abstract.
4575 * Sets the peer for this component.
4577 * @param peer the new peer
4579 final void setPeer(ComponentPeer peer)
4585 * Implementation method that allows classes such as Canvas and Window to
4586 * override the graphics configuration without violating the published API.
4588 * @return the graphics configuration
4590 GraphicsConfiguration getGraphicsConfigurationImpl()
4594 GraphicsConfiguration config = peer.getGraphicsConfiguration();
4600 return parent.getGraphicsConfiguration();
4606 * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
4607 * event ({@link Event}).
4609 * @param e an AWT 1.1 event to translate
4611 * @return an AWT 1.0 event representing e
4613 static Event translateEvent (AWTEvent e)
4615 Component target = (Component) e.getSource ();
4616 Event translated = null;
4618 if (e instanceof InputEvent)
4620 InputEvent ie = (InputEvent) e;
4621 long when = ie.getWhen ();
4624 int id = e.getID ();
4627 int mods = ie.getModifiersEx ();
4629 if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
4630 oldMods |= Event.META_MASK;
4631 else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
4632 oldMods |= Event.ALT_MASK;
4634 if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
4635 oldMods |= Event.SHIFT_MASK;
4637 if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
4638 oldMods |= Event.CTRL_MASK;
4640 if ((mods & InputEvent.META_DOWN_MASK) != 0)
4641 oldMods |= Event.META_MASK;
4643 if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
4644 oldMods |= Event.ALT_MASK;
4646 if (e instanceof MouseEvent)
4648 if (id == MouseEvent.MOUSE_PRESSED)
4649 oldID = Event.MOUSE_DOWN;
4650 else if (id == MouseEvent.MOUSE_RELEASED)
4651 oldID = Event.MOUSE_UP;
4652 else if (id == MouseEvent.MOUSE_MOVED)
4653 oldID = Event.MOUSE_MOVE;
4654 else if (id == MouseEvent.MOUSE_DRAGGED)
4655 oldID = Event.MOUSE_DRAG;
4656 else if (id == MouseEvent.MOUSE_ENTERED)
4657 oldID = Event.MOUSE_ENTER;
4658 else if (id == MouseEvent.MOUSE_EXITED)
4659 oldID = Event.MOUSE_EXIT;
4661 // No analogous AWT 1.0 mouse event.
4664 MouseEvent me = (MouseEvent) e;
4666 translated = new Event (target, when, oldID,
4667 me.getX (), me.getY (), 0, oldMods);
4669 else if (e instanceof KeyEvent)
4671 if (id == KeyEvent.KEY_PRESSED)
4672 oldID = Event.KEY_PRESS;
4673 else if (e.getID () == KeyEvent.KEY_RELEASED)
4674 oldID = Event.KEY_RELEASE;
4676 // No analogous AWT 1.0 key event.
4680 int newKey = ((KeyEvent) e).getKeyCode ();
4683 case KeyEvent.VK_BACK_SPACE:
4684 oldKey = Event.BACK_SPACE;
4686 case KeyEvent.VK_CAPS_LOCK:
4687 oldKey = Event.CAPS_LOCK;
4689 case KeyEvent.VK_DELETE:
4690 oldKey = Event.DELETE;
4692 case KeyEvent.VK_DOWN:
4693 case KeyEvent.VK_KP_DOWN:
4694 oldKey = Event.DOWN;
4696 case KeyEvent.VK_END:
4699 case KeyEvent.VK_ENTER:
4700 oldKey = Event.ENTER;
4702 case KeyEvent.VK_ESCAPE:
4703 oldKey = Event.ESCAPE;
4705 case KeyEvent.VK_F1:
4708 case KeyEvent.VK_F10:
4711 case KeyEvent.VK_F11:
4714 case KeyEvent.VK_F12:
4717 case KeyEvent.VK_F2:
4720 case KeyEvent.VK_F3:
4723 case KeyEvent.VK_F4:
4726 case KeyEvent.VK_F5:
4729 case KeyEvent.VK_F6:
4732 case KeyEvent.VK_F7:
4735 case KeyEvent.VK_F8:
4738 case KeyEvent.VK_F9:
4741 case KeyEvent.VK_HOME:
4742 oldKey = Event.HOME;
4744 case KeyEvent.VK_INSERT:
4745 oldKey = Event.INSERT;
4747 case KeyEvent.VK_LEFT:
4748 case KeyEvent.VK_KP_LEFT:
4749 oldKey = Event.LEFT;
4751 case KeyEvent.VK_NUM_LOCK:
4752 oldKey = Event.NUM_LOCK;
4754 case KeyEvent.VK_PAUSE:
4755 oldKey = Event.PAUSE;
4757 case KeyEvent.VK_PAGE_DOWN:
4758 oldKey = Event.PGDN;
4760 case KeyEvent.VK_PAGE_UP:
4761 oldKey = Event.PGUP;
4763 case KeyEvent.VK_PRINTSCREEN:
4764 oldKey = Event.PRINT_SCREEN;
4766 case KeyEvent.VK_RIGHT:
4767 case KeyEvent.VK_KP_RIGHT:
4768 oldKey = Event.RIGHT;
4770 case KeyEvent.VK_SCROLL_LOCK:
4771 oldKey = Event.SCROLL_LOCK;
4773 case KeyEvent.VK_TAB:
4776 case KeyEvent.VK_UP:
4777 case KeyEvent.VK_KP_UP:
4784 translated = new Event (target, when, oldID,
4785 0, 0, oldKey, oldMods);
4788 else if (e instanceof ActionEvent)
4789 translated = new Event (target, Event.ACTION_EVENT,
4790 ((ActionEvent) e).getActionCommand ());
4796 * Implementation of dispatchEvent. Allows trusted package classes
4797 * to dispatch additional events first. This implementation first
4798 * translates <code>e</code> to an AWT 1.0 event and sends the
4799 * result to {@link #postEvent}. If the AWT 1.0 event is not
4800 * handled, and events of type <code>e</code> are enabled for this
4801 * component, e is passed on to {@link #processEvent}.
4803 * @param e the event to dispatch
4806 void dispatchEventImpl(AWTEvent e)
4808 Event oldEvent = translateEvent (e);
4810 if (oldEvent != null)
4811 postEvent (oldEvent);
4813 if (eventTypeEnabled (e.id))
4815 // the trick we use to communicate between dispatch and redispatch
4816 // is to have KeyboardFocusManager.redispatch synchronize on the
4817 // object itself. we then do not redispatch to KeyboardFocusManager
4818 // if we are already holding the lock.
4819 if (! Thread.holdsLock(e))
4823 case WindowEvent.WINDOW_GAINED_FOCUS:
4824 case WindowEvent.WINDOW_LOST_FOCUS:
4825 case KeyEvent.KEY_PRESSED:
4826 case KeyEvent.KEY_RELEASED:
4827 case KeyEvent.KEY_TYPED:
4828 case FocusEvent.FOCUS_GAINED:
4829 case FocusEvent.FOCUS_LOST:
4830 if (KeyboardFocusManager
4831 .getCurrentKeyboardFocusManager()
4834 case MouseEvent.MOUSE_PRESSED:
4835 if (isLightweight())
4840 if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE)
4845 peer.handleEvent(e);
4849 * Tells whether or not an event type is enabled.
4851 boolean eventTypeEnabled (int type)
4853 if (type > AWTEvent.RESERVED_ID_MAX)
4858 case ComponentEvent.COMPONENT_HIDDEN:
4859 case ComponentEvent.COMPONENT_MOVED:
4860 case ComponentEvent.COMPONENT_RESIZED:
4861 case ComponentEvent.COMPONENT_SHOWN:
4862 return (componentListener != null
4863 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
4865 case KeyEvent.KEY_PRESSED:
4866 case KeyEvent.KEY_RELEASED:
4867 case KeyEvent.KEY_TYPED:
4868 return (keyListener != null
4869 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
4871 case MouseEvent.MOUSE_CLICKED:
4872 case MouseEvent.MOUSE_ENTERED:
4873 case MouseEvent.MOUSE_EXITED:
4874 case MouseEvent.MOUSE_PRESSED:
4875 case MouseEvent.MOUSE_RELEASED:
4876 case MouseEvent.MOUSE_MOVED:
4877 case MouseEvent.MOUSE_DRAGGED:
4878 return (mouseListener != null
4879 || mouseMotionListener != null
4880 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
4882 case FocusEvent.FOCUS_GAINED:
4883 case FocusEvent.FOCUS_LOST:
4884 return (focusListener != null
4885 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
4887 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4888 case InputMethodEvent.CARET_POSITION_CHANGED:
4889 return (inputMethodListener != null
4890 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
4892 case PaintEvent.PAINT:
4893 case PaintEvent.UPDATE:
4894 return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
4902 * Coalesce paint events. Current heuristic is: Merge if the union of
4903 * areas is less than twice that of the sum of the areas. The X server
4904 * tend to create a lot of paint events that are adjacent but not
4909 * | +-----+ ...will be merged
4915 * +---------------+--+
4916 * | | | ...will not be merged
4917 * +---------------+ |
4926 * @param queuedEvent the first paint event
4927 * @param newEvent the second paint event
4928 * @return the combined paint event, or null
4930 private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
4931 PaintEvent newEvent)
4933 Rectangle r1 = queuedEvent.getUpdateRect();
4934 Rectangle r2 = newEvent.getUpdateRect();
4935 Rectangle union = r1.union(r2);
4937 int r1a = r1.width * r1.height;
4938 int r2a = r2.width * r2.height;
4939 int ua = union.width * union.height;
4941 if (ua > (r1a+r2a)*2)
4943 /* The 2 factor should maybe be reconsidered. Perhaps 3/2
4946 newEvent.setUpdateRect(union);
4951 * This method is used to implement transferFocus(). CHILD is the child
4952 * making the request. This is overridden by Container; when called for an
4953 * ordinary component there is no child and so we always return null.
4955 * FIXME: is this still needed, in light of focus traversal policies?
4957 * @param child the component making the request
4958 * @return the next component to focus on
4960 Component findNextFocusComponent(Component child)
4966 * Deserializes this component. This regenerates all serializable listeners
4967 * which were registered originally.
4969 * @param s the stream to read from
4970 * @throws ClassNotFoundException if deserialization fails
4971 * @throws IOException if the stream fails
4973 private void readObject(ObjectInputStream s)
4974 throws ClassNotFoundException, IOException
4976 s.defaultReadObject();
4977 String key = (String) s.readObject();
4980 Object listener = s.readObject();
4981 if ("componentL".equals(key))
4982 addComponentListener((ComponentListener) listener);
4983 else if ("focusL".equals(key))
4984 addFocusListener((FocusListener) listener);
4985 else if ("keyL".equals(key))
4986 addKeyListener((KeyListener) listener);
4987 else if ("mouseL".equals(key))
4988 addMouseListener((MouseListener) listener);
4989 else if ("mouseMotionL".equals(key))
4990 addMouseMotionListener((MouseMotionListener) listener);
4991 else if ("inputMethodL".equals(key))
4992 addInputMethodListener((InputMethodListener) listener);
4993 else if ("hierarchyL".equals(key))
4994 addHierarchyListener((HierarchyListener) listener);
4995 else if ("hierarchyBoundsL".equals(key))
4996 addHierarchyBoundsListener((HierarchyBoundsListener) listener);
4997 else if ("mouseWheelL".equals(key))
4998 addMouseWheelListener((MouseWheelListener) listener);
4999 key = (String) s.readObject();
5004 * Serializes this component. This ignores all listeners which do not
5005 * implement Serializable, but includes those that do.
5007 * @param s the stream to write to
5008 * @throws IOException if the stream fails
5010 private void writeObject(ObjectOutputStream s) throws IOException
5012 s.defaultWriteObject();
5013 AWTEventMulticaster.save(s, "componentL", componentListener);
5014 AWTEventMulticaster.save(s, "focusL", focusListener);
5015 AWTEventMulticaster.save(s, "keyL", keyListener);
5016 AWTEventMulticaster.save(s, "mouseL", mouseListener);
5017 AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5018 AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5019 AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5020 AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5021 AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5022 s.writeObject(null);
5029 * This class provides accessibility support for subclasses of container.
5031 * @author Eric Blake (ebb9@email.byu.edu)
5033 * @status updated to 1.4
5035 protected abstract class AccessibleAWTComponent extends AccessibleContext
5036 implements Serializable, AccessibleComponent
5039 * Compatible with JDK 1.3+.
5041 private static final long serialVersionUID = 642321655757800191L;
5044 * Converts show/hide events to PropertyChange events, and is registered
5045 * as a component listener on this component.
5047 * @serial the component handler
5049 protected ComponentListener accessibleAWTComponentHandler
5050 = new AccessibleAWTComponentHandler();
5053 * Converts focus events to PropertyChange events, and is registered
5054 * as a focus listener on this component.
5056 * @serial the focus handler
5058 protected FocusListener accessibleAWTFocusHandler
5059 = new AccessibleAWTFocusHandler();
5062 * The default constructor.
5064 protected AccessibleAWTComponent()
5066 Component.this.addComponentListener(accessibleAWTComponentHandler);
5067 Component.this.addFocusListener(accessibleAWTFocusHandler);
5071 * Adds a global property change listener to the accessible component.
5073 * @param l the listener to add
5074 * @see #ACCESSIBLE_NAME_PROPERTY
5075 * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
5076 * @see #ACCESSIBLE_STATE_PROPERTY
5077 * @see #ACCESSIBLE_VALUE_PROPERTY
5078 * @see #ACCESSIBLE_SELECTION_PROPERTY
5079 * @see #ACCESSIBLE_TEXT_PROPERTY
5080 * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
5082 public void addPropertyChangeListener(PropertyChangeListener l)
5084 Component.this.addPropertyChangeListener(l);
5085 super.addPropertyChangeListener(l);
5089 * Removes a global property change listener from this accessible
5092 * @param l the listener to remove
5094 public void removePropertyChangeListener(PropertyChangeListener l)
5096 Component.this.removePropertyChangeListener(l);
5097 super.removePropertyChangeListener(l);
5101 * Returns the accessible name of this component. It is almost always
5102 * wrong to return getName(), since it is not localized. In fact, for
5103 * things like buttons, this should be the text of the button, not the
5104 * name of the object. The tooltip text might also be appropriate.
5107 * @see #setAccessibleName(String)
5109 public String getAccessibleName()
5111 return accessibleName == null ? getName() : accessibleName;
5115 * Returns a brief description of this accessible context. This should
5118 * @return a description of this component
5119 * @see #setAccessibleDescription(String)
5121 public String getAccessibleDescription()
5123 return accessibleDescription;
5127 * Returns the role of this component.
5129 * @return the accessible role
5131 public AccessibleRole getAccessibleRole()
5133 return AccessibleRole.AWT_COMPONENT;
5137 * Returns a state set describing this component's state.
5139 * @return a new state set
5140 * @see AccessibleState
5142 public AccessibleStateSet getAccessibleStateSet()
5144 AccessibleStateSet s = new AccessibleStateSet();
5145 if (Component.this.isEnabled())
5146 s.add(AccessibleState.ENABLED);
5148 s.add(AccessibleState.FOCUSABLE);
5150 s.add(AccessibleState.FOCUSED);
5152 s.add(AccessibleState.OPAQUE);
5153 if (Component.this.isShowing())
5154 s.add(AccessibleState.SHOWING);
5155 if (Component.this.isVisible())
5156 s.add(AccessibleState.VISIBLE);
5161 * Returns the parent of this component, if it is accessible.
5163 * @return the accessible parent
5165 public Accessible getAccessibleParent()
5167 if (accessibleParent == null)
5169 Container parent = getParent();
5170 accessibleParent = parent instanceof Accessible
5171 ? (Accessible) parent : null;
5173 return accessibleParent;
5177 * Returns the index of this component in its accessible parent.
5179 * @return the index, or -1 if the parent is not accessible
5180 * @see #getAccessibleParent()
5182 public int getAccessibleIndexInParent()
5184 if (getAccessibleParent() == null)
5186 AccessibleContext context
5187 = ((Component) accessibleParent).getAccessibleContext();
5188 if (context == null)
5190 for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
5191 if (context.getAccessibleChild(i) == Component.this)
5197 * Returns the number of children of this component which implement
5198 * Accessible. Subclasses must override this if they can have children.
5200 * @return the number of accessible children, default 0
5202 public int getAccessibleChildrenCount()
5208 * Returns the ith accessible child. Subclasses must override this if
5209 * they can have children.
5211 * @return the ith accessible child, or null
5212 * @see #getAccessibleChildrenCount()
5214 public Accessible getAccessibleChild(int i)
5220 * Returns the locale of this component.
5222 * @return the locale
5223 * @throws IllegalComponentStateException if the locale is unknown
5225 public Locale getLocale()
5227 return Component.this.getLocale();
5231 * Returns this, since it is an accessible component.
5233 * @return the accessible component
5235 public AccessibleComponent getAccessibleComponent()
5241 * Gets the background color.
5243 * @return the background color
5244 * @see #setBackground(Color)
5246 public Color getBackground()
5248 return Component.this.getBackground();
5252 * Sets the background color.
5254 * @param c the background color
5255 * @see #getBackground()
5258 public void setBackground(Color c)
5260 Component.this.setBackground(c);
5264 * Gets the foreground color.
5266 * @return the foreground color
5267 * @see #setForeground(Color)
5269 public Color getForeground()
5271 return Component.this.getForeground();
5275 * Sets the foreground color.
5277 * @param c the foreground color
5278 * @see #getForeground()
5280 public void setForeground(Color c)
5282 Component.this.setForeground(c);
5288 * @return the cursor
5289 * @see #setCursor(Cursor)
5291 public Cursor getCursor()
5293 return Component.this.getCursor();
5299 * @param cursor the cursor
5302 public void setCursor(Cursor cursor)
5304 Component.this.setCursor(cursor);
5311 * @see #setFont(Font)
5313 public Font getFont()
5315 return Component.this.getFont();
5324 public void setFont(Font f)
5326 Component.this.setFont(f);
5330 * Gets the font metrics for a font.
5332 * @param f the font to look up
5333 * @return its metrics
5334 * @throws NullPointerException if f is null
5337 public FontMetrics getFontMetrics(Font f)
5339 return Component.this.getFontMetrics(f);
5343 * Tests if the component is enabled.
5345 * @return true if the component is enabled
5346 * @see #setEnabled(boolean)
5347 * @see #getAccessibleStateSet()
5348 * @see AccessibleState#ENABLED
5350 public boolean isEnabled()
5352 return Component.this.isEnabled();
5356 * Set whether the component is enabled.
5358 * @param b the new enabled status
5361 public void setEnabled(boolean b)
5363 Component.this.setEnabled(b);
5367 * Test whether the component is visible (not necesarily showing).
5369 * @return true if it is visible
5370 * @see #setVisible(boolean)
5371 * @see #getAccessibleStateSet()
5372 * @see AccessibleState#VISIBLE
5374 public boolean isVisible()
5376 return Component.this.isVisible();
5380 * Sets the visibility of this component.
5382 * @param b the desired visibility
5385 public void setVisible(boolean b)
5387 Component.this.setVisible(b);
5391 * Tests if the component is showing.
5393 * @return true if this is showing
5395 public boolean isShowing()
5397 return Component.this.isShowing();
5401 * Tests if the point is contained in this component.
5403 * @param p the point to check
5404 * @return true if it is contained
5405 * @throws NullPointerException if p is null
5407 public boolean contains(Point p)
5409 return Component.this.contains(p.x, p.y);
5413 * Returns the location of this object on the screen, or null if it is
5416 * @return the location relative to screen coordinates, if showing
5418 * @see #getLocation()
5420 public Point getLocationOnScreen()
5422 return Component.this.isShowing() ? Component.this.getLocationOnScreen()
5427 * Returns the location of this object relative to its parent's coordinate
5428 * system, or null if it is not showing.
5430 * @return the location
5432 * @see #getLocationOnScreen()
5434 public Point getLocation()
5436 return Component.this.isShowing() ? Component.this.getLocation() : null;
5440 * Sets the location of this relative to its parent's coordinate system.
5442 * @param p the location
5443 * @throws NullPointerException if p is null
5444 * @see #getLocation()
5446 public void setLocation(Point p)
5448 Component.this.setLocation(p.x, p.y);
5452 * Gets the bounds of this component, or null if it is not on screen.
5454 * @return the bounds
5455 * @see #contains(Point)
5456 * @see #setBounds(Rectangle)
5458 public Rectangle getBounds()
5460 return Component.this.isShowing() ? Component.this.getBounds() : null;
5464 * Sets the bounds of this component.
5466 * @param r the bounds
5467 * @throws NullPointerException if r is null
5470 public void setBounds(Rectangle r)
5472 Component.this.setBounds(r.x, r.y, r.width, r.height);
5476 * Gets the size of this component, or null if it is not showing.
5479 * @see #setSize(Dimension)
5481 public Dimension getSize()
5483 return Component.this.isShowing() ? Component.this.getSize() : null;
5487 * Sets the size of this component.
5490 * @throws NullPointerException if d is null
5493 public void setSize(Dimension d)
5495 Component.this.setSize(d.width, d.height);
5499 * Returns the Accessible child at a point relative to the coordinate
5500 * system of this component, if one exists, or null. Since components
5501 * have no children, subclasses must override this to get anything besides
5504 * @param p the point to check
5505 * @return the accessible child at that point
5506 * @throws NullPointerException if p is null
5508 public Accessible getAccessibleAt(Point p)
5514 * Tests whether this component can accept focus.
5516 * @return true if this is focus traversable
5517 * @see #getAccessibleStateSet ()
5518 * @see AccessibleState#FOCUSABLE
5519 * @see AccessibleState#FOCUSED
5521 public boolean isFocusTraversable ()
5523 return Component.this.isFocusTraversable ();
5527 * Requests focus for this component.
5529 * @see #isFocusTraversable ()
5531 public void requestFocus ()
5533 Component.this.requestFocus ();
5537 * Adds a focus listener.
5539 * @param l the listener to add
5541 public void addFocusListener(FocusListener l)
5543 Component.this.addFocusListener(l);
5547 * Removes a focus listener.
5549 * @param l the listener to remove
5551 public void removeFocusListener(FocusListener l)
5553 Component.this.removeFocusListener(l);
5557 * Converts component changes into property changes.
5559 * @author Eric Blake (ebb9@email.byu.edu)
5561 * @status updated to 1.4
5563 protected class AccessibleAWTComponentHandler implements ComponentListener
5566 * Default constructor.
5568 protected AccessibleAWTComponentHandler()
5573 * Convert a component hidden to a property change.
5575 * @param e the event to convert
5577 public void componentHidden(ComponentEvent e)
5579 AccessibleAWTComponent.this.firePropertyChange
5580 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
5584 * Convert a component shown to a property change.
5586 * @param e the event to convert
5588 public void componentShown(ComponentEvent e)
5590 AccessibleAWTComponent.this.firePropertyChange
5591 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
5595 * Moving a component does not affect properties.
5599 public void componentMoved(ComponentEvent e)
5604 * Resizing a component does not affect properties.
5608 public void componentResized(ComponentEvent e)
5611 } // class AccessibleAWTComponentHandler
5614 * Converts focus changes into property changes.
5616 * @author Eric Blake (ebb9@email.byu.edu)
5618 * @status updated to 1.4
5620 protected class AccessibleAWTFocusHandler implements FocusListener
5623 * Default constructor.
5625 protected AccessibleAWTFocusHandler()
5630 * Convert a focus gained to a property change.
5632 * @param e the event to convert
5634 public void focusGained(FocusEvent e)
5636 AccessibleAWTComponent.this.firePropertyChange
5637 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
5641 * Convert a focus lost to a property change.
5643 * @param e the event to convert
5645 public void focusLost(FocusEvent e)
5647 AccessibleAWTComponent.this.firePropertyChange
5648 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
5650 } // class AccessibleAWTComponentHandler
5651 } // class AccessibleAWTComponent
5654 * This class provides support for blitting offscreen surfaces to a
5657 * @see BufferStrategy
5661 protected class BltBufferStrategy extends BufferStrategy
5664 * The capabilities of the image buffer.
5666 protected BufferCapabilities caps;
5669 * The back buffers used in this strategy.
5671 protected VolatileImage[] backBuffers;
5674 * Whether or not the image buffer resources are allocated and
5675 * ready to be drawn into.
5677 protected boolean validatedContents;
5680 * The width of the back buffers.
5682 protected int width;
5685 * The height of the back buffers.
5687 protected int height;
5692 private VolatileImage frontBuffer;
5695 * Creates a blitting buffer strategy.
5697 * @param numBuffers the number of buffers, including the front
5699 * @param caps the capabilities of this strategy
5701 protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
5704 createBackBuffers(numBuffers - 1);
5706 height = getHeight();
5710 * Initializes the backBuffers field with an array of numBuffers
5713 * @param numBuffers the number of backbuffers to create
5715 protected void createBackBuffers(int numBuffers)
5717 GraphicsConfiguration c =
5718 GraphicsEnvironment.getLocalGraphicsEnvironment()
5719 .getDefaultScreenDevice().getDefaultConfiguration();
5721 backBuffers = new VolatileImage[numBuffers];
5723 for (int i = 0; i < numBuffers; i++)
5724 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
5728 * Retrieves the capabilities of this buffer strategy.
5730 * @return the capabilities of this buffer strategy
5732 public BufferCapabilities getCapabilities()
5738 * Retrieves a graphics object that can be used to draw into this
5739 * strategy's image buffer.
5741 * @return a graphics object
5743 public Graphics getDrawGraphics()
5745 // Return the backmost buffer's graphics.
5746 return backBuffers[0].getGraphics();
5750 * Bring the contents of the back buffer to the front buffer.
5754 GraphicsConfiguration c =
5755 GraphicsEnvironment.getLocalGraphicsEnvironment()
5756 .getDefaultScreenDevice().getDefaultConfiguration();
5758 // draw the front buffer.
5759 getGraphics().drawImage(backBuffers[backBuffers.length - 1],
5760 width, height, null);
5762 BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
5764 // blit the back buffers.
5765 for (int i = backBuffers.length - 1; i > 0 ; i--)
5766 backBuffers[i] = backBuffers[i - 1];
5768 // create new backmost buffer.
5769 if (f == BufferCapabilities.FlipContents.UNDEFINED)
5770 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
5772 // create new backmost buffer and clear it to the background
5774 if (f == BufferCapabilities.FlipContents.BACKGROUND)
5776 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
5777 backBuffers[0].getGraphics().clearRect(0, 0, width, height);
5780 // FIXME: set the backmost buffer to the prior contents of the
5781 // front buffer. How do we retrieve the contents of the front
5784 // if (f == BufferCapabilities.FlipContents.PRIOR)
5786 // set the backmost buffer to a copy of the new front buffer.
5787 if (f == BufferCapabilities.FlipContents.COPIED)
5788 backBuffers[0] = backBuffers[backBuffers.length - 1];
5792 * Re-create the image buffer resources if they've been lost.
5794 protected void revalidate()
5796 GraphicsConfiguration c =
5797 GraphicsEnvironment.getLocalGraphicsEnvironment()
5798 .getDefaultScreenDevice().getDefaultConfiguration();
5800 for (int i = 0; i < backBuffers.length; i++)
5802 int result = backBuffers[i].validate(c);
5803 if (result == VolatileImage.IMAGE_INCOMPATIBLE)
5804 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
5806 validatedContents = true;
5810 * Returns whether or not the image buffer resources have been
5813 * @return true if the resources have been lost, false otherwise
5815 public boolean contentsLost()
5817 for (int i = 0; i < backBuffers.length; i++)
5819 if (backBuffers[i].contentsLost())
5821 validatedContents = false;
5825 // we know that the buffer resources are valid now because we
5826 // just checked them
5827 validatedContents = true;
5832 * Returns whether or not the image buffer resources have been
5835 * @return true if the resources have been restored, false
5838 public boolean contentsRestored()
5840 GraphicsConfiguration c =
5841 GraphicsEnvironment.getLocalGraphicsEnvironment()
5842 .getDefaultScreenDevice().getDefaultConfiguration();
5844 boolean imageRestored = false;
5846 for (int i = 0; i < backBuffers.length; i++)
5848 int result = backBuffers[i].validate(c);
5849 if (result == VolatileImage.IMAGE_RESTORED)
5850 imageRestored = true;
5851 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
5854 // we know that the buffer resources are valid now because we
5855 // just checked them
5856 validatedContents = true;
5857 return imageRestored;
5862 * This class provides support for flipping component buffers. It
5863 * can only be used on Canvases and Windows.
5867 protected class FlipBufferStrategy extends BufferStrategy
5870 * The number of buffers.
5872 protected int numBuffers;
5875 * The capabilities of this buffering strategy.
5877 protected BufferCapabilities caps;
5880 * An Image reference to the drawing buffer.
5882 protected Image drawBuffer;
5885 * A VolatileImage reference to the drawing buffer.
5887 protected VolatileImage drawVBuffer;
5890 * Whether or not the image buffer resources are allocated and
5891 * ready to be drawn into.
5893 protected boolean validatedContents;
5896 * The width of the back buffer.
5901 * The height of the back buffer.
5906 * Creates a flipping buffer strategy. The only supported
5907 * strategy for FlipBufferStrategy itself is a double-buffer page
5908 * flipping strategy. It forms the basis for more complex derived
5911 * @param numBuffers the number of buffers
5912 * @param caps the capabilities of this buffering strategy
5914 * @throws AWTException if the requested
5915 * number-of-buffers/capabilities combination is not supported
5917 protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
5922 height = getHeight();
5925 createBuffers(numBuffers, caps);
5928 drawVBuffer = peer.createVolatileImage(width, height);
5929 drawBuffer = drawVBuffer;
5934 * Creates a multi-buffer flipping strategy. The number of
5935 * buffers must be greater than one and the buffer capabilities
5936 * must specify page flipping.
5938 * @param numBuffers the number of flipping buffers; must be
5940 * @param caps the buffering capabilities; caps.isPageFlipping()
5943 * @throws IllegalArgumentException if numBuffers is not greater
5944 * than one or if the page flipping capability is not requested
5946 * @throws AWTException if the requested flipping strategy is not
5949 protected void createBuffers(int numBuffers, BufferCapabilities caps)
5952 if (numBuffers <= 1)
5953 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
5954 + " numBuffers must be greater than"
5957 if (!caps.isPageFlipping())
5958 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
5959 + " flipping must be a specified"
5962 peer.createBuffers(numBuffers, caps);
5966 * Return a direct reference to the back buffer image.
5968 * @return a direct reference to the back buffer image.
5970 protected Image getBackBuffer()
5972 return peer.getBackBuffer();
5976 * Perform a flip operation to transfer the contents of the back
5977 * buffer to the front buffer.
5979 protected void flip(BufferCapabilities.FlipContents flipAction)
5981 peer.flip(flipAction);
5985 * Release the back buffer's resources.
5987 protected void destroyBuffers()
5989 peer.destroyBuffers();
5993 * Retrieves the capabilities of this buffer strategy.
5995 * @return the capabilities of this buffer strategy
5997 public BufferCapabilities getCapabilities()
6003 * Retrieves a graphics object that can be used to draw into this
6004 * strategy's image buffer.
6006 * @return a graphics object
6008 public Graphics getDrawGraphics()
6010 return drawVBuffer.getGraphics();
6014 * Re-create the image buffer resources if they've been lost.
6016 protected void revalidate()
6018 GraphicsConfiguration c =
6019 GraphicsEnvironment.getLocalGraphicsEnvironment()
6020 .getDefaultScreenDevice().getDefaultConfiguration();
6022 if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
6023 drawVBuffer = peer.createVolatileImage(width, height);
6024 validatedContents = true;
6028 * Returns whether or not the image buffer resources have been
6031 * @return true if the resources have been lost, false otherwise
6033 public boolean contentsLost()
6035 if (drawVBuffer.contentsLost())
6037 validatedContents = false;
6040 // we know that the buffer resources are valid now because we
6041 // just checked them
6042 validatedContents = true;
6047 * Returns whether or not the image buffer resources have been
6050 * @return true if the resources have been restored, false
6053 public boolean contentsRestored()
6055 GraphicsConfiguration c =
6056 GraphicsEnvironment.getLocalGraphicsEnvironment()
6057 .getDefaultScreenDevice().getDefaultConfiguration();
6059 int result = drawVBuffer.validate(c);
6061 boolean imageRestored = false;
6063 if (result == VolatileImage.IMAGE_RESTORED)
6064 imageRestored = true;
6065 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6068 // we know that the buffer resources are valid now because we
6069 // just checked them
6070 validatedContents = true;
6071 return imageRestored;
6075 * Bring the contents of the back buffer to the front buffer.
6079 flip(caps.getFlipContents());