Merge from mainline
[official-gcc.git] / libjava / classpath / java / awt / Component.java
blobbd22ea3c984a4501fd93401e1bf5a4a9eb051e7a
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)
9 any later version.
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
19 02110-1301 USA.
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
24 combination.
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. */
39 package java.awt;
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;
85 import java.util.Set;
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;
95 /**
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.
112 * <pre>
113 * import java.awt.*;
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");
129 * MyApp()
131 * aButton.addActionListener(new MyActionListener());
134 * </pre>
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)
144 * @since 1.0
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
162 * other components.
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
172 * other components.
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
182 * other components.
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
191 * other components.
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
200 * other components.
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
210 * as a lock object.
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
222 int x;
225 * The y position of the component in the parent's coordinate system.
227 * @see #getLocation()
228 * @serial the y position
230 int y;
233 * The component width.
235 * @see #getSize()
236 * @serial the width
238 int width;
241 * The component height.
243 * @see #getSize()
244 * @serial the height
246 int height;
249 * The foreground color for the component. This may be null.
251 * @see #getForeground()
252 * @see #setForeground(Color)
253 * @serial the foreground color
255 Color foreground;
258 * The background color for the component. This may be null.
260 * @see #getBackground()
261 * @see #setBackground(Color)
262 * @serial the background color
264 Color background;
267 * The default font used in the component. This may be null.
269 * @see #getFont()
270 * @see #setFont(Font)
271 * @serial the font
273 Font font;
276 * The font in use by the peer, or null if there is no peer.
278 * @serial the peer's font
280 Font peerFont;
283 * The cursor displayed when the pointer is over this component. This may
284 * be null.
286 * @see #getCursor()
287 * @see #setCursor(Cursor)
289 Cursor cursor;
292 * The locale for the component.
294 * @see #getLocale()
295 * @see #setLocale(Locale)
297 Locale locale = Locale.getDefault ();
300 * True if the object should ignore repaint events (usually because it is
301 * not showing).
303 * @see #getIgnoreRepaint()
304 * @see #setIgnoreRepaint(boolean)
305 * @serial true to ignore repaints
306 * @since 1.4
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.
314 * @see #isVisible()
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.
324 * @see #isEnabled()
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.
334 * @see #isValid()
335 * @see #validate()
336 * @see #invalidate()
337 * @serial true if layout is valid
339 boolean valid;
342 * The DropTarget for drag-and-drop operations.
344 * @see #getDropTarget()
345 * @see #setDropTarget(DropTarget)
346 * @serial the drop target, or null
347 * @since 1.2
349 DropTarget dropTarget;
352 * The list of popup menus for this component.
354 * @see #add(PopupMenu)
355 * @serial the list of popups
357 Vector popups;
360 * The component's name. May be null, in which case a default name is
361 * generated on the first use.
363 * @see #getName()
364 * @see #setName(String)
365 * @serial the name
367 String name;
370 * True once the user has set the name. Note that the user may set the name
371 * to null.
373 * @see #name
374 * @see #getName()
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)
385 * @since 1.4
387 boolean focusable = true;
390 * Tracks whether this component's {@link #isFocusTraversable}
391 * method has been overridden.
393 * @since 1.4
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
401 * focus control.
403 * @see #getFocusTraversalKeys(int)
404 * @see #setFocusTraversalKeys(int, Set)
405 * @since 1.4
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)
416 * @since 1.4
418 boolean focusTraversalKeysEnabled = true;
421 * Cached information on the minimum size. Should have been transient.
423 * @serial ignore
425 Dimension minSize;
428 * Cached information on the preferred size. Should have been transient.
430 * @serial ignore
432 Dimension prefSize;
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)
449 * @see AWTEvent
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
461 * @since 1.2
463 PropertyChangeSupport changeSupport;
466 * True if the component has been packed (layed out).
468 * @serial true if this is packed
470 boolean isPacked;
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
483 * by subclasses.
485 * @see #getAccessibleContext()
486 * @serial the accessibility context
487 * @since 1.2
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.
513 * @since 1.4
515 transient MouseWheelListener mouseWheelListener;
518 * Input method listener chain.
520 * @since 1.2
522 transient InputMethodListener inputMethodListener;
525 * Hierarcy listener chain.
527 * @since 1.3
529 transient HierarchyListener hierarchyListener;
532 * Hierarcy bounds listener chain.
534 * @since 1.3
536 transient HierarchyBoundsListener hierarchyBoundsListener;
538 // Anything else is non-serializable, and should be declared "transient".
540 /** The parent. */
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.
552 * @since 1.4
554 transient GraphicsConfiguration graphicsConfig;
557 * The buffer strategy for repainting.
559 * @since 1.4
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;
575 static
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()
590 // Nothing to do here.
594 * Returns the name of this component.
596 * @return the name of this component
597 * @see #setName(String)
598 * @since 1.1
600 public String getName()
602 if (name == null && ! nameExplicitlySet)
603 name = generateName();
604 return name;
608 * Sets the name of this component to the specified name.
610 * @param name the new name of this component
611 * @see #getName()
612 * @since 1.1
614 public void setName(String name)
616 nameExplicitlySet = true;
617 this.name = name;
621 * Returns the parent of this component.
623 * @return the parent of this component
625 public Container getParent()
627 return parent;
631 * Returns the native windowing system peer for this component. Only the
632 * platform specific implementation code should call this method.
634 * @return the peer for this component
635 * @deprecated user programs should not directly manipulate peers; use
636 * {@link #isDisplayable()} instead
638 // Classpath's Gtk peers rely on this.
639 public ComponentPeer getPeer()
641 return peer;
645 * Set the associated drag-and-drop target, which receives events when this
646 * is enabled.
648 * @param dt the new drop target
649 * @see #isEnabled()
651 public void setDropTarget(DropTarget dt)
653 this.dropTarget = dt;
657 * Gets the associated drag-and-drop target, if there is one.
659 * @return the drop target
661 public DropTarget getDropTarget()
663 return dropTarget;
667 * Returns the graphics configuration of this component, if there is one.
668 * If it has not been set, it is inherited from the parent.
670 * @return the graphics configuration, or null
671 * @since 1.3
673 public GraphicsConfiguration getGraphicsConfiguration()
675 return getGraphicsConfigurationImpl();
679 * Returns the object used for synchronization locks on this component
680 * when performing tree and layout functions.
682 * @return the synchronization lock for this component
684 public final Object getTreeLock()
686 return treeLock;
690 * Returns the toolkit in use for this component. The toolkit is associated
691 * with the frame this component belongs to.
693 * @return the toolkit for this component
695 public Toolkit getToolkit()
697 if (peer != null)
699 Toolkit tk = peer.getToolkit();
700 if (tk != null)
701 return tk;
703 // Get toolkit for lightweight component.
704 if (parent != null)
705 return parent.getToolkit();
706 return Toolkit.getDefaultToolkit();
710 * Tests whether or not this component is valid. A invalid component needs
711 * to have its layout redone.
713 * @return true if this component is valid
714 * @see #validate()
715 * @see #invalidate()
717 public boolean isValid()
719 return valid;
723 * Tests if the component is displayable. It must be connected to a native
724 * screen resource. This reduces to checking that peer is not null. A
725 * containment hierarchy is made displayable when a window is packed or
726 * made visible.
728 * @return true if the component is displayable
729 * @see Container#add(Component)
730 * @see Container#remove(Component)
731 * @see Window#pack()
732 * @see Window#show()
733 * @see Window#dispose()
734 * @since 1.2
736 public boolean isDisplayable()
738 return peer != null;
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()
750 return visible;
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)
764 return false;
766 return parent == null ? false : 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()
778 return enabled;
782 * Enables or disables this component. The component must be enabled to
783 * receive events (except that lightweight components always receive mouse
784 * events).
786 * @param enabled true to enable this component
788 * @see #isEnabled()
789 * @see #isLightweight()
791 * @since 1.1
793 public void setEnabled(boolean enabled)
795 enable(enabled);
799 * Enables this component.
801 * @deprecated use {@link #setEnabled(boolean)} instead
803 public void enable()
805 this.enabled = true;
806 if (peer != null)
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)
819 if (enabled)
820 enable();
821 else
822 disable();
826 * Disables this component.
828 * @deprecated use {@link #setEnabled(boolean)} instead
830 public void disable()
832 this.enabled = false;
833 if (peer != null)
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
841 * buffering.
843 * @return true if this is double buffered; defaults to false
845 public boolean isDoubleBuffered()
847 return false;
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)
857 * @since 1.2
859 public void enableInputMethods(boolean enable)
861 if (enable)
862 eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
863 else
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
873 * @see #isVisible()
875 * @since 1.1
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.
882 show(visible);
886 * Makes this component visible on the screen.
888 * @deprecated use {@link #setVisible(boolean)} instead
890 public void show()
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
896 // and its children.
897 if(!isVisible())
899 this.visible = true;
900 // Avoid NullPointerExceptions by creating a local reference.
901 ComponentPeer currentPeer=peer;
902 if (currentPeer != null)
903 currentPeer.setVisible(true);
905 // The JDK repaints the component before invalidating the parent.
906 // So do we.
907 if (isShowing())
908 repaint();
909 // Invalidate the parent if we have one. The component itself must
910 // not be invalidated. We also avoid NullPointerException with
911 // a local reference here.
912 Container currentParent = parent;
913 if (currentParent != null)
914 currentParent.invalidate();
916 ComponentEvent ce =
917 new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
918 getToolkit().getSystemEventQueue().postEvent(ce);
923 * Makes this component visible or invisible.
925 * @param visible true to make this component visible
927 * @deprecated use {@link #setVisible(boolean)} instead
929 public void show(boolean visible)
931 if (visible)
932 show();
933 else
934 hide();
938 * Hides this component so that it is no longer shown on the screen.
940 * @deprecated use {@link #setVisible(boolean)} instead
942 public void hide()
944 if (isVisible())
946 // Avoid NullPointerExceptions by creating a local reference.
947 ComponentPeer currentPeer=peer;
948 if (currentPeer != null)
949 currentPeer.setVisible(false);
950 boolean wasShowing = isShowing();
951 this.visible = false;
953 // The JDK repaints the component before invalidating the parent.
954 // So do we.
955 if (wasShowing)
956 repaint();
957 // Invalidate the parent if we have one. The component itself must
958 // not be invalidated. We also avoid NullPointerException with
959 // a local reference here.
960 Container currentParent = parent;
961 if (currentParent != null)
962 currentParent.invalidate();
964 ComponentEvent ce =
965 new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
966 getToolkit().getSystemEventQueue().postEvent(ce);
971 * Returns this component's foreground color. If not set, this is inherited
972 * from the parent.
974 * @return this component's foreground color, or null
975 * @see #setForeground(Color)
977 public Color getForeground()
979 if (foreground != null)
980 return foreground;
981 return parent == null ? null : parent.getForeground();
985 * Sets this component's foreground color to the specified color. This is a
986 * bound property.
988 * @param c the new foreground color
989 * @see #getForeground()
991 public void setForeground(Color c)
993 if (peer != null)
994 peer.setForeground(c);
996 Color previous = foreground;
997 foreground = c;
998 firePropertyChange("foreground", previous, c);
1002 * Tests if the foreground was explicitly set, or just inherited from the
1003 * parent.
1005 * @return true if the foreground has been set
1006 * @since 1.4
1008 public boolean isForegroundSet()
1010 return foreground != null;
1014 * Returns this component's background color. If not set, this is inherited
1015 * from the parent.
1017 * @return the background color of the component, or null
1018 * @see #setBackground(Color)
1020 public Color getBackground()
1022 if (background != null)
1023 return background;
1024 return parent == null ? null : parent.getBackground();
1028 * Sets this component's background color to the specified color. The parts
1029 * of the component affected by the background color may by system dependent.
1030 * This is a bound property.
1032 * @param c the new background color
1033 * @see #getBackground()
1035 public void setBackground(Color c)
1037 // return if the background is already set to that color.
1038 if ((c != null) && c.equals(background))
1039 return;
1041 Color previous = background;
1042 background = c;
1043 if (peer != null && c != null)
1044 peer.setBackground(c);
1045 firePropertyChange("background", previous, c);
1049 * Tests if the background was explicitly set, or just inherited from the
1050 * parent.
1052 * @return true if the background has been set
1053 * @since 1.4
1055 public boolean isBackgroundSet()
1057 return background != null;
1061 * Returns the font in use for this component. If not set, this is inherited
1062 * from the parent.
1064 * @return the font for this component
1065 * @see #setFont(Font)
1067 public Font getFont()
1069 Font f = font;
1070 if (f != null)
1071 return f;
1073 Component p = parent;
1074 if (p != null)
1075 return p.getFont();
1076 if (peer != null)
1077 return peer.getGraphics().getFont();
1078 return null;
1082 * Sets the font for this component to the specified font. This is a bound
1083 * property.
1085 * @param newFont the new font for this component
1087 * @see #getFont()
1089 public void setFont(Font newFont)
1091 if((newFont != null && (font == null || !font.equals(newFont)))
1092 || newFont == null)
1094 Font oldFont = font;
1095 font = newFont;
1096 if (peer != null)
1097 peer.setFont(font);
1098 firePropertyChange("font", oldFont, newFont);
1099 invalidate();
1104 * Tests if the font was explicitly set, or just inherited from the parent.
1106 * @return true if the font has been set
1107 * @since 1.4
1109 public boolean isFontSet()
1111 return font != null;
1115 * Returns the locale for this component. If this component does not
1116 * have a locale, the locale of the parent component is returned.
1118 * @return the locale for this component
1119 * @throws IllegalComponentStateException if it has no locale or parent
1120 * @see #setLocale(Locale)
1121 * @since 1.1
1123 public Locale getLocale()
1125 if (locale != null)
1126 return locale;
1127 if (parent == null)
1128 throw new IllegalComponentStateException
1129 ("Component has no parent: can't determine Locale");
1130 return parent.getLocale();
1134 * Sets the locale for this component to the specified locale. This is a
1135 * bound property.
1137 * @param newLocale the new locale for this component
1139 public void setLocale(Locale newLocale)
1141 if (locale == newLocale)
1142 return;
1144 Locale oldLocale = locale;
1145 locale = newLocale;
1146 firePropertyChange("locale", oldLocale, newLocale);
1147 // New writing/layout direction or more/less room for localized labels.
1148 invalidate();
1152 * Returns the color model of the device this componet is displayed on.
1154 * @return this object's color model
1155 * @see Toolkit#getColorModel()
1157 public ColorModel getColorModel()
1159 GraphicsConfiguration config = getGraphicsConfiguration();
1160 return config != null ? config.getColorModel()
1161 : getToolkit().getColorModel();
1165 * Returns the location of this component's top left corner relative to
1166 * its parent component. This may be outdated, so for synchronous behavior,
1167 * you should use a component listner.
1169 * @return the location of this component
1170 * @see #setLocation(int, int)
1171 * @see #getLocationOnScreen()
1172 * @since 1.1
1174 public Point getLocation()
1176 return location ();
1180 * Returns the location of this component's top left corner in screen
1181 * coordinates.
1183 * @return the location of this component in screen coordinates
1184 * @throws IllegalComponentStateException if the component is not showing
1186 public Point getLocationOnScreen()
1188 if (! isShowing())
1189 throw new IllegalComponentStateException("component "
1190 + getClass().getName()
1191 + " not showing");
1192 // We know peer != null here.
1193 return peer.getLocationOnScreen();
1197 * Returns the location of this component's top left corner relative to
1198 * its parent component.
1200 * @return the location of this component
1201 * @deprecated use {@link #getLocation()} instead
1203 public Point location()
1205 return new Point (x, y);
1209 * Moves this component to the specified location, relative to the parent's
1210 * coordinates. The coordinates are the new upper left corner of this
1211 * component.
1213 * @param x the new X coordinate of this component
1214 * @param y the new Y coordinate of this component
1215 * @see #getLocation()
1216 * @see #setBounds(int, int, int, int)
1218 public void setLocation(int x, int y)
1220 move (x, y);
1224 * Moves this component to the specified location, relative to the parent's
1225 * coordinates. The coordinates are the new upper left corner of this
1226 * component.
1228 * @param x the new X coordinate of this component
1229 * @param y the new Y coordinate of this component
1230 * @deprecated use {@link #setLocation(int, int)} instead
1232 public void move(int x, int y)
1234 setBounds(x, y, this.width, this.height);
1238 * Moves this component to the specified location, relative to the parent's
1239 * coordinates. The coordinates are the new upper left corner of this
1240 * component.
1242 * @param p new coordinates for this component
1243 * @throws NullPointerException if p is null
1244 * @see #getLocation()
1245 * @see #setBounds(int, int, int, int)
1246 * @since 1.1
1248 public void setLocation(Point p)
1250 setLocation(p.x, p.y);
1254 * Returns the size of this object.
1256 * @return the size of this object
1257 * @see #setSize(int, int)
1258 * @since 1.1
1260 public Dimension getSize()
1262 return size ();
1266 * Returns the size of this object.
1268 * @return the size of this object
1269 * @deprecated use {@link #getSize()} instead
1271 public Dimension size()
1273 return new Dimension (width, height);
1277 * Sets the size of this component to the specified width and height.
1279 * @param width the new width of this component
1280 * @param height the new height of this component
1281 * @see #getSize()
1282 * @see #setBounds(int, int, int, int)
1284 public void setSize(int width, int height)
1286 resize (width, height);
1290 * Sets the size of this component to the specified value.
1292 * @param width the new width of the component
1293 * @param height the new height of the component
1294 * @deprecated use {@link #setSize(int, int)} instead
1296 public void resize(int width, int height)
1298 setBounds(this.x, this.y, width, height);
1302 * Sets the size of this component to the specified value.
1304 * @param d the new size of this component
1305 * @throws NullPointerException if d is null
1306 * @see #setSize(int, int)
1307 * @see #setBounds(int, int, int, int)
1308 * @since 1.1
1310 public void setSize(Dimension d)
1312 resize (d);
1316 * Sets the size of this component to the specified value.
1318 * @param d the new size of this component
1319 * @throws NullPointerException if d is null
1320 * @deprecated use {@link #setSize(Dimension)} instead
1322 public void resize(Dimension d)
1324 resize (d.width, d.height);
1328 * Returns a bounding rectangle for this component. Note that the
1329 * returned rectange is relative to this component's parent, not to
1330 * the screen.
1332 * @return the bounding rectangle for this component
1333 * @see #setBounds(int, int, int, int)
1334 * @see #getLocation()
1335 * @see #getSize()
1337 public Rectangle getBounds()
1339 return bounds ();
1343 * Returns a bounding rectangle for this component. Note that the
1344 * returned rectange is relative to this component's parent, not to
1345 * the screen.
1347 * @return the bounding rectangle for this component
1348 * @deprecated use {@link #getBounds()} instead
1350 public Rectangle bounds()
1352 return new Rectangle (x, y, width, height);
1356 * Sets the bounding rectangle for this component to the specified values.
1357 * Note that these coordinates are relative to the parent, not to the screen.
1359 * @param x the X coordinate of the upper left corner of the rectangle
1360 * @param y the Y coordinate of the upper left corner of the rectangle
1361 * @param w the width of the rectangle
1362 * @param h the height of the rectangle
1363 * @see #getBounds()
1364 * @see #setLocation(int, int)
1365 * @see #setLocation(Point)
1366 * @see #setSize(int, int)
1367 * @see #setSize(Dimension)
1368 * @since 1.1
1370 public void setBounds(int x, int y, int w, int h)
1372 reshape (x, y, w, h);
1376 * Sets the bounding rectangle for this component to the specified values.
1377 * Note that these coordinates are relative to the parent, not to the screen.
1379 * @param x the X coordinate of the upper left corner of the rectangle
1380 * @param y the Y coordinate of the upper left corner of the rectangle
1381 * @param width the width of the rectangle
1382 * @param height the height of the rectangle
1383 * @deprecated use {@link #setBounds(int, int, int, int)} instead
1385 public void reshape(int x, int y, int width, int height)
1387 int oldx = this.x;
1388 int oldy = this.y;
1389 int oldwidth = this.width;
1390 int oldheight = this.height;
1392 if (this.x == x && this.y == y
1393 && this.width == width && this.height == height)
1394 return;
1395 invalidate ();
1396 this.x = x;
1397 this.y = y;
1398 this.width = width;
1399 this.height = height;
1400 if (peer != null)
1401 peer.setBounds (x, y, width, height);
1403 // Erase old bounds and repaint new bounds for lightweights.
1404 if (isLightweight() && isShowing())
1406 if (parent != null)
1408 Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth,
1409 oldheight);
1410 Rectangle newBounds = new Rectangle(x, y, width, height);
1411 Rectangle destroyed = oldBounds.union(newBounds);
1412 if (!destroyed.isEmpty())
1413 parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
1414 destroyed.height);
1418 // Only post event if this component is visible and has changed size.
1419 if (isShowing ()
1420 && (oldx != x || oldy != y))
1422 ComponentEvent ce = new ComponentEvent(this,
1423 ComponentEvent.COMPONENT_MOVED);
1424 getToolkit().getSystemEventQueue().postEvent(ce);
1426 if (isShowing ()
1427 && (oldwidth != width || oldheight != height))
1429 ComponentEvent ce = new ComponentEvent(this,
1430 ComponentEvent.COMPONENT_RESIZED);
1431 getToolkit().getSystemEventQueue().postEvent(ce);
1436 * Sets the bounding rectangle for this component to the specified
1437 * rectangle. Note that these coordinates are relative to the parent, not
1438 * to the screen.
1440 * @param r the new bounding rectangle
1441 * @throws NullPointerException if r is null
1442 * @see #getBounds()
1443 * @see #setLocation(Point)
1444 * @see #setSize(Dimension)
1445 * @since 1.1
1447 public void setBounds(Rectangle r)
1449 setBounds (r.x, r.y, r.width, r.height);
1453 * Gets the x coordinate of the upper left corner. This is more efficient
1454 * than getBounds().x or getLocation().x.
1456 * @return the current x coordinate
1457 * @since 1.2
1459 public int getX()
1461 return x;
1465 * Gets the y coordinate of the upper left corner. This is more efficient
1466 * than getBounds().y or getLocation().y.
1468 * @return the current y coordinate
1469 * @since 1.2
1471 public int getY()
1473 return y;
1477 * Gets the width of the component. This is more efficient than
1478 * getBounds().width or getSize().width.
1480 * @return the current width
1481 * @since 1.2
1483 public int getWidth()
1485 return width;
1489 * Gets the height of the component. This is more efficient than
1490 * getBounds().height or getSize().height.
1492 * @return the current width
1493 * @since 1.2
1495 public int getHeight()
1497 return height;
1501 * Returns the bounds of this component. This allows reuse of an existing
1502 * rectangle, if r is non-null.
1504 * @param r the rectangle to use, or null
1505 * @return the bounds
1507 public Rectangle getBounds(Rectangle r)
1509 if (r == null)
1510 r = new Rectangle();
1511 r.x = x;
1512 r.y = y;
1513 r.width = width;
1514 r.height = height;
1515 return r;
1519 * Returns the size of this component. This allows reuse of an existing
1520 * dimension, if d is non-null.
1522 * @param d the dimension to use, or null
1523 * @return the size
1525 public Dimension getSize(Dimension d)
1527 if (d == null)
1528 d = new Dimension();
1529 d.width = width;
1530 d.height = height;
1531 return d;
1535 * Returns the location of this component. This allows reuse of an existing
1536 * point, if p is non-null.
1538 * @param p the point to use, or null
1539 * @return the location
1541 public Point getLocation(Point p)
1543 if (p == null)
1544 p = new Point();
1545 p.x = x;
1546 p.y = y;
1547 return p;
1551 * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1552 * components are opaque. A component is opaque if it draws all pixels in
1553 * the bounds; a lightweight component is partially transparent if it lets
1554 * pixels underneath show through. Subclasses that guarantee that all pixels
1555 * will be drawn should override this.
1557 * @return true if this is opaque
1558 * @see #isLightweight()
1559 * @since 1.2
1561 public boolean isOpaque()
1563 return ! isLightweight();
1567 * Return whether the component is lightweight. That means the component has
1568 * no native peer, but is displayable. This applies to subclasses of
1569 * Component not in this package, such as javax.swing.
1571 * @return true if the component has a lightweight peer
1572 * @see #isDisplayable()
1573 * @since 1.2
1575 public boolean isLightweight()
1577 return peer instanceof LightweightPeer;
1581 * Returns the component's preferred size.
1583 * @return the component's preferred size
1584 * @see #getMinimumSize()
1585 * @see LayoutManager
1587 public Dimension getPreferredSize()
1589 return preferredSize();
1593 * Returns the component's preferred size.
1595 * @return the component's preferred size
1596 * @deprecated use {@link #getPreferredSize()} instead
1598 public Dimension preferredSize()
1600 if (prefSize == null)
1601 if (peer == null)
1602 return new Dimension(width, height);
1603 else
1604 prefSize = peer.getPreferredSize();
1605 return prefSize;
1609 * Returns the component's minimum size.
1611 * @return the component's minimum size
1612 * @see #getPreferredSize()
1613 * @see LayoutManager
1615 public Dimension getMinimumSize()
1617 return minimumSize();
1621 * Returns the component's minimum size.
1623 * @return the component's minimum size
1624 * @deprecated use {@link #getMinimumSize()} instead
1626 public Dimension minimumSize()
1628 if (minSize == null)
1629 minSize = (peer != null ? peer.getMinimumSize()
1630 : new Dimension(width, height));
1631 return minSize;
1635 * Returns the component's maximum size.
1637 * @return the component's maximum size
1638 * @see #getMinimumSize()
1639 * @see #getPreferredSize()
1640 * @see LayoutManager
1642 public Dimension getMaximumSize()
1644 return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
1648 * Returns the preferred horizontal alignment of this component. The value
1649 * returned will be between {@link #LEFT_ALIGNMENT} and
1650 * {@link #RIGHT_ALIGNMENT}, inclusive.
1652 * @return the preferred horizontal alignment of this component
1654 public float getAlignmentX()
1656 return CENTER_ALIGNMENT;
1660 * Returns the preferred vertical alignment of this component. The value
1661 * returned will be between {@link #TOP_ALIGNMENT} and
1662 * {@link #BOTTOM_ALIGNMENT}, inclusive.
1664 * @return the preferred vertical alignment of this component
1666 public float getAlignmentY()
1668 return CENTER_ALIGNMENT;
1672 * Calls the layout manager to re-layout the component. This is called
1673 * during validation of a container in most cases.
1675 * @see #validate()
1676 * @see LayoutManager
1678 public void doLayout()
1680 layout ();
1684 * Calls the layout manager to re-layout the component. This is called
1685 * during validation of a container in most cases.
1687 * @deprecated use {@link #doLayout()} instead
1689 public void layout()
1691 // Nothing to do unless we're a container.
1695 * Called to ensure that the layout for this component is valid. This is
1696 * usually called on containers.
1698 * @see #invalidate()
1699 * @see #doLayout()
1700 * @see LayoutManager
1701 * @see Container#validate()
1703 public void validate()
1705 valid = true;
1709 * Invalidates this component and all of its parent components. This will
1710 * cause them to have their layout redone. This is called frequently, so
1711 * make it fast.
1713 public void invalidate()
1715 valid = false;
1716 prefSize = null;
1717 minSize = null;
1718 if (parent != null && parent.isValid())
1719 parent.invalidate();
1723 * Returns a graphics object for this component. Returns <code>null</code>
1724 * if this component is not currently displayed on the screen.
1726 * @return a graphics object for this component
1727 * @see #paint(Graphics)
1729 public Graphics getGraphics()
1731 if (peer != null)
1733 Graphics gfx = peer.getGraphics();
1734 // Create peer for lightweights.
1735 if (gfx == null && parent != null)
1737 gfx = parent.getGraphics();
1738 Rectangle bounds = getBounds();
1739 gfx.setClip(bounds);
1740 gfx.translate(bounds.x, bounds.y);
1741 return gfx;
1743 gfx.setFont(font);
1744 return gfx;
1746 return null;
1750 * Returns the font metrics for the specified font in this component.
1752 * @param font the font to retrieve metrics for
1753 * @return the font metrics for the specified font
1754 * @throws NullPointerException if font is null
1755 * @see #getFont()
1756 * @see Toolkit#getFontMetrics(Font)
1758 public FontMetrics getFontMetrics(Font font)
1760 return peer == null ? getToolkit().getFontMetrics(font)
1761 : peer.getFontMetrics(font);
1765 * Sets the cursor for this component to the specified cursor. The cursor
1766 * is displayed when the point is contained by the component, and the
1767 * component is visible, displayable, and enabled. This is inherited by
1768 * subcomponents unless they set their own cursor.
1770 * @param cursor the new cursor for this component
1771 * @see #isEnabled()
1772 * @see #isShowing()
1773 * @see #getCursor()
1774 * @see #contains(int, int)
1775 * @see Toolkit#createCustomCursor(Image, Point, String)
1777 public void setCursor(Cursor cursor)
1779 this.cursor = cursor;
1780 if (peer != null)
1781 peer.setCursor(cursor);
1785 * Returns the cursor for this component. If not set, this is inherited
1786 * from the parent, or from Cursor.getDefaultCursor().
1788 * @return the cursor for this component
1790 public Cursor getCursor()
1792 if (cursor != null)
1793 return cursor;
1794 return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
1798 * Tests if the cursor was explicitly set, or just inherited from the parent.
1800 * @return true if the cursor has been set
1801 * @since 1.4
1803 public boolean isCursorSet()
1805 return cursor != null;
1809 * Paints this component on the screen. The clipping region in the graphics
1810 * context will indicate the region that requires painting. This is called
1811 * whenever the component first shows, or needs to be repaired because
1812 * something was temporarily drawn on top. It is not necessary for
1813 * subclasses to call <code>super.paint(g)</code>. Components with no area
1814 * are not painted.
1816 * @param g the graphics context for this paint job
1817 * @see #update(Graphics)
1819 public void paint(Graphics g)
1821 // This is a callback method and is meant to be overridden by subclasses
1822 // that want to perform custom painting.
1826 * Updates this component. This is called in response to
1827 * <code>repaint</code>. This method fills the component with the
1828 * background color, then sets the foreground color of the specified
1829 * graphics context to the foreground color of this component and calls
1830 * the <code>paint()</code> method. The coordinates of the graphics are
1831 * relative to this component. Subclasses should call either
1832 * <code>super.update(g)</code> or <code>paint(g)</code>.
1834 * @param g the graphics context for this update
1836 * @see #paint(Graphics)
1837 * @see #repaint()
1839 * @specnote In contrast to what the spec says, tests show that the exact
1840 * behaviour is to clear the background on lightweight and
1841 * top-level components only. Heavyweight components are not
1842 * affected by this method and only call paint().
1844 public void update(Graphics g)
1846 // Tests show that the clearing of the background is only done in
1847 // two cases:
1848 // - If the component is lightweight (yes this is in contrast to the spec).
1849 // or
1850 // - If the component is a toplevel container.
1851 if (isLightweight() || getParent() == null)
1853 Rectangle clip = g.getClipBounds();
1854 if (clip == null)
1855 g.clearRect(0, 0, width, height);
1856 else
1857 g.clearRect(clip.x, clip.y, clip.width, clip.height);
1859 paint(g);
1863 * Paints this entire component, including any sub-components.
1865 * @param g the graphics context for this paint job
1867 * @see #paint(Graphics)
1869 public void paintAll(Graphics g)
1871 if (! visible)
1872 return;
1873 paint(g);
1877 * Repaint this entire component. The <code>update()</code> method
1878 * on this component will be called as soon as possible.
1880 * @see #update(Graphics)
1881 * @see #repaint(long, int, int, int, int)
1883 public void repaint()
1885 if (isShowing())
1886 repaint(0, 0, 0, width, height);
1890 * Repaint this entire component. The <code>update()</code> method on this
1891 * component will be called in approximate the specified number of
1892 * milliseconds.
1894 * @param tm milliseconds before this component should be repainted
1895 * @see #paint(Graphics)
1896 * @see #repaint(long, int, int, int, int)
1898 public void repaint(long tm)
1900 if (isShowing())
1901 repaint(tm, 0, 0, width, height);
1905 * Repaints the specified rectangular region within this component. The
1906 * <code>update</code> method on this component will be called as soon as
1907 * possible. The coordinates are relative to this component.
1909 * @param x the X coordinate of the upper left of the region to repaint
1910 * @param y the Y coordinate of the upper left of the region to repaint
1911 * @param w the width of the region to repaint
1912 * @param h the height of the region to repaint
1913 * @see #update(Graphics)
1914 * @see #repaint(long, int, int, int, int)
1916 public void repaint(int x, int y, int w, int h)
1918 if (isShowing())
1919 repaint(0, x, y, w, h);
1923 * Repaints the specified rectangular region within this component. The
1924 * <code>update</code> method on this component will be called in
1925 * approximately the specified number of milliseconds. The coordinates
1926 * are relative to this component.
1928 * @param tm milliseconds before this component should be repainted
1929 * @param x the X coordinate of the upper left of the region to repaint
1930 * @param y the Y coordinate of the upper left of the region to repaint
1931 * @param width the width of the region to repaint
1932 * @param height the height of the region to repaint
1933 * @see #update(Graphics)
1935 public void repaint(long tm, int x, int y, int width, int height)
1937 if (isShowing())
1939 ComponentPeer p = peer;
1940 if (p != null)
1941 p.repaint(tm, x, y, width, height);
1946 * Prints this component. This method is provided so that printing can be
1947 * done in a different manner from painting. However, the implementation
1948 * in this class simply calls the <code>paint()</code> method.
1950 * @param g the graphics context of the print device
1952 * @see #paint(Graphics)
1954 public void print(Graphics g)
1956 paint(g);
1960 * Prints this component, including all sub-components. This method is
1961 * provided so that printing can be done in a different manner from
1962 * painting. However, the implementation in this class simply calls the
1963 * <code>paintAll()</code> method.
1965 * @param g the graphics context of the print device
1967 * @see #paintAll(Graphics)
1969 public void printAll(Graphics g)
1971 paintAll(g);
1975 * Called when an image has changed so that this component is repainted.
1976 * This incrementally draws an image as more bits are available, when
1977 * possible. Incremental drawing is enabled if the system property
1978 * <code>awt.image.incrementalDraw</code> is not present or is true, in which
1979 * case the redraw rate is set to 100ms or the value of the system property
1980 * <code>awt.image.redrawrate</code>.
1982 * <p>The coordinate system used depends on the particular flags.
1984 * @param img the image that has been updated
1985 * @param flags tlags as specified in <code>ImageObserver</code>
1986 * @param x the X coordinate
1987 * @param y the Y coordinate
1988 * @param w the width
1989 * @param h the height
1990 * @return false if the image is completely loaded, loading has been
1991 * aborted, or an error has occurred. true if more updates are
1992 * required.
1993 * @see ImageObserver
1994 * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
1995 * @see Graphics#drawImage(Image, int, int, ImageObserver)
1996 * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
1997 * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
1998 * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2000 public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2002 if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2003 repaint();
2004 else if ((flags & SOMEBITS) != 0)
2006 if (incrementalDraw)
2008 if (redrawRate != null)
2010 long tm = redrawRate.longValue();
2011 if (tm < 0)
2012 tm = 0;
2013 repaint(tm);
2015 else
2016 repaint(100);
2019 return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2023 * Creates an image from the specified producer.
2025 * @param producer the image procedure to create the image from
2026 * @return the resulting image
2028 public Image createImage(ImageProducer producer)
2030 // Sun allows producer to be null.
2031 if (peer != null)
2032 return peer.createImage(producer);
2033 else
2034 return getToolkit().createImage(producer);
2038 * Creates an image with the specified width and height for use in
2039 * double buffering. Headless environments do not support images.
2041 * @param width the width of the image
2042 * @param height the height of the image
2043 * @return the requested image, or null if it is not supported
2045 public Image createImage (int width, int height)
2047 Image returnValue = null;
2048 if (!GraphicsEnvironment.isHeadless ())
2050 if (isLightweight () && parent != null)
2051 returnValue = parent.createImage (width, height);
2052 else if (peer != null)
2053 returnValue = peer.createImage (width, height);
2055 return returnValue;
2059 * Creates an image with the specified width and height for use in
2060 * double buffering. Headless environments do not support images.
2062 * @param width the width of the image
2063 * @param height the height of the image
2064 * @return the requested image, or null if it is not supported
2065 * @since 1.4
2067 public VolatileImage createVolatileImage(int width, int height)
2069 if (GraphicsEnvironment.isHeadless())
2070 return null;
2071 GraphicsConfiguration config = getGraphicsConfiguration();
2072 return config == null ? null
2073 : config.createCompatibleVolatileImage(width, height);
2077 * Creates an image with the specified width and height for use in
2078 * double buffering. Headless environments do not support images. The image
2079 * will support the specified capabilities.
2081 * @param width the width of the image
2082 * @param height the height of the image
2083 * @param caps the requested capabilities
2084 * @return the requested image, or null if it is not supported
2085 * @throws AWTException if a buffer with the capabilities cannot be created
2086 * @since 1.4
2088 public VolatileImage createVolatileImage(int width, int height,
2089 ImageCapabilities caps)
2090 throws AWTException
2092 if (GraphicsEnvironment.isHeadless())
2093 return null;
2094 GraphicsConfiguration config = getGraphicsConfiguration();
2095 return config == null ? null
2096 : config.createCompatibleVolatileImage(width, height, caps);
2100 * Prepares the specified image for rendering on this component.
2102 * @param image the image to prepare for rendering
2103 * @param observer the observer to notify of image preparation status
2104 * @return true if the image is already fully prepared
2105 * @throws NullPointerException if image is null
2107 public boolean prepareImage(Image image, ImageObserver observer)
2109 return prepareImage(image, image.getWidth(observer),
2110 image.getHeight(observer), observer);
2114 * Prepares the specified image for rendering on this component at the
2115 * specified scaled width and height
2117 * @param image the image to prepare for rendering
2118 * @param width the scaled width of the image
2119 * @param height the scaled height of the image
2120 * @param observer the observer to notify of image preparation status
2121 * @return true if the image is already fully prepared
2123 public boolean prepareImage(Image image, int width, int height,
2124 ImageObserver observer)
2126 if (peer != null)
2127 return peer.prepareImage(image, width, height, observer);
2128 else
2129 return getToolkit().prepareImage(image, width, height, observer);
2133 * Returns the status of the loading of the specified image. The value
2134 * returned will be those flags defined in <code>ImageObserver</code>.
2136 * @param image the image to check on
2137 * @param observer the observer to notify of image loading progress
2138 * @return the image observer flags indicating the status of the load
2139 * @see #prepareImage(Image, int, int, ImageObserver)
2140 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2141 * @throws NullPointerException if image is null
2143 public int checkImage(Image image, ImageObserver observer)
2145 return checkImage(image, -1, -1, observer);
2149 * Returns the status of the loading of the specified image. The value
2150 * returned will be those flags defined in <code>ImageObserver</code>.
2152 * @param image the image to check on
2153 * @param width the scaled image width
2154 * @param height the scaled image height
2155 * @param observer the observer to notify of image loading progress
2156 * @return the image observer flags indicating the status of the load
2157 * @see #prepareImage(Image, int, int, ImageObserver)
2158 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2160 public int checkImage(Image image, int width, int height,
2161 ImageObserver observer)
2163 if (peer != null)
2164 return peer.checkImage(image, width, height, observer);
2165 return getToolkit().checkImage(image, width, height, observer);
2169 * Sets whether paint messages delivered by the operating system should be
2170 * ignored. This does not affect messages from AWT, except for those
2171 * triggered by OS messages. Setting this to true can allow faster
2172 * performance in full-screen mode or page-flipping.
2174 * @param ignoreRepaint the new setting for ignoring repaint events
2175 * @see #getIgnoreRepaint()
2176 * @see BufferStrategy
2177 * @see GraphicsDevice#setFullScreenWindow(Window)
2178 * @since 1.4
2180 public void setIgnoreRepaint(boolean ignoreRepaint)
2182 this.ignoreRepaint = ignoreRepaint;
2186 * Test whether paint events from the operating system are ignored.
2188 * @return the status of ignoring paint events
2189 * @see #setIgnoreRepaint(boolean)
2190 * @since 1.4
2192 public boolean getIgnoreRepaint()
2194 return ignoreRepaint;
2198 * Tests whether or not the specified point is contained within this
2199 * component. Coordinates are relative to this component.
2201 * @param x the X coordinate of the point to test
2202 * @param y the Y coordinate of the point to test
2203 * @return true if the point is within this component
2204 * @see #getComponentAt(int, int)
2206 public boolean contains(int x, int y)
2208 return inside (x, y);
2212 * Tests whether or not the specified point is contained within this
2213 * component. Coordinates are relative to this component.
2215 * @param x the X coordinate of the point to test
2216 * @param y the Y coordinate of the point to test
2217 * @return true if the point is within this component
2218 * @deprecated use {@link #contains(int, int)} instead
2220 public boolean inside(int x, int y)
2222 return x >= 0 && y >= 0 && x < width && y < height;
2226 * Tests whether or not the specified point is contained within this
2227 * component. Coordinates are relative to this component.
2229 * @param p the point to test
2230 * @return true if the point is within this component
2231 * @throws NullPointerException if p is null
2232 * @see #getComponentAt(Point)
2233 * @since 1.1
2235 public boolean contains(Point p)
2237 return contains (p.x, p.y);
2241 * Returns the component occupying the position (x,y). This will either
2242 * be this component, an immediate child component, or <code>null</code>
2243 * if neither of the first two occupies the specified location.
2245 * @param x the X coordinate to search for components at
2246 * @param y the Y coordinate to search for components at
2247 * @return the component at the specified location, or null
2248 * @see #contains(int, int)
2250 public Component getComponentAt(int x, int y)
2252 return locate (x, y);
2256 * Returns the component occupying the position (x,y). This will either
2257 * be this component, an immediate child component, or <code>null</code>
2258 * if neither of the first two occupies the specified location.
2260 * @param x the X coordinate to search for components at
2261 * @param y the Y coordinate to search for components at
2262 * @return the component at the specified location, or null
2263 * @deprecated use {@link #getComponentAt(int, int)} instead
2265 public Component locate(int x, int y)
2267 return contains (x, y) ? this : null;
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 p the point to search for components at
2276 * @return the component at the specified location, or null
2277 * @throws NullPointerException if p is null
2278 * @see #contains(Point)
2279 * @since 1.1
2281 public Component getComponentAt(Point p)
2283 return getComponentAt (p.x, p.y);
2287 * AWT 1.0 event delivery.
2289 * Deliver an AWT 1.0 event to this Component. This method simply
2290 * calls {@link #postEvent}.
2292 * @param e the event to deliver
2293 * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2295 public void deliverEvent (Event e)
2297 postEvent (e);
2301 * Forwards AWT events to processEvent() if:<ul>
2302 * <li>Events have been enabled for this type of event via
2303 * <code>enableEvents()</code></li>,
2304 * <li>There is at least one registered listener for this type of event</li>
2305 * </ul>
2307 * @param e the event to dispatch
2309 public final void dispatchEvent(AWTEvent e)
2311 // Some subclasses in the AWT package need to override this behavior,
2312 // hence the use of dispatchEventImpl().
2313 dispatchEventImpl(e);
2317 * AWT 1.0 event handler.
2319 * This method simply calls handleEvent and returns the result.
2321 * @param e the event to handle
2322 * @return true if the event was handled, false otherwise
2323 * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2325 public boolean postEvent (Event e)
2327 boolean handled = handleEvent (e);
2329 if (!handled && getParent() != null)
2330 // FIXME: need to translate event coordinates to parent's
2331 // coordinate space.
2332 handled = getParent ().postEvent (e);
2334 return handled;
2338 * Adds the specified listener to this component. This is harmless if the
2339 * listener is null, but if the listener has already been registered, it
2340 * will now be registered twice.
2342 * @param listener the new listener to add
2343 * @see ComponentEvent
2344 * @see #removeComponentListener(ComponentListener)
2345 * @see #getComponentListeners()
2346 * @since 1.1
2348 public synchronized void addComponentListener(ComponentListener listener)
2350 componentListener = AWTEventMulticaster.add(componentListener, listener);
2351 if (componentListener != null)
2352 enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
2356 * Removes the specified listener from the component. This is harmless if
2357 * the listener was not previously registered.
2359 * @param listener the listener to remove
2360 * @see ComponentEvent
2361 * @see #addComponentListener(ComponentListener)
2362 * @see #getComponentListeners()
2363 * @since 1.1
2365 public synchronized void removeComponentListener(ComponentListener listener)
2367 componentListener = AWTEventMulticaster.remove(componentListener, listener);
2371 * Returns an array of all specified listeners registered on this component.
2373 * @return an array of listeners
2374 * @see #addComponentListener(ComponentListener)
2375 * @see #removeComponentListener(ComponentListener)
2376 * @since 1.4
2378 public synchronized ComponentListener[] getComponentListeners()
2380 return (ComponentListener[])
2381 AWTEventMulticaster.getListeners(componentListener,
2382 ComponentListener.class);
2386 * Adds the specified listener to this component. This is harmless if the
2387 * listener is null, but if the listener has already been registered, it
2388 * will now be registered twice.
2390 * @param listener the new listener to add
2391 * @see FocusEvent
2392 * @see #removeFocusListener(FocusListener)
2393 * @see #getFocusListeners()
2394 * @since 1.1
2396 public synchronized void addFocusListener(FocusListener listener)
2398 focusListener = AWTEventMulticaster.add(focusListener, listener);
2399 if (focusListener != null)
2400 enableEvents(AWTEvent.FOCUS_EVENT_MASK);
2404 * Removes the specified listener from the component. This is harmless if
2405 * the listener was not previously registered.
2407 * @param listener the listener to remove
2408 * @see FocusEvent
2409 * @see #addFocusListener(FocusListener)
2410 * @see #getFocusListeners()
2411 * @since 1.1
2413 public synchronized void removeFocusListener(FocusListener listener)
2415 focusListener = AWTEventMulticaster.remove(focusListener, listener);
2419 * Returns an array of all specified listeners registered on this component.
2421 * @return an array of listeners
2422 * @see #addFocusListener(FocusListener)
2423 * @see #removeFocusListener(FocusListener)
2424 * @since 1.4
2426 public synchronized FocusListener[] getFocusListeners()
2428 return (FocusListener[])
2429 AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2433 * Adds the specified listener to this component. This is harmless if the
2434 * listener is null, but if the listener has already been registered, it
2435 * will now be registered twice.
2437 * @param listener the new listener to add
2438 * @see HierarchyEvent
2439 * @see #removeHierarchyListener(HierarchyListener)
2440 * @see #getHierarchyListeners()
2441 * @since 1.3
2443 public synchronized void addHierarchyListener(HierarchyListener listener)
2445 hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
2446 if (hierarchyListener != null)
2447 enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
2451 * Removes the specified listener from the component. This is harmless if
2452 * the listener was not previously registered.
2454 * @param listener the listener to remove
2455 * @see HierarchyEvent
2456 * @see #addHierarchyListener(HierarchyListener)
2457 * @see #getHierarchyListeners()
2458 * @since 1.3
2460 public synchronized void removeHierarchyListener(HierarchyListener listener)
2462 hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
2466 * Returns an array of all specified listeners registered on this component.
2468 * @return an array of listeners
2469 * @see #addHierarchyListener(HierarchyListener)
2470 * @see #removeHierarchyListener(HierarchyListener)
2471 * @since 1.4
2473 public synchronized HierarchyListener[] getHierarchyListeners()
2475 return (HierarchyListener[])
2476 AWTEventMulticaster.getListeners(hierarchyListener,
2477 HierarchyListener.class);
2481 * Adds the specified listener to this component. This is harmless if the
2482 * listener is null, but if the listener has already been registered, it
2483 * will now be registered twice.
2485 * @param listener the new listener to add
2486 * @see HierarchyEvent
2487 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2488 * @see #getHierarchyBoundsListeners()
2489 * @since 1.3
2491 public synchronized void
2492 addHierarchyBoundsListener(HierarchyBoundsListener listener)
2494 hierarchyBoundsListener =
2495 AWTEventMulticaster.add(hierarchyBoundsListener, listener);
2496 if (hierarchyBoundsListener != null)
2497 enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2501 * Removes the specified listener from the component. This is harmless if
2502 * the listener was not previously registered.
2504 * @param listener the listener to remove
2505 * @see HierarchyEvent
2506 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2507 * @see #getHierarchyBoundsListeners()
2508 * @since 1.3
2510 public synchronized void
2511 removeHierarchyBoundsListener(HierarchyBoundsListener listener)
2513 hierarchyBoundsListener =
2514 AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
2518 * Returns an array of all specified listeners registered on this component.
2520 * @return an array of listeners
2521 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2522 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2523 * @since 1.4
2525 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
2527 return (HierarchyBoundsListener[])
2528 AWTEventMulticaster.getListeners(hierarchyBoundsListener,
2529 HierarchyBoundsListener.class);
2533 * Adds the specified listener to this component. This is harmless if the
2534 * listener is null, but if the listener has already been registered, it
2535 * will now be registered twice.
2537 * @param listener the new listener to add
2538 * @see KeyEvent
2539 * @see #removeKeyListener(KeyListener)
2540 * @see #getKeyListeners()
2541 * @since 1.1
2543 public synchronized void addKeyListener(KeyListener listener)
2545 keyListener = AWTEventMulticaster.add(keyListener, listener);
2546 if (keyListener != null)
2547 enableEvents(AWTEvent.KEY_EVENT_MASK);
2551 * Removes the specified listener from the component. This is harmless if
2552 * the listener was not previously registered.
2554 * @param listener the listener to remove
2555 * @see KeyEvent
2556 * @see #addKeyListener(KeyListener)
2557 * @see #getKeyListeners()
2558 * @since 1.1
2560 public synchronized void removeKeyListener(KeyListener listener)
2562 keyListener = AWTEventMulticaster.remove(keyListener, listener);
2566 * Returns an array of all specified listeners registered on this component.
2568 * @return an array of listeners
2569 * @see #addKeyListener(KeyListener)
2570 * @see #removeKeyListener(KeyListener)
2571 * @since 1.4
2573 public synchronized KeyListener[] getKeyListeners()
2575 return (KeyListener[])
2576 AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
2580 * Adds the specified listener to this component. This is harmless if the
2581 * listener is null, but if the listener has already been registered, it
2582 * will now be registered twice.
2584 * @param listener the new listener to add
2585 * @see MouseEvent
2586 * @see #removeMouseListener(MouseListener)
2587 * @see #getMouseListeners()
2588 * @since 1.1
2590 public synchronized void addMouseListener(MouseListener listener)
2592 mouseListener = AWTEventMulticaster.add(mouseListener, listener);
2593 if (mouseListener != null)
2594 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2598 * Removes the specified listener from the component. This is harmless if
2599 * the listener was not previously registered.
2601 * @param listener the listener to remove
2602 * @see MouseEvent
2603 * @see #addMouseListener(MouseListener)
2604 * @see #getMouseListeners()
2605 * @since 1.1
2607 public synchronized void removeMouseListener(MouseListener listener)
2609 mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
2613 * Returns an array of all specified listeners registered on this component.
2615 * @return an array of listeners
2616 * @see #addMouseListener(MouseListener)
2617 * @see #removeMouseListener(MouseListener)
2618 * @since 1.4
2620 public synchronized MouseListener[] getMouseListeners()
2622 return (MouseListener[])
2623 AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
2627 * Adds the specified listener to this component. This is harmless if the
2628 * listener is null, but if the listener has already been registered, it
2629 * will now be registered twice.
2631 * @param listener the new listener to add
2632 * @see MouseEvent
2633 * @see #removeMouseMotionListener(MouseMotionListener)
2634 * @see #getMouseMotionListeners()
2635 * @since 1.1
2637 public synchronized void addMouseMotionListener(MouseMotionListener listener)
2639 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
2640 if (mouseMotionListener != null)
2641 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
2645 * Removes the specified listener from the component. This is harmless if
2646 * the listener was not previously registered.
2648 * @param listener the listener to remove
2649 * @see MouseEvent
2650 * @see #addMouseMotionListener(MouseMotionListener)
2651 * @see #getMouseMotionListeners()
2652 * @since 1.1
2654 public synchronized void removeMouseMotionListener(MouseMotionListener listener)
2656 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
2660 * Returns an array of all specified listeners registered on this component.
2662 * @return an array of listeners
2663 * @see #addMouseMotionListener(MouseMotionListener)
2664 * @see #removeMouseMotionListener(MouseMotionListener)
2665 * @since 1.4
2667 public synchronized MouseMotionListener[] getMouseMotionListeners()
2669 return (MouseMotionListener[])
2670 AWTEventMulticaster.getListeners(mouseMotionListener,
2671 MouseMotionListener.class);
2675 * Adds the specified listener to this component. This is harmless if the
2676 * listener is null, but if the listener has already been registered, it
2677 * will now be registered twice.
2679 * @param listener the new listener to add
2680 * @see MouseEvent
2681 * @see MouseWheelEvent
2682 * @see #removeMouseWheelListener(MouseWheelListener)
2683 * @see #getMouseWheelListeners()
2684 * @since 1.4
2686 public synchronized void addMouseWheelListener(MouseWheelListener listener)
2688 mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
2689 if (mouseWheelListener != null)
2690 enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
2694 * Removes the specified listener from the component. This is harmless if
2695 * the listener was not previously registered.
2697 * @param listener the listener to remove
2698 * @see MouseEvent
2699 * @see MouseWheelEvent
2700 * @see #addMouseWheelListener(MouseWheelListener)
2701 * @see #getMouseWheelListeners()
2702 * @since 1.4
2704 public synchronized void removeMouseWheelListener(MouseWheelListener listener)
2706 mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
2710 * Returns an array of all specified listeners registered on this component.
2712 * @return an array of listeners
2713 * @see #addMouseWheelListener(MouseWheelListener)
2714 * @see #removeMouseWheelListener(MouseWheelListener)
2715 * @since 1.4
2717 public synchronized MouseWheelListener[] getMouseWheelListeners()
2719 return (MouseWheelListener[])
2720 AWTEventMulticaster.getListeners(mouseWheelListener,
2721 MouseWheelListener.class);
2725 * Adds the specified listener to this component. This is harmless if the
2726 * listener is null, but if the listener has already been registered, it
2727 * will now be registered twice.
2729 * @param listener the new listener to add
2730 * @see InputMethodEvent
2731 * @see #removeInputMethodListener(InputMethodListener)
2732 * @see #getInputMethodListeners()
2733 * @see #getInputMethodRequests()
2734 * @since 1.2
2736 public synchronized void addInputMethodListener(InputMethodListener listener)
2738 inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
2739 if (inputMethodListener != null)
2740 enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
2744 * Removes the specified listener from the component. This is harmless if
2745 * the listener was not previously registered.
2747 * @param listener the listener to remove
2748 * @see InputMethodEvent
2749 * @see #addInputMethodListener(InputMethodListener)
2750 * @see #getInputMethodRequests()
2751 * @since 1.2
2753 public synchronized void removeInputMethodListener(InputMethodListener listener)
2755 inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
2759 * Returns an array of all specified listeners registered on this component.
2761 * @return an array of listeners
2762 * @see #addInputMethodListener(InputMethodListener)
2763 * @see #removeInputMethodListener(InputMethodListener)
2764 * @since 1.4
2766 public synchronized InputMethodListener[] getInputMethodListeners()
2768 return (InputMethodListener[])
2769 AWTEventMulticaster.getListeners(inputMethodListener,
2770 InputMethodListener.class);
2774 * Returns all registered {@link EventListener}s of the given
2775 * <code>listenerType</code>.
2777 * @param listenerType the class of listeners to filter (<code>null</code>
2778 * not permitted).
2780 * @return An array of registered listeners.
2782 * @throws ClassCastException if <code>listenerType</code> does not implement
2783 * the {@link EventListener} interface.
2784 * @throws NullPointerException if <code>listenerType</code> is
2785 * <code>null</code>.
2787 * @see #getComponentListeners()
2788 * @see #getFocusListeners()
2789 * @see #getHierarchyListeners()
2790 * @see #getHierarchyBoundsListeners()
2791 * @see #getKeyListeners()
2792 * @see #getMouseListeners()
2793 * @see #getMouseMotionListeners()
2794 * @see #getMouseWheelListeners()
2795 * @see #getInputMethodListeners()
2796 * @see #getPropertyChangeListeners()
2797 * @since 1.3
2799 public EventListener[] getListeners(Class listenerType)
2801 if (listenerType == ComponentListener.class)
2802 return getComponentListeners();
2803 if (listenerType == FocusListener.class)
2804 return getFocusListeners();
2805 if (listenerType == HierarchyListener.class)
2806 return getHierarchyListeners();
2807 if (listenerType == HierarchyBoundsListener.class)
2808 return getHierarchyBoundsListeners();
2809 if (listenerType == KeyListener.class)
2810 return getKeyListeners();
2811 if (listenerType == MouseListener.class)
2812 return getMouseListeners();
2813 if (listenerType == MouseMotionListener.class)
2814 return getMouseMotionListeners();
2815 if (listenerType == MouseWheelListener.class)
2816 return getMouseWheelListeners();
2817 if (listenerType == InputMethodListener.class)
2818 return getInputMethodListeners();
2819 if (listenerType == PropertyChangeListener.class)
2820 return getPropertyChangeListeners();
2821 return (EventListener[]) Array.newInstance(listenerType, 0);
2825 * Returns the input method request handler, for subclasses which support
2826 * on-the-spot text input. By default, input methods are handled by AWT,
2827 * and this returns null.
2829 * @return the input method handler, null by default
2830 * @since 1.2
2832 public InputMethodRequests getInputMethodRequests()
2834 return null;
2838 * Gets the input context of this component, which is inherited from the
2839 * parent unless this is overridden.
2841 * @return the text input context
2842 * @since 1.2
2844 public InputContext getInputContext()
2846 return parent == null ? null : parent.getInputContext();
2850 * Enables the specified events. The events to enable are specified
2851 * by OR-ing together the desired masks from <code>AWTEvent</code>.
2853 * <p>Events are enabled by default when a listener is attached to the
2854 * component for that event type. This method can be used by subclasses
2855 * to ensure the delivery of a specified event regardless of whether
2856 * or not a listener is attached.
2858 * @param eventsToEnable the desired events to enable
2859 * @see #processEvent(AWTEvent)
2860 * @see #disableEvents(long)
2861 * @see AWTEvent
2862 * @since 1.1
2864 protected final void enableEvents(long eventsToEnable)
2866 eventMask |= eventsToEnable;
2867 // TODO: Unlike Sun's implementation, I think we should try and
2868 // enable/disable events at the peer (gtk/X) level. This will avoid
2869 // clogging the event pipeline with useless mousemove events that
2870 // we arn't interested in, etc. This will involve extending the peer
2871 // interface, but thats okay because the peer interfaces have been
2872 // deprecated for a long time, and no longer feature in the
2873 // API specification at all.
2874 if (isLightweight() && parent != null)
2875 parent.enableEvents(eventsToEnable);
2876 else if (peer != null)
2877 peer.setEventMask(eventMask);
2881 * Disables the specified events. The events to disable are specified
2882 * by OR-ing together the desired masks from <code>AWTEvent</code>.
2884 * @param eventsToDisable the desired events to disable
2885 * @see #enableEvents(long)
2886 * @since 1.1
2888 protected final void disableEvents(long eventsToDisable)
2890 eventMask &= ~eventsToDisable;
2891 // forward new event mask to peer?
2895 * This is called by the EventQueue if two events with the same event id
2896 * and owner component are queued. Returns a new combined event, or null if
2897 * no combining is done. The coelesced events are currently mouse moves
2898 * (intermediate ones are discarded) and paint events (a merged paint is
2899 * created in place of the two events).
2901 * @param existingEvent the event on the queue
2902 * @param newEvent the new event that might be entered on the queue
2903 * @return null if both events are kept, or the replacement coelesced event
2905 protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
2907 switch (existingEvent.id)
2909 case MouseEvent.MOUSE_MOVED:
2910 case MouseEvent.MOUSE_DRAGGED:
2911 // Just drop the old (intermediate) event and return the new one.
2912 return newEvent;
2913 case PaintEvent.PAINT:
2914 case PaintEvent.UPDATE:
2915 return coalescePaintEvents((PaintEvent) existingEvent,
2916 (PaintEvent) newEvent);
2917 default:
2918 return null;
2923 * Processes the specified event. In this class, this method simply
2924 * calls one of the more specific event handlers.
2926 * @param e the event to process
2927 * @throws NullPointerException if e is null
2928 * @see #processComponentEvent(ComponentEvent)
2929 * @see #processFocusEvent(FocusEvent)
2930 * @see #processKeyEvent(KeyEvent)
2931 * @see #processMouseEvent(MouseEvent)
2932 * @see #processMouseMotionEvent(MouseEvent)
2933 * @see #processInputMethodEvent(InputMethodEvent)
2934 * @see #processHierarchyEvent(HierarchyEvent)
2935 * @see #processMouseWheelEvent(MouseWheelEvent)
2936 * @since 1.1
2938 protected void processEvent(AWTEvent e)
2940 /* Note: the order of these if statements are
2941 important. Subclasses must be checked first. Eg. MouseEvent
2942 must be checked before ComponentEvent, since a MouseEvent
2943 object is also an instance of a ComponentEvent. */
2945 if (e instanceof FocusEvent)
2946 processFocusEvent((FocusEvent) e);
2947 else if (e instanceof MouseWheelEvent)
2948 processMouseWheelEvent((MouseWheelEvent) e);
2949 else if (e instanceof MouseEvent)
2951 if (e.id == MouseEvent.MOUSE_MOVED
2952 || e.id == MouseEvent.MOUSE_DRAGGED)
2953 processMouseMotionEvent((MouseEvent) e);
2954 else
2955 processMouseEvent((MouseEvent) e);
2957 else if (e instanceof KeyEvent)
2958 processKeyEvent((KeyEvent) e);
2959 else if (e instanceof InputMethodEvent)
2960 processInputMethodEvent((InputMethodEvent) e);
2961 else if (e instanceof ComponentEvent)
2962 processComponentEvent((ComponentEvent) e);
2963 else if (e instanceof HierarchyEvent)
2965 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
2966 processHierarchyEvent((HierarchyEvent) e);
2967 else
2968 processHierarchyBoundsEvent((HierarchyEvent) e);
2973 * Called when a component event is dispatched and component events are
2974 * enabled. This method passes the event along to any listeners
2975 * that are attached.
2977 * @param e the <code>ComponentEvent</code> to process
2978 * @throws NullPointerException if e is null
2979 * @see ComponentListener
2980 * @see #addComponentListener(ComponentListener)
2981 * @see #enableEvents(long)
2982 * @since 1.1
2984 protected void processComponentEvent(ComponentEvent e)
2986 if (componentListener == null)
2987 return;
2988 switch (e.id)
2990 case ComponentEvent.COMPONENT_HIDDEN:
2991 componentListener.componentHidden(e);
2992 break;
2993 case ComponentEvent.COMPONENT_MOVED:
2994 componentListener.componentMoved(e);
2995 break;
2996 case ComponentEvent.COMPONENT_RESIZED:
2997 componentListener.componentResized(e);
2998 break;
2999 case ComponentEvent.COMPONENT_SHOWN:
3000 componentListener.componentShown(e);
3001 break;
3006 * Called when a focus event is dispatched and component events are
3007 * enabled. This method passes the event along to any listeners
3008 * that are attached.
3010 * @param e the <code>FocusEvent</code> to process
3011 * @throws NullPointerException if e is null
3012 * @see FocusListener
3013 * @see #addFocusListener(FocusListener)
3014 * @see #enableEvents(long)
3015 * @since 1.1
3017 protected void processFocusEvent(FocusEvent e)
3019 if (focusListener == null)
3020 return;
3022 switch (e.id)
3024 case FocusEvent.FOCUS_GAINED:
3025 focusListener.focusGained(e);
3026 break;
3027 case FocusEvent.FOCUS_LOST:
3028 focusListener.focusLost(e);
3029 break;
3034 * Called when a key event is dispatched and component events are
3035 * enabled. This method passes the event along to any listeners
3036 * that are attached.
3038 * @param e the <code>KeyEvent</code> to process
3039 * @throws NullPointerException if e is null
3040 * @see KeyListener
3041 * @see #addKeyListener(KeyListener)
3042 * @see #enableEvents(long)
3043 * @since 1.1
3045 protected void processKeyEvent(KeyEvent e)
3047 if (keyListener == null)
3048 return;
3049 switch (e.id)
3051 case KeyEvent.KEY_PRESSED:
3052 keyListener.keyPressed(e);
3053 break;
3054 case KeyEvent.KEY_RELEASED:
3055 keyListener.keyReleased(e);
3056 break;
3057 case KeyEvent.KEY_TYPED:
3058 keyListener.keyTyped(e);
3059 break;
3064 * Called when a regular mouse event is dispatched and component events are
3065 * enabled. This method passes the event along to any listeners
3066 * that are attached.
3068 * @param e the <code>MouseEvent</code> to process
3069 * @throws NullPointerException if e is null
3070 * @see MouseListener
3071 * @see #addMouseListener(MouseListener)
3072 * @see #enableEvents(long)
3073 * @since 1.1
3075 protected void processMouseEvent(MouseEvent e)
3077 if (mouseListener == null)
3078 return;
3079 switch (e.id)
3081 case MouseEvent.MOUSE_CLICKED:
3082 mouseListener.mouseClicked(e);
3083 break;
3084 case MouseEvent.MOUSE_ENTERED:
3085 mouseListener.mouseEntered(e);
3086 break;
3087 case MouseEvent.MOUSE_EXITED:
3088 mouseListener.mouseExited(e);
3089 break;
3090 case MouseEvent.MOUSE_PRESSED:
3091 mouseListener.mousePressed(e);
3092 break;
3093 case MouseEvent.MOUSE_RELEASED:
3094 mouseListener.mouseReleased(e);
3095 break;
3097 e.consume();
3101 * Called when a mouse motion event is dispatched and component events are
3102 * enabled. This method passes the event along to any listeners
3103 * that are attached.
3105 * @param e the <code>MouseMotionEvent</code> to process
3106 * @throws NullPointerException if e is null
3107 * @see MouseMotionListener
3108 * @see #addMouseMotionListener(MouseMotionListener)
3109 * @see #enableEvents(long)
3110 * @since 1.1
3112 protected void processMouseMotionEvent(MouseEvent e)
3114 if (mouseMotionListener == null)
3115 return;
3116 switch (e.id)
3118 case MouseEvent.MOUSE_DRAGGED:
3119 mouseMotionListener.mouseDragged(e);
3120 break;
3121 case MouseEvent.MOUSE_MOVED:
3122 mouseMotionListener.mouseMoved(e);
3123 break;
3125 e.consume();
3129 * Called when a mouse wheel event is dispatched and component events are
3130 * enabled. This method passes the event along to any listeners that are
3131 * attached.
3133 * @param e the <code>MouseWheelEvent</code> to process
3134 * @throws NullPointerException if e is null
3135 * @see MouseWheelListener
3136 * @see #addMouseWheelListener(MouseWheelListener)
3137 * @see #enableEvents(long)
3138 * @since 1.4
3140 protected void processMouseWheelEvent(MouseWheelEvent e)
3142 if (mouseWheelListener != null
3143 && e.id == MouseEvent.MOUSE_WHEEL)
3145 mouseWheelListener.mouseWheelMoved(e);
3146 e.consume();
3151 * Called when an input method event is dispatched and component events are
3152 * enabled. This method passes the event along to any listeners that are
3153 * attached.
3155 * @param e the <code>InputMethodEvent</code> to process
3156 * @throws NullPointerException if e is null
3157 * @see InputMethodListener
3158 * @see #addInputMethodListener(InputMethodListener)
3159 * @see #enableEvents(long)
3160 * @since 1.2
3162 protected void processInputMethodEvent(InputMethodEvent e)
3164 if (inputMethodListener == null)
3165 return;
3166 switch (e.id)
3168 case InputMethodEvent.CARET_POSITION_CHANGED:
3169 inputMethodListener.caretPositionChanged(e);
3170 break;
3171 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3172 inputMethodListener.inputMethodTextChanged(e);
3173 break;
3178 * Called when a hierarchy change event is dispatched and component events
3179 * are enabled. This method passes the event along to any listeners that are
3180 * attached.
3182 * @param e the <code>HierarchyEvent</code> to process
3183 * @throws NullPointerException if e is null
3184 * @see HierarchyListener
3185 * @see #addHierarchyListener(HierarchyListener)
3186 * @see #enableEvents(long)
3187 * @since 1.3
3189 protected void processHierarchyEvent(HierarchyEvent e)
3191 if (hierarchyListener == null)
3192 return;
3193 if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3194 hierarchyListener.hierarchyChanged(e);
3198 * Called when a hierarchy bounds event is dispatched and component events
3199 * are enabled. This method passes the event along to any listeners that are
3200 * attached.
3202 * @param e the <code>HierarchyEvent</code> to process
3203 * @throws NullPointerException if e is null
3204 * @see HierarchyBoundsListener
3205 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3206 * @see #enableEvents(long)
3207 * @since 1.3
3209 protected void processHierarchyBoundsEvent(HierarchyEvent e)
3211 if (hierarchyBoundsListener == null)
3212 return;
3213 switch (e.id)
3215 case HierarchyEvent.ANCESTOR_MOVED:
3216 hierarchyBoundsListener.ancestorMoved(e);
3217 break;
3218 case HierarchyEvent.ANCESTOR_RESIZED:
3219 hierarchyBoundsListener.ancestorResized(e);
3220 break;
3225 * AWT 1.0 event handler.
3227 * This method calls one of the event-specific handler methods. For
3228 * example for key events, either {@link #keyDown(Event,int)}
3229 * or {@link #keyUp(Event,int)} is called. A derived
3230 * component can override one of these event-specific methods if it
3231 * only needs to handle certain event types. Otherwise it can
3232 * override handleEvent itself and handle any event.
3234 * @param evt the event to handle
3235 * @return true if the event was handled, false otherwise
3236 * @deprecated use {@link #processEvent(AWTEvent)} instead
3238 public boolean handleEvent (Event evt)
3240 switch (evt.id)
3242 // Handle key events.
3243 case Event.KEY_ACTION:
3244 case Event.KEY_PRESS:
3245 return keyDown (evt, evt.key);
3246 case Event.KEY_ACTION_RELEASE:
3247 case Event.KEY_RELEASE:
3248 return keyUp (evt, evt.key);
3250 // Handle mouse events.
3251 case Event.MOUSE_DOWN:
3252 return mouseDown (evt, evt.x, evt.y);
3253 case Event.MOUSE_UP:
3254 return mouseUp (evt, evt.x, evt.y);
3255 case Event.MOUSE_MOVE:
3256 return mouseMove (evt, evt.x, evt.y);
3257 case Event.MOUSE_DRAG:
3258 return mouseDrag (evt, evt.x, evt.y);
3259 case Event.MOUSE_ENTER:
3260 return mouseEnter (evt, evt.x, evt.y);
3261 case Event.MOUSE_EXIT:
3262 return mouseExit (evt, evt.x, evt.y);
3264 // Handle focus events.
3265 case Event.GOT_FOCUS:
3266 return gotFocus (evt, evt.arg);
3267 case Event.LOST_FOCUS:
3268 return lostFocus (evt, evt.arg);
3270 // Handle action event.
3271 case Event.ACTION_EVENT:
3272 return action (evt, evt.arg);
3274 // Unknown event.
3275 return false;
3279 * AWT 1.0 MOUSE_DOWN event handler. This method is meant to be
3280 * overridden by components providing their own MOUSE_DOWN handler.
3281 * The default implementation simply returns false.
3283 * @param evt the event to handle
3284 * @param x the x coordinate, ignored
3285 * @param y the y coordinate, ignored
3286 * @return false
3287 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3289 public boolean mouseDown(Event evt, int x, int y)
3291 return false;
3295 * AWT 1.0 MOUSE_DRAG event handler. This method is meant to be
3296 * overridden by components providing their own MOUSE_DRAG handler.
3297 * The default implementation simply returns false.
3299 * @param evt the event to handle
3300 * @param x the x coordinate, ignored
3301 * @param y the y coordinate, ignored
3302 * @return false
3303 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3305 public boolean mouseDrag(Event evt, int x, int y)
3307 return false;
3311 * AWT 1.0 MOUSE_UP event handler. This method is meant to be
3312 * overridden by components providing their own MOUSE_UP handler.
3313 * The default implementation simply returns false.
3315 * @param evt the event to handle
3316 * @param x the x coordinate, ignored
3317 * @param y the y coordinate, ignored
3318 * @return false
3319 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3321 public boolean mouseUp(Event evt, int x, int y)
3323 return false;
3327 * AWT 1.0 MOUSE_MOVE event handler. This method is meant to be
3328 * overridden by components providing their own MOUSE_MOVE handler.
3329 * The default implementation simply returns false.
3331 * @param evt the event to handle
3332 * @param x the x coordinate, ignored
3333 * @param y the y coordinate, ignored
3334 * @return false
3335 * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3337 public boolean mouseMove(Event evt, int x, int y)
3339 return false;
3343 * AWT 1.0 MOUSE_ENTER event handler. This method is meant to be
3344 * overridden by components providing their own MOUSE_ENTER handler.
3345 * The default implementation simply returns false.
3347 * @param evt the event to handle
3348 * @param x the x coordinate, ignored
3349 * @param y the y coordinate, ignored
3350 * @return false
3351 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3353 public boolean mouseEnter(Event evt, int x, int y)
3355 return false;
3359 * AWT 1.0 MOUSE_EXIT event handler. This method is meant to be
3360 * overridden by components providing their own MOUSE_EXIT handler.
3361 * The default implementation simply returns false.
3363 * @param evt the event to handle
3364 * @param x the x coordinate, ignored
3365 * @param y the y coordinate, ignored
3366 * @return false
3367 * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3369 public boolean mouseExit(Event evt, int x, int y)
3371 return false;
3375 * AWT 1.0 KEY_PRESS and KEY_ACTION event handler. This method is
3376 * meant to be overridden by components providing their own key
3377 * press handler. The default implementation simply returns false.
3379 * @param evt the event to handle
3380 * @param key the key pressed, ignored
3381 * @return false
3382 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3384 public boolean keyDown(Event evt, int key)
3386 return false;
3390 * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler. This
3391 * method is meant to be overridden by components providing their
3392 * own key release handler. The default implementation simply
3393 * returns false.
3395 * @param evt the event to handle
3396 * @param key the key pressed, ignored
3397 * @return false
3398 * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3400 public boolean keyUp(Event evt, int key)
3402 return false;
3406 * AWT 1.0 ACTION_EVENT event handler. This method is meant to be
3407 * overridden by components providing their own action event
3408 * handler. The default implementation simply returns false.
3410 * @param evt the event to handle
3411 * @param what the object acted on, ignored
3412 * @return false
3413 * @deprecated in classes which support actions, use
3414 * <code>processActionEvent(ActionEvent)</code> instead
3416 public boolean action(Event evt, Object what)
3418 return false;
3422 * Called to inform this component it has been added to a container.
3423 * A native peer - if any - is created at this time. This method is
3424 * called automatically by the AWT system and should not be called by
3425 * user level code.
3427 * @see #isDisplayable()
3428 * @see #removeNotify()
3430 public void addNotify()
3432 if (peer == null)
3433 peer = getToolkit().createComponent(this);
3434 /* Now that all the children has gotten their peers, we should
3435 have the event mask needed for this component and its
3436 lightweight subcomponents. */
3437 peer.setEventMask(eventMask);
3438 /* We do not invalidate here, but rather leave that job up to
3439 the peer. For efficiency, the peer can choose not to
3440 invalidate if it is happy with the current dimensions,
3441 etc. */
3445 * Called to inform this component is has been removed from its
3446 * container. Its native peer - if any - is destroyed at this time.
3447 * This method is called automatically by the AWT system and should
3448 * not be called by user level code.
3450 * @see #isDisplayable()
3451 * @see #addNotify()
3453 public void removeNotify()
3455 // We null our peer field before disposing of it, such that if we're
3456 // not the event dispatch thread and the dispatch thread is awoken by
3457 // the dispose call, there will be no race checking the peer's null
3458 // status.
3460 ComponentPeer tmp = peer;
3461 peer = null;
3462 if (tmp != null)
3464 tmp.hide();
3465 tmp.dispose();
3470 * AWT 1.0 GOT_FOCUS event handler. This method is meant to be
3471 * overridden by components providing their own GOT_FOCUS handler.
3472 * The default implementation simply returns false.
3474 * @param evt the event to handle
3475 * @param what the Object focused, ignored
3476 * @return false
3477 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3479 public boolean gotFocus(Event evt, Object what)
3481 return false;
3485 * AWT 1.0 LOST_FOCUS event handler. This method is meant to be
3486 * overridden by components providing their own LOST_FOCUS handler.
3487 * The default implementation simply returns false.
3489 * @param evt the event to handle
3490 * @param what the Object focused, ignored
3491 * @return false
3492 * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3494 public boolean lostFocus(Event evt, Object what)
3496 return false;
3500 * Tests whether or not this component is in the group that can be
3501 * traversed using the keyboard traversal mechanism (such as the TAB key).
3503 * @return true if the component is traversed via the TAB key
3504 * @see #setFocusable(boolean)
3505 * @since 1.1
3506 * @deprecated use {@link #isFocusable()} instead
3508 public boolean isFocusTraversable()
3510 return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
3514 * Tests if this component can receive focus.
3516 * @return true if this component can receive focus
3517 * @since 1.4
3519 public boolean isFocusable()
3521 return focusable;
3525 * Specify whether this component can receive focus. This method also
3526 * sets the {@link #isFocusTraversableOverridden} field to 1, which
3527 * appears to be the undocumented way {@link
3528 * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
3529 * respect the {@link #isFocusable()} method of the component.
3531 * @param focusable the new focusable status
3532 * @since 1.4
3534 public void setFocusable(boolean focusable)
3536 firePropertyChange("focusable", this.focusable, focusable);
3537 this.focusable = focusable;
3538 this.isFocusTraversableOverridden = 1;
3542 * Sets the focus traversal keys for one of the three focus
3543 * traversal directions supported by Components:
3544 * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
3545 * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
3546 * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
3547 * default values should match the operating system's native
3548 * choices. To disable a given traversal, use
3549 * <code>Collections.EMPTY_SET</code>. The event dispatcher will
3550 * consume PRESSED, RELEASED, and TYPED events for the specified
3551 * key, although focus can only transfer on PRESSED or RELEASED.
3553 * <p>The defaults are:
3554 * <table>
3555 * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
3556 * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
3557 * <td>Normal forward traversal</td>
3558 * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
3559 * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
3560 * <td>Normal backward traversal</td>
3561 * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
3562 * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
3563 * <td>Go up a traversal cycle</td><td>None</td></tr>
3564 * </table>
3566 * If keystrokes is null, this component's focus traversal key set
3567 * is inherited from one of its ancestors. If none of its ancestors
3568 * has its own set of focus traversal keys, the focus traversal keys
3569 * are set to the defaults retrieved from the current
3570 * KeyboardFocusManager. If not null, the set must contain only
3571 * AWTKeyStrokes that are not already focus keys and are not
3572 * KEY_TYPED events.
3574 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3575 * UP_CYCLE_TRAVERSAL_KEYS
3576 * @param keystrokes a set of keys, or null
3577 * @throws IllegalArgumentException if id or keystrokes is invalid
3578 * @see #getFocusTraversalKeys(int)
3579 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3580 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3581 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3582 * @since 1.4
3584 public void setFocusTraversalKeys(int id, Set keystrokes)
3586 if (keystrokes == null)
3588 Container parent = getParent ();
3590 while (parent != null)
3592 if (parent.areFocusTraversalKeysSet (id))
3594 keystrokes = parent.getFocusTraversalKeys (id);
3595 break;
3597 parent = parent.getParent ();
3600 if (keystrokes == null)
3601 keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
3602 getDefaultFocusTraversalKeys (id);
3605 Set sa;
3606 Set sb;
3607 String name;
3608 switch (id)
3610 case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
3611 sa = getFocusTraversalKeys
3612 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3613 sb = getFocusTraversalKeys
3614 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3615 name = "forwardFocusTraversalKeys";
3616 break;
3617 case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
3618 sa = getFocusTraversalKeys
3619 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3620 sb = getFocusTraversalKeys
3621 (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3622 name = "backwardFocusTraversalKeys";
3623 break;
3624 case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
3625 sa = getFocusTraversalKeys
3626 (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3627 sb = getFocusTraversalKeys
3628 (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3629 name = "upCycleFocusTraversalKeys";
3630 break;
3631 default:
3632 throw new IllegalArgumentException ();
3635 int i = keystrokes.size ();
3636 Iterator iter = keystrokes.iterator ();
3638 while (--i >= 0)
3640 Object o = iter.next ();
3641 if (!(o instanceof AWTKeyStroke)
3642 || sa.contains (o) || sb.contains (o)
3643 || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
3644 throw new IllegalArgumentException ();
3647 if (focusTraversalKeys == null)
3648 focusTraversalKeys = new Set[3];
3650 keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
3651 firePropertyChange (name, focusTraversalKeys[id], keystrokes);
3653 focusTraversalKeys[id] = keystrokes;
3657 * Returns the set of keys for a given focus traversal action, as
3658 * defined in <code>setFocusTraversalKeys</code>. If not set, this
3659 * is inherited from the parent component, which may have gotten it
3660 * from the KeyboardFocusManager.
3662 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3663 * or UP_CYCLE_TRAVERSAL_KEYS
3665 * @return set of traversal keys
3667 * @throws IllegalArgumentException if id is invalid
3669 * @see #setFocusTraversalKeys (int, Set)
3670 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3671 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3672 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3674 * @since 1.4
3676 public Set getFocusTraversalKeys (int id)
3678 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3679 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3680 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3681 throw new IllegalArgumentException();
3683 Set s = null;
3685 if (focusTraversalKeys != null)
3686 s = focusTraversalKeys[id];
3688 if (s == null && parent != null)
3689 s = parent.getFocusTraversalKeys (id);
3691 return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
3692 .getDefaultFocusTraversalKeys(id)) : s;
3696 * Tests whether the focus traversal keys for a given action are explicitly
3697 * set or inherited.
3699 * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
3700 * or UP_CYCLE_TRAVERSAL_KEYS
3701 * @return true if that set is explicitly specified
3702 * @throws IllegalArgumentException if id is invalid
3703 * @see #getFocusTraversalKeys (int)
3704 * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3705 * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3706 * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3707 * @since 1.4
3709 public boolean areFocusTraversalKeysSet (int id)
3711 if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
3712 id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
3713 id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3714 throw new IllegalArgumentException ();
3716 return focusTraversalKeys != null && focusTraversalKeys[id] != null;
3720 * Enable or disable focus traversal keys on this Component. If
3721 * they are, then the keyboard focus manager consumes and acts on
3722 * key press and release events that trigger focus traversal, and
3723 * discards the corresponding key typed events. If focus traversal
3724 * keys are disabled, then all key events that would otherwise
3725 * trigger focus traversal are sent to this Component.
3727 * @param focusTraversalKeysEnabled the new value of the flag
3728 * @see #getFocusTraversalKeysEnabled ()
3729 * @see #setFocusTraversalKeys (int, Set)
3730 * @see #getFocusTraversalKeys (int)
3731 * @since 1.4
3733 public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
3735 firePropertyChange ("focusTraversalKeysEnabled",
3736 this.focusTraversalKeysEnabled,
3737 focusTraversalKeysEnabled);
3738 this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
3742 * Check whether or not focus traversal keys are enabled on this
3743 * Component. If they are, then the keyboard focus manager consumes
3744 * and acts on key press and release events that trigger focus
3745 * traversal, and discards the corresponding key typed events. If
3746 * focus traversal keys are disabled, then all key events that would
3747 * otherwise trigger focus traversal are sent to this Component.
3749 * @return true if focus traversal keys are enabled
3750 * @see #setFocusTraversalKeysEnabled (boolean)
3751 * @see #setFocusTraversalKeys (int, Set)
3752 * @see #getFocusTraversalKeys (int)
3753 * @since 1.4
3755 public boolean getFocusTraversalKeysEnabled ()
3757 return focusTraversalKeysEnabled;
3761 * Request that this Component be given the keyboard input focus and
3762 * that its top-level ancestor become the focused Window.
3764 * For the request to be granted, the Component must be focusable,
3765 * displayable and showing and the top-level Window to which it
3766 * belongs must be focusable. If the request is initially denied on
3767 * the basis that the top-level Window is not focusable, the request
3768 * will be remembered and granted when the Window does become
3769 * focused.
3771 * Never assume that this Component is the focus owner until it
3772 * receives a FOCUS_GAINED event.
3774 * The behaviour of this method is platform-dependent.
3775 * {@link #requestFocusInWindow()} should be used instead.
3777 * @see #requestFocusInWindow ()
3778 * @see FocusEvent
3779 * @see #addFocusListener (FocusListener)
3780 * @see #isFocusable ()
3781 * @see #isDisplayable ()
3782 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3784 public void requestFocus ()
3786 if (isDisplayable ()
3787 && isShowing ()
3788 && isFocusable ())
3790 synchronized (getTreeLock ())
3792 // Find this Component's top-level ancestor.
3793 Container parent = (this instanceof Container) ? (Container) this
3794 : getParent();
3795 while (parent != null
3796 && !(parent instanceof Window))
3797 parent = parent.getParent ();
3799 if (parent == null)
3800 return;
3802 Window toplevel = (Window) parent;
3803 if (toplevel.isFocusableWindow ())
3805 if (peer != null && !isLightweight())
3806 // This call will cause a FOCUS_GAINED event to be
3807 // posted to the system event queue if the native
3808 // windowing system grants the focus request.
3809 peer.requestFocus ();
3810 else
3812 // Either our peer hasn't been created yet or we're a
3813 // lightweight component. In either case we want to
3814 // post a FOCUS_GAINED event.
3815 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3816 synchronized (eq)
3818 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3819 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3820 if (currentFocusOwner != null)
3822 eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
3823 false, this));
3824 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
3825 currentFocusOwner));
3827 else
3828 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
3832 else
3833 pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
3839 * Request that this Component be given the keyboard input focus and
3840 * that its top-level ancestor become the focused Window.
3842 * For the request to be granted, the Component must be focusable,
3843 * displayable and showing and the top-level Window to which it
3844 * belongs must be focusable. If the request is initially denied on
3845 * the basis that the top-level Window is not focusable, the request
3846 * will be remembered and granted when the Window does become
3847 * focused.
3849 * Never assume that this Component is the focus owner until it
3850 * receives a FOCUS_GAINED event.
3852 * The behaviour of this method is platform-dependent.
3853 * {@link #requestFocusInWindow()} should be used instead.
3855 * If the return value is false, the request is guaranteed to fail.
3856 * If the return value is true, the request will succeed unless it
3857 * is vetoed or something in the native windowing system intervenes,
3858 * preventing this Component's top-level ancestor from becoming
3859 * focused. This method is meant to be called by derived
3860 * lightweight Components that want to avoid unnecessary repainting
3861 * when they know a given focus transfer need only be temporary.
3863 * @param temporary true if the focus request is temporary
3864 * @return true if the request has a chance of success
3865 * @see #requestFocusInWindow ()
3866 * @see FocusEvent
3867 * @see #addFocusListener (FocusListener)
3868 * @see #isFocusable ()
3869 * @see #isDisplayable ()
3870 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3871 * @since 1.4
3873 protected boolean requestFocus (boolean temporary)
3875 if (isDisplayable ()
3876 && isShowing ()
3877 && isFocusable ())
3879 synchronized (getTreeLock ())
3881 // Find this Component's top-level ancestor.
3882 Container parent = getParent ();
3884 while (parent != null
3885 && !(parent instanceof Window))
3886 parent = parent.getParent ();
3888 Window toplevel = (Window) parent;
3889 if (toplevel.isFocusableWindow ())
3891 if (peer != null && !isLightweight())
3892 // This call will cause a FOCUS_GAINED event to be
3893 // posted to the system event queue if the native
3894 // windowing system grants the focus request.
3895 peer.requestFocus ();
3896 else
3898 // Either our peer hasn't been created yet or we're a
3899 // lightweight component. In either case we want to
3900 // post a FOCUS_GAINED event.
3901 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
3902 synchronized (eq)
3904 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3905 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
3906 if (currentFocusOwner != null)
3908 eq.postEvent (new FocusEvent(currentFocusOwner,
3909 FocusEvent.FOCUS_LOST,
3910 temporary, this));
3911 eq.postEvent (new FocusEvent(this,
3912 FocusEvent.FOCUS_GAINED,
3913 temporary,
3914 currentFocusOwner));
3916 else
3917 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
3921 else
3922 // FIXME: need to add a focus listener to our top-level
3923 // ancestor, so that we can post this event when it becomes
3924 // the focused window.
3925 pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
3928 // Always return true.
3929 return true;
3933 * Request that this component be given the keyboard input focus, if
3934 * its top-level ancestor is the currently focused Window. A
3935 * <code>FOCUS_GAINED</code> event will be fired if and only if this
3936 * request is successful. To be successful, the component must be
3937 * displayable, showing, and focusable, and its ancestor top-level
3938 * Window must be focused.
3940 * If the return value is false, the request is guaranteed to fail.
3941 * If the return value is true, the request will succeed unless it
3942 * is vetoed or something in the native windowing system intervenes,
3943 * preventing this Component's top-level ancestor from becoming
3944 * focused.
3946 * @return true if the request has a chance of success
3947 * @see #requestFocus ()
3948 * @see FocusEvent
3949 * @see #addFocusListener (FocusListener)
3950 * @see #isFocusable ()
3951 * @see #isDisplayable ()
3952 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3953 * @since 1.4
3955 public boolean requestFocusInWindow ()
3957 return requestFocusInWindow (false);
3961 * Request that this component be given the keyboard input focus, if
3962 * its top-level ancestor is the currently focused Window. A
3963 * <code>FOCUS_GAINED</code> event will be fired if and only if this
3964 * request is successful. To be successful, the component must be
3965 * displayable, showing, and focusable, and its ancestor top-level
3966 * Window must be focused.
3968 * If the return value is false, the request is guaranteed to fail.
3969 * If the return value is true, the request will succeed unless it
3970 * is vetoed or something in the native windowing system intervenes,
3971 * preventing this Component's top-level ancestor from becoming
3972 * focused. This method is meant to be called by derived
3973 * lightweight Components that want to avoid unnecessary repainting
3974 * when they know a given focus transfer need only be temporary.
3976 * @param temporary true if the focus request is temporary
3977 * @return true if the request has a chance of success
3978 * @see #requestFocus ()
3979 * @see FocusEvent
3980 * @see #addFocusListener (FocusListener)
3981 * @see #isFocusable ()
3982 * @see #isDisplayable ()
3983 * @see KeyboardFocusManager#clearGlobalFocusOwner ()
3984 * @since 1.4
3986 protected boolean requestFocusInWindow (boolean temporary)
3988 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
3990 Window focusedWindow = manager.getFocusedWindow ();
3992 if (isDisplayable ()
3993 && isShowing ()
3994 && isFocusable ())
3996 if (focusedWindow != null)
3998 synchronized (getTreeLock ())
4000 Container parent = getParent ();
4002 while (parent != null
4003 && !(parent instanceof Window))
4004 parent = parent.getParent ();
4006 Window toplevel = (Window) parent;
4008 // Check if top-level ancestor is currently focused window.
4009 if (focusedWindow == toplevel)
4011 if (peer != null
4012 && !isLightweight()
4013 && !(this instanceof Window))
4014 // This call will cause a FOCUS_GAINED event to be
4015 // posted to the system event queue if the native
4016 // windowing system grants the focus request.
4017 peer.requestFocus ();
4018 else
4020 // Either our peer hasn't been created yet or we're a
4021 // lightweight component. In either case we want to
4022 // post a FOCUS_GAINED event.
4023 EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
4024 synchronized (eq)
4026 Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
4027 if (currentFocusOwner != null)
4029 eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
4030 temporary, this));
4031 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
4032 currentFocusOwner));
4034 else
4035 eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
4039 else
4040 return false;
4044 return true;
4046 return false;
4050 * Transfers focus to the next component in the focus traversal
4051 * order, as though this were the current focus owner.
4053 * @see #requestFocus()
4054 * @since 1.1
4056 public void transferFocus ()
4058 nextFocus ();
4062 * Returns the root container that owns the focus cycle where this
4063 * component resides. A focus cycle root is in two cycles, one as
4064 * the ancestor, and one as the focusable element; this call always
4065 * returns the ancestor.
4067 * @return the ancestor container that owns the focus cycle
4068 * @since 1.4
4070 public Container getFocusCycleRootAncestor ()
4072 if (this instanceof Window
4073 && ((Container) this).isFocusCycleRoot ())
4074 return (Container) this;
4076 Container parent = getParent ();
4078 while (parent != null
4079 && !parent.isFocusCycleRoot ())
4080 parent = parent.getParent ();
4082 return parent;
4086 * Tests if the container is the ancestor of the focus cycle that
4087 * this component belongs to.
4089 * @param c the container to test
4090 * @return true if c is the focus cycle root
4091 * @since 1.4
4093 public boolean isFocusCycleRoot (Container c)
4095 return c == getFocusCycleRootAncestor ();
4099 * AWT 1.0 focus event processor. Transfers focus to the next
4100 * component in the focus traversal order, as though this were the
4101 * current focus owner.
4103 * @deprecated use {@link #transferFocus ()} instead
4105 public void nextFocus ()
4107 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4109 manager.focusNextComponent (this);
4113 * Transfers focus to the previous component in the focus traversal
4114 * order, as though this were the current focus owner.
4116 * @see #requestFocus ()
4117 * @since 1.4
4119 public void transferFocusBackward ()
4121 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4123 manager.focusPreviousComponent (this);
4127 * Transfers focus to the focus cycle root of this component.
4128 * However, if this is a Window, the default focus owner in the
4129 * window in the current focus cycle is focused instead.
4131 * @see #requestFocus()
4132 * @see #isFocusCycleRoot(Container)
4133 * @since 1.4
4135 public void transferFocusUpCycle ()
4137 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4139 manager.upFocusCycle (this);
4143 * Tests if this component is the focus owner. Use {@link
4144 * #isFocusOwner ()} instead.
4146 * @return true if this component owns focus
4147 * @since 1.2
4149 public boolean hasFocus ()
4151 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4153 Component focusOwner = manager.getFocusOwner ();
4155 return this == focusOwner;
4159 * Tests if this component is the focus owner.
4161 * @return true if this component owns focus
4162 * @since 1.4
4164 public boolean isFocusOwner()
4166 return hasFocus ();
4170 * Adds the specified popup menu to this component.
4172 * @param popup the popup menu to be added
4174 * @see #remove(MenuComponent)
4176 * @since 1.1
4178 public synchronized void add(PopupMenu popup)
4180 if (popups == null)
4181 popups = new Vector();
4182 popups.add(popup);
4184 if (popup.parent != null)
4185 popup.parent.remove(popup);
4186 popup.parent = this;
4187 if (peer != null)
4188 popup.addNotify();
4192 * Removes the specified popup menu from this component.
4194 * @param popup the popup menu to remove
4195 * @see #add(PopupMenu)
4196 * @since 1.1
4198 public synchronized void remove(MenuComponent popup)
4200 if (popups != null)
4201 popups.remove(popup);
4205 * Returns a debugging string representing this component. The string may
4206 * be empty but not null.
4208 * @return a string representing this component
4210 protected String paramString()
4212 StringBuffer param = new StringBuffer();
4213 String name = getName();
4214 if (name != null)
4215 param.append(name).append(",");
4216 param.append(x).append(",").append(y).append(",").append(width)
4217 .append("x").append(height);
4218 if (! isValid())
4219 param.append(",invalid");
4220 if (! isVisible())
4221 param.append(",invisible");
4222 if (! isEnabled())
4223 param.append(",disabled");
4224 if (! isOpaque())
4225 param.append(",translucent");
4226 if (isDoubleBuffered())
4227 param.append(",doublebuffered");
4228 if (parent == null)
4229 param.append(",parent=null");
4230 else
4231 param.append(",parent=").append(parent.getName());
4232 return param.toString();
4236 * Returns a string representation of this component. This is implemented
4237 * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
4239 * @return a string representation of this component
4241 public String toString()
4243 return getClass().getName() + '[' + paramString() + ']';
4247 * Prints a listing of this component to <code>System.out</code>.
4249 * @see #list(PrintStream)
4251 public void list()
4253 list(System.out, 0);
4257 * Prints a listing of this component to the specified print stream.
4259 * @param out the <code>PrintStream</code> to print to
4261 public void list(PrintStream out)
4263 list(out, 0);
4267 * Prints a listing of this component to the specified print stream,
4268 * starting at the specified indentation point.
4270 * @param out the <code>PrintStream</code> to print to
4271 * @param indent the indentation point
4273 public void list(PrintStream out, int indent)
4275 for (int i = 0; i < indent; ++i)
4276 out.print(' ');
4277 out.println(toString());
4281 * Prints a listing of this component to the specified print writer.
4283 * @param out the <code>PrintWrinter</code> to print to
4284 * @since 1.1
4286 public void list(PrintWriter out)
4288 list(out, 0);
4292 * Prints a listing of this component to the specified print writer,
4293 * starting at the specified indentation point.
4295 * @param out the <code>PrintWriter</code> to print to
4296 * @param indent the indentation point
4297 * @since 1.1
4299 public void list(PrintWriter out, int indent)
4301 for (int i = 0; i < indent; ++i)
4302 out.print(' ');
4303 out.println(toString());
4307 * Adds the specified property listener to this component. This is harmless
4308 * if the listener is null, but if the listener has already been registered,
4309 * it will now be registered twice. The property listener ignores inherited
4310 * properties. Recognized properties include:<br>
4311 * <ul>
4312 * <li>the font (<code>"font"</code>)</li>
4313 * <li>the background color (<code>"background"</code>)</li>
4314 * <li>the foreground color (<code>"foreground"</code>)</li>
4315 * <li>the focusability (<code>"focusable"</code>)</li>
4316 * <li>the focus key traversal enabled state
4317 * (<code>"focusTraversalKeysEnabled"</code>)</li>
4318 * <li>the set of forward traversal keys
4319 * (<code>"forwardFocusTraversalKeys"</code>)</li>
4320 * <li>the set of backward traversal keys
4321 * (<code>"backwardFocusTraversalKeys"</code>)</li>
4322 * <li>the set of up-cycle traversal keys
4323 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
4324 * </ul>
4326 * @param listener the new listener to add
4327 * @see #removePropertyChangeListener(PropertyChangeListener)
4328 * @see #getPropertyChangeListeners()
4329 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4330 * @since 1.1
4332 public void addPropertyChangeListener(PropertyChangeListener listener)
4334 if (changeSupport == null)
4335 changeSupport = new PropertyChangeSupport(this);
4336 changeSupport.addPropertyChangeListener(listener);
4340 * Removes the specified property listener from the component. This is
4341 * harmless if the listener was not previously registered.
4343 * @param listener the listener to remove
4344 * @see #addPropertyChangeListener(PropertyChangeListener)
4345 * @see #getPropertyChangeListeners()
4346 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4347 * @since 1.1
4349 public void removePropertyChangeListener(PropertyChangeListener listener)
4351 if (changeSupport != null)
4352 changeSupport.removePropertyChangeListener(listener);
4356 * Returns an array of all specified listeners registered on this component.
4358 * @return an array of listeners
4359 * @see #addPropertyChangeListener(PropertyChangeListener)
4360 * @see #removePropertyChangeListener(PropertyChangeListener)
4361 * @see #getPropertyChangeListeners(String)
4362 * @since 1.4
4364 public PropertyChangeListener[] getPropertyChangeListeners()
4366 return changeSupport == null ? new PropertyChangeListener[0]
4367 : changeSupport.getPropertyChangeListeners();
4371 * Adds the specified property listener to this component. This is harmless
4372 * if the listener is null, but if the listener has already been registered,
4373 * it will now be registered twice. The property listener ignores inherited
4374 * properties. The listener is keyed to a single property. Recognized
4375 * properties include:<br>
4376 * <ul>
4377 * <li>the font (<code>"font"</code>)</li>
4378 * <li>the background color (<code>"background"</code>)</li>
4379 * <li>the foreground color (<code>"foreground"</code>)</li>
4380 * <li>the focusability (<code>"focusable"</code>)</li>
4381 * <li>the focus key traversal enabled state
4382 * (<code>"focusTraversalKeysEnabled"</code>)</li>
4383 * <li>the set of forward traversal keys
4384 * (<code>"forwardFocusTraversalKeys"</code>)</li>
4385 p * <li>the set of backward traversal keys
4386 * (<code>"backwardFocusTraversalKeys"</code>)</li>
4387 * <li>the set of up-cycle traversal keys
4388 * (<code>"upCycleFocusTraversalKeys"</code>)</li>
4389 * </ul>
4391 * @param propertyName the property name to filter on
4392 * @param listener the new listener to add
4393 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4394 * @see #getPropertyChangeListeners(String)
4395 * @see #addPropertyChangeListener(PropertyChangeListener)
4396 * @since 1.1
4398 public void addPropertyChangeListener(String propertyName,
4399 PropertyChangeListener listener)
4401 if (changeSupport == null)
4402 changeSupport = new PropertyChangeSupport(this);
4403 changeSupport.addPropertyChangeListener(propertyName, listener);
4407 * Removes the specified property listener on a particular property from
4408 * the component. This is harmless if the listener was not previously
4409 * registered.
4411 * @param propertyName the property name to filter on
4412 * @param listener the listener to remove
4413 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4414 * @see #getPropertyChangeListeners(String)
4415 * @see #removePropertyChangeListener(PropertyChangeListener)
4416 * @since 1.1
4418 public void removePropertyChangeListener(String propertyName,
4419 PropertyChangeListener listener)
4421 if (changeSupport != null)
4422 changeSupport.removePropertyChangeListener(propertyName, listener);
4426 * Returns an array of all specified listeners on the named property that
4427 * are registered on this component.
4429 * @return an array of listeners
4430 * @see #addPropertyChangeListener(String, PropertyChangeListener)
4431 * @see #removePropertyChangeListener(String, PropertyChangeListener)
4432 * @see #getPropertyChangeListeners()
4433 * @since 1.4
4435 public PropertyChangeListener[] getPropertyChangeListeners(String property)
4437 return changeSupport == null ? new PropertyChangeListener[0]
4438 : changeSupport.getPropertyChangeListeners(property);
4442 * Report a change in a bound property to any registered property listeners.
4444 * @param propertyName the property that changed
4445 * @param oldValue the old property value
4446 * @param newValue the new property value
4448 protected void firePropertyChange(String propertyName, Object oldValue,
4449 Object newValue)
4451 if (changeSupport != null)
4452 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4456 * Report a change in a bound property to any registered property listeners.
4458 * @param propertyName the property that changed
4459 * @param oldValue the old property value
4460 * @param newValue the new property value
4462 protected void firePropertyChange(String propertyName, boolean oldValue,
4463 boolean newValue)
4465 if (changeSupport != null)
4466 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4470 * Report a change in a bound property to any registered property listeners.
4472 * @param propertyName the property that changed
4473 * @param oldValue the old property value
4474 * @param newValue the new property value
4476 protected void firePropertyChange(String propertyName, int oldValue,
4477 int newValue)
4479 if (changeSupport != null)
4480 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4484 * Sets the text layout orientation of this component. New components default
4485 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
4486 * the current component, while
4487 * {@link #applyComponentOrientation(ComponentOrientation)} affects the
4488 * entire hierarchy.
4490 * @param o the new orientation
4491 * @throws NullPointerException if o is null
4492 * @see #getComponentOrientation()
4494 public void setComponentOrientation(ComponentOrientation o)
4496 if (o == null)
4497 throw new NullPointerException();
4498 ComponentOrientation oldOrientation = orientation;
4499 orientation = o;
4500 firePropertyChange("componentOrientation", oldOrientation, o);
4504 * Determines the text layout orientation used by this component.
4506 * @return the component orientation
4507 * @see #setComponentOrientation(ComponentOrientation)
4509 public ComponentOrientation getComponentOrientation()
4511 return orientation;
4515 * Sets the text layout orientation of this component. New components default
4516 * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
4517 * entire hierarchy, while
4518 * {@link #setComponentOrientation(ComponentOrientation)} affects only the
4519 * current component.
4521 * @param o the new orientation
4522 * @throws NullPointerException if o is null
4523 * @see #getComponentOrientation()
4524 * @since 1.4
4526 public void applyComponentOrientation(ComponentOrientation o)
4528 setComponentOrientation(o);
4532 * Returns the accessibility framework context of this class. Component is
4533 * not accessible, so the default implementation returns null. Subclasses
4534 * must override this behavior, and return an appropriate subclass of
4535 * {@link AccessibleAWTComponent}.
4537 * @return the accessibility context
4539 public AccessibleContext getAccessibleContext()
4541 return null;
4545 // Helper methods; some are package visible for use by subclasses.
4548 * Subclasses should override this to return unique component names like
4549 * "menuitem0".
4551 * @return the generated name for this component
4553 String generateName()
4555 // Component is abstract.
4556 return null;
4560 * Sets the peer for this component.
4562 * @param peer the new peer
4564 final void setPeer(ComponentPeer peer)
4566 this.peer = peer;
4570 * Implementation method that allows classes such as Canvas and Window to
4571 * override the graphics configuration without violating the published API.
4573 * @return the graphics configuration
4575 GraphicsConfiguration getGraphicsConfigurationImpl()
4577 if (peer != null)
4579 GraphicsConfiguration config = peer.getGraphicsConfiguration();
4580 if (config != null)
4581 return config;
4584 if (parent != null)
4585 return parent.getGraphicsConfiguration();
4587 return null;
4591 * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
4592 * event ({@link Event}).
4594 * @param e an AWT 1.1 event to translate
4596 * @return an AWT 1.0 event representing e
4598 static Event translateEvent (AWTEvent e)
4600 Component target = (Component) e.getSource ();
4601 Event translated = null;
4603 if (e instanceof InputEvent)
4605 InputEvent ie = (InputEvent) e;
4606 long when = ie.getWhen ();
4608 int oldID = 0;
4609 int id = e.getID ();
4611 int oldMods = 0;
4612 int mods = ie.getModifiersEx ();
4614 if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
4615 oldMods |= Event.META_MASK;
4616 else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
4617 oldMods |= Event.ALT_MASK;
4619 if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
4620 oldMods |= Event.SHIFT_MASK;
4622 if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
4623 oldMods |= Event.CTRL_MASK;
4625 if ((mods & InputEvent.META_DOWN_MASK) != 0)
4626 oldMods |= Event.META_MASK;
4628 if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
4629 oldMods |= Event.ALT_MASK;
4631 if (e instanceof MouseEvent)
4633 if (id == MouseEvent.MOUSE_PRESSED)
4634 oldID = Event.MOUSE_DOWN;
4635 else if (id == MouseEvent.MOUSE_RELEASED)
4636 oldID = Event.MOUSE_UP;
4637 else if (id == MouseEvent.MOUSE_MOVED)
4638 oldID = Event.MOUSE_MOVE;
4639 else if (id == MouseEvent.MOUSE_DRAGGED)
4640 oldID = Event.MOUSE_DRAG;
4641 else if (id == MouseEvent.MOUSE_ENTERED)
4642 oldID = Event.MOUSE_ENTER;
4643 else if (id == MouseEvent.MOUSE_EXITED)
4644 oldID = Event.MOUSE_EXIT;
4645 else
4646 // No analogous AWT 1.0 mouse event.
4647 return null;
4649 MouseEvent me = (MouseEvent) e;
4651 translated = new Event (target, when, oldID,
4652 me.getX (), me.getY (), 0, oldMods);
4654 else if (e instanceof KeyEvent)
4656 if (id == KeyEvent.KEY_PRESSED)
4657 oldID = Event.KEY_PRESS;
4658 else if (e.getID () == KeyEvent.KEY_RELEASED)
4659 oldID = Event.KEY_RELEASE;
4660 else
4661 // No analogous AWT 1.0 key event.
4662 return null;
4664 int oldKey = 0;
4665 int newKey = ((KeyEvent) e).getKeyCode ();
4666 switch (newKey)
4668 case KeyEvent.VK_BACK_SPACE:
4669 oldKey = Event.BACK_SPACE;
4670 break;
4671 case KeyEvent.VK_CAPS_LOCK:
4672 oldKey = Event.CAPS_LOCK;
4673 break;
4674 case KeyEvent.VK_DELETE:
4675 oldKey = Event.DELETE;
4676 break;
4677 case KeyEvent.VK_DOWN:
4678 case KeyEvent.VK_KP_DOWN:
4679 oldKey = Event.DOWN;
4680 break;
4681 case KeyEvent.VK_END:
4682 oldKey = Event.END;
4683 break;
4684 case KeyEvent.VK_ENTER:
4685 oldKey = Event.ENTER;
4686 break;
4687 case KeyEvent.VK_ESCAPE:
4688 oldKey = Event.ESCAPE;
4689 break;
4690 case KeyEvent.VK_F1:
4691 oldKey = Event.F1;
4692 break;
4693 case KeyEvent.VK_F10:
4694 oldKey = Event.F10;
4695 break;
4696 case KeyEvent.VK_F11:
4697 oldKey = Event.F11;
4698 break;
4699 case KeyEvent.VK_F12:
4700 oldKey = Event.F12;
4701 break;
4702 case KeyEvent.VK_F2:
4703 oldKey = Event.F2;
4704 break;
4705 case KeyEvent.VK_F3:
4706 oldKey = Event.F3;
4707 break;
4708 case KeyEvent.VK_F4:
4709 oldKey = Event.F4;
4710 break;
4711 case KeyEvent.VK_F5:
4712 oldKey = Event.F5;
4713 break;
4714 case KeyEvent.VK_F6:
4715 oldKey = Event.F6;
4716 break;
4717 case KeyEvent.VK_F7:
4718 oldKey = Event.F7;
4719 break;
4720 case KeyEvent.VK_F8:
4721 oldKey = Event.F8;
4722 break;
4723 case KeyEvent.VK_F9:
4724 oldKey = Event.F9;
4725 break;
4726 case KeyEvent.VK_HOME:
4727 oldKey = Event.HOME;
4728 break;
4729 case KeyEvent.VK_INSERT:
4730 oldKey = Event.INSERT;
4731 break;
4732 case KeyEvent.VK_LEFT:
4733 case KeyEvent.VK_KP_LEFT:
4734 oldKey = Event.LEFT;
4735 break;
4736 case KeyEvent.VK_NUM_LOCK:
4737 oldKey = Event.NUM_LOCK;
4738 break;
4739 case KeyEvent.VK_PAUSE:
4740 oldKey = Event.PAUSE;
4741 break;
4742 case KeyEvent.VK_PAGE_DOWN:
4743 oldKey = Event.PGDN;
4744 break;
4745 case KeyEvent.VK_PAGE_UP:
4746 oldKey = Event.PGUP;
4747 break;
4748 case KeyEvent.VK_PRINTSCREEN:
4749 oldKey = Event.PRINT_SCREEN;
4750 break;
4751 case KeyEvent.VK_RIGHT:
4752 case KeyEvent.VK_KP_RIGHT:
4753 oldKey = Event.RIGHT;
4754 break;
4755 case KeyEvent.VK_SCROLL_LOCK:
4756 oldKey = Event.SCROLL_LOCK;
4757 break;
4758 case KeyEvent.VK_TAB:
4759 oldKey = Event.TAB;
4760 break;
4761 case KeyEvent.VK_UP:
4762 case KeyEvent.VK_KP_UP:
4763 oldKey = Event.UP;
4764 break;
4765 default:
4766 oldKey = newKey;
4769 translated = new Event (target, when, oldID,
4770 0, 0, oldKey, oldMods);
4773 else if (e instanceof ActionEvent)
4774 translated = new Event (target, Event.ACTION_EVENT,
4775 ((ActionEvent) e).getActionCommand ());
4777 return translated;
4781 * Implementation of dispatchEvent. Allows trusted package classes
4782 * to dispatch additional events first. This implementation first
4783 * translates <code>e</code> to an AWT 1.0 event and sends the
4784 * result to {@link #postEvent}. If the AWT 1.0 event is not
4785 * handled, and events of type <code>e</code> are enabled for this
4786 * component, e is passed on to {@link #processEvent}.
4788 * @param e the event to dispatch
4791 void dispatchEventImpl(AWTEvent e)
4793 Event oldEvent = translateEvent (e);
4794 // This boolean tells us not to process focus events when the focus
4795 // opposite component is the same as the focus component.
4796 boolean ignoreFocus =
4797 (e instanceof FocusEvent &&
4798 ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
4800 if (oldEvent != null)
4801 postEvent (oldEvent);
4803 if (eventTypeEnabled (e.id))
4805 // the trick we use to communicate between dispatch and redispatch
4806 // is to have KeyboardFocusManager.redispatch synchronize on the
4807 // object itself. we then do not redispatch to KeyboardFocusManager
4808 // if we are already holding the lock.
4809 if (! Thread.holdsLock(e))
4811 switch (e.id)
4813 case WindowEvent.WINDOW_GAINED_FOCUS:
4814 case WindowEvent.WINDOW_LOST_FOCUS:
4815 case KeyEvent.KEY_PRESSED:
4816 case KeyEvent.KEY_RELEASED:
4817 case KeyEvent.KEY_TYPED:
4818 case FocusEvent.FOCUS_GAINED:
4819 case FocusEvent.FOCUS_LOST:
4820 if (KeyboardFocusManager
4821 .getCurrentKeyboardFocusManager()
4822 .dispatchEvent(e))
4823 return;
4824 case MouseEvent.MOUSE_PRESSED:
4825 if (isLightweight())
4826 requestFocus();
4827 break;
4830 if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE
4831 && !ignoreFocus)
4832 processEvent(e);
4835 if (peer != null)
4836 peer.handleEvent(e);
4840 * Tells whether or not an event type is enabled.
4842 boolean eventTypeEnabled (int type)
4844 if (type > AWTEvent.RESERVED_ID_MAX)
4845 return true;
4847 switch (type)
4849 case ComponentEvent.COMPONENT_HIDDEN:
4850 case ComponentEvent.COMPONENT_MOVED:
4851 case ComponentEvent.COMPONENT_RESIZED:
4852 case ComponentEvent.COMPONENT_SHOWN:
4853 return (componentListener != null
4854 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
4856 case KeyEvent.KEY_PRESSED:
4857 case KeyEvent.KEY_RELEASED:
4858 case KeyEvent.KEY_TYPED:
4859 return (keyListener != null
4860 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
4862 case MouseEvent.MOUSE_CLICKED:
4863 case MouseEvent.MOUSE_ENTERED:
4864 case MouseEvent.MOUSE_EXITED:
4865 case MouseEvent.MOUSE_PRESSED:
4866 case MouseEvent.MOUSE_RELEASED:
4867 return (mouseListener != null
4868 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
4869 case MouseEvent.MOUSE_MOVED:
4870 case MouseEvent.MOUSE_DRAGGED:
4871 return (mouseMotionListener != null
4872 || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
4874 case FocusEvent.FOCUS_GAINED:
4875 case FocusEvent.FOCUS_LOST:
4876 return (focusListener != null
4877 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
4879 case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4880 case InputMethodEvent.CARET_POSITION_CHANGED:
4881 return (inputMethodListener != null
4882 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
4884 case PaintEvent.PAINT:
4885 case PaintEvent.UPDATE:
4886 return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
4888 default:
4889 return false;
4894 * Coalesce paint events. Current heuristic is: Merge if the union of
4895 * areas is less than twice that of the sum of the areas. The X server
4896 * tend to create a lot of paint events that are adjacent but not
4897 * overlapping.
4899 * <pre>
4900 * +------+
4901 * | +-----+ ...will be merged
4902 * | | |
4903 * | | |
4904 * +------+ |
4905 * +-----+
4907 * +---------------+--+
4908 * | | | ...will not be merged
4909 * +---------------+ |
4910 * | |
4911 * | |
4912 * | |
4913 * | |
4914 * | |
4915 * +--+
4916 * </pre>
4918 * @param queuedEvent the first paint event
4919 * @param newEvent the second paint event
4920 * @return the combined paint event, or null
4922 private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
4923 PaintEvent newEvent)
4925 Rectangle r1 = queuedEvent.getUpdateRect();
4926 Rectangle r2 = newEvent.getUpdateRect();
4927 Rectangle union = r1.union(r2);
4929 int r1a = r1.width * r1.height;
4930 int r2a = r2.width * r2.height;
4931 int ua = union.width * union.height;
4933 if (ua > (r1a+r2a)*2)
4934 return null;
4935 /* The 2 factor should maybe be reconsidered. Perhaps 3/2
4936 would be better? */
4938 newEvent.setUpdateRect(union);
4939 return newEvent;
4943 * This method is used to implement transferFocus(). CHILD is the child
4944 * making the request. This is overridden by Container; when called for an
4945 * ordinary component there is no child and so we always return null.
4947 * FIXME: is this still needed, in light of focus traversal policies?
4949 * @param child the component making the request
4950 * @return the next component to focus on
4952 Component findNextFocusComponent(Component child)
4954 return null;
4958 * Deserializes this component. This regenerates all serializable listeners
4959 * which were registered originally.
4961 * @param s the stream to read from
4962 * @throws ClassNotFoundException if deserialization fails
4963 * @throws IOException if the stream fails
4965 private void readObject(ObjectInputStream s)
4966 throws ClassNotFoundException, IOException
4968 s.defaultReadObject();
4969 String key = (String) s.readObject();
4970 while (key != null)
4972 Object listener = s.readObject();
4973 if ("componentL".equals(key))
4974 addComponentListener((ComponentListener) listener);
4975 else if ("focusL".equals(key))
4976 addFocusListener((FocusListener) listener);
4977 else if ("keyL".equals(key))
4978 addKeyListener((KeyListener) listener);
4979 else if ("mouseL".equals(key))
4980 addMouseListener((MouseListener) listener);
4981 else if ("mouseMotionL".equals(key))
4982 addMouseMotionListener((MouseMotionListener) listener);
4983 else if ("inputMethodL".equals(key))
4984 addInputMethodListener((InputMethodListener) listener);
4985 else if ("hierarchyL".equals(key))
4986 addHierarchyListener((HierarchyListener) listener);
4987 else if ("hierarchyBoundsL".equals(key))
4988 addHierarchyBoundsListener((HierarchyBoundsListener) listener);
4989 else if ("mouseWheelL".equals(key))
4990 addMouseWheelListener((MouseWheelListener) listener);
4991 key = (String) s.readObject();
4996 * Serializes this component. This ignores all listeners which do not
4997 * implement Serializable, but includes those that do.
4999 * @param s the stream to write to
5000 * @throws IOException if the stream fails
5002 private void writeObject(ObjectOutputStream s) throws IOException
5004 s.defaultWriteObject();
5005 AWTEventMulticaster.save(s, "componentL", componentListener);
5006 AWTEventMulticaster.save(s, "focusL", focusListener);
5007 AWTEventMulticaster.save(s, "keyL", keyListener);
5008 AWTEventMulticaster.save(s, "mouseL", mouseListener);
5009 AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5010 AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5011 AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5012 AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5013 AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5014 s.writeObject(null);
5018 // Nested classes.
5021 * This class provides accessibility support for subclasses of container.
5023 * @author Eric Blake (ebb9@email.byu.edu)
5024 * @since 1.3
5025 * @status updated to 1.4
5027 protected abstract class AccessibleAWTComponent extends AccessibleContext
5028 implements Serializable, AccessibleComponent
5031 * Compatible with JDK 1.3+.
5033 private static final long serialVersionUID = 642321655757800191L;
5036 * Converts show/hide events to PropertyChange events, and is registered
5037 * as a component listener on this component.
5039 * @serial the component handler
5041 protected ComponentListener accessibleAWTComponentHandler
5042 = new AccessibleAWTComponentHandler();
5045 * Converts focus events to PropertyChange events, and is registered
5046 * as a focus listener on this component.
5048 * @serial the focus handler
5050 protected FocusListener accessibleAWTFocusHandler
5051 = new AccessibleAWTFocusHandler();
5054 * The default constructor.
5056 protected AccessibleAWTComponent()
5058 Component.this.addComponentListener(accessibleAWTComponentHandler);
5059 Component.this.addFocusListener(accessibleAWTFocusHandler);
5063 * Adds a global property change listener to the accessible component.
5065 * @param l the listener to add
5066 * @see #ACCESSIBLE_NAME_PROPERTY
5067 * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
5068 * @see #ACCESSIBLE_STATE_PROPERTY
5069 * @see #ACCESSIBLE_VALUE_PROPERTY
5070 * @see #ACCESSIBLE_SELECTION_PROPERTY
5071 * @see #ACCESSIBLE_TEXT_PROPERTY
5072 * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
5074 public void addPropertyChangeListener(PropertyChangeListener l)
5076 Component.this.addPropertyChangeListener(l);
5077 super.addPropertyChangeListener(l);
5081 * Removes a global property change listener from this accessible
5082 * component.
5084 * @param l the listener to remove
5086 public void removePropertyChangeListener(PropertyChangeListener l)
5088 Component.this.removePropertyChangeListener(l);
5089 super.removePropertyChangeListener(l);
5093 * Returns the accessible name of this component. It is almost always
5094 * wrong to return getName(), since it is not localized. In fact, for
5095 * things like buttons, this should be the text of the button, not the
5096 * name of the object. The tooltip text might also be appropriate.
5098 * @return the name
5099 * @see #setAccessibleName(String)
5101 public String getAccessibleName()
5103 return accessibleName == null ? getName() : accessibleName;
5107 * Returns a brief description of this accessible context. This should
5108 * be localized.
5110 * @return a description of this component
5111 * @see #setAccessibleDescription(String)
5113 public String getAccessibleDescription()
5115 return accessibleDescription;
5119 * Returns the role of this component.
5121 * @return the accessible role
5123 public AccessibleRole getAccessibleRole()
5125 return AccessibleRole.AWT_COMPONENT;
5129 * Returns a state set describing this component's state.
5131 * @return a new state set
5132 * @see AccessibleState
5134 public AccessibleStateSet getAccessibleStateSet()
5136 AccessibleStateSet s = new AccessibleStateSet();
5137 if (Component.this.isEnabled())
5138 s.add(AccessibleState.ENABLED);
5139 if (isFocusable())
5140 s.add(AccessibleState.FOCUSABLE);
5141 if (isFocusOwner())
5142 s.add(AccessibleState.FOCUSED);
5143 if (isOpaque())
5144 s.add(AccessibleState.OPAQUE);
5145 if (Component.this.isShowing())
5146 s.add(AccessibleState.SHOWING);
5147 if (Component.this.isVisible())
5148 s.add(AccessibleState.VISIBLE);
5149 return s;
5153 * Returns the parent of this component, if it is accessible.
5155 * @return the accessible parent
5157 public Accessible getAccessibleParent()
5159 if (accessibleParent == null)
5161 Container parent = getParent();
5162 accessibleParent = parent instanceof Accessible
5163 ? (Accessible) parent : null;
5165 return accessibleParent;
5169 * Returns the index of this component in its accessible parent.
5171 * @return the index, or -1 if the parent is not accessible
5172 * @see #getAccessibleParent()
5174 public int getAccessibleIndexInParent()
5176 if (getAccessibleParent() == null)
5177 return -1;
5178 AccessibleContext context
5179 = ((Component) accessibleParent).getAccessibleContext();
5180 if (context == null)
5181 return -1;
5182 for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
5183 if (context.getAccessibleChild(i) == Component.this)
5184 return i;
5185 return -1;
5189 * Returns the number of children of this component which implement
5190 * Accessible. Subclasses must override this if they can have children.
5192 * @return the number of accessible children, default 0
5194 public int getAccessibleChildrenCount()
5196 return 0;
5200 * Returns the ith accessible child. Subclasses must override this if
5201 * they can have children.
5203 * @return the ith accessible child, or null
5204 * @see #getAccessibleChildrenCount()
5206 public Accessible getAccessibleChild(int i)
5208 return null;
5212 * Returns the locale of this component.
5214 * @return the locale
5215 * @throws IllegalComponentStateException if the locale is unknown
5217 public Locale getLocale()
5219 return Component.this.getLocale();
5223 * Returns this, since it is an accessible component.
5225 * @return the accessible component
5227 public AccessibleComponent getAccessibleComponent()
5229 return this;
5233 * Gets the background color.
5235 * @return the background color
5236 * @see #setBackground(Color)
5238 public Color getBackground()
5240 return Component.this.getBackground();
5244 * Sets the background color.
5246 * @param c the background color
5247 * @see #getBackground()
5248 * @see #isOpaque()
5250 public void setBackground(Color c)
5252 Component.this.setBackground(c);
5256 * Gets the foreground color.
5258 * @return the foreground color
5259 * @see #setForeground(Color)
5261 public Color getForeground()
5263 return Component.this.getForeground();
5267 * Sets the foreground color.
5269 * @param c the foreground color
5270 * @see #getForeground()
5272 public void setForeground(Color c)
5274 Component.this.setForeground(c);
5278 * Gets the cursor.
5280 * @return the cursor
5281 * @see #setCursor(Cursor)
5283 public Cursor getCursor()
5285 return Component.this.getCursor();
5289 * Sets the cursor.
5291 * @param cursor the cursor
5292 * @see #getCursor()
5294 public void setCursor(Cursor cursor)
5296 Component.this.setCursor(cursor);
5300 * Gets the font.
5302 * @return the font
5303 * @see #setFont(Font)
5305 public Font getFont()
5307 return Component.this.getFont();
5311 * Sets the font.
5313 * @param f the font
5314 * @see #getFont()
5316 public void setFont(Font f)
5318 Component.this.setFont(f);
5322 * Gets the font metrics for a font.
5324 * @param f the font to look up
5325 * @return its metrics
5326 * @throws NullPointerException if f is null
5327 * @see #getFont()
5329 public FontMetrics getFontMetrics(Font f)
5331 return Component.this.getFontMetrics(f);
5335 * Tests if the component is enabled.
5337 * @return true if the component is enabled
5338 * @see #setEnabled(boolean)
5339 * @see #getAccessibleStateSet()
5340 * @see AccessibleState#ENABLED
5342 public boolean isEnabled()
5344 return Component.this.isEnabled();
5348 * Set whether the component is enabled.
5350 * @param b the new enabled status
5351 * @see #isEnabled()
5353 public void setEnabled(boolean b)
5355 Component.this.setEnabled(b);
5359 * Test whether the component is visible (not necesarily showing).
5361 * @return true if it is visible
5362 * @see #setVisible(boolean)
5363 * @see #getAccessibleStateSet()
5364 * @see AccessibleState#VISIBLE
5366 public boolean isVisible()
5368 return Component.this.isVisible();
5372 * Sets the visibility of this component.
5374 * @param b the desired visibility
5375 * @see #isVisible()
5377 public void setVisible(boolean b)
5379 Component.this.setVisible(b);
5383 * Tests if the component is showing.
5385 * @return true if this is showing
5387 public boolean isShowing()
5389 return Component.this.isShowing();
5393 * Tests if the point is contained in this component.
5395 * @param p the point to check
5396 * @return true if it is contained
5397 * @throws NullPointerException if p is null
5399 public boolean contains(Point p)
5401 return Component.this.contains(p.x, p.y);
5405 * Returns the location of this object on the screen, or null if it is
5406 * not showing.
5408 * @return the location relative to screen coordinates, if showing
5409 * @see #getBounds()
5410 * @see #getLocation()
5412 public Point getLocationOnScreen()
5414 return Component.this.isShowing() ? Component.this.getLocationOnScreen()
5415 : null;
5419 * Returns the location of this object relative to its parent's coordinate
5420 * system, or null if it is not showing.
5422 * @return the location
5423 * @see #getBounds()
5424 * @see #getLocationOnScreen()
5426 public Point getLocation()
5428 return Component.this.isShowing() ? Component.this.getLocation() : null;
5432 * Sets the location of this relative to its parent's coordinate system.
5434 * @param p the location
5435 * @throws NullPointerException if p is null
5436 * @see #getLocation()
5438 public void setLocation(Point p)
5440 Component.this.setLocation(p.x, p.y);
5444 * Gets the bounds of this component, or null if it is not on screen.
5446 * @return the bounds
5447 * @see #contains(Point)
5448 * @see #setBounds(Rectangle)
5450 public Rectangle getBounds()
5452 return Component.this.isShowing() ? Component.this.getBounds() : null;
5456 * Sets the bounds of this component.
5458 * @param r the bounds
5459 * @throws NullPointerException if r is null
5460 * @see #getBounds()
5462 public void setBounds(Rectangle r)
5464 Component.this.setBounds(r.x, r.y, r.width, r.height);
5468 * Gets the size of this component, or null if it is not showing.
5470 * @return the size
5471 * @see #setSize(Dimension)
5473 public Dimension getSize()
5475 return Component.this.isShowing() ? Component.this.getSize() : null;
5479 * Sets the size of this component.
5481 * @param d the size
5482 * @throws NullPointerException if d is null
5483 * @see #getSize()
5485 public void setSize(Dimension d)
5487 Component.this.setSize(d.width, d.height);
5491 * Returns the Accessible child at a point relative to the coordinate
5492 * system of this component, if one exists, or null. Since components
5493 * have no children, subclasses must override this to get anything besides
5494 * null.
5496 * @param p the point to check
5497 * @return the accessible child at that point
5498 * @throws NullPointerException if p is null
5500 public Accessible getAccessibleAt(Point p)
5502 return null;
5506 * Tests whether this component can accept focus.
5508 * @return true if this is focus traversable
5509 * @see #getAccessibleStateSet ()
5510 * @see AccessibleState#FOCUSABLE
5511 * @see AccessibleState#FOCUSED
5513 public boolean isFocusTraversable ()
5515 return Component.this.isFocusTraversable ();
5519 * Requests focus for this component.
5521 * @see #isFocusTraversable ()
5523 public void requestFocus ()
5525 Component.this.requestFocus ();
5529 * Adds a focus listener.
5531 * @param l the listener to add
5533 public void addFocusListener(FocusListener l)
5535 Component.this.addFocusListener(l);
5539 * Removes a focus listener.
5541 * @param l the listener to remove
5543 public void removeFocusListener(FocusListener l)
5545 Component.this.removeFocusListener(l);
5549 * Converts component changes into property changes.
5551 * @author Eric Blake (ebb9@email.byu.edu)
5552 * @since 1.3
5553 * @status updated to 1.4
5555 protected class AccessibleAWTComponentHandler implements ComponentListener
5558 * Default constructor.
5560 protected AccessibleAWTComponentHandler()
5562 // Nothing to do here.
5566 * Convert a component hidden to a property change.
5568 * @param e the event to convert
5570 public void componentHidden(ComponentEvent e)
5572 AccessibleAWTComponent.this.firePropertyChange
5573 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
5577 * Convert a component shown to a property change.
5579 * @param e the event to convert
5581 public void componentShown(ComponentEvent e)
5583 AccessibleAWTComponent.this.firePropertyChange
5584 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
5588 * Moving a component does not affect properties.
5590 * @param e ignored
5592 public void componentMoved(ComponentEvent e)
5594 // Nothing to do here.
5598 * Resizing a component does not affect properties.
5600 * @param e ignored
5602 public void componentResized(ComponentEvent e)
5604 // Nothing to do here.
5606 } // class AccessibleAWTComponentHandler
5609 * Converts focus changes into property changes.
5611 * @author Eric Blake (ebb9@email.byu.edu)
5612 * @since 1.3
5613 * @status updated to 1.4
5615 protected class AccessibleAWTFocusHandler implements FocusListener
5618 * Default constructor.
5620 protected AccessibleAWTFocusHandler()
5622 // Nothing to do here.
5626 * Convert a focus gained to a property change.
5628 * @param e the event to convert
5630 public void focusGained(FocusEvent e)
5632 AccessibleAWTComponent.this.firePropertyChange
5633 (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
5637 * Convert a focus lost to a property change.
5639 * @param e the event to convert
5641 public void focusLost(FocusEvent e)
5643 AccessibleAWTComponent.this.firePropertyChange
5644 (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
5646 } // class AccessibleAWTComponentHandler
5647 } // class AccessibleAWTComponent
5650 * This class provides support for blitting offscreen surfaces to a
5651 * component.
5653 * @see BufferStrategy
5655 * @since 1.4
5657 protected class BltBufferStrategy extends BufferStrategy
5660 * The capabilities of the image buffer.
5662 protected BufferCapabilities caps;
5665 * The back buffers used in this strategy.
5667 protected VolatileImage[] backBuffers;
5670 * Whether or not the image buffer resources are allocated and
5671 * ready to be drawn into.
5673 protected boolean validatedContents;
5676 * The width of the back buffers.
5678 protected int width;
5681 * The height of the back buffers.
5683 protected int height;
5686 * The front buffer.
5688 private VolatileImage frontBuffer;
5691 * Creates a blitting buffer strategy.
5693 * @param numBuffers the number of buffers, including the front
5694 * buffer
5695 * @param caps the capabilities of this strategy
5697 protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
5699 this.caps = caps;
5700 createBackBuffers(numBuffers - 1);
5701 width = getWidth();
5702 height = getHeight();
5706 * Initializes the backBuffers field with an array of numBuffers
5707 * VolatileImages.
5709 * @param numBuffers the number of backbuffers to create
5711 protected void createBackBuffers(int numBuffers)
5713 GraphicsConfiguration c =
5714 GraphicsEnvironment.getLocalGraphicsEnvironment()
5715 .getDefaultScreenDevice().getDefaultConfiguration();
5717 backBuffers = new VolatileImage[numBuffers];
5719 for (int i = 0; i < numBuffers; i++)
5720 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
5724 * Retrieves the capabilities of this buffer strategy.
5726 * @return the capabilities of this buffer strategy
5728 public BufferCapabilities getCapabilities()
5730 return caps;
5734 * Retrieves a graphics object that can be used to draw into this
5735 * strategy's image buffer.
5737 * @return a graphics object
5739 public Graphics getDrawGraphics()
5741 // Return the backmost buffer's graphics.
5742 return backBuffers[0].getGraphics();
5746 * Bring the contents of the back buffer to the front buffer.
5748 public void show()
5750 GraphicsConfiguration c =
5751 GraphicsEnvironment.getLocalGraphicsEnvironment()
5752 .getDefaultScreenDevice().getDefaultConfiguration();
5754 // draw the front buffer.
5755 getGraphics().drawImage(backBuffers[backBuffers.length - 1],
5756 width, height, null);
5758 BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
5760 // blit the back buffers.
5761 for (int i = backBuffers.length - 1; i > 0 ; i--)
5762 backBuffers[i] = backBuffers[i - 1];
5764 // create new backmost buffer.
5765 if (f == BufferCapabilities.FlipContents.UNDEFINED)
5766 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
5768 // create new backmost buffer and clear it to the background
5769 // color.
5770 if (f == BufferCapabilities.FlipContents.BACKGROUND)
5772 backBuffers[0] = c.createCompatibleVolatileImage(width, height);
5773 backBuffers[0].getGraphics().clearRect(0, 0, width, height);
5776 // FIXME: set the backmost buffer to the prior contents of the
5777 // front buffer. How do we retrieve the contents of the front
5778 // buffer?
5780 // if (f == BufferCapabilities.FlipContents.PRIOR)
5782 // set the backmost buffer to a copy of the new front buffer.
5783 if (f == BufferCapabilities.FlipContents.COPIED)
5784 backBuffers[0] = backBuffers[backBuffers.length - 1];
5788 * Re-create the image buffer resources if they've been lost.
5790 protected void revalidate()
5792 GraphicsConfiguration c =
5793 GraphicsEnvironment.getLocalGraphicsEnvironment()
5794 .getDefaultScreenDevice().getDefaultConfiguration();
5796 for (int i = 0; i < backBuffers.length; i++)
5798 int result = backBuffers[i].validate(c);
5799 if (result == VolatileImage.IMAGE_INCOMPATIBLE)
5800 backBuffers[i] = c.createCompatibleVolatileImage(width, height);
5802 validatedContents = true;
5806 * Returns whether or not the image buffer resources have been
5807 * lost.
5809 * @return true if the resources have been lost, false otherwise
5811 public boolean contentsLost()
5813 for (int i = 0; i < backBuffers.length; i++)
5815 if (backBuffers[i].contentsLost())
5817 validatedContents = false;
5818 return true;
5821 // we know that the buffer resources are valid now because we
5822 // just checked them
5823 validatedContents = true;
5824 return false;
5828 * Returns whether or not the image buffer resources have been
5829 * restored.
5831 * @return true if the resources have been restored, false
5832 * otherwise
5834 public boolean contentsRestored()
5836 GraphicsConfiguration c =
5837 GraphicsEnvironment.getLocalGraphicsEnvironment()
5838 .getDefaultScreenDevice().getDefaultConfiguration();
5840 boolean imageRestored = false;
5842 for (int i = 0; i < backBuffers.length; i++)
5844 int result = backBuffers[i].validate(c);
5845 if (result == VolatileImage.IMAGE_RESTORED)
5846 imageRestored = true;
5847 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
5848 return false;
5850 // we know that the buffer resources are valid now because we
5851 // just checked them
5852 validatedContents = true;
5853 return imageRestored;
5858 * This class provides support for flipping component buffers. It
5859 * can only be used on Canvases and Windows.
5861 * @since 1.4
5863 protected class FlipBufferStrategy extends BufferStrategy
5866 * The number of buffers.
5868 protected int numBuffers;
5871 * The capabilities of this buffering strategy.
5873 protected BufferCapabilities caps;
5876 * An Image reference to the drawing buffer.
5878 protected Image drawBuffer;
5881 * A VolatileImage reference to the drawing buffer.
5883 protected VolatileImage drawVBuffer;
5886 * Whether or not the image buffer resources are allocated and
5887 * ready to be drawn into.
5889 protected boolean validatedContents;
5892 * The width of the back buffer.
5894 private int width;
5897 * The height of the back buffer.
5899 private int height;
5902 * Creates a flipping buffer strategy. The only supported
5903 * strategy for FlipBufferStrategy itself is a double-buffer page
5904 * flipping strategy. It forms the basis for more complex derived
5905 * strategies.
5907 * @param numBuffers the number of buffers
5908 * @param caps the capabilities of this buffering strategy
5910 * @throws AWTException if the requested
5911 * number-of-buffers/capabilities combination is not supported
5913 protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
5914 throws AWTException
5916 this.caps = caps;
5917 width = getWidth();
5918 height = getHeight();
5920 if (numBuffers > 1)
5921 createBuffers(numBuffers, caps);
5922 else
5924 drawVBuffer = peer.createVolatileImage(width, height);
5925 drawBuffer = drawVBuffer;
5930 * Creates a multi-buffer flipping strategy. The number of
5931 * buffers must be greater than one and the buffer capabilities
5932 * must specify page flipping.
5934 * @param numBuffers the number of flipping buffers; must be
5935 * greater than one
5936 * @param caps the buffering capabilities; caps.isPageFlipping()
5937 * must return true
5939 * @throws IllegalArgumentException if numBuffers is not greater
5940 * than one or if the page flipping capability is not requested
5942 * @throws AWTException if the requested flipping strategy is not
5943 * supported
5945 protected void createBuffers(int numBuffers, BufferCapabilities caps)
5946 throws AWTException
5948 if (numBuffers <= 1)
5949 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
5950 + " numBuffers must be greater than"
5951 + " one.");
5953 if (!caps.isPageFlipping())
5954 throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
5955 + " flipping must be a specified"
5956 + " capability.");
5958 peer.createBuffers(numBuffers, caps);
5962 * Return a direct reference to the back buffer image.
5964 * @return a direct reference to the back buffer image.
5966 protected Image getBackBuffer()
5968 return peer.getBackBuffer();
5972 * Perform a flip operation to transfer the contents of the back
5973 * buffer to the front buffer.
5975 protected void flip(BufferCapabilities.FlipContents flipAction)
5977 peer.flip(flipAction);
5981 * Release the back buffer's resources.
5983 protected void destroyBuffers()
5985 peer.destroyBuffers();
5989 * Retrieves the capabilities of this buffer strategy.
5991 * @return the capabilities of this buffer strategy
5993 public BufferCapabilities getCapabilities()
5995 return caps;
5999 * Retrieves a graphics object that can be used to draw into this
6000 * strategy's image buffer.
6002 * @return a graphics object
6004 public Graphics getDrawGraphics()
6006 return drawVBuffer.getGraphics();
6010 * Re-create the image buffer resources if they've been lost.
6012 protected void revalidate()
6014 GraphicsConfiguration c =
6015 GraphicsEnvironment.getLocalGraphicsEnvironment()
6016 .getDefaultScreenDevice().getDefaultConfiguration();
6018 if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
6019 drawVBuffer = peer.createVolatileImage(width, height);
6020 validatedContents = true;
6024 * Returns whether or not the image buffer resources have been
6025 * lost.
6027 * @return true if the resources have been lost, false otherwise
6029 public boolean contentsLost()
6031 if (drawVBuffer.contentsLost())
6033 validatedContents = false;
6034 return true;
6036 // we know that the buffer resources are valid now because we
6037 // just checked them
6038 validatedContents = true;
6039 return false;
6043 * Returns whether or not the image buffer resources have been
6044 * restored.
6046 * @return true if the resources have been restored, false
6047 * otherwise
6049 public boolean contentsRestored()
6051 GraphicsConfiguration c =
6052 GraphicsEnvironment.getLocalGraphicsEnvironment()
6053 .getDefaultScreenDevice().getDefaultConfiguration();
6055 int result = drawVBuffer.validate(c);
6057 boolean imageRestored = false;
6059 if (result == VolatileImage.IMAGE_RESTORED)
6060 imageRestored = true;
6061 else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6062 return false;
6064 // we know that the buffer resources are valid now because we
6065 // just checked them
6066 validatedContents = true;
6067 return imageRestored;
6071 * Bring the contents of the back buffer to the front buffer.
6073 public void show()
6075 flip(caps.getFlipContents());