OSDN Git Service

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