OSDN Git Service

2004-02-10 David Jee <djee@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / Component.java
1 /* Component.java -- a graphics component
2    Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
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.
25
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. */
37
38
39 package java.awt;
40
41 import java.awt.dnd.DropTarget;
42 import java.awt.event.ComponentEvent;
43 import java.awt.event.ComponentListener;
44 import java.awt.event.FocusEvent;
45 import java.awt.event.FocusListener;
46 import java.awt.event.HierarchyBoundsListener;
47 import java.awt.event.HierarchyEvent;
48 import java.awt.event.HierarchyListener;
49 import java.awt.event.KeyEvent;
50 import java.awt.event.KeyListener;
51 import java.awt.event.InputMethodEvent;
52 import java.awt.event.InputMethodListener;
53 import java.awt.event.MouseEvent;
54 import java.awt.event.MouseListener;
55 import java.awt.event.MouseMotionListener;
56 import java.awt.event.MouseWheelListener;
57 import java.awt.event.MouseWheelEvent;
58 import java.awt.event.PaintEvent;
59 import java.awt.im.InputContext;
60 import java.awt.im.InputMethodRequests;
61 import java.awt.image.BufferStrategy;
62 import java.awt.image.ColorModel;
63 import java.awt.image.ImageObserver;
64 import java.awt.image.ImageProducer;
65 import java.awt.image.VolatileImage;
66 import java.awt.peer.ComponentPeer;
67 import java.awt.peer.LightweightPeer;
68 import java.beans.PropertyChangeListener;
69 import java.beans.PropertyChangeSupport;
70 import java.io.ObjectInputStream;
71 import java.io.IOException;
72 import java.io.ObjectOutputStream;
73 import java.io.PrintStream;
74 import java.io.PrintWriter;
75 import java.io.Serializable;
76 import java.lang.reflect.Array;
77 import java.util.Collections;
78 import java.util.EventListener;
79 import java.util.HashSet;
80 import java.util.Iterator;
81 import java.util.Locale;
82 import java.util.Set;
83 import java.util.Vector;
84 import javax.accessibility.Accessible;
85 import javax.accessibility.AccessibleComponent;
86 import javax.accessibility.AccessibleContext;
87 import javax.accessibility.AccessibleRole;
88 import javax.accessibility.AccessibleState;
89 import javax.accessibility.AccessibleStateSet;
90
91 /**
92  * The root of all evil. All graphical representations are subclasses of this
93  * giant class, which is designed for screen display and user interaction.
94  * This class can be extended directly to build a lightweight component (one
95  * not associated with a native window); lightweight components must reside
96  * inside a heavyweight window.
97  *
98  * <p>This class is Serializable, which has some big implications. A user can
99  * save the state of all graphical components in one VM, and reload them in
100  * another. Note that this class will only save Serializable listeners, and
101  * ignore the rest, without causing any serialization exceptions. However, by
102  * making a listener serializable, and adding it to another element, you link
103  * in that entire element to the state of this component. To get around this,
104  * use the idiom shown in the example below - make listeners non-serializable
105  * in inner classes, rather than using this object itself as the listener, if
106  * external objects do not need to save the state of this object.
107  *
108  * <p><pre>
109  * import java.awt.*;
110  * import java.awt.event.*;
111  * import java.io.Serializable;
112  * class MyApp implements Serializable
113  * {
114  *   BigObjectThatShouldNotBeSerializedWithAButton bigOne;
115  *   // Serializing aButton will not suck in an instance of MyApp, with its
116  *   // accompanying field bigOne.
117  *   Button aButton = new Button();
118  *   class MyActionListener implements ActionListener
119  *   {
120  *     public void actionPerformed(ActionEvent e)
121  *     {
122  *       System.out.println("Hello There");
123  *     }
124  *   }
125  *   MyApp()
126  *   {
127  *     aButton.addActionListener(new MyActionListener());
128  *   }
129  * }
130  *
131  * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
132  * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
133  * incomplete or only stubs; except for methods relating to the Drag and
134  * Drop, Input Method, and Accessibility frameworks: These methods are
135  * present but commented out.
136  *
137  * @author original author unknown
138  * @author Eric Blake <ebb9@email.byu.edu>
139  * @since 1.0
140  * @status still missing 1.4 support
141  */
142 public abstract class Component
143   implements ImageObserver, MenuContainer, Serializable
144 {
145   // Word to the wise - this file is huge. Search for '\f' (^L) for logical
146   // sectioning by fields, public API, private API, and nested classes.
147 \f
148
149   /**
150    * Compatible with JDK 1.0+.
151    */
152   private static final long serialVersionUID = -7644114512714619750L;
153
154   /**
155    * Constant returned by the <code>getAlignmentY</code> method to indicate
156    * that the component wishes to be aligned to the top relative to
157    * other components.
158    *
159    * @see #getAlignmentY()
160    */
161   public static final float TOP_ALIGNMENT = 0;
162
163   /**
164    * Constant returned by the <code>getAlignmentY</code> and
165    * <code>getAlignmentX</code> methods to indicate
166    * that the component wishes to be aligned to the center relative to
167    * other components.
168    *
169    * @see #getAlignmentX()
170    * @see #getAlignmentY()
171    */
172   public static final float CENTER_ALIGNMENT = 0.5f;
173
174   /**
175    * Constant returned by the <code>getAlignmentY</code> method to indicate
176    * that the component wishes to be aligned to the bottom relative to
177    * other components.
178    *
179    * @see #getAlignmentY()
180    */
181   public static final float BOTTOM_ALIGNMENT = 1;
182
183   /**
184    * Constant returned by the <code>getAlignmentX</code> method to indicate
185    * that the component wishes to be aligned to the right relative to
186    * other components.
187    *
188    * @see #getAlignmentX()
189    */
190   public static final float RIGHT_ALIGNMENT = 1;
191
192   /**
193    * Constant returned by the <code>getAlignmentX</code> method to indicate
194    * that the component wishes to be aligned to the left relative to
195    * other components.
196    *
197    * @see #getAlignmentX()
198    */
199   public static final float LEFT_ALIGNMENT = 0;
200
201   /**
202    * Make the treelock a String so that it can easily be identified
203    * in debug dumps. We clone the String in order to avoid a conflict in
204    * the unlikely event that some other package uses exactly the same string
205    * as a lock object.
206    */
207   static final Object treeLock = new String("AWT_TREE_LOCK");
208
209   // Serialized fields from the serialization spec.
210
211   /**
212    * The x position of the component in the parent's coordinate system.
213    *
214    * @see #getLocation()
215    * @serial the x position
216    */
217   int x;
218
219   /**
220    * The y position of the component in the parent's coordinate system.
221    *
222    * @see #getLocation()
223    * @serial the y position
224    */
225   int y;
226
227   /**
228    * The component width.
229    *
230    * @see #getSize()
231    * @serial the width
232    */
233   int width;
234
235   /**
236    * The component height.
237    *
238    * @see #getSize()
239    * @serial the height
240    */
241   int height;
242
243   /**
244    * The foreground color for the component. This may be null.
245    *
246    * @see #getForeground()
247    * @see #setForeground(Color)
248    * @serial the foreground color
249    */
250   Color foreground;
251
252   /**
253    * The background color for the component. This may be null.
254    *
255    * @see #getBackground()
256    * @see #setBackground(Color)
257    * @serial the background color
258    */
259   Color background;
260
261   /**
262    * The default font used in the component. This may be null.
263    *
264    * @see #getFont()
265    * @see #setFont(Font)
266    * @serial the font
267    */
268   Font font;
269
270   /**
271    * The font in use by the peer, or null if there is no peer.
272    *
273    * @serial the peer's font
274    */
275   Font peerFont;
276
277   /**
278    * The cursor displayed when the pointer is over this component. This may
279    * be null.
280    *
281    * @see #getCursor()
282    * @see #setCursor(Cursor)
283    */
284   Cursor cursor;
285
286   /**
287    * The locale for the component.
288    *
289    * @see #getLocale()
290    * @see #setLocale(Locale)
291    */
292   Locale locale;
293
294   /**
295    * True if the object should ignore repaint events (usually because it is
296    * not showing).
297    *
298    * @see #getIgnoreRepaint()
299    * @see #setIgnoreRepaint(boolean)
300    * @serial true to ignore repaints
301    * @since 1.4
302    */
303   boolean ignoreRepaint;
304
305   /**
306    * True when the object is visible (although it is only showing if all
307    * ancestors are likewise visible). For component, this defaults to true.
308    *
309    * @see #isVisible()
310    * @see #setVisible(boolean)
311    * @serial true if visible
312    */
313   boolean visible = true;
314
315   /**
316    * True if the object is enabled, meaning it can interact with the user.
317    * For component, this defaults to true.
318    *
319    * @see #isEnabled()
320    * @see #setEnabled(boolean)
321    * @serial true if enabled
322    */
323   boolean enabled = true;
324
325   /**
326    * True if the object is valid. This is set to false any time a size
327    * adjustment means the component need to be layed out again.
328    *
329    * @see #isValid()
330    * @see #validate()
331    * @see #invalidate()
332    * @serial true if layout is valid
333    */
334   boolean valid;
335
336   /**
337    * The DropTarget for drag-and-drop operations.
338    *
339    * @see #getDropTarget()
340    * @see #setDropTarget(DropTarget)
341    * @serial the drop target, or null
342    * @since 1.2
343    */
344   DropTarget dropTarget;
345
346   /**
347    * The list of popup menus for this component.
348    *
349    * @see #add(PopupMenu)
350    * @serial the list of popups
351    */
352   Vector popups;
353
354   /**
355    * The component's name. May be null, in which case a default name is
356    * generated on the first use.
357    *
358    * @see #getName()
359    * @see #setName(String)
360    * @serial the name
361    */
362   String name;
363
364   /**
365    * True once the user has set the name. Note that the user may set the name
366    * to null.
367    *
368    * @see #name
369    * @see #getName()
370    * @see #setName(String)
371    * @serial true if the name has been explicitly set
372    */
373   boolean nameExplicitlySet;
374
375   /**
376    * Indicates if the object can be focused. Defaults to true for components.
377    *
378    * @see #isFocusable()
379    * @see #setFocusable(boolean)
380    * @since 1.4
381    */
382   boolean focusable = true;
383
384   /**
385    * Tracks whether this component uses default focus traversal, or has a
386    * different policy.
387    *
388    * @see #isFocusTraversableOverridden()
389    * @since 1.4
390    */
391   int isFocusTraversableOverridden;
392
393   /**
394    * The focus traversal keys, if not inherited from the parent or default
395    * keyboard manager. These sets will contain only AWTKeyStrokes that
396    * represent press and release events to use as focus control.
397    *
398    * @see #getFocusTraversalKeys(int)
399    * @see #setFocusTraversalKeys(int, Set)
400    * @since 1.4
401    */
402   Set[] focusTraversalKeys;
403
404   /**
405    * True if focus traversal keys are enabled. This defaults to true for
406    * Component. If this is true, keystrokes in focusTraversalKeys are trapped
407    * and processed automatically rather than being passed on to the component.
408    *
409    * @see #getFocusTraversalKeysEnabled()
410    * @see #setFocusTraversalKeysEnabled(boolean)
411    * @since 1.4
412    */
413   boolean focusTraversalKeysEnabled = true;
414
415   /**
416    * Cached information on the minimum size. Should have been transient.
417    *
418    * @serial ignore
419    */
420   Dimension minSize;
421
422   /**
423    * Cached information on the preferred size. Should have been transient.
424    *
425    * @serial ignore
426    */
427   Dimension prefSize;
428
429   /**
430    * Set to true if an event is to be handled by this component, false if
431    * it is to be passed up the hierarcy.
432    *
433    * @see #dispatchEvent(AWTEvent)
434    * @serial true to process event locally
435    */
436   boolean newEventsOnly;
437
438   /**
439    * Set by subclasses to enable event handling of particular events, and
440    * left alone when modifying listeners. For component, this defaults to
441    * enabling only input methods.
442    *
443    * @see #enableInputMethods(boolean)
444    * @see AWTEvent
445    * @serial the mask of events to process
446    */
447   long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
448
449   /**
450    * Describes all registered PropertyChangeListeners.
451    *
452    * @see #addPropertyChangeListener(PropertyChangeListener)
453    * @see #removePropertyChangeListener(PropertyChangeListener)
454    * @see #firePropertyChange(String, Object, Object)
455    * @serial the property change listeners
456    * @since 1.2
457    */
458   PropertyChangeSupport changeSupport;
459
460   /**
461    * True if the component has been packed (layed out).
462    *
463    * @serial true if this is packed
464    */
465   boolean isPacked;
466
467   /**
468    * The serialization version for this class. Currently at version 4.
469    *
470    * XXX How do we handle prior versions?
471    *
472    * @serial the serialization version
473    */
474   int componentSerializedDataVersion = 4;
475
476   /**
477    * The accessible context associated with this component. This is only set
478    * by subclasses.
479    *
480    * @see #getAccessibleContext()
481    * @serial the accessibility context
482    * @since 1.2
483    */
484   AccessibleContext accessibleContext;
485
486 \f
487   // Guess what - listeners are special cased in serialization. See
488   // readObject and writeObject.
489
490   /** Component listener chain. */
491   transient ComponentListener componentListener;
492
493   /** Focus listener chain. */
494   transient FocusListener focusListener;
495
496   /** Key listener chain. */
497   transient KeyListener keyListener;
498
499   /** Mouse listener chain. */
500   transient MouseListener mouseListener;
501
502   /** Mouse motion listener chain. */
503   transient MouseMotionListener mouseMotionListener;
504
505   /**
506    * Mouse wheel listener chain.
507    *
508    * @since 1.4
509    */
510   transient MouseWheelListener mouseWheelListener;
511
512   /**
513    * Input method listener chain.
514    *
515    * @since 1.2
516    */
517   transient InputMethodListener inputMethodListener;
518
519   /**
520    * Hierarcy listener chain.
521    *
522    * @since 1.3
523    */
524   transient HierarchyListener hierarchyListener;
525
526   /**
527    * Hierarcy bounds listener chain.
528    *
529    * @since 1.3
530    */
531   transient HierarchyBoundsListener hierarchyBoundsListener;
532
533   // Anything else is non-serializable, and should be declared "transient".
534
535   /** The parent. */
536   transient Container parent;
537
538   /** The associated native peer. */
539   transient ComponentPeer peer;
540
541   /** The preferred component orientation. */
542   transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
543
544   /**
545    * The associated graphics configuration.
546    *
547    * @since 1.4
548    */
549   transient GraphicsConfiguration graphicsConfig;
550
551   /**
552    * The buffer strategy for repainting.
553    *
554    * @since 1.4
555    */
556   transient BufferStrategy bufferStrategy;
557
558   /**
559    * The system properties that affect image updating.
560    */
561   private static transient boolean incrementalDraw;
562   private static transient Long redrawRate;
563
564   static
565   {
566     incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
567     redrawRate = Long.getLong ("awt.image.redrawrate");
568   }
569 \f
570   // Public and protected API.
571
572   /**
573    * Default constructor for subclasses. When Component is extended directly,
574    * it forms a lightweight component that must be hosted in an opaque native
575    * container higher in the tree.
576    */
577   protected Component()
578   {
579   }
580
581   /**
582    * Returns the name of this component.
583    *
584    * @return the name of this component
585    * @see #setName(String)
586    * @since 1.1
587    */
588   public String getName()
589   {
590     if (name == null && ! nameExplicitlySet)
591       name = generateName();
592     return name;
593   }
594
595   /**
596    * Sets the name of this component to the specified name.
597    *
598    * @param name the new name of this component
599    * @see #getName()
600    * @since 1.1
601    */
602   public void setName(String name)
603   {
604     nameExplicitlySet = true;
605     this.name = name;
606   }
607
608   /**
609    * Returns the parent of this component.
610    *
611    * @return the parent of this component
612    */
613   public Container getParent()
614   {
615     return parent;
616   }
617
618   /**
619    * Returns the native windowing system peer for this component. Only the
620    * platform specific implementation code should call this method.
621    *
622    * @return the peer for this component
623    * @deprecated user programs should not directly manipulate peers; use
624    *             {@link #isDisplayable()} instead
625    */
626   // Classpath's Gtk peers rely on this.
627   public ComponentPeer getPeer()
628   {
629     return peer;
630   }
631
632   /**
633    * Set the associated drag-and-drop target, which receives events when this
634    * is enabled.
635    *
636    * @param dt the new drop target
637    * @see #isEnabled()
638    */
639   public void setDropTarget(DropTarget dt)
640   {
641     this.dropTarget = dt;
642   }
643
644   /**
645    * Gets the associated drag-and-drop target, if there is one.
646    *
647    * @return the drop target
648    */
649   public DropTarget getDropTarget()
650   {
651     return dropTarget;
652   }
653
654   /**
655    * Returns the graphics configuration of this component, if there is one.
656    * If it has not been set, it is inherited from the parent.
657    *
658    * @return the graphics configuration, or null
659    * @since 1.3
660    */
661   public GraphicsConfiguration getGraphicsConfiguration()
662   {
663     return getGraphicsConfigurationImpl();
664   }
665
666   /**
667    * Returns the object used for synchronization locks on this component
668    * when performing tree and layout functions.
669    *
670    * @return the synchronization lock for this component
671    */
672   public final Object getTreeLock()
673   {
674     return treeLock;
675   }
676
677   /**
678    * Returns the toolkit in use for this component. The toolkit is associated
679    * with the frame this component belongs to.
680    *
681    * @return the toolkit for this component
682    */
683   public Toolkit getToolkit()
684   {
685     if (peer != null)
686       {
687         Toolkit tk = peer.getToolkit();
688         if (tk != null)
689           return tk;
690       }
691     // Get toolkit for lightweight component.
692     if (parent != null)
693       return parent.getToolkit();
694     return Toolkit.getDefaultToolkit();
695   }
696
697   /**
698    * Tests whether or not this component is valid. A invalid component needs
699    * to have its layout redone.
700    *
701    * @return true if this component is valid
702    * @see #validate()
703    * @see #invalidate()
704    */
705   public boolean isValid()
706   {
707     return valid;
708   }
709
710   /**
711    * Tests if the component is displayable. It must be connected to a native
712    * screen resource, and all its ancestors must be displayable. A containment
713    * hierarchy is made displayable when a window is packed or made visible.
714    *
715    * @return true if the component is displayable
716    * @see Container#add(Component)
717    * @see Container#remove(Component)
718    * @see Window#pack()
719    * @see Window#show()
720    * @see Window#dispose()
721    * @since 1.2
722    */
723   public boolean isDisplayable()
724   {
725     if (parent != null)
726       return parent.isDisplayable();
727     return false;
728   }
729
730   /**
731    * Tests whether or not this component is visible. Except for top-level
732    * frames, components are initially visible.
733    *
734    * @return true if the component is visible
735    * @see #setVisible(boolean)
736    */
737   public boolean isVisible()
738   {
739     return visible;
740   }
741
742   /**
743    * Tests whether or not this component is actually being shown on
744    * the screen. This will be true if and only if it this component is
745    * visible and its parent components are all visible.
746    *
747    * @return true if the component is showing on the screen
748    * @see #setVisible(boolean)
749    */
750   public boolean isShowing()
751   {
752     if (! visible || peer == null)
753       return false;
754
755     return parent == null ? true : parent.isShowing();
756   }
757
758   /**
759    * Tests whether or not this component is enabled. Components are enabled
760    * by default, and must be enabled to receive user input or generate events.
761    *
762    * @return true if the component is enabled
763    * @see #setEnabled(boolean)
764    */
765   public boolean isEnabled()
766   {
767     return enabled;
768   }
769
770   /**
771    * Enables or disables this component. The component must be enabled to
772    * receive events (except that lightweight components always receive mouse
773    * events).
774    *
775    * @param enabled true to enable this component
776    * @see #isEnabled()
777    * @see #isLightweight()
778    * @since 1.1
779    */
780   public void setEnabled(boolean b)
781   {
782     enable (b);
783   }
784
785   /**
786    * Enables this component.
787    *
788    * @deprecated use {@link #setEnabled(boolean)} instead
789    */
790   public void enable()
791   {
792     this.enabled = true;
793     if (peer != null)
794       peer.setEnabled (true);
795   }
796
797   /**
798    * Enables or disables this component.
799    *
800    * @param enabled true to enable this component
801    * @deprecated use {@link #setEnabled(boolean)} instead
802    */
803   public void enable(boolean b)
804   {
805     if (b)
806       enable ();
807     else
808       disable ();
809   }
810
811   /**
812    * Disables this component.
813    *
814    * @deprecated use {@link #setEnabled(boolean)} instead
815    */
816   public void disable()
817   {
818     this.enabled = false;
819     if (peer != null)
820       peer.setEnabled (false);
821   }
822
823   /**
824    * Checks if this image is painted to an offscreen image buffer that is
825    * later copied to screen (double buffering reduces flicker). This version
826    * returns false, so subclasses must override it if they provide double
827    * buffering.
828    *
829    * @return true if this is double buffered; defaults to false
830    */
831   public boolean isDoubleBuffered()
832   {
833     return false;
834   }
835
836   /**
837    * Enables or disables input method support for this component. By default,
838    * components have this enabled. Input methods are given the opportunity
839    * to process key events before this component and its listeners.
840    *
841    * @param enable true to enable input method processing
842    * @see #processKeyEvent(KeyEvent)
843    * @since 1.2
844    */
845   public void enableInputMethods(boolean enable)
846   {
847     // XXX Implement.
848     throw new Error("not implemented");
849   }
850
851   /**
852    * Makes this component visible or invisible. Note that it wtill might
853    * not show the component, if a parent is invisible.
854    *
855    * @param visible true to make this component visible
856    * @see #isVisible()
857    * @since 1.1
858    */
859   public void setVisible(boolean b)
860   {
861     // Inspection by subclassing shows that Sun's implementation calls
862     // show(boolean) which then calls show() or hide(). It is the show()
863     // method that is overriden in subclasses like Window.
864     show (b);
865   }
866
867   /**
868    * Makes this component visible on the screen.
869    *
870    * @deprecated use {@link #setVisible(boolean)} instead
871    */
872   public void show()
873   {
874     // We must set visible before showing the peer.  Otherwise the
875     // peer could post paint events before visible is true, in which
876     // case lightweight components are not initially painted --
877     // Container.paint first calls isShowing () before painting itself
878     // and its children.
879     this.visible = true;
880     if (peer != null)
881       peer.setVisible(true);
882     invalidate();
883   }
884
885   /**
886    * Makes this component visible or invisible.
887    *
888    * @param visible true to make this component visible
889    * @deprecated use {@link #setVisible(boolean)} instead
890    */
891   public void show(boolean b)
892   {
893     if (b)
894       show ();
895     else
896       hide ();
897   }
898
899   /**
900    * Hides this component so that it is no longer shown on the screen.
901    *
902    * @deprecated use {@link #setVisible(boolean)} instead
903    */
904   public void hide()
905   {
906     if (peer != null)
907       peer.setVisible(false);
908     this.visible = false;
909     invalidate();
910   }
911
912   /**
913    * Returns this component's foreground color. If not set, this is inherited
914    * from the parent.
915    *
916    * @return this component's foreground color, or null
917    * @see #setForeground(Color)
918    */
919   public Color getForeground()
920   {
921     if (foreground != null)
922       return foreground;
923     return parent == null ? null : parent.getForeground();
924   }
925
926   /**
927    * Sets this component's foreground color to the specified color. This is a
928    * bound property.
929    *
930    * @param c the new foreground color
931    * @see #getForeground()
932    */
933   public void setForeground(Color c)
934   {
935     firePropertyChange("foreground", foreground, c);
936     if (peer != null)
937       peer.setForeground(c);
938     foreground = c;
939   }
940
941   /**
942    * Tests if the foreground was explicitly set, or just inherited from the
943    * parent.
944    *
945    * @return true if the foreground has been set
946    * @since 1.4
947    */
948   public boolean isForegroundSet()
949   {
950     return foreground != null;
951   }
952
953   /**
954    * Returns this component's background color. If not set, this is inherited
955    * from the parent.
956    *
957    * @return the background color of the component, or null
958    * @see #setBackground(Color)
959    */
960   public Color getBackground()
961   {
962     if (background != null)
963       return background;
964     return parent == null ? null : parent.getBackground();
965   }
966
967   /**
968    * Sets this component's background color to the specified color. The parts
969    * of the component affected by the background color may by system dependent.
970    * This is a bound property.
971    *
972    * @param c the new background color
973    * @see #getBackground()
974    */
975   public void setBackground(Color c)
976   {
977     firePropertyChange("background", background, c);
978     if (peer != null)
979       peer.setBackground(c);
980     background = c;
981   }
982
983   /**
984    * Tests if the background was explicitly set, or just inherited from the
985    * parent.
986    *
987    * @return true if the background has been set
988    * @since 1.4
989    */
990   public boolean isBackgroundSet()
991   {
992     return background != null;
993   }
994
995   /**
996    * Returns the font in use for this component. If not set, this is inherited
997    * from the parent.
998    *
999    * @return the font for this component
1000    * @see #setFont(Font)
1001    */
1002   public Font getFont()
1003   {
1004     if (font != null)
1005       return font;
1006
1007     if (parent != null)
1008       return parent.getFont ();
1009     else
1010       return new Font ("Fixed", Font.PLAIN, 12);
1011   }
1012
1013   /**
1014    * Sets the font for this component to the specified font. This is a bound
1015    * property.
1016    *
1017    * @param font the new font for this component
1018    * @see #getFont()
1019    */
1020   public void setFont(Font f)
1021   {
1022     firePropertyChange("font", font, f);
1023     if (peer != null)
1024       peer.setFont(f);
1025     font = f;
1026   }
1027
1028   /**
1029    * Tests if the font was explicitly set, or just inherited from the parent.
1030    *
1031    * @return true if the font has been set
1032    * @since 1.4
1033    */
1034   public boolean isFontSet()
1035   {
1036     return font != null;
1037   }
1038
1039   /**
1040    * Returns the locale for this component. If this component does not
1041    * have a locale, the locale of the parent component is returned.
1042    *
1043    * @return the locale for this component
1044    * @throws IllegalComponentStateException if it has no locale or parent
1045    * @see setLocale(Locale)
1046    * @since 1.1
1047    */
1048   public Locale getLocale()
1049   {
1050     if (locale != null)
1051       return locale;
1052     if (parent == null)
1053       throw new IllegalComponentStateException
1054         ("Component has no parent: can't determine Locale");
1055     return parent.getLocale();
1056   }
1057
1058   /**
1059    * Sets the locale for this component to the specified locale. This is a
1060    * bound property.
1061    *
1062    * @param locale the new locale for this component
1063    */
1064   public void setLocale(Locale l)
1065   {
1066     firePropertyChange("locale", locale, l);
1067     locale = l;
1068     // New writing/layout direction or more/less room for localized labels.
1069     invalidate();
1070   }
1071
1072   /**
1073    * Returns the color model of the device this componet is displayed on.
1074    *
1075    * @return this object's color model
1076    * @see Toolkit#getColorModel()
1077    */
1078   public ColorModel getColorModel()
1079   {
1080     GraphicsConfiguration config = getGraphicsConfiguration();
1081     return config != null ? config.getColorModel()
1082       : getToolkit().getColorModel();
1083   }
1084
1085   /**
1086    * Returns the location of this component's top left corner relative to
1087    * its parent component. This may be outdated, so for synchronous behavior,
1088    * you should use a component listner.
1089    *
1090    * @return the location of this component
1091    * @see #setLocation(int, int)
1092    * @see #getLocationOnScreen()
1093    * @since 1.1
1094    */
1095   public Point getLocation()
1096   {
1097     return location ();
1098   }
1099
1100   /**
1101    * Returns the location of this component's top left corner in screen
1102    * coordinates.
1103    *
1104    * @return the location of this component in screen coordinates
1105    * @throws IllegalComponentStateException if the component is not showing
1106    */
1107   public Point getLocationOnScreen()
1108   {
1109     if (! isShowing())
1110       throw new IllegalComponentStateException("component not showing");
1111     // We know peer != null here.
1112     return peer.getLocationOnScreen();
1113   }
1114
1115   /**
1116    * Returns the location of this component's top left corner relative to
1117    * its parent component.
1118    *
1119    * @return the location of this component
1120    * @deprecated use {@link #getLocation()} instead
1121    */
1122   public Point location()
1123   {
1124     return new Point (x, y);
1125   }
1126
1127   /**
1128    * Moves this component to the specified location, relative to the parent's
1129    * coordinates. The coordinates are the new upper left corner of this
1130    * component.
1131    *
1132    * @param x the new X coordinate of this component
1133    * @param y the new Y coordinate of this component
1134    * @see #getLocation()
1135    * @see #setBounds(int, int, int, int)
1136    */
1137   public void setLocation(int x, int y)
1138   {
1139     move (x, y);
1140   }
1141
1142   /**
1143    * Moves this component to the specified location, relative to the parent's
1144    * coordinates. The coordinates are the new upper left corner of this
1145    * component.
1146    *
1147    * @param x the new X coordinate of this component
1148    * @param y the new Y coordinate of this component
1149    * @deprecated use {@link #setLocation(int, int)} instead
1150    */
1151   public void move(int x, int y)
1152   {
1153     if (this.x == x && this.y == y)
1154       return;
1155     invalidate ();
1156     this.x = x;
1157     this.y = y;
1158     if (peer != null)
1159       peer.setBounds (x, y, width, height);
1160   }
1161
1162   /**
1163    * Moves this component to the specified location, relative to the parent's
1164    * coordinates. The coordinates are the new upper left corner of this
1165    * component.
1166    *
1167    * @param p new coordinates for this component
1168    * @throws NullPointerException if p is null
1169    * @see #getLocation()
1170    * @see #setBounds(int, int, int, int)
1171    * @since 1.1
1172    */
1173   public void setLocation(Point p)
1174   {
1175     setLocation(p.x, p.y);
1176   }
1177
1178   /**
1179    * Returns the size of this object.
1180    *
1181    * @return the size of this object
1182    * @see #setSize(int, int)
1183    * @since 1.1
1184    */
1185   public Dimension getSize()
1186   {
1187     return size ();
1188   }
1189
1190   /**
1191    * Returns the size of this object.
1192    *
1193    * @return the size of this object
1194    * @deprecated use {@link #getSize()} instead
1195    */
1196   public Dimension size()
1197   {
1198     return new Dimension (width, height);
1199   }
1200
1201   /**
1202    * Sets the size of this component to the specified width and height.
1203    *
1204    * @param width the new width of this component
1205    * @param height the new height of this component
1206    * @see #getSize()
1207    * @see #setBounds(int, int, int, int)
1208    */
1209   public void setSize(int width, int height)
1210   {
1211     resize (width, height);
1212   }
1213
1214   /**
1215    * Sets the size of this component to the specified value.
1216    *
1217    * @param width the new width of the component
1218    * @param height the new height of the component
1219    * @deprecated use {@link #setSize(int, int)} instead
1220    */
1221   public void resize(int width, int height)
1222   {
1223     if (this.width == width && this.height == height)
1224       return;
1225     invalidate ();
1226     this.width = width;
1227     this.height = height;
1228     if (peer != null)
1229       peer.setBounds (x, y, width, height);
1230   }
1231
1232   /**
1233    * Sets the size of this component to the specified value.
1234    *
1235    * @param d the new size of this component
1236    * @throws NullPointerException if d is null
1237    * @see #setSize(int, int)
1238    * @see #setBounds(int, int, int, int)
1239    * @since 1.1
1240    */
1241   public void setSize(Dimension d)
1242   {
1243     resize (d);
1244   }
1245
1246   /**
1247    * Sets the size of this component to the specified value.
1248    *
1249    * @param d the new size of this component
1250    * @throws NullPointerException if d is null
1251    * @deprecated use {@link #setSize(Dimension)} instead
1252    */
1253   public void resize(Dimension d)
1254   {
1255     resize (d.width, d.height);
1256   }
1257
1258   /**
1259    * Returns a bounding rectangle for this component. Note that the
1260    * returned rectange is relative to this component's parent, not to
1261    * the screen.
1262    *
1263    * @return the bounding rectangle for this component
1264    * @see #setBounds(int, int, int, int)
1265    * @see #getLocation()
1266    * @see #getSize()
1267    */
1268   public Rectangle getBounds()
1269   {
1270     return bounds ();
1271   }
1272
1273   /**
1274    * Returns a bounding rectangle for this component. Note that the
1275    * returned rectange is relative to this component's parent, not to
1276    * the screen.
1277    *
1278    * @return the bounding rectangle for this component
1279    * @deprecated use {@link #getBounds()} instead
1280    */
1281   public Rectangle bounds()
1282   {
1283     return new Rectangle (x, y, width, height);
1284   }
1285
1286   /**
1287    * Sets the bounding rectangle for this component to the specified values.
1288    * Note that these coordinates are relative to the parent, not to the screen.
1289    *
1290    * @param x the X coordinate of the upper left corner of the rectangle
1291    * @param y the Y coordinate of the upper left corner of the rectangle
1292    * @param w the width of the rectangle
1293    * @param h the height of the rectangle
1294    * @see #getBounds()
1295    * @see #setLocation(int, int)
1296    * @see #setLocation(Point)
1297    * @see #setSize(int, int)
1298    * @see #setSize(Dimension)
1299    * @since 1.1
1300    */
1301   public void setBounds(int x, int y, int w, int h)
1302   {
1303     reshape (x, y, w, h);
1304   }
1305
1306   /**
1307    * Sets the bounding rectangle for this component to the specified values.
1308    * Note that these coordinates are relative to the parent, not to the screen.
1309    *
1310    * @param x the X coordinate of the upper left corner of the rectangle
1311    * @param y the Y coordinate of the upper left corner of the rectangle
1312    * @param width the width of the rectangle
1313    * @param height the height of the rectangle
1314    * @deprecated use {@link #setBounds(int, int, int, int)} instead
1315    */
1316   public void reshape(int x, int y, int width, int height)
1317   {
1318     if (this.x == x && this.y == y
1319         && this.width == width && this.height == height)
1320       return;
1321     invalidate ();
1322     this.x = x;
1323     this.y = y;
1324     this.width = width;
1325     this.height = height;
1326     if (peer != null)
1327       peer.setBounds (x, y, width, height);
1328   }
1329
1330   /**
1331    * Sets the bounding rectangle for this component to the specified
1332    * rectangle. Note that these coordinates are relative to the parent, not
1333    * to the screen.
1334    *
1335    * @param r the new bounding rectangle
1336    * @throws NullPointerException if r is null
1337    * @see #getBounds()
1338    * @see #setLocation(Point)
1339    * @see #setSize(Dimension)
1340    * @since 1.1
1341    */
1342   public void setBounds(Rectangle r)
1343   {
1344     setBounds (r.x, r.y, r.width, r.height);
1345   }
1346
1347   /**
1348    * Gets the x coordinate of the upper left corner. This is more efficient
1349    * than getBounds().x or getLocation().x.
1350    *
1351    * @return the current x coordinate
1352    * @since 1.2
1353    */
1354   public int getX()
1355   {
1356     return x;
1357   }
1358
1359   /**
1360    * Gets the y coordinate of the upper left corner. This is more efficient
1361    * than getBounds().y or getLocation().y.
1362    *
1363    * @return the current y coordinate
1364    * @since 1.2
1365    */
1366   public int getY()
1367   {
1368     return y;
1369   }
1370
1371   /**
1372    * Gets the width of the component. This is more efficient than
1373    * getBounds().width or getSize().width.
1374    *
1375    * @return the current width
1376    * @since 1.2
1377    */
1378   public int getWidth()
1379   {
1380     return width;
1381   }
1382
1383   /**
1384    * Gets the height of the component. This is more efficient than
1385    * getBounds().height or getSize().height.
1386    *
1387    * @return the current width
1388    * @since 1.2
1389    */
1390   public int getHeight()
1391   {
1392     return height;
1393   }
1394
1395   /**
1396    * Returns the bounds of this component. This allows reuse of an existing
1397    * rectangle, if r is non-null.
1398    *
1399    * @param r the rectangle to use, or null
1400    * @return the bounds
1401    */
1402   public Rectangle getBounds(Rectangle r)
1403   {
1404     if (r == null)
1405       r = new Rectangle();
1406     r.x = x;
1407     r.y = y;
1408     r.width = width;
1409     r.height = height;
1410     return r;
1411   }
1412
1413   /**
1414    * Returns the size of this component. This allows reuse of an existing
1415    * dimension, if d is non-null.
1416    *
1417    * @param d the dimension to use, or null
1418    * @return the size
1419    */
1420   public Dimension getSize(Dimension d)
1421   {
1422     if (d == null)
1423       d = new Dimension();
1424     d.width = width;
1425     d.height = height;
1426     return d;
1427   }
1428
1429   /**
1430    * Returns the location of this component. This allows reuse of an existing
1431    * point, if p is non-null.
1432    *
1433    * @param p the point to use, or null
1434    * @return the location
1435    */
1436   public Point getLocation(Point p)
1437   {
1438     if (p == null)
1439       p = new Point();
1440     p.x = x;
1441     p.y = y;
1442     return p;
1443   }
1444
1445   /**
1446    * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1447    * components are opaque. A component is opaque if it draws all pixels in
1448    * the bounds; a lightweight component is partially transparent if it lets
1449    * pixels underneath show through. Subclasses that guarantee that all pixels
1450    * will be drawn should override this.
1451    *
1452    * @return true if this is opaque
1453    * @see #isLightweight()
1454    * @since 1.2
1455    */
1456   public boolean isOpaque()
1457   {
1458     return ! isLightweight();
1459   }
1460
1461   /**
1462    * Return whether the component is lightweight. That means the component has
1463    * no native peer, but is displayable. This applies to subclasses of
1464    * Component not in this package, such as javax.swing.
1465    *
1466    * @return true if the component has a lightweight peer
1467    * @see #isDisplayable()
1468    * @since 1.2
1469    */
1470   public boolean isLightweight()
1471   {
1472     return peer instanceof LightweightPeer;
1473   }
1474
1475   /**
1476    * Returns the component's preferred size.
1477    *
1478    * @return the component's preferred size
1479    * @see #getMinimumSize()
1480    * @see LayoutManager
1481    */
1482   public Dimension getPreferredSize()
1483   {
1484     return preferredSize();
1485   }
1486
1487   /**
1488    * Returns the component's preferred size.
1489    *
1490    * @return the component's preferred size
1491    * @deprecated use {@link #getPreferredSize()} instead
1492    */
1493   public Dimension preferredSize()
1494   {
1495     if (prefSize == null)
1496       if (peer == null)
1497         return new Dimension(width, height);
1498       else 
1499         prefSize = peer.getPreferredSize();
1500     return prefSize;
1501   }
1502
1503   /**
1504    * Returns the component's minimum size.
1505    *
1506    * @return the component's minimum size
1507    * @see #getPreferredSize()
1508    * @see LayoutManager
1509    */
1510   public Dimension getMinimumSize()
1511   {
1512     return minimumSize();
1513   }
1514
1515   /**
1516    * Returns the component's minimum size.
1517    *
1518    * @return the component's minimum size
1519    * @deprecated use {@link #getMinimumSize()} instead
1520    */
1521   public Dimension minimumSize()
1522   {
1523     if (minSize == null)
1524       minSize = (peer != null ? peer.getMinimumSize()
1525                  : new Dimension(width, height));
1526     return minSize;
1527   }
1528
1529   /**
1530    * Returns the component's maximum size.
1531    *
1532    * @return the component's maximum size
1533    * @see #getMinimumSize()
1534    * @see #getPreferredSize()
1535    * @see LayoutManager
1536    */
1537   public Dimension getMaximumSize()
1538   {
1539     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1540   }
1541
1542   /**
1543    * Returns the preferred horizontal alignment of this component. The value
1544    * returned will be between {@link #LEFT_ALIGNMENT} and
1545    * {@link #RIGHT_ALIGNMENT}, inclusive.
1546    *
1547    * @return the preferred horizontal alignment of this component
1548    */
1549   public float getAlignmentX()
1550   {
1551     return CENTER_ALIGNMENT;
1552   }
1553
1554   /**
1555    * Returns the preferred vertical alignment of this component. The value
1556    * returned will be between {@link #TOP_ALIGNMENT} and
1557    * {@link #BOTTOM_ALIGNMENT}, inclusive.
1558    *
1559    * @return the preferred vertical alignment of this component
1560    */
1561   public float getAlignmentY()
1562   {
1563     return CENTER_ALIGNMENT;
1564   }
1565
1566   /**
1567    * Calls the layout manager to re-layout the component. This is called
1568    * during validation of a container in most cases.
1569    *
1570    * @see #validate()
1571    * @see LayoutManager
1572    */
1573   public void doLayout()
1574   {
1575     layout ();
1576   }
1577
1578   /**
1579    * Calls the layout manager to re-layout the component. This is called
1580    * during validation of a container in most cases.
1581    *
1582    * @deprecated use {@link #doLayout()} instead
1583    */
1584   public void layout()
1585   {
1586     // Nothing to do unless we're a container.
1587   }
1588
1589   /**
1590    * Called to ensure that the layout for this component is valid. This is
1591    * usually called on containers.
1592    *
1593    * @see #invalidate()
1594    * @see #doLayout()
1595    * @see LayoutManager
1596    * @see Container#validate()
1597    */
1598   public void validate()
1599   {
1600     valid = true;
1601   }
1602
1603   /**
1604    * Invalidates this component and all of its parent components. This will
1605    * cause them to have their layout redone. This is called frequently, so
1606    * make it fast.
1607    */
1608   public void invalidate()
1609   {
1610     valid = false;
1611     prefSize = null;
1612     minSize = null;
1613     if (parent != null && parent.valid)
1614       parent.invalidate();
1615   }
1616
1617   /**
1618    * Returns a graphics object for this component. Returns <code>null</code>
1619    * if this component is not currently displayed on the screen.
1620    *
1621    * @return a graphics object for this component
1622    * @see #paint(Graphics)
1623    */
1624   public Graphics getGraphics()
1625   {
1626     if (peer != null)
1627       {
1628         Graphics gfx = peer.getGraphics();
1629         if (gfx != null)
1630           return gfx;
1631         // create graphics for lightweight:
1632         Container parent = getParent();
1633         if (parent != null)
1634           {
1635             gfx = parent.getGraphics();
1636             Rectangle bounds = getBounds();
1637             gfx.setClip(bounds);
1638             gfx.translate(bounds.x, bounds.y);
1639             return gfx;
1640           }
1641       }
1642     return null;
1643   }
1644
1645   /**
1646    * Returns the font metrics for the specified font in this component.
1647    *
1648    * @param font the font to retrieve metrics for
1649    * @return the font metrics for the specified font
1650    * @throws NullPointerException if font is null
1651    * @see #getFont()
1652    * @see Toolkit#getFontMetrics(Font)
1653    */
1654   public FontMetrics getFontMetrics(Font font)
1655   {
1656     return peer == null ? getToolkit().getFontMetrics(font)
1657       : peer.getFontMetrics(font);
1658   }
1659
1660   /**
1661    * Sets the cursor for this component to the specified cursor. The cursor
1662    * is displayed when the point is contained by the component, and the
1663    * component is visible, displayable, and enabled. This is inherited by
1664    * subcomponents unless they set their own cursor.
1665    *
1666    * @param cursor the new cursor for this component
1667    * @see #isEnabled()
1668    * @see #isShowing()
1669    * @see #getCursor()
1670    * @see #contains(int, int)
1671    * @see Toolkit#createCustomCursor(Image, Point, String)
1672    */
1673   public void setCursor(Cursor cursor)
1674   {
1675     this.cursor = cursor;
1676     if (peer != null)
1677       peer.setCursor(cursor);
1678   }
1679
1680   /**
1681    * Returns the cursor for this component. If not set, this is inherited
1682    * from the parent, or from Cursor.getDefaultCursor().
1683    *
1684    * @return the cursor for this component
1685    */
1686   public Cursor getCursor()
1687   {
1688     if (cursor != null)
1689       return cursor;
1690     return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
1691   }
1692
1693   /**
1694    * Tests if the cursor was explicitly set, or just inherited from the parent.
1695    *
1696    * @return true if the cursor has been set
1697    * @since 1.4
1698    */
1699   public boolean isCursorSet()
1700   {
1701     return cursor != null;
1702   }
1703
1704   /**
1705    * Paints this component on the screen. The clipping region in the graphics
1706    * context will indicate the region that requires painting. This is called
1707    * whenever the component first shows, or needs to be repaired because
1708    * something was temporarily drawn on top. It is not necessary for
1709    * subclasses to call <code>super.paint(g)</code>. Components with no area
1710    * are not painted.
1711    *
1712    * @param g the graphics context for this paint job
1713    * @see #update(Graphics)
1714    */
1715   public void paint(Graphics g)
1716   {
1717     // Paint the heavyweight peer
1718     if (!isLightweight() && peer != null)
1719       peer.paint(g);
1720   }
1721
1722   /**
1723    * Updates this component. This is called in response to
1724    * <code>repaint</code>. This method fills the component with the
1725    * background color, then sets the foreground color of the specified
1726    * graphics context to the foreground color of this component and calls
1727    * the <code>paint()</code> method. The coordinates of the graphics are
1728    * relative to this component. Subclasses should call either
1729    * <code>super.update(g)</code> or <code>paint(g)</code>.
1730    *
1731    * @param graphics the graphics context for this update
1732    * @see #paint(Graphics)
1733    * @see #repaint()
1734    */
1735   public void update(Graphics g)
1736   {
1737     if (!isLightweight())
1738       {
1739         Rectangle clip = g.getClipBounds();
1740         if (clip == null)
1741           g.clearRect(0, 0, width, height);
1742         else
1743           g.clearRect(clip.x, clip.y, clip.width, clip.height);
1744       }
1745
1746     paint(g);
1747   }
1748
1749   /**
1750    * Paints this entire component, including any sub-components.
1751    *
1752    * @param graphics the graphics context for this paint job
1753    * @see #paint(Graphics)
1754    */
1755   public void paintAll(Graphics g)
1756   {
1757     if (! visible)
1758       return;
1759     paint(g);
1760   }
1761
1762   /**
1763    * Repaint this entire component. The <code>update()</code> method
1764    * on this component will be called as soon as possible.
1765    *
1766    * @see #update(Graphics)
1767    * @see #repaint(long, int, int, int, int)
1768    */
1769   public void repaint()
1770   {
1771     repaint(0, 0, 0, width, height);
1772   }
1773
1774   /**
1775    * Repaint this entire component. The <code>update()</code> method on this
1776    * component will be called in approximate the specified number of
1777    * milliseconds.
1778    *
1779    * @param tm milliseconds before this component should be repainted
1780    * @see #paint(Graphics)
1781    * @see #repaint(long, int, int, int, int)
1782    */
1783   public void repaint(long tm)
1784   {
1785     repaint(tm, 0, 0, width, height);
1786   }
1787
1788   /**
1789    * Repaints the specified rectangular region within this component. The
1790    * <code>update</code> method on this component will be called as soon as
1791    * possible. The coordinates are relative to this component.
1792    *
1793    * @param x the X coordinate of the upper left of the region to repaint
1794    * @param y the Y coordinate of the upper left of the region to repaint
1795    * @param w the width of the region to repaint
1796    * @param h the height of the region to repaint
1797    * @see #update(Graphics)
1798    * @see #repaint(long, int, int, int, int)
1799    */
1800   public void repaint(int x, int y, int w, int h)
1801   {
1802     repaint(0, x, y, w, h);
1803   }
1804
1805   /**
1806    * Repaints the specified rectangular region within this component. The
1807    * <code>update</code> method on this component will be called in
1808    * approximately the specified number of milliseconds. The coordinates
1809    * are relative to this component.
1810    *
1811    * @param tm milliseconds before this component should be repainted
1812    * @param x the X coordinate of the upper left of the region to repaint
1813    * @param y the Y coordinate of the upper left of the region to repaint
1814    * @param w the width of the region to repaint
1815    * @param h the height of the region to repaint
1816    * @see #update(Graphics)
1817    */
1818   public void repaint(long tm, int x, int y, int width, int height)
1819   {
1820     // Handle lightweight repainting by forwarding to native parent
1821     if (isLightweight() && parent != null)
1822       {
1823         if (parent != null)
1824           parent.repaint(tm, x + getX(), y + getY(), width, height);
1825       }
1826     else if (peer != null)
1827       peer.repaint(tm, x, y, width, height);
1828   }
1829
1830   /**
1831    * Prints this component. This method is provided so that printing can be
1832    * done in a different manner from painting. However, the implementation
1833    * in this class simply calls the <code>paint()</code> method.
1834    *
1835    * @param graphics the graphics context of the print device
1836    * @see #paint(Graphics)
1837    */
1838   public void print(Graphics g)
1839   {
1840     paint(g);
1841   }
1842
1843   /**
1844    * Prints this component, including all sub-components. This method is
1845    * provided so that printing can be done in a different manner from
1846    * painting. However, the implementation in this class simply calls the
1847    * <code>paintAll()</code> method.
1848    *
1849    * @param graphics the graphics context of the print device
1850    * @see #paintAll(Graphics)
1851    */
1852   public void printAll(Graphics g)
1853   {
1854     paintAll(g);
1855   }
1856
1857   /**
1858    * Called when an image has changed so that this component is repainted.
1859    * This incrementally draws an image as more bits are available, when
1860    * possible. Incremental drawing is enabled if the system property
1861    * <code>awt.image.incrementalDraw</code> is not present or is true, in which
1862    * case the redraw rate is set to 100ms or the value of the system property
1863    * <code>awt.image.redrawrate</code>.
1864    *
1865    * <p>The coordinate system used depends on the particular flags.
1866    *
1867    * @param image the image that has been updated
1868    * @param flags tlags as specified in <code>ImageObserver</code>
1869    * @param x the X coordinate
1870    * @param y the Y coordinate
1871    * @param w the width
1872    * @param h the height
1873    * @return false if the image is completely loaded, loading has been
1874    * aborted, or an error has occurred.  true if more updates are
1875    * required.
1876    * @see ImageObserver
1877    * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
1878    * @see Graphics#drawImage(Image, int, int, ImageObserver)
1879    * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
1880    * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
1881    * @see ImageObserver#update(Image, int, int, int, int, int)
1882    */
1883   public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
1884   {
1885     if ((flags & (FRAMEBITS | ALLBITS)) != 0)
1886       repaint ();
1887     else if ((flags & SOMEBITS) != 0)
1888       {
1889         if (incrementalDraw)
1890           {
1891             if (redrawRate != null)
1892               {
1893                 long tm = redrawRate.longValue();
1894                 if (tm < 0)
1895                   tm = 0;
1896                 repaint (tm);
1897               }
1898             else
1899               repaint (100);
1900           }
1901       }
1902     return (flags & (ALLBITS | ABORT | ERROR)) == 0;
1903   }
1904
1905   /**
1906    * Creates an image from the specified producer.
1907    *
1908    * @param producer the image procedure to create the image from
1909    * @return the resulting image
1910    */
1911   public Image createImage(ImageProducer producer)
1912   {
1913     // Sun allows producer to be null.
1914     if (peer != null)
1915       return peer.createImage(producer);
1916     else
1917       return getToolkit().createImage(producer);
1918   }
1919
1920   /**
1921    * Creates an image with the specified width and height for use in
1922    * double buffering. Headless environments do not support images.
1923    *
1924    * @param width the width of the image
1925    * @param height the height of the image
1926    * @return the requested image, or null if it is not supported
1927    */
1928   public Image createImage (int width, int height)
1929   {
1930     Image returnValue = null;
1931     if (!GraphicsEnvironment.isHeadless ())
1932       {
1933         if (isLightweight () && parent != null)
1934           returnValue = parent.createImage (width, height);
1935         else if (peer != null)
1936           returnValue = peer.createImage (width, height);
1937       }
1938     return returnValue;
1939   }
1940
1941   /**
1942    * Creates an image with the specified width and height for use in
1943    * double buffering. Headless environments do not support images.
1944    *
1945    * @param width the width of the image
1946    * @param height the height of the image
1947    * @return the requested image, or null if it is not supported
1948    * @since 1.4
1949    */
1950   public VolatileImage createVolatileImage(int width, int height)
1951   {
1952     if (GraphicsEnvironment.isHeadless())
1953       return null;
1954     GraphicsConfiguration config = getGraphicsConfiguration();
1955     return config == null ? null
1956       : config.createCompatibleVolatileImage(width, height);
1957   }
1958
1959   /**
1960    * Creates an image with the specified width and height for use in
1961    * double buffering. Headless environments do not support images. The image
1962    * will support the specified capabilities.
1963    *
1964    * @param width the width of the image
1965    * @param height the height of the image
1966    * @param caps the requested capabilities
1967    * @return the requested image, or null if it is not supported
1968    * @throws AWTException if a buffer with the capabilities cannot be created
1969    * @since 1.4
1970    */
1971   public VolatileImage createVolatileImage(int width, int height,
1972                                            ImageCapabilities caps)
1973     throws AWTException
1974   {
1975     if (GraphicsEnvironment.isHeadless())
1976       return null;
1977     GraphicsConfiguration config = getGraphicsConfiguration();
1978     return config == null ? null
1979       : config.createCompatibleVolatileImage(width, height, caps);
1980   }
1981
1982   /**
1983    * Prepares the specified image for rendering on this component.
1984    *
1985    * @param image the image to prepare for rendering
1986    * @param observer the observer to notify of image preparation status
1987    * @return true if the image is already fully prepared
1988    * @throws NullPointerException if image is null
1989    */
1990   public boolean prepareImage(Image image, ImageObserver observer)
1991   {
1992     return prepareImage(image, image.getWidth(observer),
1993                         image.getHeight(observer), observer);
1994   }
1995
1996   /**
1997    * Prepares the specified image for rendering on this component at the
1998    * specified scaled width and height
1999    *
2000    * @param image the image to prepare for rendering
2001    * @param width the scaled width of the image
2002    * @param height the scaled height of the image
2003    * @param observer the observer to notify of image preparation status
2004    * @return true if the image is already fully prepared
2005    */
2006   public boolean prepareImage(Image image, int width, int height,
2007                               ImageObserver observer)
2008   {
2009     if (peer != null)
2010         return peer.prepareImage(image, width, height, observer);
2011     else
2012         return getToolkit().prepareImage(image, width, height, observer);
2013   }
2014
2015   /**
2016    * Returns the status of the loading of the specified image. The value
2017    * returned will be those flags defined in <code>ImageObserver</code>.
2018    *
2019    * @param image the image to check on
2020    * @param observer the observer to notify of image loading progress
2021    * @return the image observer flags indicating the status of the load
2022    * @see #prepareImage(Image, int, int, ImageObserver)
2023    * @see #Toolkit#checkImage(Image, int, int, ImageObserver)
2024    * @throws NullPointerException if image is null
2025    */
2026   public int checkImage(Image image, ImageObserver observer)
2027   {
2028     return checkImage(image, -1, -1, observer);
2029   }
2030
2031   /**
2032    * Returns the status of the loading of the specified image. The value
2033    * returned will be those flags defined in <code>ImageObserver</code>.
2034    *
2035    * @param image the image to check on
2036    * @param width the scaled image width
2037    * @param height the scaled image height
2038    * @param observer the observer to notify of image loading progress
2039    * @return the image observer flags indicating the status of the load
2040    * @see #prepareImage(Image, int, int, ImageObserver)
2041    * @see #Toolkit#checkImage(Image, int, int, ImageObserver)
2042    */
2043   public int checkImage(Image image, int width, int height,
2044                         ImageObserver observer)
2045   {
2046     if (peer != null)
2047       return peer.checkImage(image, width, height, observer);
2048     return getToolkit().checkImage(image, width, height, observer);
2049   }
2050
2051   /**
2052    * Sets whether paint messages delivered by the operating system should be
2053    * ignored. This does not affect messages from AWT, except for those
2054    * triggered by OS messages. Setting this to true can allow faster
2055    * performance in full-screen mode or page-flipping.
2056    *
2057    * @param ignoreRepaint the new setting for ignoring repaint events
2058    * @see #getIgnoreRepaint()
2059    * @see BufferStrategy
2060    * @see GraphicsDevice.setFullScreenWindow(Window)
2061    * @since 1.4
2062    */
2063   public void setIgnoreRepaint(boolean ignoreRepaint)
2064   {
2065     this.ignoreRepaint = ignoreRepaint;
2066   }
2067
2068   /**
2069    * Test whether paint events from the operating system are ignored.
2070    *
2071    * @return the status of ignoring paint events
2072    * @see #setIgnoreRepaint(boolean)
2073    * @since 1.4
2074    */
2075   public boolean getIgnoreRepaint()
2076   {
2077     return ignoreRepaint;
2078   }
2079
2080   /**
2081    * Tests whether or not the specified point is contained within this
2082    * component. Coordinates are relative to this component.
2083    *
2084    * @param x the X coordinate of the point to test
2085    * @param y the Y coordinate of the point to test
2086    * @return true if the point is within this component
2087    * @see #getComponentAt(int, int)
2088    */
2089   public boolean contains(int x, int y)
2090   {
2091     return inside (x, y);
2092   }
2093
2094   /**
2095    * Tests whether or not the specified point is contained within this
2096    * component. Coordinates are relative to this component.
2097    *
2098    * @param x the X coordinate of the point to test
2099    * @param y the Y coordinate of the point to test
2100    * @return true if the point is within this component
2101    * @deprecated use {@link #contains(int, int)} instead
2102    */
2103   public boolean inside(int x, int y)
2104   {
2105     return x >= 0 && y >= 0 && x < width && y < height;
2106   }
2107
2108   /**
2109    * Tests whether or not the specified point is contained within this
2110    * component. Coordinates are relative to this component.
2111    *
2112    * @param p the point to test
2113    * @return true if the point is within this component
2114    * @throws NullPointerException if p is null
2115    * @see #getComponentAt(Point)
2116    * @since 1.1
2117    */
2118   public boolean contains(Point p)
2119   {
2120     return contains (p.x, p.y);
2121   }
2122
2123   /**
2124    * Returns the component occupying the position (x,y). This will either
2125    * be this component, an immediate child component, or <code>null</code>
2126    * if neither of the first two occupies the specified location.
2127    *
2128    * @param x the X coordinate to search for components at
2129    * @param y the Y coordinate to search for components at
2130    * @return the component at the specified location, or null
2131    * @see #contains(int, int)
2132    */
2133   public Component getComponentAt(int x, int y)
2134   {
2135     return locate (x, y);
2136   }
2137
2138   /**
2139    * Returns the component occupying the position (x,y). This will either
2140    * be this component, an immediate child component, or <code>null</code>
2141    * if neither of the first two occupies the specified location.
2142    *
2143    * @param x the X coordinate to search for components at
2144    * @param y the Y coordinate to search for components at
2145    * @return the component at the specified location, or null
2146    * @deprecated use {@link #getComponentAt(int, int)} instead
2147    */
2148   public Component locate(int x, int y)
2149   {
2150     return contains (x, y) ? this : null;
2151   }
2152
2153   /**
2154    * Returns the component occupying the position (x,y). This will either
2155    * be this component, an immediate child component, or <code>null</code>
2156    * if neither of the first two occupies the specified location.
2157    *
2158    * @param p the point to search for components at
2159    * @return the component at the specified location, or null
2160    * @throws NullPointerException if p is null
2161    * @see #contains(Point)
2162    * @since 1.1
2163    */
2164   public Component getComponentAt(Point p)
2165   {
2166     return getComponentAt (p.x, p.y);
2167   }
2168
2169   /**
2170    * AWT 1.0 event dispatcher.
2171    *
2172    * @param e the event to dispatch
2173    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2174    */
2175   public void deliverEvent(Event e)
2176   {
2177     // XXX Add backward compatibility handling.
2178   }
2179
2180   /**
2181    * Forwards AWT events to processEvent() if:<ul>
2182    * <li>Events have been enabled for this type of event via
2183    * <code>enableEvents()</code></li>,
2184    * <li>There is at least one registered listener for this type of event</li>
2185    * </ul>
2186    *
2187    * @param e the event to dispatch
2188    */
2189   public final void dispatchEvent(AWTEvent e)
2190   {
2191     // Some subclasses in the AWT package need to override this behavior,
2192     // hence the use of dispatchEventImpl().
2193     dispatchEventImpl(e);
2194     if (peer != null && ! e.consumed)
2195       peer.handleEvent(e);
2196   }
2197
2198   /**
2199    * AWT 1.0 event dispatcher.
2200    *
2201    * @param e the event to dispatch
2202    * @return false: since the method was deprecated, the return has no meaning
2203    * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2204    */
2205   public boolean postEvent(Event e)
2206   {
2207     // XXX Add backward compatibility handling.
2208     return false;
2209   }
2210
2211   /**
2212    * Adds the specified listener to this component. This is harmless if the
2213    * listener is null, but if the listener has already been registered, it
2214    * will now be registered twice.
2215    *
2216    * @param listener the new listener to add
2217    * @see ComponentEvent
2218    * @see #removeComponentListener(ComponentListener)
2219    * @see #getComponentListeners()
2220    * @since 1.1
2221    */
2222   public synchronized void addComponentListener(ComponentListener l)
2223   {
2224     componentListener = AWTEventMulticaster.add(componentListener, l);
2225     if (componentListener != null)
2226       enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
2227   }
2228
2229   /**
2230    * Removes the specified listener from the component. This is harmless if
2231    * the listener was not previously registered.
2232    *
2233    * @param listener the listener to remove
2234    * @see ComponentEvent
2235    * @see #addComponentListener(ComponentListener)
2236    * @see #getComponentListeners()
2237    * @since 1.1
2238    */
2239   public synchronized void removeComponentListener(ComponentListener l)
2240   {
2241     componentListener = AWTEventMulticaster.remove(componentListener, l);
2242   }
2243
2244   /**
2245    * Returns an array of all specified listeners registered on this component.
2246    *
2247    * @return an array of listeners
2248    * @see #addComponentListener(ComponentListener)
2249    * @see #removeComponentListener(ComponentListener)
2250    * @since 1.4
2251    */
2252   public synchronized ComponentListener[] getComponentListeners()
2253   {
2254     return (ComponentListener[])
2255       AWTEventMulticaster.getListeners(componentListener,
2256                                        ComponentListener.class);
2257   }
2258
2259   /**
2260    * Adds the specified listener to this component. This is harmless if the
2261    * listener is null, but if the listener has already been registered, it
2262    * will now be registered twice.
2263    *
2264    * @param listener the new listener to add
2265    * @see FocusEvent
2266    * @see #removeFocusListener(FocusListener)
2267    * @see #getFocusListeners()
2268    * @since 1.1
2269    */
2270   public synchronized void addFocusListener(FocusListener l)
2271   {
2272     focusListener = AWTEventMulticaster.add(focusListener, l);
2273     if (focusListener != null)
2274       enableEvents(AWTEvent.FOCUS_EVENT_MASK);
2275   }
2276
2277   /**
2278    * Removes the specified listener from the component. This is harmless if
2279    * the listener was not previously registered.
2280    *
2281    * @param listener the listener to remove
2282    * @see FocusEvent
2283    * @see #addFocusListener(FocusListener)
2284    * @see #getFocusListeners()
2285    * @since 1.1
2286    */
2287   public synchronized void removeFocusListener(FocusListener l)
2288   {
2289     focusListener = AWTEventMulticaster.remove(focusListener, l);
2290   }
2291
2292   /**
2293    * Returns an array of all specified listeners registered on this component.
2294    *
2295    * @return an array of listeners
2296    * @see #addFocusListener(FocusListener)
2297    * @see #removeFocusListener(FocusListener)
2298    * @since 1.4
2299    */
2300   public synchronized FocusListener[] getFocusListeners()
2301   {
2302     return (FocusListener[])
2303       AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2304   }
2305
2306   /**
2307    * Adds the specified listener to this component. This is harmless if the
2308    * listener is null, but if the listener has already been registered, it
2309    * will now be registered twice.
2310    *
2311    * @param listener the new listener to add
2312    * @see HierarchyEvent
2313    * @see #removeHierarchyListener(HierarchyListener)
2314    * @see #getHierarchyListeners()
2315    * @since 1.3
2316    */
2317   public synchronized void addHierarchyListener(HierarchyListener l)
2318   {
2319     hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
2320     if (hierarchyListener != null)
2321       enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
2322   }
2323
2324   /**
2325    * Removes the specified listener from the component. This is harmless if
2326    * the listener was not previously registered.
2327    *
2328    * @param listener the listener to remove
2329    * @see HierarchyEvent
2330    * @see #addHierarchyListener(HierarchyListener)
2331    * @see #getHierarchyListeners()
2332    * @since 1.3
2333    */
2334   public synchronized void removeHierarchyListener(HierarchyListener l)
2335   {
2336     hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, l);
2337   }
2338
2339   /**
2340    * Returns an array of all specified listeners registered on this component.
2341    *
2342    * @return an array of listeners
2343    * @see #addHierarchyListener(HierarchyListener)
2344    * @see #removeHierarchyListener(HierarchyListener)
2345    * @since 1.4
2346    */
2347   public synchronized HierarchyListener[] getHierarchyListeners()
2348   {
2349     return (HierarchyListener[])
2350       AWTEventMulticaster.getListeners(hierarchyListener,
2351                                        HierarchyListener.class);
2352   }
2353
2354   /**
2355    * Adds the specified listener to this component. This is harmless if the
2356    * listener is null, but if the listener has already been registered, it
2357    * will now be registered twice.
2358    *
2359    * @param listener the new listener to add
2360    * @see HierarchyEvent
2361    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2362    * @see #getHierarchyBoundsListeners()
2363    * @since 1.3
2364    */
2365   public synchronized void
2366     addHierarchyBoundsListener(HierarchyBoundsListener l)
2367   {
2368     hierarchyBoundsListener =
2369       AWTEventMulticaster.add(hierarchyBoundsListener, l);
2370     if (hierarchyBoundsListener != null)
2371       enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2372   }
2373
2374   /**
2375    * Removes the specified listener from the component. This is harmless if
2376    * the listener was not previously registered.
2377    *
2378    * @param listener the listener to remove
2379    * @see HierarchyEvent
2380    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2381    * @see #getHierarchyBoundsListeners()
2382    * @since 1.3
2383    */
2384   public synchronized void
2385     removeHierarchyBoundsListener(HierarchyBoundsListener l)
2386   {
2387     hierarchyBoundsListener =
2388       AWTEventMulticaster.remove(hierarchyBoundsListener, l);
2389   }
2390
2391   /**
2392    * Returns an array of all specified listeners registered on this component.
2393    *
2394    * @return an array of listeners
2395    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2396    * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2397    * @since 1.4
2398    */
2399   public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
2400   {
2401     return (HierarchyBoundsListener[])
2402       AWTEventMulticaster.getListeners(hierarchyBoundsListener,
2403                                        HierarchyBoundsListener.class);
2404   }
2405
2406   /**
2407    * Adds the specified listener to this component. This is harmless if the
2408    * listener is null, but if the listener has already been registered, it
2409    * will now be registered twice.
2410    *
2411    * @param listener the new listener to add
2412    * @see KeyEvent
2413    * @see #removeKeyListener(KeyListener)
2414    * @see #getKeyListeners()
2415    * @since 1.1
2416    */
2417   public synchronized void addKeyListener(KeyListener l)
2418   {
2419     keyListener = AWTEventMulticaster.add(keyListener, l);
2420     if (keyListener != null)
2421       enableEvents(AWTEvent.KEY_EVENT_MASK);
2422   }
2423
2424   /**
2425    * Removes the specified listener from the component. This is harmless if
2426    * the listener was not previously registered.
2427    *
2428    * @param listener the listener to remove
2429    * @see KeyEvent
2430    * @see #addKeyListener(KeyListener)
2431    * @see #getKeyListeners()
2432    * @since 1.1
2433    */
2434   public synchronized void removeKeyListener(KeyListener l)
2435   {
2436     keyListener = AWTEventMulticaster.remove(keyListener, l);
2437   }
2438
2439   /**
2440    * Returns an array of all specified listeners registered on this component.
2441    *
2442    * @return an array of listeners
2443    * @see #addKeyListener(KeyListener)
2444    * @see #removeKeyListener(KeyListener)
2445    * @since 1.4
2446    */
2447   public synchronized KeyListener[] getKeyListeners()
2448   {
2449     return (KeyListener[])
2450       AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
2451   }
2452
2453   /**
2454    * Adds the specified listener to this component. This is harmless if the
2455    * listener is null, but if the listener has already been registered, it
2456    * will now be registered twice.
2457    *
2458    * @param listener the new listener to add
2459    * @see MouseEvent
2460    * @see #removeMouseListener(MouseListener)
2461    * @see #getMouseListeners()
2462    * @since 1.1
2463    */
2464   public synchronized void addMouseListener(MouseListener l)
2465   {
2466     mouseListener = AWTEventMulticaster.add(mouseListener, l);
2467     if (mouseListener != null)
2468       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2469   }
2470
2471   /**
2472    * Removes the specified listener from the component. This is harmless if
2473    * the listener was not previously registered.
2474    *
2475    * @param listener the listener to remove
2476    * @see MouseEvent
2477    * @see #addMouseListener(MouseListener)
2478    * @see #getMouseListeners()
2479    * @since 1.1
2480    */
2481   public synchronized void removeMouseListener(MouseListener l)
2482   {
2483     mouseListener = AWTEventMulticaster.remove(mouseListener, l);
2484   }
2485
2486   /**
2487    * Returns an array of all specified listeners registered on this component.
2488    *
2489    * @return an array of listeners
2490    * @see #addMouseListener(MouseListener)
2491    * @see #removeMouseListener(MouseListener)
2492    * @since 1.4
2493    */
2494   public synchronized MouseListener[] getMouseListeners()
2495   {
2496     return (MouseListener[])
2497       AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
2498   }
2499
2500   /**
2501    * Adds the specified listener to this component. This is harmless if the
2502    * listener is null, but if the listener has already been registered, it
2503    * will now be registered twice.
2504    *
2505    * @param listener the new listener to add
2506    * @see MouseEvent
2507    * @see #removeMouseMotionListener(MouseMotionListener)
2508    * @see #getMouseMotionListeners()
2509    * @since 1.1
2510    */
2511   public synchronized void addMouseMotionListener(MouseMotionListener l)
2512   {
2513     mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, l);
2514     if (mouseMotionListener != null)
2515       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2516   }
2517
2518   /**
2519    * Removes the specified listener from the component. This is harmless if
2520    * the listener was not previously registered.
2521    *
2522    * @param listener the listener to remove
2523    * @see MouseEvent
2524    * @see #addMouseMotionListener(MouseMotionListener)
2525    * @see #getMouseMotionListeners()
2526    * @since 1.1
2527    */
2528   public synchronized void removeMouseMotionListener(MouseMotionListener l)
2529   {
2530     mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
2531   }
2532
2533   /**
2534    * Returns an array of all specified listeners registered on this component.
2535    *
2536    * @return an array of listeners
2537    * @see #addMouseMotionListener(MouseMotionListener)
2538    * @see #removeMouseMotionListener(MouseMotionListener)
2539    * @since 1.4
2540    */
2541   public synchronized MouseMotionListener[] getMouseMotionListeners()
2542   {
2543     return (MouseMotionListener[])
2544       AWTEventMulticaster.getListeners(mouseMotionListener,
2545                                        MouseMotionListener.class);
2546   }
2547
2548   /**
2549    * Adds the specified listener to this component. This is harmless if the
2550    * listener is null, but if the listener has already been registered, it
2551    * will now be registered twice.
2552    *
2553    * @param listener the new listener to add
2554    * @see MouseEvent
2555    * @see MouseWheelEvent
2556    * @see #removeMouseWheelListener(MouseWheelListener)
2557    * @see #getMouseWheelListeners()
2558    * @since 1.4
2559    */
2560   public synchronized void addMouseWheelListener(MouseWheelListener l)
2561   {
2562     mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, l);
2563     if (mouseWheelListener != null)
2564       enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
2565   }
2566
2567   /**
2568    * Removes the specified listener from the component. This is harmless if
2569    * the listener was not previously registered.
2570    *
2571    * @param listener the listener to remove
2572    * @see MouseEvent
2573    * @see MouseWheelEvent
2574    * @see #addMouseWheelListener(MouseWheelListener)
2575    * @see #getMouseWheelListeners()
2576    * @since 1.4
2577    */
2578   public synchronized void removeMouseWheelListener(MouseWheelListener l)
2579   {
2580     mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
2581   }
2582
2583   /**
2584    * Returns an array of all specified listeners registered on this component.
2585    *
2586    * @return an array of listeners
2587    * @see #addMouseWheelListener(MouseWheelListener)
2588    * @see #removeMouseWheelListener(MouseWheelListener)
2589    * @since 1.4
2590    */
2591   public synchronized MouseWheelListener[] getMouseWheelListeners()
2592   {
2593     return (MouseWheelListener[])
2594       AWTEventMulticaster.getListeners(mouseWheelListener,
2595                                        MouseWheelListener.class);
2596   }
2597
2598   /**
2599    * Adds the specified listener to this component. This is harmless if the
2600    * listener is null, but if the listener has already been registered, it
2601    * will now be registered twice.
2602    *
2603    * @param listener the new listener to add
2604    * @see InputMethodEvent
2605    * @see #removeInputMethodListener(InputMethodListener)
2606    * @see #getInputMethodListeners()
2607    * @see #getInputMethodRequests()
2608    * @since 1.2
2609    */
2610   public synchronized void addInputMethodListener(InputMethodListener l)
2611   {
2612     inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
2613     if (inputMethodListener != null)
2614       enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
2615   }
2616
2617   /**
2618    * Removes the specified listener from the component. This is harmless if
2619    * the listener was not previously registered.
2620    *
2621    * @param listener the listener to remove
2622    * @see InputMethodEvent
2623    * @see #addInputMethodListener(InputMethodListener)
2624    * @see #getInputMethodRequests()
2625    * @since 1.2
2626    */
2627   public synchronized void removeInputMethodListener(InputMethodListener l)
2628   {
2629     inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
2630   }
2631
2632   /**
2633    * Returns an array of all specified listeners registered on this component.
2634    *
2635    * @return an array of listeners
2636    * @see #addInputMethodListener(InputMethodListener)
2637    * @see #removeInputMethodListener(InputMethodListener)
2638    * @since 1.4
2639    */
2640   public synchronized InputMethodListener[] getInputMethodListeners()
2641   {
2642     return (InputMethodListener[])
2643       AWTEventMulticaster.getListeners(inputMethodListener,
2644                                        InputMethodListener.class);
2645   }
2646
2647   /**
2648    * Returns all registered EventListers of the given listenerType.
2649    *
2650    * @param listenerType the class of listeners to filter
2651    * @return an array of registered listeners
2652    * @see #getComponentListeners()
2653    * @see #getFocusListeners()
2654    * @see #getHierarchyListeners()
2655    * @see #getHierarchyBoundsListeners()
2656    * @see #getKeyListeners()
2657    * @see #getMouseListeners()
2658    * @see #getMouseMotionListeners()
2659    * @see #getMouseWheelListeners()
2660    * @see #getInputMethodListeners()
2661    * @see #getPropertyChangeListeners()
2662    * @since 1.3
2663    */
2664   public EventListener[] getListeners(Class listenerType)
2665   {
2666     if (listenerType == ComponentListener.class)
2667       return getComponentListeners();
2668     if (listenerType == FocusListener.class)
2669       return getFocusListeners();
2670     if (listenerType == HierarchyListener.class)
2671       return getHierarchyListeners();
2672     if (listenerType == HierarchyBoundsListener.class)
2673       return getHierarchyBoundsListeners();
2674     if (listenerType == KeyListener.class)
2675       return getKeyListeners();
2676     if (listenerType == MouseListener.class)
2677       return getMouseListeners();
2678     if (listenerType == MouseMotionListener.class)
2679       return getMouseMotionListeners();
2680     if (listenerType == MouseWheelListener.class)
2681       return getMouseWheelListeners();
2682     if (listenerType == InputMethodListener.class)
2683       return getInputMethodListeners();
2684     if (listenerType == PropertyChangeListener.class)
2685       return getPropertyChangeListeners();
2686     return (EventListener[]) Array.newInstance(listenerType, 0);
2687   }
2688
2689   /**
2690    * Returns the input method request handler, for subclasses which support
2691    * on-the-spot text input. By default, input methods are handled by AWT,
2692    * and this returns null.
2693    *
2694    * @return the input method handler, null by default
2695    * @since 1.2
2696    */
2697   public InputMethodRequests getInputMethodRequests()
2698   {
2699     return null;
2700   }
2701
2702   /**
2703    * Gets the input context of this component, which is inherited from the
2704    * parent unless this is overridden.
2705    *
2706    * @return the text input context
2707    * @since 1.2
2708    */
2709   public InputContext getInputContext()
2710   {
2711     return parent == null ? null : parent.getInputContext();
2712   }
2713
2714   /**
2715    * Enables the specified events. The events to enable are specified
2716    * by OR-ing together the desired masks from <code>AWTEvent</code>.
2717    *
2718    * <p>Events are enabled by default when a listener is attached to the
2719    * component for that event type. This method can be used by subclasses
2720    * to ensure the delivery of a specified event regardless of whether
2721    * or not a listener is attached.
2722    *
2723    * @param eventsToEnable the desired events to enable
2724    * @see #processEvent(AWTEvent)
2725    * @see #disableEvents(long)
2726    * @see AWTEvent
2727    * @since 1.1
2728    */
2729   protected final void enableEvents(long eventsToEnable)
2730   {
2731     eventMask |= eventsToEnable;
2732     // TODO: Unlike Sun's implementation, I think we should try and
2733     // enable/disable events at the peer (gtk/X) level. This will avoid
2734     // clogging the event pipeline with useless mousemove events that
2735     // we arn't interested in, etc. This will involve extending the peer
2736     // interface, but thats okay because the peer interfaces have been
2737     // deprecated for a long time, and no longer feature in the
2738     // API specification at all.
2739     if (isLightweight() && parent != null)
2740       parent.enableEvents(eventsToEnable);
2741     else if (peer != null)
2742       peer.setEventMask(eventMask);
2743   }
2744
2745   /**
2746    * Disables the specified events. The events to disable are specified
2747    * by OR-ing together the desired masks from <code>AWTEvent</code>.
2748    *
2749    * @param eventsToDisable the desired events to disable
2750    * @see #enableEvents(long)
2751    * @since 1.1
2752    */
2753   protected final void disableEvents(long eventsToDisable)
2754   {
2755     eventMask &= ~eventsToDisable;
2756     // forward new event mask to peer?
2757   }
2758
2759   /**
2760    * This is called by the EventQueue if two events with the same event id
2761    * and owner component are queued. Returns a new combined event, or null if
2762    * no combining is done. The coelesced events are currently mouse moves
2763    * (intermediate ones are discarded) and paint events (a merged paint is
2764    * created in place of the two events).
2765    *
2766    * @param existingEvent the event on the queue
2767    * @param newEvent the new event that might be entered on the queue
2768    * @return null if both events are kept, or the replacement coelesced event
2769    */
2770   protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
2771   {
2772     switch (existingEvent.id)
2773       {
2774       case MouseEvent.MOUSE_MOVED:
2775       case MouseEvent.MOUSE_DRAGGED:
2776         // Just drop the old (intermediate) event and return the new one.
2777         return newEvent;
2778       case PaintEvent.PAINT:
2779       case PaintEvent.UPDATE:
2780         return coalescePaintEvents((PaintEvent) existingEvent,
2781                                    (PaintEvent) newEvent);
2782       default:
2783         return null;
2784       }
2785   }
2786
2787   /**
2788    * Processes the specified event. In this class, this method simply
2789    * calls one of the more specific event handlers.
2790    *
2791    * @param event the event to process
2792    * @throws NullPointerException if e is null
2793    * @see #processComponentEvent(ComponentEvent)
2794    * @see #processFocusEvent(FocusEvent)
2795    * @see #processKeyEvent(KeyEvent)
2796    * @see #processMouseEvent(MouseEvent)
2797    * @see #processMouseMotionEvent(MouseEvent)
2798    * @see #processInputMethodEvent(InputMethodEvent)
2799    * @see #processHierarchyEvent(HierarchyEvent)
2800    * @see #processMouseWheelEvent(MouseWheelEvent)
2801    * @since 1.1
2802    */
2803   protected void processEvent(AWTEvent e)
2804   {
2805     /* Note: the order of these if statements are
2806        important. Subclasses must be checked first. Eg. MouseEvent
2807        must be checked before ComponentEvent, since a MouseEvent
2808        object is also an instance of a ComponentEvent. */
2809
2810     if (e instanceof FocusEvent)
2811       processFocusEvent((FocusEvent) e);
2812     else if (e instanceof MouseWheelEvent)
2813       processMouseWheelEvent((MouseWheelEvent) e);
2814     else if (e instanceof MouseEvent)
2815       {
2816         if (e.id == MouseEvent.MOUSE_MOVED
2817             || e.id == MouseEvent.MOUSE_DRAGGED)
2818           processMouseMotionEvent((MouseEvent) e);
2819         else
2820           processMouseEvent((MouseEvent) e);
2821       }
2822     else if (e instanceof KeyEvent)
2823       processKeyEvent((KeyEvent) e);
2824     else if (e instanceof InputMethodEvent)
2825       processInputMethodEvent((InputMethodEvent) e);
2826     else if (e instanceof ComponentEvent)
2827       processComponentEvent((ComponentEvent) e);
2828     else if (e instanceof HierarchyEvent)
2829       {
2830         if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
2831           processHierarchyEvent((HierarchyEvent) e);
2832         else
2833           processHierarchyBoundsEvent((HierarchyEvent) e);
2834       }
2835   }
2836
2837   /**
2838    * Called when a component event is dispatched and component events are
2839    * enabled. This method passes the event along to any listeners
2840    * that are attached.
2841    *
2842    * @param event the <code>ComponentEvent</code> to process
2843    * @throws NullPointerException if e is null
2844    * @see ComponentListener
2845    * @see #addComponentListener(ComponentListener)
2846    * @see #enableEvents(long)
2847    * @since 1.1
2848    */
2849   protected void processComponentEvent(ComponentEvent e)
2850   {
2851     if (componentListener == null)
2852       return;
2853     switch (e.id)
2854       {
2855       case ComponentEvent.COMPONENT_HIDDEN:
2856         componentListener.componentHidden(e);
2857         break;
2858       case ComponentEvent.COMPONENT_MOVED:
2859         componentListener.componentMoved(e);
2860         break;
2861       case ComponentEvent.COMPONENT_RESIZED:
2862         componentListener.componentResized(e);
2863         break;
2864       case ComponentEvent.COMPONENT_SHOWN:
2865         componentListener.componentShown(e);
2866         break;
2867       }
2868   }
2869
2870   /**
2871    * Called when a focus event is dispatched and component events are
2872    * enabled. This method passes the event along to any listeners
2873    * that are attached.
2874    *
2875    * @param event the <code>FocusEvent</code> to process
2876    * @throws NullPointerException if e is null
2877    * @see FocusListener
2878    * @see #addFocusListener(FocusListener)
2879    * @see #enableEvents(long)
2880    * @since 1.1
2881    */
2882   protected void processFocusEvent(FocusEvent e)
2883   {
2884     if (focusListener == null)
2885       return;
2886     switch (e.id)
2887       {
2888         case FocusEvent.FOCUS_GAINED:
2889           focusListener.focusGained(e);
2890         break;
2891         case FocusEvent.FOCUS_LOST:
2892           focusListener.focusLost(e);
2893         break;
2894       }
2895   }
2896
2897   /**
2898    * Called when a key event is dispatched and component events are
2899    * enabled. This method passes the event along to any listeners
2900    * that are attached.
2901    *
2902    * @param event the <code>KeyEvent</code> to process
2903    * @throws NullPointerException if e is null
2904    * @see KeyListener
2905    * @see #addKeyListener(KeyListener)
2906    * @see #enableEvents(long)
2907    * @since 1.1
2908    */
2909   protected void processKeyEvent(KeyEvent e)
2910   {
2911     if (keyListener == null)
2912       return;
2913     switch (e.id)
2914       {
2915         case KeyEvent.KEY_PRESSED:
2916           keyListener.keyPressed(e);
2917         break;
2918         case KeyEvent.KEY_RELEASED:
2919           keyListener.keyReleased(e);
2920         break;
2921         case KeyEvent.KEY_TYPED:
2922           keyListener.keyTyped(e);
2923         break;
2924       }
2925   }
2926
2927   /**
2928    * Called when a regular mouse event is dispatched and component events are
2929    * enabled. This method passes the event along to any listeners
2930    * that are attached.
2931    *
2932    * @param event the <code>MouseEvent</code> to process
2933    * @throws NullPointerException if e is null
2934    * @see MouseListener
2935    * @see #addMouseListener(MouseListener)
2936    * @see #enableEvents(long)
2937    * @since 1.1
2938    */
2939   protected void processMouseEvent(MouseEvent e)
2940   {
2941     if (mouseListener == null)
2942       return;
2943     switch (e.id)
2944       {
2945         case MouseEvent.MOUSE_CLICKED:
2946           mouseListener.mouseClicked(e);
2947         break;
2948         case MouseEvent.MOUSE_ENTERED:
2949           mouseListener.mouseEntered(e);
2950         break;
2951         case MouseEvent.MOUSE_EXITED:
2952           mouseListener.mouseExited(e);
2953         break;
2954         case MouseEvent.MOUSE_PRESSED:
2955           mouseListener.mousePressed(e);
2956         break;
2957         case MouseEvent.MOUSE_RELEASED:
2958           mouseListener.mouseReleased(e);
2959         break;
2960       }
2961   }
2962
2963   /**
2964    * Called when a mouse motion event is dispatched and component events are
2965    * enabled. This method passes the event along to any listeners
2966    * that are attached.
2967    *
2968    * @param event the <code>MouseMotionEvent</code> to process
2969    * @throws NullPointerException if e is null
2970    * @see MouseMotionListener
2971    * @see #addMouseMotionListener(MouseMotionListener)
2972    * @see #enableEvents(long)
2973    * @since 1.1
2974    */
2975   protected void processMouseMotionEvent(MouseEvent e)
2976   {
2977     if (mouseMotionListener == null)
2978       return;
2979     switch (e.id)
2980       {
2981         case MouseEvent.MOUSE_DRAGGED:
2982           mouseMotionListener.mouseDragged(e);
2983         break;
2984         case MouseEvent.MOUSE_MOVED:
2985           mouseMotionListener.mouseMoved(e);
2986         break;
2987       }
2988   }
2989
2990   /**
2991    * Called when a mouse wheel event is dispatched and component events are
2992    * enabled. This method passes the event along to any listeners that are
2993    * attached.
2994    *
2995    * @param event the <code>MouseWheelEvent</code> to process
2996    * @throws NullPointerException if e is null
2997    * @see MouseWheelListener
2998    * @see #addMouseWheelListener(MouseWheelListener)
2999    * @see #enableEvents(long)
3000    * @since 1.4
3001    */
3002   protected void processMouseWheelEvent(MouseWheelEvent e)
3003   {
3004     if (mouseWheelListener != null
3005         && e.id == MouseEvent.MOUSE_WHEEL)
3006       mouseWheelListener.mouseWheelMoved(e);
3007   }
3008
3009   /**
3010    * Called when an input method event is dispatched and component events are
3011    * enabled. This method passes the event along to any listeners that are
3012    * attached.
3013    *
3014    * @param event the <code>InputMethodEvent</code> to process
3015    * @throws NullPointerException if e is null
3016    * @see InputMethodListener
3017    * @see #addInputMethodListener(InputMethodListener)
3018    * @see #enableEvents(long)
3019    * @since 1.2
3020    */
3021   protected void processInputMethodEvent(InputMethodEvent e)
3022   {
3023     if (inputMethodListener == null)
3024       return;
3025     switch (e.id)
3026       {
3027         case InputMethodEvent.CARET_POSITION_CHANGED:
3028           inputMethodListener.caretPositionChanged(e);
3029         break;
3030         case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3031           inputMethodListener.inputMethodTextChanged(e);
3032         break;
3033       }
3034   }
3035
3036   /**
3037    * Called when a hierarchy change event is dispatched and component events
3038    * are enabled. This method passes the event along to any listeners that are
3039    * attached.
3040    *
3041    * @param event the <code>HierarchyEvent</code> to process
3042    * @throws NullPointerException if e is null
3043    * @see HierarchyListener
3044    * @see #addHierarchyListener(HierarchyListener)
3045    * @see #enableEvents(long)
3046    * @since 1.3
3047    */
3048   protected void processHierarchyEvent(HierarchyEvent e)
3049   {
3050     if (hierarchyListener == null)
3051       return;
3052     if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3053       hierarchyListener.hierarchyChanged(e);
3054   }
3055
3056   /**
3057    * Called when a hierarchy bounds event is dispatched and component events
3058    * are enabled. This method passes the event along to any listeners that are
3059    * attached.
3060    *
3061    * @param event the <code>HierarchyEvent</code> to process
3062    * @throws NullPointerException if e is null
3063    * @see HierarchyBoundsListener
3064    * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3065    * @see #enableEvents(long)
3066    * @since 1.3
3067    */
3068   protected void processHierarchyBoundsEvent(HierarchyEvent e)
3069   {
3070     if (hierarchyBoundsListener == null)
3071       return;
3072     switch (e.id)
3073       {
3074         case HierarchyEvent.ANCESTOR_MOVED:
3075           hierarchyBoundsListener.ancestorMoved(e);
3076         break;
3077         case HierarchyEvent.ANCESTOR_RESIZED:
3078           hierarchyBoundsListener.ancestorResized(e);
3079         break;
3080       }
3081   }
3082
3083   /**
3084    * AWT 1.0 event processor.
3085    *
3086    * @param evt the event to handle
3087    * @return false: since the method was deprecated, the return has no meaning
3088    * @deprecated use {@link #processEvent(AWTEvent)} instead
3089    */
3090   public boolean handleEvent(Event evt)
3091   {
3092     // XXX Add backward compatibility handling.
3093     return false;
3094   }
3095
3096   /**
3097    * AWT 1.0 mouse event.
3098    *
3099    * @param evt the event to handle
3100    * @param x the x coordinate, ignored
3101    * @param y the y coordinate, ignored
3102    * @return false: since the method was deprecated, the return has no meaning
3103    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3104    */
3105   public boolean mouseDown(Event evt, int x, int y)
3106   {
3107     // XXX Add backward compatibility handling.
3108     return false;
3109   }
3110
3111   /**
3112    * AWT 1.0 mouse event.
3113    *
3114    * @param evt the event to handle
3115    * @param x the x coordinate, ignored
3116    * @param y the y coordinate, ignored
3117    * @return false: since the method was deprecated, the return has no meaning
3118    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3119    */
3120   public boolean mouseDrag(Event evt, int x, int y)
3121   {
3122     // XXX Add backward compatibility handling.
3123     return false;
3124   }
3125
3126   /**
3127    * AWT 1.0 mouse event.
3128    *
3129    * @param evt the event to handle
3130    * @param x the x coordinate, ignored
3131    * @param y the y coordinate, ignored
3132    * @return false: since the method was deprecated, the return has no meaning
3133    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3134    */
3135   public boolean mouseUp(Event evt, int x, int y)
3136   {
3137     // XXX Add backward compatibility handling.
3138     return false;
3139   }
3140
3141   /**
3142    * AWT 1.0 mouse event.
3143    *
3144    * @param evt the event to handle
3145    * @param x the x coordinate, ignored
3146    * @param y the y coordinate, ignored
3147    * @return false: since the method was deprecated, the return has no meaning
3148    * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
3149    */
3150   public boolean mouseMove(Event evt, int x, int y)
3151   {
3152     // XXX Add backward compatibility handling.
3153     return false;
3154   }
3155
3156   /**
3157    * AWT 1.0 mouse event.
3158    *
3159    * @param evt the event to handle
3160    * @param x the x coordinate, ignored
3161    * @param y the y coordinate, ignored
3162    * @return false: since the method was deprecated, the return has no meaning
3163    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3164    */
3165   public boolean mouseEnter(Event evt, int x, int y)
3166   {
3167     // XXX Add backward compatibility handling.
3168     return false;
3169   }
3170
3171   /**
3172    * AWT 1.0 mouse event.
3173    *
3174    * @param evt the event to handle
3175    * @param x the x coordinate, ignored
3176    * @param y the y coordinate, ignored
3177    * @return false: since the method was deprecated, the return has no meaning
3178    * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
3179    */
3180   public boolean mouseExit(Event evt, int x, int y)
3181   {
3182     // XXX Add backward compatibility handling.
3183     return false;
3184   }
3185
3186   /**
3187    * AWT 1.0 key press event.
3188    *
3189    * @param evt the event to handle
3190    * @param key the key pressed, ignored
3191    * @return false: since the method was deprecated, the return has no meaning
3192    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3193    */
3194   public boolean keyDown(Event evt, int key)
3195   {
3196     // XXX Add backward compatibility handling.
3197     return false;
3198   }
3199
3200   /**
3201    * AWT 1.0 key press event.
3202    *
3203    * @param evt the event to handle
3204    * @param key the key pressed, ignored
3205    * @return false: since the method was deprecated, the return has no meaning
3206    * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
3207    */
3208   public boolean keyUp(Event evt, int key)
3209   {
3210     // XXX Add backward compatibility handling.
3211     return false;
3212   }
3213
3214   /**
3215    * AWT 1.0 action event processor.
3216    *
3217    * @param evt the event to handle
3218    * @param what the object acted on, ignored
3219    * @return false: since the method was deprecated, the return has no meaning
3220    * @deprecated in classes which support actions, use
3221    *             <code>processActionEvent(ActionEvent)</code> instead
3222    */
3223   public boolean action(Event evt, Object what)
3224   {
3225     // XXX Add backward compatibility handling.
3226     return false;
3227   }
3228
3229   /**
3230    * Called to inform this component it has been added to a container.
3231    * A native peer - if any - is created at this time. This method is
3232    * called automatically by the AWT system and should not be called by
3233    * user level code.
3234    *
3235    * @see #isDisplayable()
3236    * @see #removeNotify()
3237    */
3238   public void addNotify()
3239   {
3240     if (peer == null)
3241       peer = getToolkit().createComponent(this);
3242     /* Now that all the children has gotten their peers, we should
3243        have the event mask needed for this component and its
3244        lightweight subcomponents. */
3245     peer.setEventMask(eventMask);
3246     /* We do not invalidate here, but rather leave that job up to
3247        the peer. For efficiency, the peer can choose not to
3248        invalidate if it is happy with the current dimensions,
3249        etc. */
3250   }
3251
3252   /**
3253    * Called to inform this component is has been removed from its
3254    * container. Its native peer - if any - is destroyed at this time.
3255    * This method is called automatically by the AWT system and should
3256    * not be called by user level code.
3257    *
3258    * @see #isDisplayable()
3259    * @see #addNotify()
3260    */
3261   public void removeNotify()
3262   {
3263     if (peer != null)
3264       peer.dispose();
3265     peer = null;
3266   }
3267
3268   /**
3269    * AWT 1.0 focus event.
3270    *
3271    * @param evt the event to handle
3272    * @param what the Object focused, ignored
3273    * @return false: since the method was deprecated, the return has no meaning
3274    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3275    */
3276   public boolean gotFocus(Event evt, Object what)
3277   {
3278     // XXX Add backward compatibility handling.
3279     return false;
3280   }
3281
3282   /**
3283    * AWT 1.0 focus event.
3284    *
3285    * @param evt the event to handle
3286    * @param what the Object focused, ignored
3287    * @return false: since the method was deprecated, the return has no meaning
3288    * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
3289    */
3290   public boolean lostFocus(Event evt, Object what)
3291   {
3292     // XXX Add backward compatibility handling.
3293     return false;
3294   }
3295
3296   /**
3297    * Tests whether or not this component is in the group that can be
3298    * traversed using the keyboard traversal mechanism (such as the TAB key).
3299    *
3300    * @return true if the component is traversed via the TAB key
3301    * @see #setFocusable(boolean)
3302    * @since 1.1
3303    * @deprecated use {@link #isFocusable()} instead
3304    */
3305   public boolean isFocusTraversable()
3306   {
3307     return enabled && visible && (peer == null || peer.isFocusTraversable());
3308   }
3309
3310   /**
3311    * Tests if this component can receive focus.
3312    *
3313    * @return true if this component can receive focus
3314    * @since 1.4
3315    */
3316   public boolean isFocusable()
3317   {
3318     return focusable;
3319   }
3320
3321   /**
3322    * Specify whether this component can receive focus.
3323    *
3324    * @param focusable the new focusable status
3325    * @since 1.4
3326    */
3327   public void setFocusable(boolean focusable)
3328   {
3329     firePropertyChange("focusable", this.focusable, focusable);
3330     this.focusable = focusable;
3331   }
3332
3333   /**
3334    * Sets the focus traversal keys for a given type of focus events. Normally,
3335    * the default values should match the operating system's native choices. To
3336    * disable a given traversal, use <code>Collections.EMPTY_SET</code>. The
3337    * event dispatcher will consume PRESSED, RELEASED, and TYPED events for the
3338    * specified key, although focus can only transfer on PRESSED or RELEASED.
3339    *
3340    * <p>The defauts are:
3341    * <table>
3342    *   <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
3343    *   <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
3344    *     <td>Normal forward traversal</td>
3345    *     <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
3346    *   <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
3347    *     <td>Normal backward traversal</td>
3348    *     <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
3349    *   <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
3350    *     <td>Go up a traversal cycle</td><td>None</td></tr>
3351    * </table>
3352    *
3353    * <p>Specifying null allows inheritance from the parent, or from the current
3354    * KeyboardFocusManager default set. If not null, the set must contain only
3355    * AWTKeyStrokes that are not already focus keys and are not KEY_TYPED
3356    * events.
3357    *
3358    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3359    *        UP_CYCLE_TRAVERSAL_KEYS
3360    * @param keystrokes a set of keys, or null
3361    * @throws IllegalArgumentException if id or keystrokes is invalid
3362    * @see #getFocusTraversalKeys(int)
3363    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3364    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3365    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3366    * @since 1.4
3367    */
3368   public void setFocusTraversalKeys(int id, Set keystrokes)
3369   {
3370     if (keystrokes == null)
3371       throw new IllegalArgumentException();
3372     Set sa;
3373     Set sb;
3374     String name;
3375     switch (id)
3376       {
3377       case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
3378         sa = getFocusTraversalKeys
3379           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3380         sb = getFocusTraversalKeys
3381           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3382         name = "forwardFocusTraversalKeys";
3383         break;
3384       case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
3385         sa = getFocusTraversalKeys
3386           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3387         sb = getFocusTraversalKeys
3388           (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
3389         name = "backwardFocusTraversalKeys";
3390         break;
3391       case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
3392         sa = getFocusTraversalKeys
3393           (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
3394         sb = getFocusTraversalKeys
3395           (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
3396         name = "upCycleFocusTraversalKeys";
3397         break;
3398       default:
3399         throw new IllegalArgumentException();
3400       }
3401     int i = keystrokes.size();
3402     Iterator iter = keystrokes.iterator();
3403     while (--i >= 0)
3404       {
3405         Object o = iter.next();
3406         if (! (o instanceof AWTKeyStroke)
3407             || sa.contains(o) || sb.contains(o)
3408             || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
3409           throw new IllegalArgumentException();
3410       }
3411     if (focusTraversalKeys == null)
3412       focusTraversalKeys = new Set[3];
3413     keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes));
3414     firePropertyChange(name, focusTraversalKeys[id], keystrokes);
3415     focusTraversalKeys[id] = keystrokes;
3416   }
3417
3418   /**
3419    * Returns the set of keys for a given focus traversal action, as defined
3420    * in <code>setFocusTraversalKeys</code>. If not set, this is inherited from
3421    * the parent component, which may have gotten it from the
3422    * KeyboardFocusManager.
3423    *
3424    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3425    *        UP_CYCLE_TRAVERSAL_KEYS
3426    * @throws IllegalArgumentException if id is invalid
3427    * @see #setFocusTraversalKeys(int, Set)
3428    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3429    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3430    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3431    * @since 1.4
3432    */
3433   public Set getFocusTraversalKeys(int id)
3434   {
3435     if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
3436         || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3437       throw new IllegalArgumentException();
3438     Set s = null;
3439     if (focusTraversalKeys != null)
3440       s = focusTraversalKeys[id];
3441     if (s == null && parent != null)
3442       s = parent.getFocusTraversalKeys(id);
3443     return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
3444                         .getDefaultFocusTraversalKeys(id)) : s;
3445   }
3446
3447   /**
3448    * Tests whether the focus traversal keys for a given action are explicitly
3449    * set or inherited.
3450    *
3451    * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
3452    *        UP_CYCLE_TRAVERSAL_KEYS
3453    * @return true if that set is explicitly specified
3454    * @throws IllegalArgumentException if id is invalid
3455    * @see #getFocusTraversalKeys(int)
3456    * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3457    * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3458    * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3459    * @since 1.4
3460    */
3461   public boolean areFocusTraversalKeysSet(int id)
3462   {
3463     if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS
3464         || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
3465       throw new IllegalArgumentException();
3466     return focusTraversalKeys != null && focusTraversalKeys[id] != null;
3467   }
3468
3469   /**
3470    * Sets whether focus traversal keys are enabled, which consumes traversal
3471    * keys and performs the focus event automatically.
3472    *
3473    * @param focusTraversalKeysEnabled the new value of the flag
3474    * @see #getFocusTraversalKeysEnabled()
3475    * @see #setFocusTraversalKeys(int, Set)
3476    * @see #getFocusTraversalKeys(int)
3477    * @since 1.4
3478    */
3479   public void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)
3480   {
3481     firePropertyChange("focusTraversalKeysEnabled",
3482                        this.focusTraversalKeysEnabled,
3483                        focusTraversalKeysEnabled);
3484     this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
3485   }
3486
3487   /**
3488    * Tests whether focus traversal keys are enabled. If they are, then focus
3489    * traversal keys are consumed and focus events performed automatically,
3490    * without the component seeing the keystrokes.
3491    *
3492    * @return true if focus traversal is enabled
3493    * @see #setFocusTraversalKeysEnabled(boolean)
3494    * @see #setFocusTraversalKeys(int, Set)
3495    * @see #getFocusTraversalKeys(int)
3496    * @since 1.4
3497    */
3498   public boolean getFocusTraversalKeysEnabled()
3499   {
3500     return focusTraversalKeysEnabled;
3501   }
3502
3503   /**
3504    * Requests that this component be given focus. A <code>FOCUS_GAINED</code>
3505    * event will be fired if and only if this request is successful. To be
3506    * successful, the component must be displayable, visible, and focusable,
3507    * and the top-level Window must be able to receive focus. Thus, this
3508    * request may fail, or be delayed until the window receives focus. It is
3509    * recommended that <code>requestFocusInWindow</code> be used where
3510    * possible to be more platform-independent.
3511    *
3512    * @see #requestFocusInWindow()
3513    * @see FocusEvent
3514    * @see #addFocusListener(FocusListener)
3515    * @see #isFocusable()
3516    * @see #isDisplayable()
3517    * @see KeyboardFocusManager#clearGlobalFocusOwner()
3518    */
3519   public void requestFocus()
3520   {
3521     // If there's no peer then this component can't get the focus. We
3522     // treat it as a silent rejection of the request.
3523     if (peer != null)
3524       peer.requestFocus();
3525   }
3526
3527   /**
3528    * Requests that this component be given focus. A <code>FOCUS_GAINED</code>
3529    * event will be fired if and only if this request is successful. To be
3530    * successful, the component must be displayable, visible, and focusable,
3531    * and the top-level Window must be able to receive focus. Thus, this
3532    * request may fail, or be delayed until the window receives focus. It is
3533    * recommended that <code>requestFocusInWindow</code> be used where
3534    * possible to be more platform-independent.
3535    *
3536    * <p>If the return value is false, the request is guaranteed to fail. If
3537    * it is true, it will likely succeed unless the action is vetoed or
3538    * something in the native windowing system intervenes. The temporary flag,
3539    * and thus this method in general, is not designed for public use; rather
3540    * it is a hook for lightweight components to notify their container in
3541    * an attempt to reduce the amount of repainting necessary.
3542    *
3543    * @param temporary true if the focus request is temporary
3544    * @return true if the request has a chance of success
3545    * @see #requestFocusInWindow()
3546    * @see FocusEvent
3547    * @see #addFocusListener(FocusListener)
3548    * @see #isFocusable()
3549    * @see #isDisplayable()
3550    * @see KeyboardFocusManager#clearGlobalFocusOwner()
3551    * @since 1.4
3552    */
3553   protected boolean requestFocus(boolean temporary)
3554   {
3555     // XXX Implement correctly.
3556     requestFocus();
3557     return true;
3558   }
3559
3560   /**
3561    * Requests that this component be given focus, if it resides in the
3562    * top-level window which already has focus. A <code>FOCUS_GAINED</code>
3563    * event will be fired if and only if this request is successful. To be
3564    * successful, the component must be displayable, visible, and focusable,
3565    * and the top-level Window must be focused.
3566    *
3567    * <p>If the return value is false, the request is guaranteed to fail. If
3568    * it is true, it will likely succeed unless the action is vetoed or
3569    * something in the native windowing system intervenes. The temporary flag,
3570    * and thus this method in general, is not designed for public use; rather
3571    * it is a hook for lightweight components to notify their container in
3572    * an attempt to reduce the amount of repainting necessary.
3573    *
3574    * @return true if the request has a chance of success
3575    * @see #requestFocus()
3576    * @see FocusEvent
3577    * @see #addFocusListener(FocusListener)
3578    * @see #isFocusable()
3579    * @see #isDisplayable()
3580    * @see KeyboardFocusManager#clearGlobalFocusOwner()
3581    * @since 1.4
3582    */
3583   public boolean requestFocusInWindow()
3584   {
3585     // XXX Implement correctly.
3586     requestFocus();
3587     return true;
3588   }
3589
3590   /**
3591    * Requests that this component be given focus, if it resides in the
3592    * top-level window which already has focus. A <code>FOCUS_GAINED</code>
3593    * event will be fired if and only if this request is successful. To be
3594    * successful, the component must be displayable, visible, and focusable,
3595    * and the top-level Window must be focused.
3596    *
3597    * <p>If the return value is false, the request is guaranteed to fail. If
3598    * it is true, it will likely succeed unless the action is vetoed or
3599    * something in the native windowing system intervenes. The temporary flag,
3600    * and thus this method in general, is not designed for public use; rather
3601    * it is a hook for lightweight components to notify their container in
3602    * an attempt to reduce the amount of repainting necessary.
3603    *
3604    * @param temporary true if the focus request is temporary
3605    * @return true if the request has a chance of success
3606    * @see #requestFocus()
3607    * @see FocusEvent
3608    * @see #addFocusListener(FocusListener)
3609    * @see #isFocusable()
3610    * @see #isDisplayable()
3611    * @see KeyboardFocusManager#clearGlobalFocusOwner()
3612    * @since 1.4
3613    */
3614   protected boolean requestFocusInWindow(boolean temporary)
3615   {
3616     // XXX Implement correctly.
3617     requestFocus();
3618     return true;
3619   }
3620
3621   /**
3622    * Transfers focus to the next component in the focus traversal order, as
3623    * though this were the current focus owner.
3624    *
3625    * @see #requestFocus()
3626    * @since 1.1
3627    */
3628   public void transferFocus()
3629   {
3630     Component next;
3631     if (parent == null)
3632       next = findNextFocusComponent(null);
3633     else
3634       next = parent.findNextFocusComponent(this);
3635     if (next != null && next != this)
3636       next.requestFocus();
3637   }
3638
3639   /**
3640    * Returns the root container that owns the focus cycle where this component
3641    * resides. A focus cycle root is in two cycles, one as the ancestor, and
3642    * one as the focusable element; this call always returns the ancestor.
3643    *
3644    * @return the ancestor container that owns the focus cycle
3645    * @since 1.4
3646    */
3647   public Container getFocusCycleRootAncestor()
3648   {
3649     // XXX Implement.
3650     throw new Error("not implemented");
3651   }
3652
3653   /**
3654    * Tests if the container is the ancestor of the focus cycle that this
3655    * component belongs to.
3656    *
3657    * @param c the container to test
3658    * @return true if c is the focus cycle root
3659    * @since 1.4
3660    */
3661   public boolean isFocusCycleRoot(Container c)
3662   {
3663     return c == getFocusCycleRootAncestor();
3664   }
3665
3666   /**
3667    * AWT 1.0 focus event processor.
3668    *
3669    * @deprecated use {@link #transferFocus()} instead
3670    */
3671   public void nextFocus()
3672   {
3673     transferFocus();
3674   }
3675
3676   /**
3677    * Transfers focus to the previous component in the focus traversal order, as
3678    * though this were the current focus owner.
3679    *
3680    * @see #requestFocus()
3681    * @since 1.4
3682    */
3683   public void transferFocusBackward()
3684   {
3685     // XXX Implement.
3686     throw new Error("not implemented");
3687   }
3688
3689   /**
3690    * Transfers focus to the focus cycle root of this component. However, if
3691    * this is a Window, the default focus owner in the window in the current
3692    * focus cycle is focused instead.
3693    *
3694    * @see #requestFocus()
3695    * @see #isFocusCycleRoot()
3696    * @since 1.4
3697    */
3698   public void transferFocusUpCycle()
3699   {
3700     // XXX Implement.
3701     throw new Error("not implemented");
3702   }
3703
3704   /**
3705    * Tests if this component is the focus owner. Use {@link #isFocusOwner()}
3706    * instead.
3707    *
3708    * @return true if this component owns focus
3709    * @since 1.2
3710    */
3711   public boolean hasFocus()
3712   {
3713     return isFocusOwner();
3714   }
3715
3716   /**
3717    * Tests if this component is the focus owner.
3718    *
3719    * @return true if this component owns focus
3720    * @since 1.4
3721    */
3722   public boolean isFocusOwner()
3723   {
3724     // XXX Implement.
3725     throw new Error("not implemented");
3726   }
3727
3728   /**
3729    * Adds the specified popup menu to this component.
3730    *
3731    * @param menu the popup menu to be added
3732    * @see #remove(MenuComponent)
3733    * @since 1.1
3734    */
3735   public synchronized void add(PopupMenu popup)
3736   {
3737     if (popups == null)
3738       popups = new Vector();
3739     popups.add(popup);
3740   }
3741
3742   /**
3743    * Removes the specified popup menu from this component.
3744    *
3745    * @param menu the popup menu to remove
3746    * @see #add(PopupMenu)
3747    * @since 1.1
3748    */
3749   public synchronized void remove(MenuComponent popup)
3750   {
3751     if (popups != null)
3752       popups.remove(popup);
3753   }
3754
3755   /**
3756    * Returns a debugging string representing this component. The string may
3757    * be empty but not null.
3758    *
3759    * @return a string representing this component
3760    */
3761   protected String paramString()
3762   {
3763     StringBuffer param = new StringBuffer();
3764     String name = getName();
3765     if (name != null)
3766       param.append(name).append(",");
3767     param.append(width).append("x").append(height).append("+").append(x)
3768       .append("+").append(y);
3769     if (! isValid())
3770       param.append(",invalid");
3771     if (! isVisible())
3772       param.append(",invisible");
3773     if (! isEnabled())
3774       param.append(",disabled");
3775     if (! isOpaque())
3776       param.append(",translucent");
3777     if (isDoubleBuffered())
3778       param.append(",doublebuffered");
3779     return param.toString();
3780   }
3781
3782   /**
3783    * Returns a string representation of this component. This is implemented
3784    * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
3785    *
3786    * @return a string representation of this component
3787    */
3788   public String toString()
3789   {
3790     return getClass().getName() + '[' + paramString() + ']';
3791   }
3792
3793   /**
3794    * Prints a listing of this component to <code>System.out</code>.
3795    *
3796    * @see #list(PrintStream)
3797    */
3798   public void list()
3799   {
3800     list(System.out, 0);
3801   }
3802
3803   /**
3804    * Prints a listing of this component to the specified print stream.
3805    *
3806    * @param stream the <code>PrintStream</code> to print to
3807    */
3808   public void list(PrintStream out)
3809   {
3810     list(out, 0);
3811   }
3812
3813   /**
3814    * Prints a listing of this component to the specified print stream,
3815    * starting at the specified indentation point.
3816    *
3817    * @param stream the <code>PrintStream</code> to print to
3818    * @param indent the indentation point
3819    */
3820   public void list(PrintStream out, int indent)
3821   {
3822     for (int i = 0; i < indent; ++i)
3823       out.print(' ');
3824     out.println(toString());
3825   }
3826
3827   /**
3828    * Prints a listing of this component to the specified print writer.
3829    *
3830    * @param writer the <code>PrintWrinter</code> to print to
3831    * @since 1.1
3832    */
3833   public void list(PrintWriter out)
3834   {
3835     list(out, 0);
3836   }
3837
3838   /**
3839    * Prints a listing of this component to the specified print writer,
3840    * starting at the specified indentation point.
3841    *
3842    * @param writer the <code>PrintWriter</code> to print to
3843    * @param indent the indentation point
3844    * @since 1.1
3845    */
3846   public void list(PrintWriter out, int indent)
3847   {
3848     for (int i = 0; i < indent; ++i)
3849       out.print(' ');
3850     out.println(toString());
3851   }
3852
3853   /**
3854    * Adds the specified property listener to this component. This is harmless
3855    * if the listener is null, but if the listener has already been registered,
3856    * it will now be registered twice. The property listener ignores inherited
3857    * properties. Recognized properties include:<br>
3858    * <ul>
3859    * <li>the font (<code>"font"</code>)</li>
3860    * <li>the background color (<code>"background"</code>)</li>
3861    * <li>the foreground color (<code>"foreground"</code>)</li>
3862    * <li>the focusability (<code>"focusable"</code>)</li>
3863    * <li>the focus key traversal enabled state
3864    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
3865    * <li>the set of forward traversal keys
3866    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
3867    * <li>the set of backward traversal keys
3868    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
3869    * <li>the set of up-cycle traversal keys
3870    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
3871    * </ul>
3872    *
3873    * @param listener the new listener to add
3874    * @see #removePropertyChangeListener(PropertyChangeListener)
3875    * @see #getPropertyChangeListeners()
3876    * @see #addPropertyChangeListener(String, PropertyChangeListener)
3877    * @since 1.1
3878    */
3879   public void addPropertyChangeListener(PropertyChangeListener listener)
3880   {
3881     if (changeSupport == null)
3882       changeSupport = new PropertyChangeSupport(this);
3883     changeSupport.addPropertyChangeListener(listener);
3884   }
3885
3886   /**
3887    * Removes the specified property listener from the component. This is
3888    * harmless if the listener was not previously registered.
3889    *
3890    * @param listener the listener to remove
3891    * @see #addPropertyChangeListener(PropertyChangeListener)
3892    * @see #getPropertyChangeListeners()
3893    * @see #removePropertyChangeListener(String, PropertyChangeListener)
3894    * @since 1.1
3895    */
3896   public void removePropertyChangeListener(PropertyChangeListener listener)
3897   {
3898     if (changeSupport != null)
3899       changeSupport.removePropertyChangeListener(listener);
3900   }
3901
3902   /**
3903    * Returns an array of all specified listeners registered on this component.
3904    *
3905    * @return an array of listeners
3906    * @see #addPropertyChangeListener(PropertyChangeListener)
3907    * @see #removePropertyChangeListener(PropertyChangeListener)
3908    * @see #getPropertyChangeListeners(String)
3909    * @since 1.4
3910    */
3911   public PropertyChangeListener[] getPropertyChangeListeners()
3912   {
3913     return changeSupport == null ? new PropertyChangeListener[0]
3914       : changeSupport.getPropertyChangeListeners();
3915   }
3916
3917   /**
3918    * Adds the specified property listener to this component. This is harmless
3919    * if the listener is null, but if the listener has already been registered,
3920    * it will now be registered twice. The property listener ignores inherited
3921    * properties. The listener is keyed to a single property. Recognized
3922    * properties include:<br>
3923    * <ul>
3924    * <li>the font (<code>"font"</code>)</li>
3925    * <li>the background color (<code>"background"</code>)</li>
3926    * <li>the foreground color (<code>"foreground"</code>)</li>
3927    * <li>the focusability (<code>"focusable"</code>)</li>
3928    * <li>the focus key traversal enabled state
3929    *     (<code>"focusTraversalKeysEnabled"</code>)</li>
3930    * <li>the set of forward traversal keys
3931    *     (<code>"forwardFocusTraversalKeys"</code>)</li>
3932 p   * <li>the set of backward traversal keys
3933    *     (<code>"backwardFocusTraversalKeys"</code>)</li>
3934    * <li>the set of up-cycle traversal keys
3935    *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
3936    * </ul>
3937    *
3938    * @param propertyName the property name to filter on
3939    * @param listener the new listener to add
3940    * @see #removePropertyChangeListener(String, PropertyChangeListener)
3941    * @see #getPropertyChangeListeners(String)
3942    * @see #addPropertyChangeListener(PropertyChangeListener)
3943    * @since 1.1
3944    */
3945   public void addPropertyChangeListener(String propertyName,
3946                                         PropertyChangeListener listener)
3947   {
3948     if (changeSupport == null)
3949       changeSupport = new PropertyChangeSupport(this);
3950     changeSupport.addPropertyChangeListener(propertyName, listener);
3951   }
3952
3953   /**
3954    * Removes the specified property listener on a particular property from
3955    * the component. This is harmless if the listener was not previously
3956    * registered.
3957    *
3958    * @param propertyName the property name to filter on
3959    * @param listener the listener to remove
3960    * @see #addPropertyChangeListener(String, PropertyChangeListener)
3961    * @see #getPropertyChangeListeners(String)
3962    * @see #removePropertyChangeListener(PropertyChangeListener)
3963    * @since 1.1
3964    */
3965   public void removePropertyChangeListener(String propertyName,
3966                                            PropertyChangeListener listener)
3967   {
3968     if (changeSupport != null)
3969       changeSupport.removePropertyChangeListener(propertyName, listener);
3970   }
3971
3972   /**
3973    * Returns an array of all specified listeners on the named property that
3974    * are registered on this component.
3975    *
3976    * @return an array of listeners
3977    * @see #addPropertyChangeListener(String, PropertyChangeListener)
3978    * @see #removePropertyChangeListener(String, PropertyChangeListener)
3979    * @see #getPropertyChangeListeners()
3980    * @since 1.4
3981    */
3982   public PropertyChangeListener[] getPropertyChangeListeners(String property)
3983   {
3984     return changeSupport == null ? new PropertyChangeListener[0]
3985       : changeSupport.getPropertyChangeListeners(property);
3986   }
3987
3988   /**
3989    * Report a change in a bound property to any registered property listeners.
3990    *
3991    * @param propertyName the property that changed
3992    * @param oldValue the old property value
3993    * @param newValue the new property value
3994    */
3995   protected void firePropertyChange(String propertyName, Object oldValue,
3996                                     Object newValue)
3997   {
3998     if (changeSupport != null)
3999       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4000   }
4001
4002   /**
4003    * Report a change in a bound property to any registered property listeners.
4004    *
4005    * @param propertyName the property that changed
4006    * @param oldValue the old property value
4007    * @param newValue the new property value
4008    */
4009   protected void firePropertyChange(String propertyName, boolean oldValue,
4010                                     boolean newValue)
4011   {
4012     if (changeSupport != null)
4013       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4014   }
4015
4016   /**
4017    * Report a change in a bound property to any registered property listeners.
4018    *
4019    * @param propertyName the property that changed
4020    * @param oldValue the old property value
4021    * @param newValue the new property value
4022    */
4023   protected void firePropertyChange(String propertyName, int oldValue,
4024                                     int newValue)
4025   {
4026     if (changeSupport != null)
4027       changeSupport.firePropertyChange(propertyName, oldValue, newValue);
4028   }
4029
4030   /**
4031    * Sets the text layout orientation of this component. New components default
4032    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
4033    * the current component, while
4034    * {@link #applyComponentOrientation(ComponentOrientation)} affects the
4035    * entire hierarchy.
4036    *
4037    * @param o the new orientation
4038    * @throws NullPointerException if o is null
4039    * @see #getComponentOrientation()
4040    */
4041   public void setComponentOrientation(ComponentOrientation o)
4042   {
4043     if (o == null)
4044       throw new NullPointerException();
4045     orientation = o;
4046   }
4047
4048   /**
4049    * Determines the text layout orientation used by this component.
4050    *
4051    * @return the component orientation
4052    * @see #setComponentOrientation(ComponentOrientation)
4053    */
4054   public ComponentOrientation getComponentOrientation()
4055   {
4056     return orientation;
4057   }
4058
4059   /**
4060    * Sets the text layout orientation of this component. New components default
4061    * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
4062    * entire hierarchy, while
4063    * {@link #setComponentOrientation(ComponentOrientation)} affects only the
4064    * current component.
4065    *
4066    * @param o the new orientation
4067    * @throws NullPointerException if o is null
4068    * @see #getComponentOrientation()
4069    * @since 1.4
4070    */
4071   public void applyComponentOrientation(ComponentOrientation o)
4072   {
4073     setComponentOrientation(o);
4074   }
4075
4076   /**
4077    * Returns the accessibility framework context of this class. Component is
4078    * not accessible, so the default implementation returns null. Subclasses
4079    * must override this behavior, and return an appropriate subclass of
4080    * {@link AccessibleAWTComponent}.
4081    *
4082    * @return the accessibility context
4083    */
4084   public AccessibleContext getAccessibleContext()
4085   {
4086     return null;
4087   }
4088
4089 \f
4090   // Helper methods; some are package visible for use by subclasses.
4091
4092   /**
4093    * Subclasses should override this to return unique component names like
4094    * "menuitem0".
4095    *
4096    * @return the generated name for this component
4097    */
4098   String generateName()
4099   {
4100     // Component is abstract.
4101     return null;
4102   }
4103
4104   /**
4105    * Sets the peer for this component.
4106    *
4107    * @param peer the new peer
4108    */
4109   final void setPeer(ComponentPeer peer)
4110   {
4111     this.peer = peer;
4112   }
4113
4114   /**
4115    * Implementation method that allows classes such as Canvas and Window to
4116    * override the graphics configuration without violating the published API.
4117    *
4118    * @return the graphics configuration
4119    */
4120   GraphicsConfiguration getGraphicsConfigurationImpl()
4121   {
4122     if (peer != null)
4123       {
4124         GraphicsConfiguration config = peer.getGraphicsConfiguration();
4125         if (config != null)
4126           return config;
4127       }
4128
4129     if (parent != null)
4130       return parent.getGraphicsConfiguration();
4131
4132     return null;
4133   }
4134
4135   /**
4136    * Implementation of dispatchEvent. Allows trusted package classes to
4137    * dispatch additional events first.
4138    *
4139    * @param e the event to dispatch
4140    */
4141   void dispatchEventImpl(AWTEvent e)
4142   {
4143     if (eventTypeEnabled (e.id))
4144       processEvent(e);
4145   }
4146
4147   /**
4148    * Tells whether or not an event type is enabled.
4149    */
4150   boolean eventTypeEnabled (int type)
4151   {
4152     if (type > AWTEvent.RESERVED_ID_MAX)
4153       return true;
4154
4155     switch (type)
4156       {
4157       case ComponentEvent.COMPONENT_HIDDEN:
4158       case ComponentEvent.COMPONENT_MOVED:
4159       case ComponentEvent.COMPONENT_RESIZED:
4160       case ComponentEvent.COMPONENT_SHOWN:
4161         return (componentListener != null
4162                 || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
4163
4164       case KeyEvent.KEY_PRESSED:
4165       case KeyEvent.KEY_RELEASED:
4166       case KeyEvent.KEY_TYPED:
4167         return (keyListener != null
4168                 || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
4169
4170       case MouseEvent.MOUSE_CLICKED:
4171       case MouseEvent.MOUSE_ENTERED:
4172       case MouseEvent.MOUSE_EXITED:
4173       case MouseEvent.MOUSE_PRESSED:
4174       case MouseEvent.MOUSE_RELEASED:
4175         return (mouseListener != null
4176                 || mouseMotionListener != null
4177                 || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
4178         
4179       case FocusEvent.FOCUS_GAINED:
4180       case FocusEvent.FOCUS_LOST:
4181         return (focusListener != null
4182                 || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
4183
4184       case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4185       case InputMethodEvent.CARET_POSITION_CHANGED:
4186         return (inputMethodListener != null
4187                 || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
4188         
4189       case PaintEvent.PAINT:
4190       case PaintEvent.UPDATE:
4191         return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
4192         
4193       default:
4194         return false;
4195       }
4196   }
4197
4198   /**
4199    * Coalesce paint events. Current heuristic is: Merge if the union of
4200    * areas is less than twice that of the sum of the areas. The X server
4201    * tend to create a lot of paint events that are adjacent but not
4202    * overlapping.
4203    *
4204    * <pre>
4205    * +------+
4206    * |      +-----+  ...will be merged
4207    * |      |     |
4208    * |      |     |
4209    * +------+     |
4210    *        +-----+
4211    *
4212    * +---------------+--+
4213    * |               |  |  ...will not be merged
4214    * +---------------+  |
4215    *                 |  |
4216    *                 |  |
4217    *                 |  |
4218    *                 |  |
4219    *                 |  |
4220    *                 +--+
4221    * </pre>
4222    *
4223    * @param queuedEvent the first paint event
4224    * @param newEvent the second paint event
4225    * @return the combined paint event, or null
4226    */
4227   private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
4228                                          PaintEvent newEvent)
4229   {
4230     Rectangle r1 = queuedEvent.getUpdateRect();
4231     Rectangle r2 = newEvent.getUpdateRect();
4232     Rectangle union = r1.union(r2);
4233
4234     int r1a = r1.width * r1.height;
4235     int r2a = r2.width * r2.height;
4236     int ua  = union.width * union.height;
4237
4238     if (ua > (r1a+r2a)*2)
4239       return null;
4240     /* The 2 factor should maybe be reconsidered. Perhaps 3/2
4241        would be better? */
4242
4243     newEvent.setUpdateRect(union);
4244     return newEvent;
4245   }
4246
4247   /**
4248    * This method is used to implement transferFocus(). CHILD is the child
4249    * making the request. This is overridden by Container; when called for an
4250    * ordinary component there is no child and so we always return null.
4251    *
4252    * @param child the component making the request
4253    * @return the next component to focus on
4254    */
4255   Component findNextFocusComponent(Component child)
4256   {
4257     return null;
4258   }
4259
4260   /**
4261    * Deserializes this component. This regenerates all serializable listeners
4262    * which were registered originally.
4263    *
4264    * @param s the stream to read from
4265    * @throws ClassNotFoundException if deserialization fails
4266    * @throws IOException if the stream fails
4267    */
4268   private void readObject(ObjectInputStream s)
4269     throws ClassNotFoundException, IOException
4270   {
4271     s.defaultReadObject();
4272     String key = (String) s.readObject();
4273     while (key != null)
4274       {
4275         Object listener = s.readObject();
4276         if ("componentL".equals(key))
4277           addComponentListener((ComponentListener) listener);
4278         else if ("focusL".equals(key))
4279           addFocusListener((FocusListener) listener);
4280         else if ("keyL".equals(key))
4281           addKeyListener((KeyListener) listener);
4282         else if ("mouseL".equals(key))
4283           addMouseListener((MouseListener) listener);
4284         else if ("mouseMotionL".equals(key))
4285           addMouseMotionListener((MouseMotionListener) listener);
4286         else if ("inputMethodL".equals(key))
4287           addInputMethodListener((InputMethodListener) listener);
4288         else if ("hierarchyL".equals(key))
4289           addHierarchyListener((HierarchyListener) listener);
4290         else if ("hierarchyBoundsL".equals(key))
4291           addHierarchyBoundsListener((HierarchyBoundsListener) listener);
4292         else if ("mouseWheelL".equals(key))
4293           addMouseWheelListener((MouseWheelListener) listener);
4294         key = (String) s.readObject();
4295       }
4296   }
4297
4298   /**
4299    * Serializes this component. This ignores all listeners which do not
4300    * implement Serializable, but includes those that do.
4301    *
4302    * @param s the stream to write to
4303    * @throws IOException if the stream fails
4304    */
4305   private void writeObject(ObjectOutputStream s) throws IOException
4306   {
4307     s.defaultWriteObject();
4308     AWTEventMulticaster.save(s, "componentL", componentListener);
4309     AWTEventMulticaster.save(s, "focusL", focusListener);
4310     AWTEventMulticaster.save(s, "keyL", keyListener);
4311     AWTEventMulticaster.save(s, "mouseL", mouseListener);
4312     AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
4313     AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
4314     AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
4315     AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
4316     AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
4317     s.writeObject(null);
4318   }
4319
4320 \f
4321   // Nested classes.
4322
4323   /**
4324    * This class provides accessibility support for subclasses of container.
4325    *
4326    * @author Eric Blake <ebb9@email.byu.edu>
4327    * @since 1.3
4328    * @status updated to 1.4
4329    */
4330   protected abstract class AccessibleAWTComponent extends AccessibleContext
4331     implements Serializable, AccessibleComponent
4332   {
4333     /**
4334      * Compatible with JDK 1.3+.
4335      */
4336     private static final long serialVersionUID = 642321655757800191L;
4337
4338     /**
4339      * Converts show/hide events to PropertyChange events, and is registered
4340      * as a component listener on this component.
4341      *
4342      * @serial the component handler
4343      */
4344     protected ComponentListener accessibleAWTComponentHandler
4345       = new AccessibleAWTComponentHandler();
4346
4347     /**
4348      * Converts focus events to PropertyChange events, and is registered
4349      * as a focus listener on this component.
4350      *
4351      * @serial the focus handler
4352      */
4353     protected FocusListener accessibleAWTFocusHandler
4354       = new AccessibleAWTFocusHandler();
4355
4356     /**
4357      * The default constructor.
4358      */
4359     protected AccessibleAWTComponent()
4360     {
4361       Component.this.addComponentListener(accessibleAWTComponentHandler);
4362       Component.this.addFocusListener(accessibleAWTFocusHandler);
4363     }
4364
4365     /**
4366      * Adds a global property change listener to the accessible component.
4367      *
4368      * @param l the listener to add
4369      * @see #ACCESSIBLE_NAME_PROPERTY
4370      * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
4371      * @see #ACCESSIBLE_STATE_PROPERTY
4372      * @see #ACCESSIBLE_VALUE_PROPERTY
4373      * @see #ACCESSIBLE_SELECTION_PROPERTY
4374      * @see #ACCESSIBLE_TEXT_PROPERTY
4375      * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
4376      */
4377     public void addPropertyChangeListener(PropertyChangeListener l)
4378     {
4379       Component.this.addPropertyChangeListener(l);
4380       super.addPropertyChangeListener(l);
4381     }
4382
4383     /**
4384      * Removes a global property change listener from this accessible
4385      * component.
4386      *
4387      * @param l the listener to remove
4388      */
4389     public void removePropertyChangeListener(PropertyChangeListener l)
4390     {
4391       Component.this.removePropertyChangeListener(l);
4392       super.removePropertyChangeListener(l);
4393     }
4394
4395     /**
4396      * Returns the accessible name of this component. It is almost always
4397      * wrong to return getName(), since it is not localized. In fact, for
4398      * things like buttons, this should be the text of the button, not the
4399      * name of the object. The tooltip text might also be appropriate.
4400      *
4401      * @return the name
4402      * @see #setAccessibleName(String)
4403      */
4404     public String getAccessibleName()
4405     {
4406       return accessibleName == null ? getName() : accessibleName;
4407     }
4408
4409     /**
4410      * Returns a brief description of this accessible context. This should
4411      * be localized.
4412      *
4413      * @return a description of this component
4414      * @see #setAccessibleDescription(String)
4415      */
4416     public String getAccessibleDescription()
4417     {
4418       return accessibleDescription;
4419     }
4420
4421     /**
4422      * Returns the role of this component.
4423      *
4424      * @return the accessible role
4425      */
4426     public AccessibleRole getAccessibleRole()
4427     {
4428       return AccessibleRole.AWT_COMPONENT;
4429     }
4430
4431     /**
4432      * Returns a state set describing this component's state.
4433      *
4434      * @return a new state set
4435      * @see AccessibleState
4436      */
4437     public AccessibleStateSet getAccessibleStateSet()
4438     {
4439       AccessibleStateSet s = new AccessibleStateSet();
4440       if (Component.this.isEnabled())
4441         s.add(AccessibleState.ENABLED);
4442       if (isFocusable())
4443         s.add(AccessibleState.FOCUSABLE);
4444       if (isFocusOwner())
4445         s.add(AccessibleState.FOCUSED);
4446       if (isOpaque())
4447         s.add(AccessibleState.OPAQUE);
4448       if (Component.this.isShowing())
4449         s.add(AccessibleState.SHOWING);
4450       if (Component.this.isVisible())
4451         s.add(AccessibleState.VISIBLE);
4452       return s;
4453     }
4454
4455     /**
4456      * Returns the parent of this component, if it is accessible.
4457      *
4458      * @return the accessible parent
4459      */
4460     public Accessible getAccessibleParent()
4461     {
4462       if (accessibleParent == null)
4463         {
4464           Container parent = getParent();
4465           accessibleParent = parent instanceof Accessible
4466             ? (Accessible) parent : null;
4467         }
4468       return accessibleParent;
4469     }
4470
4471     /**
4472      * Returns the index of this component in its accessible parent.
4473      *
4474      * @return the index, or -1 if the parent is not accessible
4475      * @see #getAccessibleParent()
4476      */
4477     public int getAccessibleIndexInParent()
4478     {
4479       if (getAccessibleParent() == null)
4480         return -1;
4481       AccessibleContext context
4482         = ((Component) accessibleParent).getAccessibleContext();
4483       if (context == null)
4484         return -1;
4485       for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
4486         if (context.getAccessibleChild(i) == Component.this)
4487           return i;
4488       return -1;
4489     }
4490
4491     /**
4492      * Returns the number of children of this component which implement
4493      * Accessible. Subclasses must override this if they can have children.
4494      *
4495      * @return the number of accessible children, default 0
4496      */
4497     public int getAccessibleChildrenCount()
4498     {
4499       return 0;
4500     }
4501
4502     /**
4503      * Returns the ith accessible child. Subclasses must override this if
4504      * they can have children.
4505      *
4506      * @return the ith accessible child, or null
4507      * @see #getAccessibleChildrenCount()
4508      */
4509     public Accessible getAccessibleChild(int i)
4510     {
4511       return null;
4512     }
4513
4514     /**
4515      * Returns the locale of this component.
4516      *
4517      * @return the locale
4518      * @throws IllegalComponentStateException if the locale is unknown
4519      */
4520     public Locale getLocale()
4521     {
4522       return Component.this.getLocale();
4523     }
4524
4525     /**
4526      * Returns this, since it is an accessible component.
4527      *
4528      * @return the accessible component
4529      */
4530     public AccessibleComponent getAccessibleComponent()
4531     {
4532       return this;
4533     }
4534
4535     /**
4536      * Gets the background color.
4537      *
4538      * @return the background color
4539      * @see #setBackground(Color)
4540      */
4541     public Color getBackground()
4542     {
4543       return Component.this.getBackground();
4544     }
4545
4546     /**
4547      * Sets the background color.
4548      *
4549      * @param c the background color
4550      * @see #getBackground()
4551      * @see #isOpaque()
4552      */
4553     public void setBackground(Color c)
4554     {
4555       Component.this.setBackground(c);
4556     }
4557
4558     /**
4559      * Gets the foreground color.
4560      *
4561      * @return the foreground color
4562      * @see #setForeground(Color)
4563      */
4564     public Color getForeground()
4565     {
4566       return Component.this.getForeground();
4567     }
4568
4569     /**
4570      * Sets the foreground color.
4571      *
4572      * @param c the foreground color
4573      * @see #getForeground()
4574      */
4575     public void setForeground(Color c)
4576     {
4577       Component.this.setForeground(c);
4578     }
4579
4580     /**
4581      * Gets the cursor.
4582      *
4583      * @return the cursor
4584      * @see #setCursor(Cursor)
4585      */
4586     public Cursor getCursor()
4587     {
4588       return Component.this.getCursor();
4589     }
4590
4591     /**
4592      * Sets the cursor.
4593      *
4594      * @param cursor the cursor
4595      * @see #getCursor()
4596      */
4597     public void setCursor(Cursor cursor)
4598     {
4599       Component.this.setCursor(cursor);
4600     }
4601
4602     /**
4603      * Gets the font.
4604      *
4605      * @return the font
4606      * @see #setFont(Font)
4607      */
4608     public Font getFont()
4609     {
4610       return Component.this.getFont();
4611     }
4612
4613     /**
4614      * Sets the font.
4615      *
4616      * @param f the font
4617      * @see #getFont()
4618      */
4619     public void setFont(Font f)
4620     {
4621       Component.this.setFont(f);
4622     }
4623
4624     /**
4625      * Gets the font metrics for a font.
4626      *
4627      * @param f the font to look up
4628      * @return its metrics
4629      * @throws NullPointerException if f is null
4630      * @see #getFont()
4631      */
4632     public FontMetrics getFontMetrics(Font f)
4633     {
4634       return Component.this.getFontMetrics(f);
4635     }
4636
4637     /**
4638      * Tests if the component is enabled.
4639      *
4640      * @return true if the component is enabled
4641      * @see #setEnabled(boolean)
4642      * @see #getAccessibleStateSet()
4643      * @see AccessibleState#ENABLED
4644      */
4645     public boolean isEnabled()
4646     {
4647       return Component.this.isEnabled();
4648     }
4649
4650     /**
4651      * Set whether the component is enabled.
4652      *
4653      * @param b the new enabled status
4654      * @see #isEnabled()
4655      */
4656     public void setEnabled(boolean b)
4657     {
4658       Component.this.setEnabled(b);
4659     }
4660
4661     /**
4662      * Test whether the component is visible (not necesarily showing).
4663      *
4664      * @return true if it is visible
4665      * @see #setVisible(boolean)
4666      * @see #getAccessibleStateSet()
4667      * @see AccessibleState#VISIBLE
4668      */
4669     public boolean isVisible()
4670     {
4671       return Component.this.isVisible();
4672     }
4673
4674     /**
4675      * Sets the visibility of this component.
4676      *
4677      * @param b the desired visibility
4678      * @see #isVisible()
4679      */
4680     public void setVisible(boolean b)
4681     {
4682       Component.this.setVisible(b);
4683     }
4684
4685     /**
4686      * Tests if the component is showing.
4687      *
4688      * @return true if this is showing
4689      */
4690     public boolean isShowing()
4691     {
4692       return Component.this.isShowing();
4693     }
4694
4695     /**
4696      * Tests if the point is contained in this component.
4697      *
4698      * @param p the point to check
4699      * @return true if it is contained
4700      * @throws NullPointerException if p is null
4701      */
4702     public boolean contains(Point p)
4703     {
4704       return Component.this.contains(p.x, p.y);
4705     }
4706
4707     /**
4708      * Returns the location of this object on the screen, or null if it is
4709      * not showing.
4710      *
4711      * @return the location relative to screen coordinates, if showing
4712      * @see #getBounds()
4713      * @see #getLocation()
4714      */
4715     public Point getLocationOnScreen()
4716     {
4717       return Component.this.isShowing() ? Component.this.getLocationOnScreen()
4718         : null;
4719     }
4720
4721     /**
4722      * Returns the location of this object relative to its parent's coordinate
4723      * system, or null if it is not showing.
4724      *
4725      * @return the location
4726      * @see #getBounds()
4727      * @see #getLocationOnScreen()
4728      */
4729     public Point getLocation()
4730     {
4731       return Component.this.isShowing() ? Component.this.getLocation() : null;
4732     }
4733
4734     /**
4735      * Sets the location of this relative to its parent's coordinate system.
4736      *
4737      * @param p the location
4738      * @throws NullPointerException if p is null
4739      * @see #getLocation()
4740      */
4741     public void setLocation(Point p)
4742     {
4743       Component.this.setLocation(p.x, p.y);
4744     }
4745
4746     /**
4747      * Gets the bounds of this component, or null if it is not on screen.
4748      *
4749      * @return the bounds
4750      * @see #contains(Point)
4751      * @see #setBounds(Rectangle)
4752      */
4753     public Rectangle getBounds()
4754     {
4755       return Component.this.isShowing() ? Component.this.getBounds() : null;
4756     }
4757
4758     /**
4759      * Sets the bounds of this component.
4760      *
4761      * @param r the bounds
4762      * @throws NullPointerException if r is null
4763      * @see #getBounds()
4764      */
4765     public void setBounds(Rectangle r)
4766     {
4767       Component.this.setBounds(r.x, r.y, r.width, r.height);
4768     }
4769
4770     /**
4771      * Gets the size of this component, or null if it is not showing.
4772      *
4773      * @return the size
4774      * @see #setSize(Dimension)
4775      */
4776     public Dimension getSize()
4777     {
4778       return Component.this.isShowing() ? Component.this.getSize() : null;
4779     }
4780
4781     /**
4782      * Sets the size of this component.
4783      *
4784      * @param d the size
4785      * @throws NullPointerException if d is null
4786      * @see #getSize()
4787      */
4788     public void setSize(Dimension d)
4789     {
4790       Component.this.setSize(d.width, d.height);
4791     }
4792
4793     /**
4794      * Returns the Accessible child at a point relative to the coordinate
4795      * system of this component, if one exists, or null. Since components
4796      * have no children, subclasses must override this to get anything besides
4797      * null.
4798      *
4799      * @param p the point to check
4800      * @return the accessible child at that point
4801      * @throws NullPointerException if p is null
4802      */
4803     public Accessible getAccessibleAt(Point p)
4804     {
4805       return null;
4806     }
4807
4808     /**
4809      * Tests whether this component can accept focus.
4810      *
4811      * @return true if this is focus traversable
4812      * @see #getAccessibleStateSet()
4813      * @see AccessibleState#FOCUSABLE
4814      * @see AccessibleState#FOCUSED
4815      */
4816     public boolean isFocusTraversable()
4817     {
4818       return Component.this.isFocusTraversable();
4819     }
4820
4821     /**
4822      * Requests focus for this component.
4823      *
4824      * @see #isFocusTraversable()
4825      */
4826     public void requestFocus()
4827     {
4828       Component.this.requestFocus();
4829     }
4830
4831     /**
4832      * Adds a focus listener.
4833      *
4834      * @param l the listener to add
4835      */
4836     public void addFocusListener(FocusListener l)
4837     {
4838       Component.this.addFocusListener(l);
4839     }
4840
4841     /**
4842      * Removes a focus listener.
4843      *
4844      * @param l the listener to remove
4845      */
4846     public void removeFocusListener(FocusListener l)
4847     {
4848       Component.this.removeFocusListener(l);
4849     }
4850
4851     /**
4852      * Converts component changes into property changes.
4853      *
4854      * @author Eric Blake <ebb9@email.byu.edu>
4855      * @since 1.3
4856      * @status updated to 1.4
4857      */
4858     protected class AccessibleAWTComponentHandler implements ComponentListener
4859     {
4860       /**
4861        * Default constructor.
4862        */
4863       protected AccessibleAWTComponentHandler()
4864       {
4865       }
4866
4867       /**
4868        * Convert a component hidden to a property change.
4869        *
4870        * @param e the event to convert
4871        */
4872       public void componentHidden(ComponentEvent e)
4873       {
4874         AccessibleAWTComponent.this.firePropertyChange
4875           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
4876       }
4877
4878       /**
4879        * Convert a component shown to a property change.
4880        *
4881        * @param e the event to convert
4882        */
4883       public void componentShown(ComponentEvent e)
4884       {
4885         AccessibleAWTComponent.this.firePropertyChange
4886           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
4887       }
4888
4889       /**
4890        * Moving a component does not affect properties.
4891        *
4892        * @param e ignored
4893        */
4894       public void componentMoved(ComponentEvent e)
4895       {
4896       }
4897
4898       /**
4899        * Resizing a component does not affect properties.
4900        *
4901        * @param e ignored
4902        */
4903       public void componentResized(ComponentEvent e)
4904       {
4905       }
4906     } // class AccessibleAWTComponentHandler
4907
4908     /**
4909      * Converts focus changes into property changes.
4910      *
4911      * @author Eric Blake <ebb9@email.byu.edu>
4912      * @since 1.3
4913      * @status updated to 1.4
4914      */
4915     protected class AccessibleAWTFocusHandler implements FocusListener
4916     {
4917       /**
4918        * Default constructor.
4919        */
4920       protected AccessibleAWTFocusHandler()
4921       {
4922       }
4923
4924       /**
4925        * Convert a focus gained to a property change.
4926        *
4927        * @param e the event to convert
4928        */
4929       public void focusGained(FocusEvent e)
4930       {
4931         AccessibleAWTComponent.this.firePropertyChange
4932           (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
4933       }
4934
4935       /**
4936        * Convert a focus lost to a property change.
4937        *
4938        * @param e the event to convert
4939        */
4940       public void focusLost(FocusEvent e)
4941       {
4942         AccessibleAWTComponent.this.firePropertyChange
4943           (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
4944       }
4945     } // class AccessibleAWTComponentHandler
4946   } // class AccessibleAWTComponent
4947
4948   /**
4949    * This class provides support for blitting offscreen surfaces.
4950    *
4951    * @author Eric Blake <ebb9@email.byu.edu>
4952    * @since 1.4
4953    * @XXX Shell class, to allow compilation. This needs documentation and
4954    * correct implementation.
4955    */
4956   protected class BltBufferStrategy extends BufferStrategy
4957   {
4958     protected BufferCapabilities caps;
4959     protected VolatileImage[] backBuffers;
4960     protected boolean validatedContents;
4961     protected int width;
4962     protected int height;
4963     protected BltBufferStrategy(int num, BufferCapabilities caps)
4964     {
4965       this.caps = caps;
4966       createBackBuffers(num);
4967     }
4968     protected void createBackBuffers(int num)
4969     {
4970       backBuffers = new VolatileImage[num];
4971     }
4972     public BufferCapabilities getCapabilities()
4973     {
4974       return caps;
4975     }
4976     public Graphics getDrawGraphics() { return null; }
4977     public void show() {}
4978     protected void revalidate() {}
4979     public boolean contentsLost() { return false; }
4980     public boolean contentsRestored() { return false; }
4981   } // class BltBufferStrategy
4982
4983   /**
4984    * This class provides support for flipping component buffers. It is only
4985    * designed for use by Canvas and Window.
4986    *
4987    * @author Eric Blake <ebb9@email.byu.edu>
4988    * @since 1.4
4989    * @XXX Shell class, to allow compilation. This needs documentation and
4990    * correct implementation.
4991    */
4992   protected class FlipBufferStrategy extends BufferStrategy
4993   {
4994     protected int numBuffers;
4995     protected BufferCapabilities caps;
4996     protected Image drawBuffer;
4997     protected VolatileImage drawVBuffer;
4998     protected boolean validatedContents;
4999     protected FlipBufferStrategy(int num, BufferCapabilities caps)
5000       throws AWTException
5001     {
5002       this.caps = caps;
5003       createBuffers(num, caps);
5004     }
5005     protected void createBuffers(int num, BufferCapabilities caps)
5006       throws AWTException {}
5007     protected Image getBackBuffer()
5008     {
5009       return drawBuffer;
5010     }
5011     protected void flip(BufferCapabilities.FlipContents flipAction) {}
5012     protected void destroyBuffers() {}
5013     public BufferCapabilities getCapabilities()
5014     {
5015       return caps;
5016     }
5017     public Graphics getDrawGraphics() { return null; }
5018     protected void revalidate() {}
5019     public boolean contentsLost() { return false; }
5020     public boolean contentsRestored() { return false; }
5021     public void show() {}
5022   } // class FlipBufferStrategy
5023 } // class Component