OSDN Git Service

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