KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > Component


1 /*
2  * @(#)Component.java 1.392 07/03/13
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package java.awt;
8
9 import java.io.PrintStream JavaDoc;
10 import java.io.PrintWriter JavaDoc;
11 import java.util.Vector JavaDoc;
12 import java.util.Locale JavaDoc;
13 import java.util.EventListener JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.awt.peer.ComponentPeer;
19 import java.awt.peer.ContainerPeer;
20 import java.awt.peer.LightweightPeer;
21 import java.awt.image.BufferStrategy JavaDoc;
22 import java.awt.image.ImageObserver JavaDoc;
23 import java.awt.image.ImageProducer JavaDoc;
24 import java.awt.image.ColorModel JavaDoc;
25 import java.awt.image.VolatileImage JavaDoc;
26 import java.awt.event.*;
27 import java.awt.datatransfer.Transferable JavaDoc;
28 import java.awt.dnd.DnDConstants JavaDoc;
29 import java.awt.dnd.DragSource JavaDoc;
30 import java.awt.dnd.DragSourceContext JavaDoc;
31 import java.awt.dnd.DragSourceListener JavaDoc;
32 import java.awt.dnd.InvalidDnDOperationException JavaDoc;
33 import java.io.Serializable JavaDoc;
34 import java.io.ObjectOutputStream JavaDoc;
35 import java.io.ObjectInputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.beans.PropertyChangeListener JavaDoc;
38 import java.beans.PropertyChangeSupport JavaDoc;
39 import java.awt.event.InputMethodListener JavaDoc;
40 import java.awt.event.InputMethodEvent JavaDoc;
41 import java.awt.im.InputContext JavaDoc;
42 import java.awt.im.InputMethodRequests JavaDoc;
43 import java.awt.dnd.DropTarget JavaDoc;
44 import java.lang.reflect.InvocationTargetException JavaDoc;
45 import java.lang.reflect.Method JavaDoc;
46 import javax.accessibility.*;
47 import java.awt.GraphicsConfiguration JavaDoc;
48 import java.security.AccessController JavaDoc;
49 import java.security.PrivilegedAction JavaDoc;
50 import javax.accessibility.*;
51
52 import java.util.logging.*;
53
54 import sun.security.action.GetPropertyAction;
55 import sun.awt.AppContext;
56 import sun.awt.SunToolkit;
57 import sun.awt.ConstrainableGraphics;
58 import sun.awt.DebugHelper;
59 import sun.awt.WindowClosingListener;
60 import sun.awt.WindowClosingSupport;
61 import sun.awt.GlobalCursorManager;
62 import sun.awt.dnd.SunDropTargetEvent;
63 import sun.awt.im.CompositionArea;
64
65 import sun.font.FontManager;
66
67 /**
68  * A <em>component</em> is an object having a graphical representation
69  * that can be displayed on the screen and that can interact with the
70  * user. Examples of components are the buttons, checkboxes, and scrollbars
71  * of a typical graphical user interface. <p>
72  * The <code>Component</code> class is the abstract superclass of
73  * the nonmenu-related Abstract Window Toolkit components. Class
74  * <code>Component</code> can also be extended directly to create a
75  * lightweight component. A lightweight component is a component that is
76  * not associated with a native opaque window.
77  * <p>
78  * <h3>Serialization</h3>
79  * It is important to note that only AWT listeners which conform
80  * to the <code>Serializable</code> protocol will be saved when
81  * the object is stored. If an AWT object has listeners that
82  * aren't marked serializable, they will be dropped at
83  * <code>writeObject</code> time. Developers will need, as always,
84  * to consider the implications of making an object serializable.
85  * One situation to watch out for is this:
86  * <pre>
87  * import java.awt.*;
88  * import java.awt.event.*;
89  * import java.io.Serializable;
90  *
91  * class MyApp implements ActionListener, Serializable
92  * {
93  * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
94  * Button aButton = new Button();
95  *
96  * MyApp()
97  * {
98  * // Oops, now aButton has a listener with a reference
99  * // to bigOne!
100  * aButton.addActionListener(this);
101  * }
102  *
103  * public void actionPerformed(ActionEvent e)
104  * {
105  * System.out.println("Hello There");
106  * }
107  * }
108  * </pre>
109  * In this example, serializing <code>aButton</code> by itself
110  * will cause <code>MyApp</code> and everything it refers to
111  * to be serialized as well. The problem is that the listener
112  * is serializable by coincidence, not by design. To separate
113  * the decisions about <code>MyApp</code> and the
114  * <code>ActionListener</code> being serializable one can use a
115  * nested class, as in the following example:
116  * <pre>
117  * import java.awt.*;
118  * import java.awt.event.*;
119  * import java.io.Serializable;
120  *
121  * class MyApp java.io.Serializable
122  * {
123  * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
124  * Button aButton = new Button();
125  *
126  * class MyActionListener implements ActionListener
127  * {
128  * public void actionPerformed(ActionEvent e)
129  * {
130  * System.out.println("Hello There");
131  * }
132  * }
133  *
134  * MyApp()
135  * {
136  * aButton.addActionListener(new MyActionListener());
137  * }
138  * }
139  * </pre>
140  * <p>
141  * <b>Note</b>: For more information on the paint mechanisms utilitized
142  * by AWT and Swing, including information on how to write the most
143  * efficient painting code, see
144  * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
145  * <p>
146  * For details on the focus subsystem, see
147  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
148  * How to Use the Focus Subsystem</a>,
149  * a section in <em>The Java Tutorial</em>, and the
150  * <a HREF="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
151  * for more information.
152  *
153  * @version 1.392, 03/13/07
154  * @author Arthur van Hoff
155  * @author Sami Shaio
156  */

157 public abstract class Component implements ImageObserver JavaDoc, MenuContainer JavaDoc,
158                                            Serializable JavaDoc
159 {
160
161     private static final Logger focusLog = Logger.getLogger("java.awt.focus.Component");
162     private static final Logger log = Logger.getLogger("java.awt.Component");
163     /**
164      * The peer of the component. The peer implements the component's
165      * behavior. The peer is set when the <code>Component</code> is
166      * added to a container that also is a peer.
167      * @see #addNotify
168      * @see #removeNotify
169      */

170     transient ComponentPeer peer;
171
172     /**
173      * The parent of the object. It may be <code>null</code>
174      * for top-level components.
175      * @see #getParent
176      */

177     transient Container JavaDoc parent;
178
179     /**
180      * The <code>AppContext</code> of the component. Applets/Plugin may
181      * change the AppContext.
182      */

183     transient AppContext appContext;
184
185     /**
186      * The x position of the component in the parent's coordinate system.
187      *
188      * @serial
189      * @see #getLocation
190      */

191     int x;
192
193     /**
194      * The y position of the component in the parent's coordinate system.
195      *
196      * @serial
197      * @see #getLocation
198      */

199     int y;
200
201     /**
202      * The width of the component.
203      *
204      * @serial
205      * @see #getSize
206      */

207     int width;
208
209     /**
210      * The height of the component.
211      *
212      * @serial
213      * @see #getSize
214      */

215     int height;
216
217     /**
218      * The foreground color for this component.
219      * <code>foreground</code> can be <code>null</code>.
220      *
221      * @serial
222      * @see #getForeground
223      * @see #setForeground
224      */

225     Color JavaDoc foreground;
226
227     /**
228      * The background color for this component.
229      * <code>background</code> can be <code>null</code>.
230      *
231      * @serial
232      * @see #getBackground
233      * @see #setBackground
234      */

235     Color JavaDoc background;
236
237     /**
238      * The font used by this component.
239      * The <code>font</code> can be <code>null</code>.
240      *
241      * @serial
242      * @see #getFont
243      * @see #setFont
244      */

245     Font JavaDoc font;
246
247     /**
248      * The font which the peer is currently using.
249      * (<code>null</code> if no peer exists.)
250      */

251     Font JavaDoc peerFont;
252
253     /**
254      * The cursor displayed when pointer is over this component.
255      * This value can be <code>null</code>.
256      *
257      * @serial
258      * @see #getCursor
259      * @see #setCursor
260      */

261     Cursor JavaDoc cursor;
262
263     /**
264      * The locale for the component.
265      *
266      * @serial
267      * @see #getLocale
268      * @see #setLocale
269      */

270     Locale JavaDoc locale;
271
272     /**
273      * A reference to a <code>GraphicsConfiguration</code> object
274      * used to describe the characteristics of a graphics
275      * destination.
276      * This value can be <code>null</code>.
277      *
278      * @since 1.3
279      * @serial
280      * @see GraphicsConfiguration
281      * @see #getGraphicsConfiguration
282      */

283     transient GraphicsConfiguration JavaDoc graphicsConfig = null;
284         
285     /**
286      * A reference to a <code>BufferStrategy</code> object
287      * used to manipulate the buffers on this component.
288      *
289      * @since 1.4
290      * @see java.awt.image.BufferStrategy
291      * @see #getBufferStrategy()
292      */

293     transient BufferStrategy JavaDoc bufferStrategy = null;
294         
295     /**
296      * True when the object should ignore all repaint events.
297      *
298      * @since 1.4
299      * @serial
300      * @see #setIgnoreRepaint
301      * @see #getIgnoreRepaint
302      */

303     boolean ignoreRepaint = false;
304
305     /**
306      * True when the object is visible. An object that is not
307      * visible is not drawn on the screen.
308      *
309      * @serial
310      * @see #isVisible
311      * @see #setVisible
312      */

313     boolean visible = true;
314
315     /**
316      * True when the object is enabled. An object that is not
317      * enabled does not interact with the user.
318      *
319      * @serial
320      * @see #isEnabled
321      * @see #setEnabled
322      */

323     boolean enabled = true;
324
325     /**
326      * True when the object is valid. An invalid object needs to
327      * be layed out. This flag is set to false when the object
328      * size is changed.
329      *
330      * @serial
331      * @see #isValid
332      * @see #validate
333      * @see #invalidate
334      */

335     boolean valid = false;
336
337     /**
338      * The <code>DropTarget</code> associated with this component.
339      *
340      * @since 1.2
341      * @serial
342      * @see #setDropTarget
343      * @see #getDropTarget
344      */

345     DropTarget JavaDoc dropTarget;
346
347     /**
348      * @serial
349      * @see #add
350      */

351     Vector JavaDoc popups;
352
353     /**
354      * A component's name.
355      * This field can be <code>null</code>.
356      *
357      * @serial
358      * @see #getName
359      * @see #setName(String)
360      */

361     private String JavaDoc name;
362   
363     /**
364      * A bool to determine whether the name has
365      * been set explicitly. <code>nameExplicitlySet</code> will
366      * be false if the name has not been set and
367      * true if it has.
368      *
369      * @serial
370      * @see #getName
371      * @see #setName(String)
372      */

373     private boolean nameExplicitlySet = false;
374
375     /**
376      * Indicates whether this Component can be focused.
377      *
378      * @serial
379      * @see #setFocusable
380      * @see #isFocusable
381      * @since 1.4
382      */

383     private boolean focusable = true;
384
385     private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
386     private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
387     private static final int FOCUS_TRAVERSABLE_SET = 2;
388
389     /**
390      * Tracks whether this Component is relying on default focus travesability.
391      *
392      * @serial
393      * @since 1.4
394      */

395     private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
396
397     /**
398      * The focus traversal keys. These keys will generate focus traversal
399      * behavior for Components for which focus traversal keys are enabled. If a
400      * value of null is specified for a traversal key, this Component inherits
401      * that traversal key from its parent. If all ancestors of this Component
402      * have null specified for that traversal key, then the current
403      * KeyboardFocusManager's default traversal key is used.
404      *
405      * @serial
406      * @see #setFocusTraversalKeys
407      * @see #getFocusTraversalKeys
408      * @since 1.4
409      */

410     Set JavaDoc[] focusTraversalKeys;
411
412     private static final String JavaDoc[] focusTraversalKeyPropertyNames = {
413         "forwardFocusTraversalKeys",
414         "backwardFocusTraversalKeys",
415         "upCycleFocusTraversalKeys",
416         "downCycleFocusTraversalKeys"
417     };
418
419     /**
420      * Indicates whether focus traversal keys are enabled for this Component.
421      * Components for which focus traversal keys are disabled receive key
422      * events for focus traversal keys. Components for which focus traversal
423      * keys are enabled do not see these events; instead, the events are
424      * automatically converted to traversal operations.
425      *
426      * @serial
427      * @see #setFocusTraversalKeysEnabled
428      * @see #getFocusTraversalKeysEnabled
429      * @since 1.4
430      */

431     private boolean focusTraversalKeysEnabled = true;
432
433     /**
434      * The locking object for AWT component-tree and layout operations.
435      *
436      * @see #getTreeLock
437      */

438     static final Object JavaDoc LOCK = new AWTTreeLock();
439     static class AWTTreeLock {}
440
441     /**
442      * Minimum size.
443      * (This field perhaps should have been transient).
444      *
445      * @serial
446      */

447     Dimension JavaDoc minSize;
448
449     /**
450      * Whether or not setMinimumSize has been invoked with a non-null value.
451      */

452     boolean minSizeSet;
453
454     /**
455      * Preferred size.
456      * (This field perhaps should have been transient).
457      *
458      * @serial
459      */

460     Dimension JavaDoc prefSize;
461
462     /**
463      * Whether or not setPreferredSize has been invoked with a non-null value.
464      */

465     boolean prefSizeSet;
466
467     /**
468      * Maximum size
469      *
470      * @serial
471      */

472     Dimension JavaDoc maxSize;
473
474     /**
475      * Whether or not setMaximumSize has been invoked with a non-null value.
476      */

477     boolean maxSizeSet;
478
479     /**
480      * The orientation for this component.
481      * @see #getComponentOrientation
482      * @see #setComponentOrientation
483      */

484     transient ComponentOrientation JavaDoc componentOrientation
485     = ComponentOrientation.UNKNOWN;
486
487     /**
488      * <code>newEventsOnly</code> will be true if the event is
489      * one of the event types enabled for the component.
490      * It will then allow for normal processing to
491      * continue. If it is false the event is passed
492      * to the component's parent and up the ancestor
493      * tree until the event has been consumed.
494      *
495      * @serial
496      * @see #dispatchEvent
497      */

498     boolean newEventsOnly = false;
499     transient ComponentListener componentListener;
500     transient FocusListener focusListener;
501     transient HierarchyListener hierarchyListener;
502     transient HierarchyBoundsListener hierarchyBoundsListener;
503     transient KeyListener keyListener;
504     transient MouseListener mouseListener;
505     transient MouseMotionListener mouseMotionListener;
506     transient MouseWheelListener mouseWheelListener;
507     transient InputMethodListener JavaDoc inputMethodListener;
508     
509     transient RuntimeException JavaDoc windowClosingException = null;
510
511     /** Internal, constants for serialization */
512     final static String JavaDoc actionListenerK = "actionL";
513     final static String JavaDoc adjustmentListenerK = "adjustmentL";
514     final static String JavaDoc componentListenerK = "componentL";
515     final static String JavaDoc containerListenerK = "containerL";
516     final static String JavaDoc focusListenerK = "focusL";
517     final static String JavaDoc itemListenerK = "itemL";
518     final static String JavaDoc keyListenerK = "keyL";
519     final static String JavaDoc mouseListenerK = "mouseL";
520     final static String JavaDoc mouseMotionListenerK = "mouseMotionL";
521     final static String JavaDoc mouseWheelListenerK = "mouseWheelL";
522     final static String JavaDoc textListenerK = "textL";
523     final static String JavaDoc ownedWindowK = "ownedL";
524     final static String JavaDoc windowListenerK = "windowL";
525     final static String JavaDoc inputMethodListenerK = "inputMethodL";
526     final static String JavaDoc hierarchyListenerK = "hierarchyL";
527     final static String JavaDoc hierarchyBoundsListenerK = "hierarchyBoundsL";
528     final static String JavaDoc windowStateListenerK = "windowStateL";
529     final static String JavaDoc windowFocusListenerK = "windowFocusL";
530
531     /**
532      * The <code>eventMask</code> is ONLY set by subclasses via
533      * <code>enableEvents</code>.
534      * The mask should NOT be set when listeners are registered
535      * so that we can distinguish the difference between when
536      * listeners request events and subclasses request them.
537      * One bit is used to indicate whether input methods are
538      * enabled; this bit is set by <code>enableInputMethods</code> and is
539      * on by default.
540      *
541      * @serial
542      * @see #enableInputMethods
543      * @see AWTEvent
544      */

545     long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK;
546
547     private static final DebugHelper dbg = DebugHelper.create(Component JavaDoc.class);
548
549     /**
550      * Static properties for incremental drawing.
551      * @see #imageUpdate
552      */

553     static boolean isInc;
554     static int incRate;
555     static {
556         /* ensure that the necessary native libraries are loaded */
557         Toolkit.loadLibraries();
558         /* initialize JNI field and method ids */
559         if (!GraphicsEnvironment.isHeadless()) {
560             initIDs();
561         }
562
563         String JavaDoc s = (String JavaDoc) java.security.AccessController.doPrivileged(
564                                                                         new GetPropertyAction("awt.image.incrementaldraw"));
565         isInc = (s == null || s.equals("true"));
566
567         s = (String JavaDoc) java.security.AccessController.doPrivileged(
568                                                                  new GetPropertyAction("awt.image.redrawrate"));
569         incRate = (s != null) ? Integer.parseInt(s) : 100;
570     }
571
572     /**
573      * Ease-of-use constant for <code>getAlignmentY()</code>.
574      * Specifies an alignment to the top of the component.
575      * @see #getAlignmentY
576      */

577     public static final float TOP_ALIGNMENT = 0.0f;
578
579     /**
580      * Ease-of-use constant for <code>getAlignmentY</code> and
581      * <code>getAlignmentX</code>. Specifies an alignment to
582      * the center of the component
583      * @see #getAlignmentX
584      * @see #getAlignmentY
585      */

586     public static final float CENTER_ALIGNMENT = 0.5f;
587
588     /**
589      * Ease-of-use constant for <code>getAlignmentY</code>.
590      * Specifies an alignment to the bottom of the component.
591      * @see #getAlignmentY
592      */

593     public static final float BOTTOM_ALIGNMENT = 1.0f;
594
595     /**
596      * Ease-of-use constant for <code>getAlignmentX</code>.
597      * Specifies an alignment to the left side of the component.
598      * @see #getAlignmentX
599      */

600     public static final float LEFT_ALIGNMENT = 0.0f;
601
602     /**
603      * Ease-of-use constant for <code>getAlignmentX</code>.
604      * Specifies an alignment to the right side of the component.
605      * @see #getAlignmentX
606      */

607     public static final float RIGHT_ALIGNMENT = 1.0f;
608
609     /*
610      * JDK 1.1 serialVersionUID
611      */

612     private static final long serialVersionUID = -7644114512714619750L;
613
614     /**
615      * If any <code>PropertyChangeListeners</code> have been registered,
616      * the <code>changeSupport</code> field describes them.
617      *
618      * @serial
619      * @since 1.2
620      * @see #addPropertyChangeListener
621      * @see #removePropertyChangeListener
622      * @see #firePropertyChange
623      */

624     private PropertyChangeSupport JavaDoc changeSupport;
625
626     boolean isPacked = false;
627
628     /**
629      * This object is used as a key for internal hashtables.
630      */

631     transient private Object JavaDoc privateKey = new Object JavaDoc();
632
633     /**
634      * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize
635      * to signal setBounds what's changing. Should be used under TreeLock.
636      * This is only needed due to the inability to change the cross-calling
637      * order of public and deprecated methods.
638      */

639     private int boundsOp = ComponentPeer.DEFAULT_OPERATION;
640      
641     /**
642      * Should only be used in subclass getBounds to check that part of bounds
643      * is actualy changing
644      */

645     int getBoundsOp() {
646         assert Thread.holdsLock(getTreeLock());
647         return boundsOp;
648     }
649
650     void setBoundsOp(int op) {
651         assert Thread.holdsLock(getTreeLock());
652         if (op == ComponentPeer.RESET_OPERATION) {
653             boundsOp = ComponentPeer.DEFAULT_OPERATION;
654         } else
655             if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
656                 boundsOp = op;
657             }
658     }
659
660     /**
661      * Constructs a new component. Class <code>Component</code> can be
662      * extended directly to create a lightweight component that does not
663      * utilize an opaque native window. A lightweight component must be
664      * hosted by a native container somewhere higher up in the component
665      * tree (for example, by a <code>Frame</code> object).
666      */

667     protected Component() {
668         appContext = AppContext.getAppContext();
669     }
670
671     void initializeFocusTraversalKeys() {
672         focusTraversalKeys = new Set JavaDoc[3];
673     }
674
675     /**
676      * Constructs a name for this component. Called by <code>getName</code>
677      * when the name is <code>null</code>.
678      */

679     String JavaDoc constructComponentName() {
680         return null; // For strict compliance with prior platform versions, a Component
681
// that doesn't set its name should return null from
682
// getName()
683
}
684
685     /**
686      * Gets the name of the component.
687      * @return this component's name
688      * @see #setName
689      * @since JDK1.1
690      */

691     public String JavaDoc getName() {
692         if (name == null && !nameExplicitlySet) {
693             synchronized(this) {
694                 if (name == null && !nameExplicitlySet)
695                     name = constructComponentName();
696             }
697         }
698         return name;
699     }
700
701     /**
702      * Sets the name of the component to the specified string.
703      * @param name the string that is to be this
704      * component's name
705      * @see #getName
706      * @since JDK1.1
707      */

708     public void setName(String JavaDoc name) {
709         String JavaDoc oldName;
710         synchronized(this) {
711             oldName = this.name;
712             this.name = name;
713             nameExplicitlySet = true;
714         }
715         firePropertyChange("name", oldName, name);
716     }
717
718     /**
719      * Gets the parent of this component.
720      * @return the parent container of this component
721      * @since JDK1.0
722      */

723     public Container JavaDoc getParent() {
724         return getParent_NoClientCode();
725     }
726
727     // NOTE: This method may be called by privileged threads.
728
// This functionality is implemented in a package-private method
729
// to insure that it cannot be overridden by client subclasses.
730
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
731
final Container JavaDoc getParent_NoClientCode() {
732         return parent;
733     }
734
735     /**
736      * @deprecated As of JDK version 1.1,
737      * programs should not directly manipulate peers;
738      * replaced by <code>boolean isDisplayable()</code>.
739      */

740     @Deprecated JavaDoc
741     public ComponentPeer getPeer() {
742         return peer;
743     }
744
745     /**
746      * Associate a <code>DropTarget</code> with this component.
747      * The <code>Component</code> will receive drops only if it
748      * is enabled.
749      *
750      * @see #isEnabled
751      * @param dt The DropTarget
752      */

753
754     public synchronized void setDropTarget(DropTarget JavaDoc dt) {
755         if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))
756             return;
757
758         DropTarget JavaDoc old;
759
760         if ((old = dropTarget) != null) {
761             if (peer != null) dropTarget.removeNotify(peer);
762
763             DropTarget JavaDoc t = dropTarget;
764
765             dropTarget = null;
766
767             try {
768                 t.setComponent(null);
769             } catch (IllegalArgumentException JavaDoc iae) {
770                 // ignore it.
771
}
772         }
773
774         // if we have a new one, and we have a peer, add it!
775

776         if ((dropTarget = dt) != null) {
777             try {
778                 dropTarget.setComponent(this);
779                 if (peer != null) dropTarget.addNotify(peer);
780             } catch (IllegalArgumentException JavaDoc iae) {
781                 if (old != null) {
782                     try {
783                         old.setComponent(this);
784                         if (peer != null) dropTarget.addNotify(peer);
785                     } catch (IllegalArgumentException JavaDoc iae1) {
786                         // ignore it!
787
}
788                 }
789             }
790         }
791     }
792
793     /**
794      * Gets the <code>DropTarget</code> associated with this
795      * <code>Component</code>.
796      */

797
798     public synchronized DropTarget JavaDoc getDropTarget() { return dropTarget; }
799
800     /**
801      * Gets the <code>GraphicsConfiguration</code> associated with this
802      * <code>Component</code>.
803      * If the <code>Component</code> has not been assigned a specific
804      * <code>GraphicsConfiguration</code>,
805      * the <code>GraphicsConfiguration</code> of the
806      * <code>Component</code> object's top-level container is
807      * returned.
808      * If the <code>Component</code> has been created, but not yet added
809      * to a <code>Container</code>, this method returns <code>null</code>.
810      *
811      * @return the <code>GraphicsConfiguration</code> used by this
812      * <code>Component</code> or <code>null</code>
813      * @since 1.3
814      */

815     public GraphicsConfiguration JavaDoc getGraphicsConfiguration() {
816         synchronized(getTreeLock()) {
817             if (graphicsConfig != null) {
818                 return graphicsConfig;
819             } else if (getParent() != null) {
820                 return getParent().getGraphicsConfiguration();
821             } else {
822                 return null;
823             }
824         }
825     }
826
827     /**
828      * Resets this <code>Component</code>'s
829      * <code>GraphicsConfiguration</code> back to a default
830      * value. For most componenets, this is <code>null</code>.
831      * Called from the Toolkit thread, so NO CLIENT CODE.
832      */

833     void resetGC() {
834         synchronized(getTreeLock()) {
835             graphicsConfig = null;
836         }
837     }
838
839     /*
840      * Not called on Component, but needed for Canvas and Window
841      */

842     void setGCFromPeer() {
843         synchronized(getTreeLock()) {
844             if (peer != null) { // can't imagine how this will be false,
845
// but just in case
846
graphicsConfig = peer.getGraphicsConfiguration();
847             } else {
848                 graphicsConfig = null;
849             }
850         }
851     }
852
853     /**
854      * Checks that this component's <code>GraphicsDevice</code>
855      * <code>idString</code> matches the string argument.
856      */

857     void checkGD(String JavaDoc stringID) {
858         if (graphicsConfig != null) {
859             if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {
860                 throw new IllegalArgumentException JavaDoc(
861                                                    "adding a container to a container on a different GraphicsDevice");
862             }
863         }
864     }
865         
866     /**
867      * Gets this component's locking object (the object that owns the thread
868      * sychronization monitor) for AWT component-tree and layout
869      * operations.
870      * @return this component's locking object
871      */

872     public final Object JavaDoc getTreeLock() {
873         return LOCK;
874     }
875
876     /**
877      * Gets the toolkit of this component. Note that
878      * the frame that contains a component controls which
879      * toolkit is used by that component. Therefore if the component
880      * is moved from one frame to another, the toolkit it uses may change.
881      * @return the toolkit of this component
882      * @since JDK1.0
883      */

884     public Toolkit JavaDoc getToolkit() {
885         return getToolkitImpl();
886     }
887
888     /*
889      * This is called by the native code, so client code can't
890      * be called on the toolkit thread.
891      */

892     final Toolkit JavaDoc getToolkitImpl() {
893         ComponentPeer peer = this.peer;
894         if ((peer != null) && ! (peer instanceof LightweightPeer)){
895             return peer.getToolkit();
896         }
897         Container JavaDoc parent = this.parent;
898         if (parent != null) {
899             return parent.getToolkitImpl();
900         }
901         return Toolkit.getDefaultToolkit();
902     }
903
904     /**
905      * Determines whether this component is valid. A component is valid
906      * when it is correctly sized and positioned within its parent
907      * container and all its children are also valid.
908      * In order to account for peers' size requirements, components are invalidated
909      * before they are first shown on the screen. By the time the parent container
910      * is fully realized, all its components will be valid.
911      * @return <code>true</code> if the component is valid, <code>false</code>
912      * otherwise
913      * @see #validate
914      * @see #invalidate
915      * @since JDK1.0
916      */

917     public boolean isValid() {
918         return (peer != null) && valid;
919     }
920
921     /**
922      * Determines whether this component is displayable. A component is
923      * displayable when it is connected to a native screen resource.
924      * <p>
925      * A component is made displayable either when it is added to
926      * a displayable containment hierarchy or when its containment
927      * hierarchy is made displayable.
928      * A containment hierarchy is made displayable when its ancestor
929      * window is either packed or made visible.
930      * <p>
931      * A component is made undisplayable either when it is removed from
932      * a displayable containment hierarchy or when its containment hierarchy
933      * is made undisplayable. A containment hierarchy is made
934      * undisplayable when its ancestor window is disposed.
935      *
936      * @return <code>true</code> if the component is displayable,
937      * <code>false</code> otherwise
938      * @see Container#add(Component)
939      * @see Window#pack
940      * @see Window#show
941      * @see Container#remove(Component)
942      * @see Window#dispose
943      * @since 1.2
944      */

945     public boolean isDisplayable() {
946         return getPeer() != null;
947     }
948
949     /**
950      * Determines whether this component should be visible when its
951      * parent is visible. Components are
952      * initially visible, with the exception of top level components such
953      * as <code>Frame</code> objects.
954      * @return <code>true</code> if the component is visible,
955      * <code>false</code> otherwise
956      * @see #setVisible
957      * @since JDK1.0
958      */

959     public boolean isVisible() {
960         return visible;
961     }
962
963     /**
964      * Determines whether this component will be displayed on the screen
965      * if it's displayable.
966      * @return <code>true</code> if the component and all of its ancestors
967      * are visible, <code>false</code> otherwise
968      */

969     boolean isRecursivelyVisible() {
970         return visible && (parent == null || parent.isRecursivelyVisible());
971     }
972
973     /**
974      * Translates absolute coordinates into coordinates in the coordinate
975      * space of this component.
976      */

977     Point JavaDoc pointRelativeToComponent(Point JavaDoc absolute) {
978         Point JavaDoc compCoords = getLocationOnScreen();
979         return new Point JavaDoc(absolute.x - compCoords.x,
980                          absolute.y - compCoords.y);
981     }
982
983     /**
984      * Assuming that mouse location is stored in PointerInfo passed
985      * to this method, it finds a Component that is in the same
986      * Window as this Component and is located under the mouse pointer.
987      * If no such Component exists, null is returned.
988      * NOTE: this method should be called under the protection of
989      * tree lock, as it is done in Component.getMousePosition() and
990      * Container.getMousePosition(boolean).
991      */

992     Component JavaDoc findUnderMouseInWindow(PointerInfo JavaDoc pi) {
993         if (!isShowing()) {
994             return null;
995         }
996         Window JavaDoc win = getContainingWindow();
997         if (!Toolkit.getDefaultToolkit().getMouseInfoPeer().isWindowUnderMouse(win)) {
998             return null;
999         }
1000        final boolean INCLUDE_DISABLED = true;
1001        Point JavaDoc relativeToWindow = win.pointRelativeToComponent(pi.getLocation());
1002        Component JavaDoc inTheSameWindow = win.findComponentAt(relativeToWindow.x,
1003                                                        relativeToWindow.y,
1004                                                        INCLUDE_DISABLED);
1005        return inTheSameWindow;
1006    }
1007
1008    /**
1009     * Returns the position of the mouse pointer in this <code>Component</code>'s
1010     * coordinate space if the <code>Component</code> is directly under the mouse
1011     * pointer, otherwise returns <code>null</code>.
1012     * If the <code>Component</code> is not showing on the screen, this method
1013     * returns <code>null</code> even if the mouse pointer is above the area
1014     * where the <code>Component</code> would be displayed.
1015     * If the <code>Component</code> is partially or fully obscured by other
1016     * <code>Component</code>s or native windows, this method returns a non-null
1017     * value only if the mouse pointer is located above the unobscured part of the
1018     * <code>Component</code>.
1019     * <p>
1020     * For <code>Container</code>s it returns a non-null value if the mouse is
1021     * above the <code>Container</code> itself or above any of its descendants.
1022     * Use {@link Container#getMousePosition(boolean)} if you need to exclude children.
1023     * <p>
1024     * Sometimes the exact mouse coordinates are not important, and the only thing
1025     * that matters is whether a specific <code>Component</code> is under the mouse
1026     * pointer. If the return value of this method is <code>null</code>, mouse
1027     * pointer is not directly above the <code>Component</code>.
1028     *
1029     * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
1030     * @see #isShowing
1031     * @see Container#getMousePosition
1032     * @return mouse coordinates relative to this <code>Component</code>, or null
1033     * @since 1.5
1034     */

1035    public Point JavaDoc getMousePosition() throws HeadlessException JavaDoc {
1036        if (GraphicsEnvironment.isHeadless()) {
1037            throw new HeadlessException JavaDoc();
1038        }
1039
1040        PointerInfo JavaDoc pi = (PointerInfo JavaDoc)java.security.AccessController.doPrivileged(
1041                                                                                  new java.security.PrivilegedAction JavaDoc() {
1042                                                                                      public Object JavaDoc run() {
1043                                                                                          return MouseInfo.getPointerInfo();
1044                                                                                      }
1045                                                                                  }
1046                                                                                  );
1047
1048        synchronized (getTreeLock()) {
1049            Component JavaDoc inTheSameWindow = findUnderMouseInWindow(pi);
1050            if (!isSameOrAncestorOf(inTheSameWindow, true)) {
1051                return null;
1052            }
1053            return pointRelativeToComponent(pi.getLocation());
1054        }
1055    }
1056
1057    /**
1058     * Overridden in Container. Must be called under TreeLock.
1059     */

1060    boolean isSameOrAncestorOf(Component JavaDoc comp, boolean allowChildren) {
1061        return comp == this;
1062    }
1063
1064    /**
1065     * Determines whether this component is showing on screen. This means
1066     * that the component must be visible, and it must be in a container
1067     * that is visible and showing.
1068     * @return <code>true</code> if the component is showing,
1069     * <code>false</code> otherwise
1070     * @see #setVisible
1071     * @since JDK1.0
1072     */

1073    public boolean isShowing() {
1074        if (visible && (peer != null)) {
1075            Container JavaDoc parent = this.parent;
1076            return (parent == null) || parent.isShowing();
1077        }
1078        return false;
1079    }
1080
1081    /**
1082     * Determines whether this component is enabled. An enabled component
1083     * can respond to user input and generate events. Components are
1084     * enabled initially by default. A component may be enabled or disabled by
1085     * calling its <code>setEnabled</code> method.
1086     * @return <code>true</code> if the component is enabled,
1087     * <code>false</code> otherwise
1088     * @see #setEnabled
1089     * @since JDK1.0
1090     */

1091    public boolean isEnabled() {
1092        return isEnabledImpl();
1093    }
1094
1095    /*
1096     * This is called by the native code, so client code can't
1097     * be called on the toolkit thread.
1098     */

1099    final boolean isEnabledImpl() {
1100        return enabled;
1101    }
1102
1103    /**
1104     * Enables or disables this component, depending on the value of the
1105     * parameter <code>b</code>. An enabled component can respond to user
1106     * input and generate events. Components are enabled initially by default.
1107     *
1108     * <p>Note: Disabling a lightweight component does not prevent it from
1109     * receiving MouseEvents.
1110     *
1111     * @param b If <code>true</code>, this component is
1112     * enabled; otherwise this component is disabled
1113     * @see #isEnabled
1114     * @see #isLightweight
1115     * @since JDK1.1
1116     */

1117    public void setEnabled(boolean b) {
1118        enable(b);
1119    }
1120
1121    /**
1122     * @deprecated As of JDK version 1.1,
1123     * replaced by <code>setEnabled(boolean)</code>.
1124     */

1125    @Deprecated JavaDoc
1126    public void enable() {
1127        if (!enabled) {
1128            synchronized (getTreeLock()) {
1129                enabled = true;
1130                ComponentPeer peer = this.peer;
1131                if (peer != null) {
1132                    peer.enable();
1133                    if (visible) {
1134                        updateCursorImmediately();
1135                    }
1136                }
1137            }
1138            if (accessibleContext != null) {
1139                accessibleContext.firePropertyChange(
1140                                                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1141                                                     null, AccessibleState.ENABLED);
1142            }
1143        }
1144    }
1145
1146    /**
1147     * @deprecated As of JDK version 1.1,
1148     * replaced by <code>setEnabled(boolean)</code>.
1149     */

1150    @Deprecated JavaDoc
1151    public void enable(boolean b) {
1152        if (b) {
1153            enable();
1154        } else {
1155            disable();
1156        }
1157    }
1158
1159    /**
1160     * @deprecated As of JDK version 1.1,
1161     * replaced by <code>setEnabled(boolean)</code>.
1162     */

1163    @Deprecated JavaDoc
1164    public void disable() {
1165        if (enabled) {
1166            KeyboardFocusManager.clearMostRecentFocusOwner(this);
1167            synchronized (getTreeLock()) {
1168                enabled = false;
1169                if (isFocusOwner()) {
1170                    // Don't clear the global focus owner. If transferFocus
1171
// fails, we want the focus to stay on the disabled
1172
// Component so that keyboard traversal, et. al. still
1173
// makes sense to the user.
1174
autoTransferFocus(false);
1175                }
1176                ComponentPeer peer = this.peer;
1177                if (peer != null) {
1178                    peer.disable();
1179                    if (visible) {
1180                        updateCursorImmediately();
1181                    }
1182                }
1183            }
1184            if (accessibleContext != null) {
1185                accessibleContext.firePropertyChange(
1186                                                     AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
1187                                                     null, AccessibleState.ENABLED);
1188            }
1189        }
1190    }
1191
1192    /**
1193     * Returns true if this component is painted to an offscreen image
1194     * ("buffer") that's copied to the screen later. Component
1195     * subclasses that support double buffering should override this
1196     * method to return true if double buffering is enabled.
1197     *
1198     * @return false by default
1199     */

1200    public boolean isDoubleBuffered() {
1201        return false;
1202    }
1203
1204    /**
1205     * Enables or disables input method support for this component. If input
1206     * method support is enabled and the component also processes key events,
1207     * incoming events are offered to
1208     * the current input method and will only be processed by the component or
1209     * dispatched to its listeners if the input method does not consume them.
1210     * By default, input method support is enabled.
1211     *
1212     * @param enable true to enable, false to disable
1213     * @see #processKeyEvent
1214     * @since 1.2
1215     */

1216    public void enableInputMethods(boolean enable) {
1217        if (enable) {
1218            if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)
1219                return;
1220
1221            // If this component already has focus, then activate the
1222
// input method by dispatching a synthesized focus gained
1223
// event.
1224
if (isFocusOwner()) {
1225                InputContext JavaDoc inputContext = getInputContext();
1226                if (inputContext != null) {
1227                    FocusEvent focusGainedEvent =
1228                        new FocusEvent(this, FocusEvent.FOCUS_GAINED);
1229                    inputContext.dispatchEvent(focusGainedEvent);
1230                }
1231            }
1232
1233            eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK;
1234        } else {
1235            if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
1236                InputContext JavaDoc inputContext = getInputContext();
1237                if (inputContext != null) {
1238                    inputContext.endComposition();
1239                    inputContext.removeNotify(this);
1240                }
1241            }
1242            eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK;
1243        }
1244    }
1245
1246    /**
1247     * Shows or hides this component depending on the value of parameter
1248     * <code>b</code>.
1249     * @param b if <code>true</code>, shows this component;
1250     * otherwise, hides this component
1251     * @see #isVisible
1252     * @since JDK1.1
1253     */

1254    public void setVisible(boolean b) {
1255        show(b);
1256    }
1257
1258    /**
1259     * @deprecated As of JDK version 1.1,
1260     * replaced by <code>setVisible(boolean)</code>.
1261     */

1262    @Deprecated JavaDoc
1263    public void show() {
1264        if (!visible) {
1265            synchronized (getTreeLock()) {
1266                visible = true;
1267                ComponentPeer peer = this.peer;
1268                if (peer != null) {
1269                    peer.show();
1270                    createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1271                                          this, parent,
1272                                          HierarchyEvent.SHOWING_CHANGED,
1273                                          Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1274                    if (peer instanceof LightweightPeer) {
1275                        repaint();
1276                    }
1277                    updateCursorImmediately();
1278                }
1279
1280                if (componentListener != null ||
1281                    (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
1282                    Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1283                    ComponentEvent e = new ComponentEvent(this,
1284                                                          ComponentEvent.COMPONENT_SHOWN);
1285                    Toolkit.getEventQueue().postEvent(e);
1286                }
1287            }
1288            Container JavaDoc parent = this.parent;
1289            if (parent != null) {
1290                parent.invalidate();
1291            }
1292        }
1293    }
1294
1295    /**
1296     * @deprecated As of JDK version 1.1,
1297     * replaced by <code>setVisible(boolean)</code>.
1298     */

1299    @Deprecated JavaDoc
1300    public void show(boolean b) {
1301        if (b) {
1302            show();
1303        } else {
1304            hide();
1305        }
1306    }
1307
1308    boolean containsFocus() {
1309        return isFocusOwner();
1310    }
1311
1312    void clearMostRecentFocusOwnerOnHide() {
1313        KeyboardFocusManager.clearMostRecentFocusOwner(this);
1314    }
1315
1316    void clearCurrentFocusCycleRootOnHide() {
1317        /* do nothing */
1318    }
1319
1320    /**
1321     * @deprecated As of JDK version 1.1,
1322     * replaced by <code>setVisible(boolean)</code>.
1323     */

1324    @Deprecated JavaDoc
1325    public void hide() {
1326        isPacked = false;
1327
1328        if (visible) {
1329            clearCurrentFocusCycleRootOnHide();
1330            clearMostRecentFocusOwnerOnHide();
1331            synchronized (getTreeLock()) {
1332                visible = false;
1333                if (containsFocus()) {
1334                    autoTransferFocus(true);
1335                }
1336                ComponentPeer peer = this.peer;
1337                if (peer != null) {
1338                    peer.hide();
1339                    createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
1340                                          this, parent,
1341                                          HierarchyEvent.SHOWING_CHANGED,
1342                                          Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
1343                    if (peer instanceof LightweightPeer) {
1344                        repaint();
1345                    }
1346                    updateCursorImmediately();
1347                }
1348                if (componentListener != null ||
1349                    (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
1350                    Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
1351                    ComponentEvent e = new ComponentEvent(this,
1352                                                          ComponentEvent.COMPONENT_HIDDEN);
1353                    Toolkit.getEventQueue().postEvent(e);
1354                }
1355            }
1356            Container JavaDoc parent = this.parent;
1357            if (parent != null) {
1358                parent.invalidate();
1359            }
1360        }
1361    }
1362
1363    /**
1364     * Gets the foreground color of this component.
1365     * @return this component's foreground color; if this component does
1366     * not have a foreground color, the foreground color of its parent
1367     * is returned
1368     * @see #setForeground
1369     * @since JDK1.0
1370     * @beaninfo
1371     * bound: true
1372     */

1373    public Color JavaDoc getForeground() {
1374        Color JavaDoc foreground = this.foreground;
1375        if (foreground != null) {
1376            return foreground;
1377        }
1378        Container JavaDoc parent = this.parent;
1379        return (parent != null) ? parent.getForeground() : null;
1380    }
1381
1382    /**
1383     * Sets the foreground color of this component.
1384     * @param c the color to become this component's
1385     * foreground color; if this parameter is <code>null</code>
1386     * then this component will inherit
1387     * the foreground color of its parent
1388     * @see #getForeground
1389     * @since JDK1.0
1390     */

1391    public void setForeground(Color JavaDoc c) {
1392        Color JavaDoc oldColor = foreground;
1393        ComponentPeer peer = this.peer;
1394        foreground = c;
1395        if (peer != null) {
1396            c = getForeground();
1397            if (c != null) {
1398                peer.setForeground(c);
1399            }
1400        }
1401        // This is a bound property, so report the change to
1402
// any registered listeners. (Cheap if there are none.)
1403
firePropertyChange("foreground", oldColor, c);
1404    }
1405
1406    /**
1407     * Returns whether the foreground color has been explicitly set for this
1408     * Component. If this method returns <code>false</code>, this Component is
1409     * inheriting its foreground color from an ancestor.
1410     *
1411     * @return <code>true</code> if the foreground color has been explicitly
1412     * set for this Component; <code>false</code> otherwise.
1413     * @since 1.4
1414     */

1415    public boolean isForegroundSet() {
1416        return (foreground != null);
1417    }
1418
1419    /**
1420     * Gets the background color of this component.
1421     * @return this component's background color; if this component does
1422     * not have a background color,
1423     * the background color of its parent is returned
1424     * @see #setBackground
1425     * @since JDK1.0
1426     */

1427    public Color JavaDoc getBackground() {
1428        Color JavaDoc background = this.background;
1429        if (background != null) {
1430            return background;
1431        }
1432        Container JavaDoc parent = this.parent;
1433        return (parent != null) ? parent.getBackground() : null;
1434    }
1435
1436    /**
1437     * Sets the background color of this component.
1438     * <p>
1439     * The background color affects each component differently and the
1440     * parts of the component that are affected by the background color
1441     * may differ between operating systems.
1442     *
1443     * @param c the color to become this component's color;
1444     * if this parameter is <code>null</code>, then this
1445     * component will inherit the background color of its parent
1446     * @see #getBackground
1447     * @since JDK1.0
1448     * @beaninfo
1449     * bound: true
1450     */

1451    public void setBackground(Color JavaDoc c) {
1452        Color JavaDoc oldColor = background;
1453        ComponentPeer peer = this.peer;
1454        background = c;
1455        if (peer != null) {
1456            c = getBackground();
1457            if (c != null) {
1458                peer.setBackground(c);
1459            }
1460        }
1461        // This is a bound property, so report the change to
1462
// any registered listeners. (Cheap if there are none.)
1463
firePropertyChange("background", oldColor, c);
1464    }
1465
1466    /**
1467     * Returns whether the background color has been explicitly set for this
1468     * Component. If this method returns <code>false</code>, this Component is
1469     * inheriting its background color from an ancestor.
1470     *
1471     * @return <code>true</code> if the background color has been explicitly
1472     * set for this Component; <code>false</code> otherwise.
1473     * @since 1.4
1474     */

1475    public boolean isBackgroundSet() {
1476        return (background != null);
1477    }
1478
1479    /**
1480     * Gets the font of this component.
1481     * @return this component's font; if a font has not been set
1482     * for this component, the font of its parent is returned
1483     * @see #setFont
1484     * @since JDK1.0
1485     */

1486    public Font JavaDoc getFont() {
1487        return getFont_NoClientCode();
1488    }
1489
1490    // NOTE: This method may be called by privileged threads.
1491
// This functionality is implemented in a package-private method
1492
// to insure that it cannot be overridden by client subclasses.
1493
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
1494
final Font JavaDoc getFont_NoClientCode() {
1495        Font JavaDoc font = this.font;
1496        if (font != null) {
1497            return font;
1498        }
1499        Container JavaDoc parent = this.parent;
1500        return (parent != null) ? parent.getFont_NoClientCode() : null;
1501    }
1502
1503    /**
1504     * Sets the font of this component.
1505     * @param f the font to become this component's font;
1506     * if this parameter is <code>null</code> then this
1507     * component will inherit the font of its parent
1508     * @see #getFont
1509     * @since JDK1.0
1510     * @beaninfo
1511     * bound: true
1512     */

1513    public void setFont(Font JavaDoc f) {
1514        Font JavaDoc oldFont, newFont;
1515        synchronized(getTreeLock()) {
1516            synchronized (this) {
1517                oldFont = font;
1518                newFont = font = f;
1519            }
1520            ComponentPeer peer = this.peer;
1521            if (peer != null) {
1522                f = getFont();
1523                if (f != null) {
1524                    peer.setFont(f);
1525                    peerFont = f;
1526                }
1527            }
1528        }
1529        // This is a bound property, so report the change to
1530
// any registered listeners. (Cheap if there are none.)
1531
firePropertyChange("font", oldFont, newFont);
1532
1533        // This could change the preferred size of the Component.
1534
if (valid) {
1535            invalidate();
1536        }
1537    }
1538
1539    /**
1540     * Returns whether the font has been explicitly set for this Component. If
1541     * this method returns <code>false</code>, this Component is inheriting its
1542     * font from an ancestor.
1543     *
1544     * @return <code>true</code> if the font has been explicitly set for this
1545     * Component; <code>false</code> otherwise.
1546     * @since 1.4
1547     */

1548    public boolean isFontSet() {
1549        return (font != null);
1550    }
1551
1552    /**
1553     * Gets the locale of this component.
1554     * @return this component's locale; if this component does not
1555     * have a locale, the locale of its parent is returned
1556     * @see #setLocale
1557     * @exception IllegalComponentStateException if the <code>Component</code>
1558     * does not have its own locale and has not yet been added to
1559     * a containment hierarchy such that the locale can be determined
1560     * from the containing parent
1561     * @since JDK1.1
1562     */

1563    public Locale JavaDoc getLocale() {
1564        Locale JavaDoc locale = this.locale;
1565        if (locale != null) {
1566            return locale;
1567        }
1568        Container JavaDoc parent = this.parent;
1569
1570        if (parent == null) {
1571            throw new IllegalComponentStateException JavaDoc("This component must have a parent in order to determine its locale");
1572        } else {
1573            return parent.getLocale();
1574        }
1575    }
1576
1577    /**
1578     * Sets the locale of this component. This is a bound property.
1579     * @param l the locale to become this component's locale
1580     * @see #getLocale
1581     * @since JDK1.1
1582     */

1583    public void setLocale(Locale JavaDoc l) {
1584        Locale JavaDoc oldValue = locale;
1585        locale = l;
1586
1587        // This is a bound property, so report the change to
1588
// any registered listeners. (Cheap if there are none.)
1589
firePropertyChange("locale", oldValue, l);
1590
1591        // This could change the preferred size of the Component.
1592
if (valid) {
1593            invalidate();
1594        }
1595    }
1596
1597    /**
1598     * Gets the instance of <code>ColorModel</code> used to display
1599     * the component on the output device.
1600     * @return the color model used by this component
1601     * @see java.awt.image.ColorModel
1602     * @see java.awt.peer.ComponentPeer#getColorModel()
1603     * @see Toolkit#getColorModel()
1604     * @since JDK1.0
1605     */

1606    public ColorModel JavaDoc getColorModel() {
1607        ComponentPeer peer = this.peer;
1608        if ((peer != null) && ! (peer instanceof LightweightPeer)) {
1609            return peer.getColorModel();
1610        } else if (GraphicsEnvironment.isHeadless()) {
1611            return ColorModel.getRGBdefault();
1612        } // else
1613
return getToolkit().getColorModel();
1614    }
1615
1616    /**
1617     * Gets the location of this component in the form of a
1618     * point specifying the component's top-left corner.
1619     * The location will be relative to the parent's coordinate space.
1620     * <p>
1621     * Due to the asynchronous nature of native event handling, this
1622     * method can return outdated values (for instance, after several calls
1623     * of <code>setLocation()</code> in rapid succession). For this
1624     * reason, the recommended method of obtaining a component's position is
1625     * within <code>java.awt.event.ComponentListener.componentMoved()</code>,
1626     * which is called after the operating system has finished moving the
1627     * component.
1628     * </p>
1629     * @return an instance of <code>Point</code> representing
1630     * the top-left corner of the component's bounds in
1631     * the coordinate space of the component's parent
1632     * @see #setLocation
1633     * @see #getLocationOnScreen
1634     * @since JDK1.1
1635     */

1636    public Point JavaDoc getLocation() {
1637        return location();
1638    }
1639
1640    /**
1641     * Gets the location of this component in the form of a point
1642     * specifying the component's top-left corner in the screen's
1643     * coordinate space.
1644     * @return an instance of <code>Point</code> representing
1645     * the top-left corner of the component's bounds in the
1646     * coordinate space of the screen
1647     * @throws <code>IllegalComponentStateException</code> if the
1648     * component is not showing on the screen
1649     * @see #setLocation
1650     * @see #getLocation
1651     */

1652    public Point JavaDoc getLocationOnScreen() {
1653        synchronized (getTreeLock()) {
1654            return getLocationOnScreen_NoTreeLock();
1655        }
1656    }
1657
1658    /*
1659     * a package private version of getLocationOnScreen
1660     * used by GlobalCursormanager to update cursor
1661     */

1662    final Point JavaDoc getLocationOnScreen_NoTreeLock() {
1663        
1664        if (peer != null && isShowing()) {
1665            if (peer instanceof LightweightPeer) {
1666                // lightweight component location needs to be translated
1667
// relative to a native component.
1668
Container JavaDoc host = getNativeContainer();
1669                Point JavaDoc pt = host.peer.getLocationOnScreen();
1670                for(Component JavaDoc c = this; c != host; c = c.getParent()) {
1671                    pt.x += c.x;
1672                    pt.y += c.y;
1673                }
1674                return pt;
1675            } else {
1676                Point JavaDoc pt = peer.getLocationOnScreen();
1677                return pt;
1678            }
1679        } else {
1680            throw new IllegalComponentStateException JavaDoc("component must be showing on the screen to determine its location");
1681        }
1682    }
1683    
1684    
1685    /**
1686     * @deprecated As of JDK version 1.1,
1687     * replaced by <code>getLocation()</code>.
1688     */

1689    @Deprecated JavaDoc
1690    public Point JavaDoc location() {
1691        return new Point JavaDoc(x, y);
1692    }
1693    
1694    /**
1695     * Moves this component to a new location. The top-left corner of
1696     * the new location is specified by the <code>x</code> and <code>y</code>
1697     * parameters in the coordinate space of this component's parent.
1698     * @param x the <i>x</i>-coordinate of the new location's
1699     * top-left corner in the parent's coordinate space
1700     * @param y the <i>y</i>-coordinate of the new location's
1701     * top-left corner in the parent's coordinate space
1702     * @see #getLocation
1703     * @see #setBounds
1704     * @since JDK1.1
1705     */

1706    public void setLocation(int x, int y) {
1707        move(x, y);
1708    }
1709    
1710    /**
1711     * @deprecated As of JDK version 1.1,
1712     * replaced by <code>setLocation(int, int)</code>.
1713     */

1714    @Deprecated JavaDoc
1715    public void move(int x, int y) {
1716        synchronized(getTreeLock()) {
1717            setBoundsOp(ComponentPeer.SET_LOCATION);
1718            setBounds(x, y, width, height);
1719        }
1720    }
1721
1722    /**
1723     * Moves this component to a new location. The top-left corner of
1724     * the new location is specified by point <code>p</code>. Point
1725     * <code>p</code> is given in the parent's coordinate space.
1726     * @param p the point defining the top-left corner
1727     * of the new location, given in the coordinate space of this
1728     * component's parent
1729     * @see #getLocation
1730     * @see #setBounds
1731     * @since JDK1.1
1732     */

1733    public void setLocation(Point JavaDoc p) {
1734        setLocation(p.x, p.y);
1735    }
1736
1737    /**
1738     * Returns the size of this component in the form of a
1739     * <code>Dimension</code> object. The <code>height</code>
1740     * field of the <code>Dimension</code> object contains
1741     * this component's height, and the <code>width</code>
1742     * field of the <code>Dimension</code> object contains
1743     * this component's width.
1744     * @return a <code>Dimension</code> object that indicates the
1745     * size of this component
1746     * @see #setSize
1747     * @since JDK1.1
1748     */

1749    public Dimension JavaDoc getSize() {
1750        return size();
1751    }
1752
1753    /**
1754     * @deprecated As of JDK version 1.1,
1755     * replaced by <code>getSize()</code>.
1756     */

1757    @Deprecated JavaDoc
1758    public Dimension JavaDoc size() {
1759        return new Dimension JavaDoc(width, height);
1760    }
1761
1762    /**
1763     * Resizes this component so that it has width <code>width</code>
1764     * and height <code>height</code>.
1765     * @param width the new width of this component in pixels
1766     * @param height the new height of this component in pixels
1767     * @see #getSize
1768     * @see #setBounds
1769     * @since JDK1.1
1770     */

1771    public void setSize(int width, int height) {
1772        resize(width, height);
1773    }
1774
1775    /**
1776     * @deprecated As of JDK version 1.1,
1777     * replaced by <code>setSize(int, int)</code>.
1778     */

1779    @Deprecated JavaDoc
1780    public void resize(int width, int height) {
1781        synchronized(getTreeLock()) {
1782            setBoundsOp(ComponentPeer.SET_SIZE);
1783            setBounds(x, y, width, height);
1784        }
1785    }
1786
1787    /**
1788     * Resizes this component so that it has width <code>d.width</code>
1789     * and height <code>d.height</code>.
1790     * @param d the dimension specifying the new size
1791     * of this component
1792     * @see #setSize
1793     * @see #setBounds
1794     * @since JDK1.1
1795     */

1796    public void setSize(Dimension JavaDoc d) {
1797        resize(d);
1798    }
1799
1800    /**
1801     * @deprecated As of JDK version 1.1,
1802     * replaced by <code>setSize(Dimension)</code>.
1803     */

1804    @Deprecated JavaDoc
1805    public void resize(Dimension JavaDoc d) {
1806        setSize(d.width, d.height);
1807    }
1808
1809    /**
1810     * Gets the bounds of this component in the form of a
1811     * <code>Rectangle</code> object. The bounds specify this
1812     * component's width, height, and location relative to
1813     * its parent.
1814     * @return a rectangle indicating this component's bounds
1815     * @see #setBounds
1816     * @see #getLocation
1817     * @see #getSize
1818     */

1819    public Rectangle JavaDoc getBounds() {
1820        return bounds();
1821    }
1822
1823    /**
1824     * @deprecated As of JDK version 1.1,
1825     * replaced by <code>getBounds()</code>.
1826     */

1827    @Deprecated JavaDoc
1828    public Rectangle JavaDoc bounds() {
1829        return new Rectangle JavaDoc(x, y, width, height);
1830    }
1831
1832    /**
1833     * Moves and resizes this component. The new location of the top-left
1834     * corner is specified by <code>x</code> and <code>y</code>, and the
1835     * new size is specified by <code>width</code> and <code>height</code>.
1836     * @param x the new <i>x</i>-coordinate of this component
1837     * @param y the new <i>y</i>-coordinate of this component
1838     * @param width the new <code>width</code> of this component
1839     * @param height the new <code>height</code> of this
1840     * component
1841     * @see #getBounds
1842     * @see #setLocation(int, int)
1843     * @see #setLocation(Point)
1844     * @see #setSize(int, int)
1845     * @see #setSize(Dimension)
1846     * @since JDK1.1
1847     */

1848    public void setBounds(int x, int y, int width, int height) {
1849        reshape(x, y, width, height);
1850    }
1851
1852    /**
1853     * @deprecated As of JDK version 1.1,
1854     * replaced by <code>setBounds(int, int, int, int)</code>.
1855     */

1856    @Deprecated JavaDoc
1857    public void reshape(int x, int y, int width, int height) {
1858        synchronized (getTreeLock()) {
1859            try {
1860                setBoundsOp(ComponentPeer.SET_BOUNDS);
1861                boolean resized = (this.width != width) || (this.height != height);
1862                boolean moved = (this.x != x) || (this.y != y);
1863                if (!resized && !moved) {
1864                    return;
1865                }
1866                int oldX = this.x;
1867                int oldY = this.y;
1868                int oldWidth = this.width;
1869                int oldHeight = this.height;
1870                this.x = x;
1871                this.y = y;
1872                this.width = width;
1873                this.height = height;
1874
1875                if (resized) {
1876                    isPacked = false;
1877                }
1878                
1879                if (peer != null) {
1880                    // LightwightPeer is an empty stub so can skip peer.reshape
1881
if (!(peer instanceof LightweightPeer)) {
1882                        reshapeNativePeer(x, y, width, height, getBoundsOp());
1883                        // Check peer actualy changed coordinates
1884
resized = (oldWidth != this.width) || (oldHeight != this.height);
1885                        moved = (oldX != this.x) || (oldY != this.y);
1886                    }
1887                
1888                    if (resized) {
1889                        invalidate();
1890                    }
1891                    if (parent != null && parent.valid) {
1892                        parent.invalidate();
1893                    }
1894                }
1895                notifyNewBounds(resized, moved);
1896                repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight);
1897            } finally {
1898                setBoundsOp(ComponentPeer.RESET_OPERATION);
1899            }
1900        }
1901    }
1902    
1903    private void repaintParentIfNeeded(int oldX, int oldY, int oldWidth,
1904                                       int oldHeight)
1905    {
1906        if (parent != null && peer instanceof LightweightPeer && isShowing()) {
1907            // Have the parent redraw the area this component occupied.
1908
parent.repaint(oldX, oldY, oldWidth, oldHeight);
1909            // Have the parent redraw the area this component *now* occupies.
1910
repaint();
1911        }
1912    }
1913
1914    private void reshapeNativePeer(int x, int y, int width, int height, int op) {
1915        // native peer might be offset by more than direct
1916
// parent since parent might be lightweight.
1917
int nativeX = x;
1918        int nativeY = y;
1919        for (Component JavaDoc c = parent;
1920             (c != null) && (c.peer instanceof LightweightPeer);
1921             c = c.parent)
1922        {
1923            nativeX += c.x;
1924            nativeY += c.y;
1925        }
1926        peer.setBounds(nativeX, nativeY, width, height, op);
1927    }
1928
1929    
1930    private void notifyNewBounds(boolean resized, boolean moved) {
1931        if (componentListener != null
1932            || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
1933            || Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK))
1934        {
1935            if (resized) {
1936                ComponentEvent e = new ComponentEvent(this,
1937                                                      ComponentEvent.COMPONENT_RESIZED);
1938                Toolkit.getEventQueue().postEvent(e);
1939            }
1940            if (moved) {
1941                ComponentEvent e = new ComponentEvent(this,
1942                                                      ComponentEvent.COMPONENT_MOVED);
1943                Toolkit.getEventQueue().postEvent(e);
1944            }
1945        } else
1946            // Swing optimization. JComponent extends Container
1947
if (this instanceof Container JavaDoc && ((Container JavaDoc)this).ncomponents > 0) {
1948                boolean enabledOnToolkit =
1949                    Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
1950                // Container.dispatchEventImpl will create
1951
// HierarchyEvents
1952
if (resized) {
1953                    ((Container JavaDoc)this).createChildHierarchyEvents(
1954                                                                 HierarchyEvent.ANCESTOR_RESIZED, 0, enabledOnToolkit);
1955                }
1956                if (moved) {
1957                    ((Container JavaDoc)this).createChildHierarchyEvents(
1958                                                                 HierarchyEvent.ANCESTOR_MOVED, 0, enabledOnToolkit);
1959                }
1960            }
1961    }
1962
1963    /**
1964     * Moves and resizes this component to conform to the new
1965     * bounding rectangle <code>r</code>. This component's new
1966     * position is specified by <code>r.x</code> and <code>r.y</code>,
1967     * and its new size is specified by <code>r.width</code> and
1968     * <code>r.height</code>
1969     * @param r the new bounding rectangle for this component
1970     * @see #getBounds
1971     * @see #setLocation(int, int)
1972     * @see #setLocation(Point)
1973     * @see #setSize(int, int)
1974     * @see #setSize(Dimension)
1975     * @since JDK1.1
1976     */

1977    public void setBounds(Rectangle JavaDoc r) {
1978        setBounds(r.x, r.y, r.width, r.height);
1979    }
1980
1981
1982    /**
1983     * Returns the current x coordinate of the components origin.
1984     * This method is preferable to writing
1985     * <code>component.getBounds().x</code>,
1986     * or <code>component.getLocation().x</code> because it doesn't
1987     * cause any heap allocations.
1988     *
1989     * @return the current x coordinate of the components origin
1990     * @since 1.2
1991     */

1992    public int getX() {
1993        return x;
1994    }
1995
1996
1997    /**
1998     * Returns the current y coordinate of the components origin.
1999     * This method is preferable to writing
2000     * <code>component.getBounds().y</code>,
2001     * or <code>component.getLocation().y</code> because it
2002     * doesn't cause any heap allocations.
2003     *
2004     * @return the current y coordinate of the components origin
2005     * @since 1.2
2006     */

2007    public int getY() {
2008        return y;
2009    }
2010
2011
2012    /**
2013     * Returns the current width of this component.
2014     * This method is preferable to writing
2015     * <code>component.getBounds().width</code>,
2016     * or <code>component.getSize().width</code> because it
2017     * doesn't cause any heap allocations.
2018     *
2019     * @return the current width of this component
2020     * @since 1.2
2021     */

2022    public int getWidth() {
2023        return width;
2024    }
2025
2026
2027    /**
2028     * Returns the current height of this component.
2029     * This method is preferable to writing
2030     * <code>component.getBounds().height</code.,
2031     * or <code>component.getSize().height</code> because it
2032     * doesn't cause any heap allocations.
2033     *
2034     * @return the current height of this component
2035     * @since 1.2
2036     */

2037    public int getHeight() {
2038        return height;
2039    }
2040
2041    /**
2042     * Stores the bounds of this component into "return value" <b>rv</b> and
2043     * return <b>rv</b>. If rv is <code>null</code> a new
2044     * <code>Rectangle</code> is allocated.
2045     * This version of <code>getBounds</code> is useful if the caller
2046     * wants to avoid allocating a new <code>Rectangle</code> object
2047     * on the heap.
2048     *
2049     * @param rv the return value, modified to the components bounds
2050     * @return rv
2051     */

2052    public Rectangle JavaDoc getBounds(Rectangle JavaDoc rv) {
2053        if (rv == null) {
2054            return new Rectangle JavaDoc(getX(), getY(), getWidth(), getHeight());
2055        }
2056        else {
2057            rv.setBounds(getX(), getY(), getWidth(), getHeight());
2058            return rv;
2059        }
2060    }
2061
2062    /**
2063     * Stores the width/height of this component into "return value" <b>rv</b>
2064     * and return <b>rv</b>. If rv is <code>null</code> a new
2065     * <code>Dimension</code> object is allocated. This version of
2066     * <code>getSize</code> is useful if the caller wants to avoid
2067     * allocating a new <code>Dimension</code> object on the heap.
2068     *
2069     * @param rv the return value, modified to the components size
2070     * @return rv
2071     */

2072    public Dimension JavaDoc getSize(Dimension JavaDoc rv) {
2073        if (rv == null) {
2074            return new Dimension JavaDoc(getWidth(), getHeight());
2075        }
2076        else {
2077            rv.setSize(getWidth(), getHeight());
2078            return rv;
2079        }
2080    }
2081
2082    /**
2083     * Stores the x,y origin of this component into "return value" <b>rv</b>
2084     * and return <b>rv</b>. If rv is <code>null</code> a new
2085     * <code>Point</code> is allocated.
2086     * This version of <code>getLocation</code> is useful if the
2087     * caller wants to avoid allocating a new <code>Point</code>
2088     * object on the heap.
2089     *
2090     * @param rv the return value, modified to the components location
2091     * @return rv
2092     */

2093    public Point JavaDoc getLocation(Point JavaDoc rv) {
2094        if (rv == null) {
2095            return new Point JavaDoc(getX(), getY());
2096        }
2097        else {
2098            rv.setLocation(getX(), getY());
2099            return rv;
2100        }
2101    }
2102
2103    /**
2104     * Returns true if this component is completely opaque, returns
2105     * false by default.
2106     * <p>
2107     * An opaque component paints every pixel within its
2108     * rectangular region. A non-opaque component paints only some of
2109     * its pixels, allowing the pixels underneath it to "show through".
2110     * A component that does not fully paint its pixels therefore
2111     * provides a degree of transparency. Only lightweight
2112     * components can be transparent.
2113     * <p>
2114     * Subclasses that guarantee to always completely paint their
2115     * contents should override this method and return true. All
2116     * of the "heavyweight" AWT components are opaque.
2117     *
2118     * @return true if this component is completely opaque
2119     * @see #isLightweight
2120     * @since 1.2
2121     */

2122    public boolean isOpaque() {
2123        if (getPeer() == null) {
2124            return false;
2125        }
2126        else {
2127            return !isLightweight();
2128        }
2129    }
2130
2131
2132    /**
2133     * A lightweight component doesn't have a native toolkit peer.
2134     * Subclasses of <code>Component</code> and <code>Container</code>,
2135     * other than the ones defined in this package like <code>Button</code>
2136     * or <code>Scrollbar</code>, are lightweight.
2137     * All of the Swing components are lightweights.
2138     * <p>
2139     * This method will always return <code>false</code> if this component
2140     * is not displayable because it is impossible to determine the
2141     * weight of an undisplayable component.
2142     *
2143     * @return true if this component has a lightweight peer; false if
2144     * it has a native peer or no peer
2145     * @see #isDisplayable
2146     * @since 1.2
2147     */

2148    public boolean isLightweight() {
2149        return getPeer() instanceof LightweightPeer;
2150    }
2151
2152
2153    /**
2154     * Sets the preferred size of this component to a constant
2155     * value. Subsequent calls to <code>getPreferredSize</code> will always
2156     * return this value. Setting the preferred size to <code>null</code>
2157     * restores the default behavior.
2158     *
2159     * @param preferredSize The new preferred size, or null
2160     * @see #getPreferredSize
2161     * @see #isPreferredSizeSet
2162     * @since 1.5
2163     */

2164    public void setPreferredSize(Dimension JavaDoc preferredSize) {
2165        Dimension JavaDoc old;
2166        // If the preferred size was set, use it as the old value, otherwise
2167
// use null to indicate we didn't previously have a set preferred
2168
// size.
2169
if (prefSizeSet) {
2170            old = this.prefSize;
2171        }
2172        else {
2173            old = null;
2174        }
2175        this.prefSize = preferredSize;
2176        prefSizeSet = (preferredSize != null);
2177        firePropertyChange("preferredSize", old, preferredSize);
2178    }
2179
2180
2181    /**
2182     * Returns true if the preferred size has been set to a
2183     * non-<code>null</code> value otherwise returns false.
2184     *
2185     * @return true if <code>setPreferredSize</code> has been invoked
2186     * with a non-null value.
2187     * @since 1.5
2188     */

2189    public boolean isPreferredSizeSet() {
2190        return prefSizeSet;
2191    }
2192
2193
2194    /**
2195     * Gets the preferred size of this component.
2196     * @return a dimension object indicating this component's preferred size
2197     * @see #getMinimumSize
2198     * @see LayoutManager
2199     */

2200    public Dimension JavaDoc getPreferredSize() {
2201        return preferredSize();
2202    }
2203
2204
2205    /**
2206     * @deprecated As of JDK version 1.1,
2207     * replaced by <code>getPreferredSize()</code>.
2208     */

2209    @Deprecated JavaDoc
2210    public Dimension JavaDoc preferredSize() {
2211        /* Avoid grabbing the lock if a reasonable cached size value
2212         * is available.
2213         */

2214        Dimension JavaDoc dim = prefSize;
2215        if (dim == null || !(isPreferredSizeSet() || isValid())) {
2216            synchronized (getTreeLock()) {
2217                prefSize = (peer != null) ?
2218                    peer.preferredSize() :
2219                    getMinimumSize();
2220                dim = prefSize;
2221            }
2222        }
2223        return new Dimension JavaDoc(dim);
2224    }
2225
2226    /**
2227     * Sets the minimum size of this component to a constant
2228     * value. Subsequent calls to <code>getMinimumSize</code> will always
2229     * return this value. Setting the minimum size to <code>null</code>
2230     * restores the default behavior.
2231     *
2232     * @param minimumSize the new minimum size of this component
2233     * @see #getMinimumSize
2234     * @see #isMinimumSizeSet
2235     * @since 1.5
2236     */

2237    public void setMinimumSize(Dimension JavaDoc minimumSize) {
2238        Dimension JavaDoc old;
2239        // If the minimum size was set, use it as the old value, otherwise
2240
// use null to indicate we didn't previously have a set minimum
2241
// size.
2242
if (minSizeSet) {
2243            old = this.minSize;
2244        }
2245        else {
2246            old = null;
2247        }
2248        this.minSize = minimumSize;
2249        minSizeSet = (minimumSize != null);
2250        firePropertyChange("minimumSize", old, minimumSize);
2251    }
2252
2253    /**
2254     * Returns whether or not <code>setMinimumSize</code> has been
2255     * invoked with a non-null value.
2256     *
2257     * @return true if <code>setMinimumSize</code> has been invoked with a
2258     * non-null value.
2259     * @since 1.5
2260     */

2261    public boolean isMinimumSizeSet() {
2262        return minSizeSet;
2263    }
2264
2265    /**
2266     * Gets the mininimum size of this component.
2267     * @return a dimension object indicating this component's minimum size
2268     * @see #getPreferredSize
2269     * @see LayoutManager
2270     */

2271    public Dimension JavaDoc getMinimumSize() {
2272        return minimumSize();
2273    }
2274
2275    /**
2276     * @deprecated As of JDK version 1.1,
2277     * replaced by <code>getMinimumSize()</code>.
2278     */

2279    @Deprecated JavaDoc
2280    public Dimension JavaDoc minimumSize() {
2281        /* Avoid grabbing the lock if a reasonable cached size value
2282         * is available.
2283         */

2284        Dimension JavaDoc dim = minSize;
2285        if (dim == null || !(isMinimumSizeSet() || isValid())) {
2286            synchronized (getTreeLock()) {
2287                minSize = (peer != null) ?
2288                    peer.minimumSize() :
2289                    size();
2290                dim = minSize;
2291            }
2292        }
2293        return new Dimension JavaDoc(dim);
2294    }
2295
2296    /**
2297     * Sets the maximum size of this component to a constant
2298     * value. Subsequent calls to <code>getMaximumSize</code> will always
2299     * return this value. Setting the maximum size to <code>null</code>
2300     * restores the default behavior.
2301     *
2302     * @param maximumSize a <code>Dimension</code> containing the
2303     * desired maximum allowable size
2304     * @see #getMaximumSize
2305     * @see #isMaximumSizeSet
2306     * @since 1.5
2307     */

2308    public void setMaximumSize(Dimension JavaDoc maximumSize) {
2309        // If the maximum size was set, use it as the old value, otherwise
2310
// use null to indicate we didn't previously have a set maximum
2311
// size.
2312
Dimension JavaDoc old;
2313        if (maxSizeSet) {
2314            old = this.maxSize;
2315        }
2316        else {
2317            old = null;
2318        }
2319        this.maxSize = maximumSize;
2320        maxSizeSet = (maximumSize != null);
2321        firePropertyChange("maximumSize", old, maximumSize);
2322    }
2323
2324    /**
2325     * Returns true if the maximum size has been set to a non-<code>null</code>
2326     * value otherwise returns false.
2327     *
2328     * @return true if <code>maximumSize</code> is non-<code>null</code>,
2329     * false otherwise
2330     * @since 1.5
2331     */

2332    public boolean isMaximumSizeSet() {
2333        return maxSizeSet;
2334    }
2335
2336    /**
2337     * Gets the maximum size of this component.
2338     * @return a dimension object indicating this component's maximum size
2339     * @see #getMinimumSize
2340     * @see #getPreferredSize
2341     * @see LayoutManager
2342     */

2343    public Dimension JavaDoc getMaximumSize() {
2344        if (isMaximumSizeSet()) {
2345            return new Dimension JavaDoc(maxSize);
2346        }
2347        return new Dimension JavaDoc(Short.MAX_VALUE, Short.MAX_VALUE);
2348    }
2349
2350    /**
2351     * Returns the alignment along the x axis. This specifies how
2352     * the component would like to be aligned relative to other
2353     * components. The value should be a number between 0 and 1
2354     * where 0 represents alignment along the origin, 1 is aligned
2355     * the furthest away from the origin, 0.5 is centered, etc.
2356     */

2357    public float getAlignmentX() {
2358        return CENTER_ALIGNMENT;
2359    }
2360
2361    /**
2362     * Returns the alignment along the y axis. This specifies how
2363     * the component would like to be aligned relative to other
2364     * components. The value should be a number between 0 and 1
2365     * where 0 represents alignment along the origin, 1 is aligned
2366     * the furthest away from the origin, 0.5 is centered, etc.
2367     */

2368    public float getAlignmentY() {
2369        return CENTER_ALIGNMENT;
2370    }
2371
2372    /**
2373     * Prompts the layout manager to lay out this component. This is
2374     * usually called when the component (more specifically, container)
2375     * is validated.
2376     * @see #validate
2377     * @see LayoutManager
2378     */

2379    public void doLayout() {
2380        layout();
2381    }
2382
2383    /**
2384     * @deprecated As of JDK version 1.1,
2385     * replaced by <code>doLayout()</code>.
2386     */

2387    @Deprecated JavaDoc
2388    public void layout() {
2389    }
2390
2391    /**
2392     * Ensures that this component has a valid layout. This method is
2393     * primarily intended to operate on instances of <code>Container</code>.
2394     * @see #invalidate
2395     * @see #doLayout()
2396     * @see LayoutManager
2397     * @see Container#validate
2398     * @since JDK1.0
2399     */

2400    public void validate() {
2401        if (!valid) {
2402            synchronized (getTreeLock()) {
2403                ComponentPeer peer = this.peer;
2404                if (!valid && peer != null) {
2405                    Font JavaDoc newfont = getFont();
2406                    Font JavaDoc oldfont = peerFont;
2407                    if (newfont != oldfont && (oldfont == null
2408                                               || !oldfont.equals(newfont))) {
2409                        peer.setFont(newfont);
2410                        peerFont = newfont;
2411                    }
2412                    peer.layout();
2413                }
2414            }
2415            valid = true;
2416        }
2417    }
2418
2419    /**
2420     * Invalidates this component. This component and all parents
2421     * above it are marked as needing to be laid out. This method can
2422     * be called often, so it needs to execute quickly.
2423     * @see #validate
2424     * @see #doLayout
2425     * @see LayoutManager
2426     * @since JDK1.0
2427     */

2428    public void invalidate() {
2429        synchronized (getTreeLock()) {
2430            /* Nullify cached layout and size information.
2431             * For efficiency, propagate invalidate() upwards only if
2432             * some other component hasn't already done so first.
2433             */

2434            valid = false;
2435            if (!isPreferredSizeSet()) {
2436                prefSize = null;
2437            }
2438            if (!isMinimumSizeSet()) {
2439                minSize = null;
2440            }
2441            if (!isMaximumSizeSet()) {
2442                maxSize = null;
2443            }
2444            if (parent != null && parent.valid) {
2445                parent.invalidate();
2446            }
2447        }
2448    }
2449
2450    /**
2451     * Creates a graphics context for this component. This method will
2452     * return <code>null</code> if this component is currently not
2453     * displayable.
2454     * @return a graphics context for this component, or <code>null</code>
2455     * if it has none
2456     * @see #paint
2457     * @since JDK1.0
2458     */

2459    public Graphics JavaDoc getGraphics() {
2460        if (peer instanceof LightweightPeer) {
2461            // This is for a lightweight component, need to
2462
// translate coordinate spaces and clip relative
2463
// to the parent.
2464
if (parent == null) return null;
2465            Graphics JavaDoc g = parent.getGraphics();
2466            if (g == null) return null;
2467            if (g instanceof ConstrainableGraphics) {
2468                ((ConstrainableGraphics) g).constrain(x, y, width, height);
2469            } else {
2470                g.translate(x,y);
2471                g.setClip(0, 0, width, height);
2472            }
2473            g.setFont(getFont());
2474            return g;
2475        } else {
2476            ComponentPeer peer = this.peer;
2477            return (peer != null) ? peer.getGraphics() : null;
2478        }
2479    }
2480
2481    /** saves an internal cache of FontMetrics for better performance **/
2482
2483    static java.util.Hashtable JavaDoc metrics = new java.util.Hashtable JavaDoc();
2484    /**
2485     * Gets the font metrics for the specified font.
2486     * @param font the font for which font metrics is to be
2487     * obtained
2488     * @return the font metrics for <code>font</code>
2489     * @see #getFont
2490     * @see #getPeer
2491     * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
2492     * @see Toolkit#getFontMetrics(Font)
2493     * @since JDK1.0
2494     */

2495    public FontMetrics JavaDoc getFontMetrics(Font JavaDoc font) {
2496        boolean altCompFonts = FontManager.maybeUsingAlternateCompositeFonts();
2497        FontMetrics JavaDoc result;
2498
2499        /* No caching when using alternate composite fonts. */
2500        if (altCompFonts) {
2501            result = null;
2502        } else {
2503            result = (FontMetrics JavaDoc) metrics.get(font);
2504        }
2505        if (result != null) {
2506            return result;
2507        }
2508        // REMIND: PlatformFont flag should be obsolete soon...
2509
if (sun.font.FontManager.usePlatformFontMetrics()) {
2510            if (peer != null &&
2511                !(peer instanceof LightweightPeer)) {
2512                result = peer.getFontMetrics(font);
2513                if (!altCompFonts) {
2514                    metrics.put(font, result);
2515                }
2516                return result;
2517            }
2518        }
2519        if (parent != null) {
2520            // These are the lines that cost the big dollars. Calling
2521
// parent.getGraphics triggers the construcion (at great
2522
// expense) of a new Graphics object that is then quickly
2523
// discarded. - Graham
2524
Graphics JavaDoc g = parent.getGraphics();
2525            if (g != null) {
2526                try {
2527                    result = g.getFontMetrics(font);
2528                    if (!altCompFonts) {
2529                        metrics.put(font, result);
2530                    }
2531                    return result;
2532                } finally {
2533                    g.dispose();
2534                }
2535            }
2536        }
2537
2538        result = getToolkit().getFontMetrics(font);
2539        if (!altCompFonts) {
2540            metrics.put(font, result);
2541        }
2542        return result;
2543    }
2544
2545    /**
2546     * Sets the cursor image to the specified cursor. This cursor
2547     * image is displayed when the <code>contains</code> method for
2548     * this component returns true for the current cursor location, and
2549     * this Component is visible, displayable, and enabled. Setting the
2550     * cursor of a <code>Container</code> causes that cursor to be displayed
2551     * within all of the container's subcomponents, except for those
2552     * that have a non-<code>null</code> cursor.
2553     *
2554     * @param cursor One of the constants defined
2555     * by the <code>Cursor</code> class;
2556     * if this parameter is <code>null</code>
2557     * then this component will inherit
2558     * the cursor of its parent
2559     * @see #isEnabled
2560     * @see #isShowing
2561     * @see #getCursor
2562     * @see #contains
2563     * @see Toolkit#createCustomCursor
2564     * @see Cursor
2565     * @since JDK1.1
2566     */

2567    public void setCursor(Cursor JavaDoc cursor) {
2568        this.cursor = cursor;
2569        updateCursorImmediately();
2570    }
2571
2572    /**
2573     * Updates the cursor. May not be invoked from the native
2574     * message pump.
2575     */

2576    final void updateCursorImmediately() {
2577        if (peer instanceof LightweightPeer) {
2578            Container JavaDoc nativeContainer = getNativeContainer();
2579         
2580            if (nativeContainer == null) return;
2581        
2582            ComponentPeer cPeer = nativeContainer.getPeer();
2583
2584            if (cPeer != null) {
2585                cPeer.updateCursorImmediately();
2586            }
2587        } else if (peer != null) {
2588            peer.updateCursorImmediately();
2589        }
2590    }
2591
2592    /**
2593     * Gets the cursor set in the component. If the component does
2594     * not have a cursor set, the cursor of its parent is returned.
2595     * If no cursor is set in the entire hierarchy,
2596     * <code>Cursor.DEFAULT_CURSOR</code> is returned.
2597     * @see #setCursor
2598     * @since JDK1.1
2599     */

2600    public Cursor JavaDoc getCursor() {
2601        Cursor JavaDoc cursor = this.cursor;
2602        if (cursor != null) {
2603            return cursor;
2604        }
2605        Container JavaDoc parent = this.parent;
2606        if (parent != null) {
2607            return parent.getCursor();
2608        } else {
2609            return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
2610        }
2611    }
2612
2613    /**
2614     * Returns whether the cursor has been explicitly set for this Component.
2615     * If this method returns <code>false</code>, this Component is inheriting
2616     * its cursor from an ancestor.
2617     *
2618     * @return <code>true</code> if the cursor has been explicitly set for this
2619     * Component; <code>false</code> otherwise.
2620     * @since 1.4
2621     */

2622    public boolean isCursorSet() {
2623        return (cursor != null);
2624    }
2625
2626    /**
2627     * Paints this component.
2628     * <p>
2629     * This method is called when the contents of the component should
2630     * be painted; such as when the component is first being shown or
2631     * is damaged and in need of repair. The clip rectangle in the
2632     * <code>Graphics</code> parameter is set to the area
2633     * which needs to be painted.
2634     * Subclasses of <code>Component</code> that override this
2635     * method need not call <code>super.paint(g)</code>.
2636     * <p>
2637     * For performance reasons, <code>Component</code>s with zero width
2638     * or height aren't considered to need painting when they are first shown,
2639     * and also aren't considered to need repair.
2640     * <p>
2641     * <b>Note</b>: For more information on the paint mechanisms utilitized
2642     * by AWT and Swing, including information on how to write the most
2643     * efficient painting code, see
2644     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2645     *
2646     * @param g the graphics context to use for painting
2647     * @see #update
2648     * @since JDK1.0
2649     */

2650    public void paint(Graphics JavaDoc g) {
2651    }
2652
2653    /**
2654     * Updates this component.
2655     * <p>
2656     * If this component is not a lightweight component, the
2657     * AWT calls the <code>update</code> method in response to
2658     * a call to <code>repaint</code>. You can assume that
2659     * the background is not cleared.
2660     * <p>
2661     * The <code>update</code> method of <code>Component</code>
2662     * calls this component's <code>paint</code> method to redraw
2663     * this component. This method is commonly overridden by subclasses
2664     * which need to do additional work in response to a call to
2665     * <code>repaint</code>.
2666     * Subclasses of Component that override this method should either
2667     * call <code>super.update(g)</code>, or call <code>paint(g)</code>
2668     * directly from their <code>update</code> method.
2669     * <p>
2670     * The origin of the graphics context, its
2671     * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
2672     * top-left corner of this component. The clipping region of the
2673     * graphics context is the bounding rectangle of this component.
2674     *
2675     * <p>
2676     * <b>Note</b>: For more information on the paint mechanisms utilitized
2677     * by AWT and Swing, including information on how to write the most
2678     * efficient painting code, see
2679     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2680     *
2681     * @param g the specified context to use for updating
2682     * @see #paint
2683     * @see #repaint()
2684     * @since JDK1.0
2685     */

2686    public void update(Graphics JavaDoc g) {
2687        paint(g);
2688    }
2689
2690    /**
2691     * Paints this component and all of its subcomponents.
2692     * <p>
2693     * The origin of the graphics context, its
2694     * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
2695     * top-left corner of this component. The clipping region of the
2696     * graphics context is the bounding rectangle of this component.
2697     *
2698     * @param g the graphics context to use for painting
2699     * @see #paint
2700     * @since JDK1.0
2701     */

2702    public void paintAll(Graphics JavaDoc g) {
2703        if (isShowing()) {
2704            GraphicsCallback.PeerPaintCallback.getInstance().
2705                runOneComponent(this, new Rectangle JavaDoc(0, 0, width, height),
2706                                g, g.getClip(),
2707                                GraphicsCallback.LIGHTWEIGHTS |
2708                                GraphicsCallback.HEAVYWEIGHTS);
2709        }
2710    }
2711
2712    /**
2713     * Simulates the peer callbacks into java.awt for painting of
2714     * lightweight Components.
2715     * @param g the graphics context to use for painting
2716     * @see #paintAll
2717     */

2718    void lightweightPaint(Graphics JavaDoc g) {
2719        paint(g);
2720    }
2721
2722    /**
2723     * Paints all the heavyweight subcomponents.
2724     */

2725    void paintHeavyweightComponents(Graphics JavaDoc g) {
2726    }
2727
2728    /**
2729     * Repaints this component.
2730     * <p>
2731     * If this component is a lightweight component, this method
2732     * causes a call to this component's <code>paint</code>
2733     * method as soon as possible. Otherwise, this method causes
2734     * a call to this component's <code>update</code> method as soon
2735     * as possible.
2736     * <p>
2737     * <b>Note</b>: For more information on the paint mechanisms utilitized
2738     * by AWT and Swing, including information on how to write the most
2739     * efficient painting code, see
2740     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2741
2742     *
2743     * @see #update(Graphics)
2744     * @since JDK1.0
2745     */

2746    public void repaint() {
2747        repaint(0, 0, 0, width, height);
2748    }
2749
2750    /**
2751     * Repaints the component. If this component is a lightweight
2752     * component, this results in a call to <code>paint</code>
2753     * within <code>tm</code> milliseconds.
2754     * <p>
2755     * <b>Note</b>: For more information on the paint mechanisms utilitized
2756     * by AWT and Swing, including information on how to write the most
2757     * efficient painting code, see
2758     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2759     *
2760     * @param tm maximum time in milliseconds before update
2761     * @see #paint
2762     * @see #update(Graphics)
2763     * @since JDK1.0
2764     */

2765    public void repaint(long tm) {
2766        repaint(tm, 0, 0, width, height);
2767    }
2768
2769    /**
2770     * Repaints the specified rectangle of this component.
2771     * <p>
2772     * If this component is a lightweight component, this method
2773     * causes a call to this component's <code>paint</code> method
2774     * as soon as possible. Otherwise, this method causes a call to
2775     * this component's <code>update</code> method as soon as possible.
2776     * <p>
2777     * <b>Note</b>: For more information on the paint mechanisms utilitized
2778     * by AWT and Swing, including information on how to write the most
2779     * efficient painting code, see
2780     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2781     *
2782     * @param x the <i>x</i> coordinate
2783     * @param y the <i>y</i> coordinate
2784     * @param width the width
2785     * @param height the height
2786     * @see #update(Graphics)
2787     * @since JDK1.0
2788     */

2789    public void repaint(int x, int y, int width, int height) {
2790        repaint(0, x, y, width, height);
2791    }
2792
2793    /**
2794     * Repaints the specified rectangle of this component within
2795     * <code>tm</code> milliseconds.
2796     * <p>
2797     * If this component is a lightweight component, this method causes
2798     * a call to this component's <code>paint</code> method.
2799     * Otherwise, this method causes a call to this component's
2800     * <code>update</code> method.
2801     * <p>
2802     * <b>Note</b>: For more information on the paint mechanisms utilitized
2803     * by AWT and Swing, including information on how to write the most
2804     * efficient painting code, see
2805     * <a HREF="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
2806     *
2807     * @param tm maximum time in milliseconds before update
2808     * @param x the <i>x</i> coordinate
2809     * @param y the <i>y</i> coordinate
2810     * @param width the width
2811     * @param height the height
2812     * @see #update(Graphics)
2813     * @since JDK1.0
2814     */

2815    public void repaint(long tm, int x, int y, int width, int height) {
2816        if (this.peer instanceof LightweightPeer) {
2817            // Needs to be translated to parent coordinates since
2818
// a parent native container provides the actual repaint
2819
// services. Additionally, the request is restricted to
2820
// the bounds of the component.
2821
if (parent != null) {
2822                int px = this.x + ((x < 0) ? 0 : x);
2823                int py = this.y + ((y < 0) ? 0 : y);
2824                int pwidth = (width > this.width) ? this.width : width;
2825                int pheight = (height > this.height) ? this.height : height;
2826                parent.repaint(tm, px, py, pwidth, pheight);
2827            }
2828        } else {
2829            if (isVisible() && (this.peer != null) &&
2830                (width > 0) && (height > 0)) {
2831                PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
2832                                              new Rectangle JavaDoc(x, y, width, height));
2833                Toolkit.getEventQueue().postEvent(e);
2834            }
2835        }
2836    }
2837
2838    /**
2839     * Prints this component. Applications should override this method
2840     * for components that must do special processing before being
2841     * printed or should be printed differently than they are painted.
2842     * <p>
2843     * The default implementation of this method calls the
2844     * <code>paint</code> method.
2845     * <p>
2846     * The origin of the graphics context, its
2847     * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
2848     * top-left corner of this component. The clipping region of the
2849     * graphics context is the bounding rectangle of this component.
2850     * @param g the graphics context to use for printing
2851     * @see #paint(Graphics)
2852     * @since JDK1.0
2853     */

2854    public void print(Graphics JavaDoc g) {
2855        paint(g);
2856    }
2857
2858    /**
2859     * Prints this component and all of its subcomponents.
2860     * <p>
2861     * The origin of the graphics context, its
2862     * (<code>0</code>,&nbsp;<code>0</code>) coordinate point, is the
2863     * top-left corner of this component. The clipping region of the
2864     * graphics context is the bounding rectangle of this component.
2865     * @param g the graphics context to use for printing
2866     * @see #print(Graphics)
2867     * @since JDK1.0
2868     */

2869    public void printAll(Graphics JavaDoc g) {
2870        if (isShowing()) {
2871            GraphicsCallback.PeerPrintCallback.getInstance().
2872                runOneComponent(this, new Rectangle JavaDoc(0, 0, width, height),
2873                                g, g.getClip(),
2874                                GraphicsCallback.LIGHTWEIGHTS |
2875                                GraphicsCallback.HEAVYWEIGHTS);
2876        }
2877    }
2878
2879    /**
2880     * Simulates the peer callbacks into java.awt for printing of
2881     * lightweight Components.
2882     * @param g the graphics context to use for printing
2883     * @see #printAll
2884     */

2885    void lightweightPrint(Graphics JavaDoc g) {
2886        print(g);
2887    }
2888
2889    /**
2890     * Prints all the heavyweight subcomponents.
2891     */

2892    void printHeavyweightComponents(Graphics JavaDoc g) {
2893    }
2894
2895    /**
2896     * Repaints the component when the image has changed.
2897     * This <code>imageUpdate</code> method of an <code>ImageObserver</code>
2898     * is called when more information about an
2899     * image which had been previously requested using an asynchronous
2900     * routine such as the <code>drawImage</code> method of
2901     * <code>Graphics</code> becomes available.
2902     * See the definition of <code>imageUpdate</code> for
2903     * more information on this method and its arguments.
2904     * <p>
2905     * The <code>imageUpdate</code> method of <code>Component</code>
2906     * incrementally draws an image on the component as more of the bits
2907     * of the image are available.
2908     * <p>
2909     * If the system property <code>awt.image.incrementaldraw</code>
2910     * is missing or has the value <code>true</code>, the image is
2911     * incrementally drawn. If the system property has any other value,
2912     * then the image is not drawn until it has been completely loaded.
2913     * <p>
2914     * Also, if incremental drawing is in effect, the value of the
2915     * system property <code>awt.image.redrawrate</code> is interpreted
2916     * as an integer to give the maximum redraw rate, in milliseconds. If
2917     * the system property is missing or cannot be interpreted as an
2918     * integer, the redraw rate is once every 100ms.
2919     * <p>
2920     * The interpretation of the <code>x</code>, <code>y</code>,
2921     * <code>width</code>, and <code>height</code> arguments depends on
2922     * the value of the <code>infoflags</code> argument.
2923     *
2924     * @param img the image being observed
2925     * @param infoflags see <code>imageUpdate</code> for more information
2926     * @param x the <i>x</i> coordinate
2927     * @param y the <i>y</i> coordinate
2928     * @param w the width
2929     * @param h the height
2930     * @return <code>false</code> if the infoflags indicate that the
2931     * image is completely loaded; <code>true</code> otherwise.
2932     *
2933     * @see java.awt.image.ImageObserver
2934     * @see Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver)
2935     * @see Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver)
2936     * @see Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver)
2937     * @see Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver)
2938     * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
2939     * @since JDK1.0
2940     */

2941    public boolean imageUpdate(Image JavaDoc img, int infoflags,
2942                               int x, int y, int w, int h) {
2943        int rate = -1;
2944        if ((infoflags & (FRAMEBITS|ALLBITS)) != 0) {
2945            rate = 0;
2946        } else if ((infoflags & SOMEBITS) != 0) {
2947            if (isInc) {
2948                rate = incRate;
2949                if (rate < 0) {
2950                    rate = 0;
2951                }
2952            }
2953        }
2954        if (rate >= 0) {
2955            repaint(rate, 0, 0, width, height);
2956        }
2957        return (infoflags & (ALLBITS|ABORT)) == 0;
2958    }
2959
2960    /**
2961     * Creates an image from the specified image producer.
2962     * @param producer the image producer
2963     * @return the image produced
2964     * @since JDK1.0
2965     */

2966    public Image JavaDoc createImage(ImageProducer JavaDoc producer) {
2967        ComponentPeer peer = this.peer;
2968        if ((peer != null) && ! (peer instanceof LightweightPeer)) {
2969            return peer.createImage(producer);
2970        }
2971        return getToolkit().createImage(producer);
2972    }
2973
2974    /**
2975     * Creates an off-screen drawable image
2976     * to be used for double buffering.
2977     * @param width the specified width
2978     * @param height the specified height
2979     * @return an off-screen drawable image, which can be used for double
2980     * buffering. The return value may be <code>null</code> if the
2981     * component is not displayable. This will always happen if
2982     * <code>GraphicsEnvironment.isHeadless()</code> returns
2983     * <code>true</code>.
2984     * @see #isDisplayable
2985     * @see GraphicsEnvironment#isHeadless
2986     * @since JDK1.0
2987     */

2988    public Image JavaDoc createImage(int width, int height) {
2989        ComponentPeer peer = this.peer;
2990        if (peer instanceof LightweightPeer) {
2991            if (parent != null) { return parent.createImage(width, height); }
2992            else { return null;}
2993        } else {
2994            return (peer != null) ? peer.createImage(width, height) : null;
2995        }
2996    }
2997
2998    /**
2999     * Creates a volatile off-screen drawable image
3000     * to be used for double buffering.
3001     * @param width the specified width.
3002     * @param height the specified height.
3003     * @return an off-screen drawable image, which can be used for double
3004     * buffering. The return value may be <code>null</code> if the
3005     * component is not displayable. This will always happen if
3006     * <code>GraphicsEnvironment.isHeadless()</code> returns
3007     * <code>true</code>.
3008     * @see java.awt.image.VolatileImage
3009     * @see #isDisplayable
3010     * @see GraphicsEnvironment#isHeadless
3011     * @since 1.4
3012     */

3013    public VolatileImage JavaDoc createVolatileImage(int width, int height) {
3014        ComponentPeer peer = this.peer;
3015        if (peer instanceof LightweightPeer) {
3016            if (parent != null) {
3017                return parent.createVolatileImage(width, height);
3018            }
3019            else { return null;}
3020        } else {
3021            return (peer != null) ?
3022                peer.createVolatileImage(width, height) : null;
3023        }
3024    }
3025
3026    /**
3027     * Creates a volatile off-screen drawable image, with the given capabilities.
3028     * The contents of this image may be lost at any time due
3029     * to operating system issues, so the image must be managed
3030     * via the <code>VolatileImage</code> interface.
3031     * @param width the specified width.
3032     * @param height the specified height.
3033     * @param caps the image capabilities
3034     * @exception AWTException if an image with the specified capabilities cannot
3035     * be created
3036     * @return a VolatileImage object, which can be used
3037     * to manage surface contents loss and capabilities.
3038     * @see java.awt.image.VolatileImage
3039     * @since 1.4
3040     */

3041    public VolatileImage JavaDoc createVolatileImage(int width, int height,
3042                                             ImageCapabilities JavaDoc caps) throws AWTException JavaDoc {
3043        // REMIND : check caps
3044
return createVolatileImage(width, height);
3045    }
3046
3047    /**
3048     * Prepares an image for rendering on this component. The image
3049     * data is downloaded asynchronously in another thread and the
3050     * appropriate screen representation of the image is generated.
3051     * @param image the <code>Image</code> for which to
3052     * prepare a screen representation
3053     * @param observer the <code>ImageObserver</code> object
3054     * to be notified as the image is being prepared
3055     * @return <code>true</code> if the image has already been fully
3056     * prepared; <code>false</code> otherwise
3057     * @since JDK1.0
3058     */

3059    public boolean prepareImage(Image JavaDoc image, ImageObserver JavaDoc observer) {
3060        return prepareImage(image, -1, -1, observer);
3061    }
3062
3063    /**
3064     * Prepares an image for rendering on this component at the
3065     * specified width and height.
3066     * <p>
3067     * The image data is downloaded asynchronously in another thread,
3068     * and an appropriately scaled screen representation of the image is
3069     * generated.
3070     * @param image the instance of <code>Image</code>
3071     * for which to prepare a screen representation
3072     * @param width the width of the desired screen representation
3073     * @param height the height of the desired screen representation
3074     * @param observer the <code>ImageObserver</code> object
3075     * to be notified as the image is being prepared
3076     * @return <code>true</code> if the image has already been fully
3077     * prepared; <code>false</code> otherwise
3078     * @see java.awt.image.ImageObserver
3079     * @since JDK1.0
3080     */

3081    public boolean prepareImage(Image JavaDoc image, int width, int height,
3082                                ImageObserver JavaDoc observer) {
3083        ComponentPeer peer = this.peer;
3084        if (peer instanceof LightweightPeer) {
3085            return (parent != null)
3086                ? parent.prepareImage(image, width, height, observer)
3087                : getToolkit().prepareImage(image, width, height, observer);
3088        } else {
3089            return (peer != null)
3090                ? peer.prepareImage(image, width, height, observer)
3091                : getToolkit().prepareImage(image, width, height, observer);
3092        }
3093    }
3094
3095    /**
3096     * Returns the status of the construction of a screen representation
3097     * of the specified image.
3098     * <p>
3099     * This method does not cause the image to begin loading. An
3100     * application must use the <code>prepareImage</code> method
3101     * to force the loading of an image.
3102     * <p>
3103     * Information on the flags returned by this method can be found
3104     * with the discussion of the <code>ImageObserver</code> interface.
3105     * @param image the <code>Image</code> object whose status
3106     * is being checked
3107     * @param observer the <code>ImageObserver</code>
3108     * object to be notified as the image is being prepared
3109     * @return the bitwise inclusive <b>OR</b> of
3110     * <code>ImageObserver</code> flags indicating what
3111     * information about the image is currently available
3112     * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3113     * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3114     * @see java.awt.image.ImageObserver
3115     * @since JDK1.0
3116     */

3117    public int checkImage(Image JavaDoc image, ImageObserver JavaDoc observer) {
3118        return checkImage(image, -1, -1, observer);
3119    }
3120
3121    /**
3122     * Returns the status of the construction of a screen representation
3123     * of the specified image.
3124     * <p>
3125     * This method does not cause the image to begin loading. An
3126     * application must use the <code>prepareImage</code> method
3127     * to force the loading of an image.
3128     * <p>
3129     * The <code>checkImage</code> method of <code>Component</code>
3130     * calls its peer's <code>checkImage</code> method to calculate
3131     * the flags. If this component does not yet have a peer, the
3132     * component's toolkit's <code>checkImage</code> method is called
3133     * instead.
3134     * <p>
3135     * Information on the flags returned by this method can be found
3136     * with the discussion of the <code>ImageObserver</code> interface.
3137     * @param image the <code>Image</code> object whose status
3138     * is being checked
3139     * @param width the width of the scaled version
3140     * whose status is to be checked
3141     * @param height the height of the scaled version
3142     * whose status is to be checked
3143     * @param observer the <code>ImageObserver</code> object
3144     * to be notified as the image is being prepared
3145     * @return the bitwise inclusive <b>OR</b> of
3146     * <code>ImageObserver</code> flags indicating what
3147     * information about the image is currently available
3148     * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
3149     * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
3150     * @see java.awt.image.ImageObserver
3151     * @since JDK1.0
3152     */

3153    public int checkImage(Image JavaDoc image, int width, int height,
3154                          ImageObserver JavaDoc observer) {
3155        ComponentPeer peer = this.peer;
3156        if (peer instanceof LightweightPeer) {
3157            return (parent != null)
3158                ? parent.checkImage(image, width, height, observer)
3159                : getToolkit().checkImage(image, width, height, observer);
3160        } else {
3161            return (peer != null)
3162                ? peer.checkImage(image, width, height, observer)
3163                : getToolkit().checkImage(image, width, height, observer);
3164        }
3165    }
3166
3167    /**
3168     * Creates a new strategy for multi-buffering on this component.
3169     * Multi-buffering is useful for rendering performance. This method
3170     * attempts to create the best strategy available with the number of
3171     * buffers supplied. It will always create a <code>BufferStrategy</code>
3172     * with that number of buffers.
3173     * A page-flipping strategy is attempted first, then a blitting strategy
3174     * using accelerated buffers. Finally, an unaccelerated blitting
3175     * strategy is used.
3176     * <p>
3177     * Each time this method is called,
3178     * the existing buffer strategy for this component is discarded.
3179     * @param numBuffers number of buffers to create, including the front buffer
3180     * @exception IllegalArgumentException if numBuffers is less than 1.
3181     * @exception IllegalStateException if the component is not displayable
3182     * @see #isDisplayable
3183     * @see #getBufferStrategy()
3184     * @since 1.4
3185     */

3186    void createBufferStrategy(int numBuffers) {
3187        BufferCapabilities JavaDoc bufferCaps;
3188        if (numBuffers > 1) {
3189            // Try to create a page-flipping strategy
3190
bufferCaps = new BufferCapabilities JavaDoc(
3191                                                new ImageCapabilities JavaDoc(true), new ImageCapabilities JavaDoc(true),
3192                                                BufferCapabilities.FlipContents.UNDEFINED);
3193            try {
3194                createBufferStrategy(numBuffers, bufferCaps);
3195                return; // Success
3196
} catch (AWTException JavaDoc e) {
3197                // Failed
3198
}
3199        }
3200        // Try a blitting (but still accelerated) strategy
3201
bufferCaps = new BufferCapabilities JavaDoc(
3202                                            new ImageCapabilities JavaDoc(true), new ImageCapabilities JavaDoc(true), null);
3203        try {
3204            createBufferStrategy(numBuffers, bufferCaps);
3205            return; // Success
3206
} catch (AWTException JavaDoc e) {
3207            // Failed
3208
}
3209        // Try an unaccelerated blitting strategy
3210
bufferCaps = new BufferCapabilities JavaDoc(
3211                                            new ImageCapabilities JavaDoc(false), new ImageCapabilities JavaDoc(false), null);
3212        try {
3213            createBufferStrategy(numBuffers, bufferCaps);
3214            return; // Success
3215
} catch (AWTException JavaDoc e) {
3216            // Failed
3217
}
3218        // Code should never reach here (an unaccelerated blitting
3219
// strategy should always work)
3220
throw new InternalError JavaDoc("Could not create a buffer strategy");
3221    }
3222    
3223    /**
3224     * Creates a new strategy for multi-buffering on this component with the
3225     * required buffer capabilities. This is useful, for example, if only
3226     * accelerated memory or page flipping is desired (as specified by the
3227     * buffer capabilities).
3228     * <p>
3229     * Each time this method
3230     * is called, the existing buffer strategy for this component is discarded.
3231     * @param numBuffers number of buffers to create
3232     * @param caps the required capabilities for creating the buffer strategy;
3233     * cannot be <code>null</code>
3234     * @exception AWTException if the capabilities supplied could not be
3235     * supported or met; this may happen, for example, if there is not enough
3236     * accelerated memory currently available, or if page flipping is specified
3237     * but not possible.
3238     * @exception IllegalArgumentException if numBuffers is less than 1, or if
3239     * caps is <code>null</code>
3240     * @see #getBufferStrategy()
3241     * @since 1.4
3242     */

3243    void createBufferStrategy(int numBuffers,
3244                              BufferCapabilities JavaDoc caps) throws AWTException JavaDoc {
3245        // Check arguments
3246
if (numBuffers < 1) {
3247            throw new IllegalArgumentException JavaDoc(
3248                                               "Number of buffers must be at least 1");
3249        }
3250        if (caps == null) {
3251            throw new IllegalArgumentException JavaDoc("No capabilities specified");
3252        }
3253        // Destroy old buffers
3254
if (bufferStrategy instanceof FlipBufferStrategy) {
3255            ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
3256        }
3257        if (numBuffers == 1) {
3258            bufferStrategy = new SingleBufferStrategy(caps);
3259        } else {
3260            // assert numBuffers > 1;
3261
if (caps.isPageFlipping()) {
3262                bufferStrategy = new FlipBufferStrategy(numBuffers, caps);
3263            } else {
3264                bufferStrategy = new BltBufferStrategy(numBuffers, caps);
3265            }
3266        }
3267    }
3268    
3269    /**
3270     * @return the buffer strategy used by this component
3271     * @see Window#createBufferStrategy
3272     * @see Canvas#createBufferStrategy
3273     * @since 1.4
3274     */

3275    BufferStrategy JavaDoc getBufferStrategy() {
3276        if (bufferStrategy == null) {
3277            createBufferStrategy(1);
3278        }
3279        return bufferStrategy;
3280    }
3281    
3282    /**
3283     * @return the back buffer currently used by this component's
3284     * BufferStrategy. If there is no BufferStrategy or no
3285     * back buffer, this method returns null.
3286     */

3287    Image JavaDoc getBackBuffer() {
3288        if (bufferStrategy != null) {
3289            if (bufferStrategy instanceof BltBufferStrategy) {
3290                BltBufferStrategy bltBS = (BltBufferStrategy)bufferStrategy;
3291                return bltBS.getBackBuffer();
3292            } else if (bufferStrategy instanceof FlipBufferStrategy) {
3293                FlipBufferStrategy flipBS = (FlipBufferStrategy)bufferStrategy;
3294                return flipBS.getBackBuffer();
3295            }
3296        }
3297        return null;
3298    }
3299    
3300    /**
3301     * Inner class for flipping buffers on a component. That component must
3302     * be a <code>Canvas</code> or <code>Window</code>.
3303     * @see Canvas
3304     * @see Window
3305     * @see java.awt.image.BufferStrategy
3306     * @author Michael Martak
3307     * @since 1.4
3308     */

3309    protected class FlipBufferStrategy extends BufferStrategy JavaDoc {
3310        /**
3311         * The number of buffers
3312         */

3313        protected int numBuffers; // = 0
3314
/**
3315         * The buffering capabilities
3316         */

3317        protected BufferCapabilities JavaDoc caps; // = null
3318
/**
3319         * The drawing buffer
3320         */

3321        protected Image JavaDoc drawBuffer; // = null
3322
/**
3323         * The drawing buffer as a volatile image
3324         */

3325        protected VolatileImage JavaDoc drawVBuffer; // = null
3326
/**
3327         * Whether or not the drawing buffer has been recently restored from
3328         * a lost state.
3329         */

3330        protected boolean validatedContents; // = false
3331

3332        /**
3333         * Creates a new flipping buffer strategy for this component.
3334         * The component must be a <code>Canvas</code> or <code>Window</code>.
3335         * @see Canvas
3336         * @see Window
3337         * @param numBuffers the number of buffers
3338         * @param caps the capabilities of the buffers
3339         * @exception AWTException if the capabilities supplied could not be
3340         * supported or met
3341         * @exception ClassCastException if the component is not a canvas or
3342         * window.
3343         */

3344        protected FlipBufferStrategy(int numBuffers, BufferCapabilities JavaDoc caps)
3345          throws AWTException JavaDoc {
3346            if (!(Component.this instanceof Window JavaDoc) &&
3347                !(Component.this instanceof Canvas JavaDoc)) {
3348                throw new ClassCastException JavaDoc(
3349                                             "Component must be a Canvas or Window");
3350            }
3351            this.numBuffers = numBuffers;
3352            this.caps = caps;
3353            createBuffers(numBuffers, caps);
3354        }
3355        
3356        /**
3357         * Creates one or more complex, flipping buffers with the given
3358         * capabilities.
3359         * @param numBuffers number of buffers to create; must be greater than
3360         * one
3361         * @param caps the capabilities of the buffers.
3362         * <code>BufferCapabilities.isPageFlipping</code> must be
3363         * <code>true</code>.
3364         * @exception AWTException if the capabilities supplied could not be
3365         * supported or met
3366         * @exception IllegalStateException if the component has no peer
3367         * @exception IllegalArgumentException if numBuffers is less than two,
3368         * or if <code>BufferCapabilities.isPageFlipping</code> is not
3369         * <code>true</code>.
3370         * @see java.awt.BufferCapabilities#isPageFlipping()
3371         */

3372        protected void createBuffers(int numBuffers, BufferCapabilities JavaDoc caps)
3373          throws AWTException JavaDoc {
3374            if (numBuffers < 2) {
3375                throw new IllegalArgumentException JavaDoc(
3376                                                   "Number of buffers cannot be less than two");
3377            } else if (peer == null) {
3378                throw new IllegalStateException JavaDoc(
3379                                                "Component must have a valid peer");
3380            } else if (caps == null || !caps.isPageFlipping()) {
3381                throw new IllegalArgumentException JavaDoc(
3382                                                   "Page flipping capabilities must be specified");
3383            } else {
3384                peer.createBuffers(numBuffers, caps);
3385            }
3386        }
3387        
3388        /**
3389         * @return direct access to the back buffer, as an image.
3390         * @exception IllegalStateException if the buffers have not yet
3391         * been created
3392         */

3393        protected Image JavaDoc getBackBuffer() {
3394            if (peer != null) {
3395                Image JavaDoc drawBuffer = peer.getBackBuffer();
3396                if (drawBuffer instanceof VolatileImage JavaDoc) {
3397                    drawVBuffer = (VolatileImage JavaDoc)drawBuffer;
3398                }
3399                revalidate();
3400                return drawBuffer;
3401            } else {
3402                throw new IllegalStateException JavaDoc(
3403                                                "Component must have a valid peer");
3404            }
3405        }
3406        
3407        /**
3408         * Flipping moves the contents of the back buffer to the front buffer,
3409         * either by copying or by moving the video pointer.
3410         * @param flipAction an integer value describing the flipping action
3411         * for the contents of the back buffer. This should be one of the
3412         * values of the <code>BufferCapabilities.FlipContents</code>
3413         * property.
3414         * @exception IllegalStateException if the buffers have not yet
3415         * been created
3416         * @see java.awt.BufferCapabilities#getFlipContents()
3417         */

3418        protected void flip(BufferCapabilities.FlipContents JavaDoc flipAction) {
3419            if (peer != null) {
3420                peer.flip(flipAction);
3421            } else {
3422                throw new IllegalStateException JavaDoc(
3423                                                "Component must have a valid peer");
3424            }
3425        }
3426        
3427        /**
3428         * Destroys the buffers created through this object
3429         */

3430        protected void destroyBuffers() {
3431            if (peer != null) {
3432                peer.destroyBuffers();
3433            } else {
3434                throw new IllegalStateException JavaDoc(
3435                                                "Component must have a valid peer");
3436            }
3437        }
3438    
3439        /**
3440         * @return the buffering capabilities of this strategy
3441         */

3442        public BufferCapabilities JavaDoc getCapabilities() {
3443            return caps;
3444        }
3445
3446        /**
3447         * @return the graphics on the drawing buffer. This method may not
3448         * be synchronized for performance reasons; use of this method by multiple
3449         * threads should be handled at the application level. Disposal of the
3450         * graphics object must be handled by the application.
3451         */

3452        public Graphics JavaDoc getDrawGraphics() {
3453            if (drawBuffer == null) {
3454                // Set up drawing buffer
3455
drawBuffer = getBackBuffer();
3456                if (drawBuffer instanceof VolatileImage JavaDoc) {
3457                    drawVBuffer = (VolatileImage JavaDoc)drawBuffer;
3458                }
3459            }
3460            revalidate();
3461            return drawBuffer.getGraphics();
3462        }
3463
3464        /**
3465         * Restore the drawing buffer if it has been lost
3466         */

3467        protected void revalidate() {
3468            // REMIND: this whole validation mechanism needs to be re-examined
3469
// for correctness. Currently, the value of validatedContents
3470
// may be changed and overwritten before the user has a chance to
3471
// see that there was any restoration to the surface. Also, we
3472
// need to handle the IMAGE_INCOMPATIBLE case.
3473
if (drawVBuffer != null) {
3474                validatedContents = (drawVBuffer.validate(
3475                                                          getGraphicsConfiguration()) == VolatileImage.IMAGE_RESTORED);
3476            } else {
3477                validatedContents = false;
3478            }
3479        }
3480        
3481        /**
3482         * @return whether the drawing buffer was lost since the last call to
3483         * <code>getDrawGraphics</code>
3484         */

3485        public boolean contentsLost() {
3486            if (drawVBuffer == null) {
3487                return false;
3488            }
3489            return drawVBuffer.contentsLost();
3490        }
3491
3492        /**
3493         * @return whether the drawing buffer was recently restored from a lost
3494         * state and reinitialized to the default background color (white)
3495         */

3496        public boolean contentsRestored() {
3497            return validatedContents;
3498        }
3499
3500        /**
3501         * Makes the next available buffer visible by either blitting or
3502         * flipping.
3503         */

3504        public void show() {
3505            flip(caps.getFlipContents());
3506        }
3507
3508    } // Inner class FlipBufferStrategy
3509

3510    /**
3511     * Inner class for blitting offscreen surfaces to a component.
3512     *
3513     * @author Michael Martak
3514     * @since 1.4
3515     */

3516    protected class BltBufferStrategy extends BufferStrategy JavaDoc {
3517
3518        /**
3519         * The buffering capabilities
3520         */

3521        protected BufferCapabilities JavaDoc caps; // = null
3522
/**
3523         * The back buffers
3524         */

3525        protected VolatileImage JavaDoc[] backBuffers; // = null
3526
/**
3527         * Whether or not the drawing buffer has been recently restored from
3528         * a lost state.
3529         */

3530        protected boolean validatedContents; // = false
3531
/**
3532         * Size of the back buffers
3533         */

3534        protected int width;
3535        protected int height;
3536    
3537        /**
3538         * Creates a new blt buffer strategy around a component
3539         * @param numBuffers the component to use as the front buffer
3540         * @param caps the capabilities of the buffers
3541         */

3542        protected BltBufferStrategy(int numBuffers, BufferCapabilities JavaDoc caps) {
3543            this.caps = caps;
3544            createBackBuffers(numBuffers - 1);
3545        }
3546        
3547        /**
3548         * Creates the back buffers
3549         */

3550        protected void createBackBuffers(int numBuffers) {
3551            if (numBuffers == 0) {
3552                backBuffers = null;
3553            } else {
3554                width = getWidth();
3555                height = getHeight();
3556                backBuffers = new VolatileImage JavaDoc[numBuffers];
3557                for (int i = 0; i < numBuffers; i++) {
3558                    backBuffers[i] = createVolatileImage(width, height);
3559                }
3560            }
3561        }
3562    
3563        /**
3564         * @return the buffering capabilities of this strategy
3565         */

3566        public BufferCapabilities JavaDoc getCapabilities() {
3567            return caps;
3568        }
3569
3570        /**
3571         * @return the draw graphics
3572         */

3573        public Graphics JavaDoc getDrawGraphics() {
3574            revalidate();
3575            Image JavaDoc backBuffer = getBackBuffer();
3576            if (backBuffer == null) {
3577                return getGraphics();
3578            }
3579            return backBuffer.getGraphics();
3580        }
3581    
3582        /**
3583         * @return direct access to the back buffer, as an image.
3584         * If there is no back buffer, returns null.
3585         */

3586        Image JavaDoc getBackBuffer() {
3587            if (backBuffers != null) {
3588                return backBuffers[backBuffers.length - 1];
3589            } else {
3590                return null;
3591            }
3592        }
3593        
3594        /**
3595         * Makes the next available buffer visible.
3596         */

3597        public void show() {
3598            if (backBuffers == null) {
3599                return;
3600            }
3601
3602            Graphics JavaDoc g = getGraphics();
3603            try {
3604                for (int i = 0; i < backBuffers.length; i++) {
3605                    g.drawImage(backBuffers[i], 0, 0, Component.this);
3606                    g.dispose();
3607                    g = null;
3608                    g = backBuffers[i].getGraphics();
3609                }
3610            } finally {
3611                if (g != null) {
3612                    g.dispose();
3613                }
3614            }
3615        }
3616
3617        /**
3618         * Restore the drawing buffer if it has been lost
3619         */

3620        protected void revalidate() {
3621            if (backBuffers == null) {
3622                validatedContents = false;
3623            } else if (getWidth() != width || getHeight() != height) {
3624                createBackBuffers(backBuffers.length);
3625                validatedContents = true;
3626            } else {
3627                validatedContents =
3628                    (backBuffers[backBuffers.length - 1].validate(
3629                                                                  getGraphicsConfiguration())
3630                     == VolatileImage.IMAGE_RESTORED);
3631                // REMIND : handle IMAGE_INCOMPATIBLE
3632
}
3633        }
3634        
3635        /**
3636         * @return whether the drawing buffer was lost since the last call to
3637         * <code>getDrawGraphics</code>
3638         */

3639        public boolean contentsLost() {
3640            if (width < getWidth() || height < getHeight()) {
3641                return true;
3642            } else {
3643                return backBuffers[backBuffers.length - 1].contentsLost();
3644            }
3645        }
3646
3647        /**
3648         * @return whether the drawing buffer was recently restored from a lost
3649         * state and reinitialized to the default background color (white)
3650         */

3651        public boolean contentsRestored() {
3652            return validatedContents;
3653        }
3654
3655    } // Inner class BltBufferStrategy
3656

3657    /**
3658     * Inner class for flipping buffers on a component. That component must
3659     * be a <code>Canvas</code> or <code>Window</code>.
3660     * @see Canvas
3661     * @see Window
3662     * @see java.awt.image.BufferStrategy
3663     * @author Michael Martak
3664     * @since 1.4
3665     */

3666    private class SingleBufferStrategy extends BufferStrategy JavaDoc {
3667        
3668        private BufferCapabilities JavaDoc caps;
3669        
3670        public SingleBufferStrategy(BufferCapabilities JavaDoc caps) {
3671            this.caps = caps;
3672        }
3673        public BufferCapabilities JavaDoc getCapabilities() {
3674            return caps;
3675        }
3676        public Graphics JavaDoc getDrawGraphics() {
3677            return getGraphics();
3678        }
3679        public boolean contentsLost() {
3680            // return peer.getSurfaceData().contentsLost();
3681
return false;
3682        }
3683        public boolean contentsRestored() {
3684            // return peer.getSurfaceData().validate();
3685
return false;
3686        }
3687        public void show() {
3688            // Do nothing; could repaint
3689
}
3690    } // Inner class SingleBufferStrategy
3691

3692    /**
3693     * Sets whether or not paint messages received from the operating system
3694     * should be ignored. This does not affect paint events generated in
3695     * software by the AWT, unless they are an immediate response to an
3696     * OS-level paint message.
3697     * <p>
3698     * This is useful, for example, if running under full-screen mode and
3699     * better performance is desired, or if page-flipping is used as the
3700     * buffer strategy.
3701     *
3702     * @since 1.4
3703     * @see #getIgnoreRepaint
3704     * @see Canvas#createBufferStrategy
3705     * @see Window#createBufferStrategy
3706     * @see java.awt.image.BufferStrategy
3707     * @see GraphicsDevice#setFullScreenWindow
3708     */

3709    public void setIgnoreRepaint(boolean ignoreRepaint) {
3710        this.ignoreRepaint = ignoreRepaint;
3711    }
3712    
3713    /**
3714     * @return whether or not paint messages received from the operating system
3715     * should be ignored.
3716     *
3717     * @since 1.4
3718     * @see #setIgnoreRepaint
3719     */

3720    public boolean getIgnoreRepaint() {
3721        return ignoreRepaint;
3722    }
3723    
3724    /**
3725     * Checks whether this component "contains" the specified point,
3726     * where <code>x</code> and <code>y</code> are defined to be
3727     * relative to the coordinate system of this component.
3728     * @param x the <i>x</i> coordinate of the point
3729     * @param y the <i>y</i> coordinate of the point
3730     * @see #getComponentAt(int, int)
3731     * @since JDK1.1
3732     */

3733    public boolean contains(int x, int y) {
3734        return inside(x, y);
3735    }
3736
3737    /**
3738     * @deprecated As of JDK version 1.1,
3739     * replaced by contains(int, int).
3740     */

3741    @Deprecated JavaDoc
3742    public boolean inside(int x, int y) {
3743        return (x >= 0) && (x < width) && (y >= 0) && (y < height);
3744    }
3745
3746    /**
3747     * Checks whether this component "contains" the specified point,
3748     * where the point's <i>x</i> and <i>y</i> coordinates are defined
3749     * to be relative to the coordinate system of this component.
3750     * @param p the point
3751     * @see #getComponentAt(Point)
3752     * @since JDK1.1
3753     */

3754    public boolean contains(Point JavaDoc p) {
3755        return contains(p.x, p.y);
3756    }
3757
3758    /**
3759     * Determines if this component or one of its immediate
3760     * subcomponents contains the (<i>x</i>,&nbsp;<i>y</i>) location,
3761     * and if so, returns the containing component. This method only
3762     * looks one level deep. If the point (<i>x</i>,&nbsp;<i>y</i>) is
3763     * inside a subcomponent that itself has subcomponents, it does not
3764     * go looking down the subcomponent tree.
3765     * <p>
3766     * The <code>locate</code> method of <code>Component</code> simply
3767     * returns the component itself if the (<i>x</i>,&nbsp;<i>y</i>)
3768     * coordinate location is inside its bounding box, and <code>null</code>
3769     * otherwise.
3770     * @param x the <i>x</i> coordinate
3771     * @param y the <i>y</i> coordinate
3772     * @return the component or subcomponent that contains the
3773     * (<i>x</i>,&nbsp;<i>y</i>) location;
3774     * <code>null</code> if the location
3775     * is outside this component
3776     * @see #contains(int, int)
3777     * @since JDK1.0
3778     */

3779    public Component JavaDoc getComponentAt(int x, int y) {
3780        return locate(x, y);
3781    }
3782
3783    /**
3784     * @deprecated As of JDK version 1.1,
3785     * replaced by getComponentAt(int, int).
3786     */

3787    @Deprecated JavaDoc
3788    public Component JavaDoc locate(int x, int y) {
3789        return contains(x, y) ? this : null;
3790    }
3791
3792    /**
3793     * Returns the component or subcomponent that contains the
3794     * specified point.
3795     * @param p the point
3796     * @see java.awt.Component#contains
3797     * @since JDK1.1
3798     */

3799    public Component JavaDoc getComponentAt(Point JavaDoc p) {
3800        return getComponentAt(p.x, p.y);
3801    }
3802
3803    /**
3804     * @deprecated As of JDK version 1.1,
3805     * replaced by <code>dispatchEvent(AWTEvent e)</code>.
3806     */

3807    @Deprecated JavaDoc
3808    public void deliverEvent(Event JavaDoc e) {
3809        postEvent(e);
3810    }
3811
3812    /**
3813     * Dispatches an event to this component or one of its sub components.
3814     * Calls <code>processEvent</code> before returning for 1.1-style
3815     * events which have been enabled for the <code>Component</code>.
3816     * @param e the event
3817     */

3818    public final void dispatchEvent(AWTEvent JavaDoc e) {
3819        dispatchEventImpl(e);
3820    }
3821
3822    void dispatchEventImpl(AWTEvent JavaDoc e) {
3823        int id = e.getID();
3824
3825        // Check that this component belongs to this app-context
3826
AppContext compContext = appContext;
3827        if (compContext != null && !compContext.equals(AppContext.getAppContext())) {
3828            log.fine("Event " + e + " is being dispatched on the wrong AppContext");
3829        }
3830
3831        /*
3832         * 0. Set timestamp and modifiers of current event.
3833         */

3834        EventQueue.setCurrentEventAndMostRecentTime(e);
3835
3836        /*
3837         * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
3838         * before we notify AWTEventListeners.
3839         */

3840
3841        if (e instanceof SunDropTargetEvent) {
3842            ((SunDropTargetEvent)e).dispatch();
3843            return;
3844        }
3845
3846        if (!e.focusManagerIsDispatching) {
3847            // Invoke the private focus retargeting method which provides
3848
// lightweight Component support
3849
if (e.isPosted) {
3850                e = KeyboardFocusManager.retargetFocusEvent(e);
3851                e.isPosted = true;
3852            }
3853
3854            // Now, with the event properly targeted to a lightweight
3855
// descendant if necessary, invoke the public focus retargeting
3856
// and dispatching function
3857
if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
3858                dispatchEvent(e))
3859            {
3860                return;
3861            }
3862        }
3863        if (e instanceof FocusEvent && focusLog.isLoggable(Level.FINE)) {
3864            focusLog.fine("" + e);
3865        }
3866        // MouseWheel may need to be retargeted here so that
3867
// AWTEventListener sees the event go to the correct
3868
// Component. If the MouseWheelEvent needs to go to an ancestor,
3869
// the event is dispatched to the ancestor, and dispatching here
3870
// stops.
3871
if (id == MouseEvent.MOUSE_WHEEL &&
3872            (!eventTypeEnabled(id)) &&
3873            (peer != null && !peer.handlesWheelScrolling()) &&
3874            (dispatchMouseWheelToAncestor((MouseWheelEvent)e)))
3875        {
3876            return;
3877        }
3878
3879        /*
3880         * 2. Allow the Toolkit to pass this to AWTEventListeners.
3881         */

3882        Toolkit JavaDoc toolkit = Toolkit.getDefaultToolkit();
3883        toolkit.notifyAWTEventListeners(e);
3884
3885
3886        /*
3887         * 3. If no one has consumed a key event, allow the
3888         * KeyboardFocusManager to process it.
3889         */

3890        if (!e.isConsumed()) {
3891            if (e instanceof java.awt.event.KeyEvent JavaDoc) {
3892                KeyboardFocusManager.getCurrentKeyboardFocusManager().
3893                    processKeyEvent(this, (KeyEvent)e);
3894                if (e.isConsumed()) {
3895                    return;
3896                }
3897            }
3898        }
3899
3900        /*
3901         * 4. Allow input methods to process the event
3902         */

3903        if (areInputMethodsEnabled()) {
3904        // We need to pass on InputMethodEvents since some host
3905
// input method adapters send them through the Java
3906
// event queue instead of directly to the component,
3907
// and the input context also handles the Java composition window
3908
if(((e instanceof InputMethodEvent JavaDoc) && !(this instanceof CompositionArea))
3909           ||
3910           // Otherwise, we only pass on input and focus events, because
3911
// a) input methods shouldn't know about semantic or component-level events
3912
// b) passing on the events takes time
3913
// c) isConsumed() is always true for semantic events.
3914
(e instanceof InputEvent) || (e instanceof FocusEvent)) {
3915        InputContext JavaDoc inputContext = getInputContext();
3916
3917
3918        if (inputContext != null) {
3919            inputContext.dispatchEvent(e);
3920            if (e.isConsumed()) {
3921            if (e instanceof FocusEvent && focusLog.isLoggable(Level.FINER)) {
3922                focusLog.finer("3579: Skipping " + e);
3923            }
3924            return;
3925            }
3926        }
3927        }
3928    } else {
3929        // When non-clients get focus, we need to explicitly disable the native
3930
// input method. The native input method is actually not disabled when
3931
// the active/passive/peered clients loose focus.
3932
if (id == FocusEvent.FOCUS_GAINED) {
3933        InputContext JavaDoc inputContext = getInputContext();
3934        if (inputContext != null && inputContext instanceof sun.awt.im.InputContext) {
3935            ((sun.awt.im.InputContext)inputContext).disableNativeIM();
3936        }
3937        }
3938    }
3939
3940
3941        /*
3942         * 5. Pre-process any special events before delivery
3943         */

3944        switch(id) {
3945            // Handling of the PAINT and UPDATE events is now done in the
3946
// peer's handleEvent() method so the background can be cleared
3947
// selectively for non-native components on Windows only.
3948
// - Fred.Ecks@Eng.sun.com, 5-8-98
3949

3950          case KeyEvent.KEY_PRESSED:
3951          case KeyEvent.KEY_RELEASED:
3952              Container JavaDoc p = (Container JavaDoc)((this instanceof Container JavaDoc) ? this : parent);
3953              if (p != null) {
3954                  p.preProcessKeyEvent((KeyEvent)e);
3955                  if (e.isConsumed()) {
3956                      return;
3957                  }
3958              }
3959              break;
3960
3961          case WindowEvent.WINDOW_CLOSING:
3962              if (toolkit instanceof WindowClosingListener) {
3963                  windowClosingException = ((WindowClosingListener)
3964                                            toolkit).windowClosingNotify((WindowEvent)e);
3965                  if (checkWindowClosingException()) {
3966                      return;
3967                  }
3968              }
3969              break;
3970                
3971          default:
3972              break;
3973        }
3974
3975        /*
3976         * 6. Deliver event for normal processing
3977         */

3978        if (newEventsOnly) {
3979            // Filtering needs to really be moved to happen at a lower
3980
// level in order to get maximum performance gain; it is
3981
// here temporarily to ensure the API spec is honored.
3982
//
3983
if (eventEnabled(e)) {
3984                processEvent(e);
3985            }
3986        } else if (id == MouseEvent.MOUSE_WHEEL) {
3987            // newEventsOnly will be false for a listenerless ScrollPane, but
3988
// MouseWheelEvents still need to be dispatched to it so scrolling
3989
// can be done.
3990
autoProcessMouseWheel((MouseWheelEvent)e);
3991        } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {
3992            //
3993
// backward compatibility
3994
//
3995
Event JavaDoc olde = e.convertToOld();
3996            if (olde != null) {
3997                int key = olde.key;
3998                int modifiers = olde.modifiers;
3999
4000                postEvent(olde);
4001                if (olde.isConsumed()) {
4002                    e.consume();
4003                }
4004                // if target changed key or modifier values, copy them
4005
// back to original event
4006
//
4007
switch(olde.id) {
4008                  case Event.KEY_PRESS:
4009                  case Event.KEY_RELEASE:
4010                  case Event.KEY_ACTION:
4011                  case Event.KEY_ACTION_RELEASE:
4012                      if (olde.key != key) {
4013                          ((KeyEvent)e).setKeyChar(olde.getKeyEventChar());
4014                      }
4015                      if (olde.modifiers != modifiers) {
4016                          ((KeyEvent)e).setModifiers(olde.modifiers);
4017                      }
4018                      break;
4019                  default:
4020                      break;
4021                }
4022            }
4023        }
4024
4025        /*
4026         * 8. Special handling for 4061116 : Hook for browser to close modal
4027         * dialogs.
4028         */

4029        if (id == WindowEvent.WINDOW_CLOSING && !e.isConsumed()) {
4030            if (toolkit instanceof WindowClosingListener) {
4031                windowClosingException =
4032                    ((WindowClosingListener)toolkit).
4033                    windowClosingDelivered((WindowEvent)e);
4034                if (checkWindowClosingException()) {
4035                    return;
4036                }
4037            }
4038        }
4039  
4040        /*
4041         * 9. Allow the peer to process the event.
4042         * Except KeyEvents, they will be processed by peer after
4043         * all KeyEventPostProcessors
4044         * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
4045         */

4046        if (!(e instanceof KeyEvent)) {
4047            ComponentPeer tpeer = peer;
4048            if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
4049                // if focus owner is lightweight then its native container
4050
// processes event
4051
Component JavaDoc source = (Component JavaDoc)e.getSource();
4052                if (source != null) {
4053                    Container JavaDoc target = source.getNativeContainer();
4054                    if (target != null) {
4055                        tpeer = target.getPeer();
4056                    }
4057                }
4058            }
4059            if (tpeer != null) {
4060                tpeer.handleEvent(e);
4061            }
4062        }
4063    } // dispatchEventImpl()
4064

4065    /*
4066     * If newEventsOnly is false, method is called so that ScrollPane can
4067     * override it and handle common-case mouse wheel scrolling. NOP
4068     * for Component.
4069     */

4070    void autoProcessMouseWheel(MouseWheelEvent e) {}
4071
4072    /*
4073     * Dispatch given MouseWheelEvent to the first ancestor for which
4074     * MouseWheelEvents are enabled.
4075     *
4076     * Returns whether or not event was dispatched to an ancestor
4077     */

4078    boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
4079        int newX, newY;
4080        newX = e.getX() + getX(); // Coordinates take into account at least
4081
newY = e.getY() + getY(); // the cursor's position relative to this
4082
// Component (e.getX()), and this Component's
4083
// position relative to its parent.
4084
MouseWheelEvent newMWE;
4085
4086        if (dbg.on) {
4087            dbg.println("Component.dispatchMouseWheelToAncestor");
4088            dbg.println("orig event src is of " + e.getSource().getClass());
4089        }
4090
4091        /* parent field for Window refers to the owning Window.
4092         * MouseWheelEvents should NOT be propagated into owning Windows
4093         */

4094        synchronized (getTreeLock()) {
4095            Container JavaDoc anc = getParent();
4096            while (anc != null && !anc.eventEnabled(e)) {
4097                // fix coordinates to be relative to new event source
4098
newX += anc.getX();
4099                newY += anc.getY();
4100
4101                if (!(anc instanceof Window JavaDoc)) {
4102                    anc = anc.getParent();
4103                }
4104                else {
4105                    break;
4106                }
4107            }
4108
4109            if (dbg.on) dbg.println("new event src is " + anc.getClass());
4110
4111            if (anc != null && anc.eventEnabled(e)) {
4112                // Change event to be from new source, with new x,y
4113
// For now, just create a new event - yucky
4114

4115                newMWE = new MouseWheelEvent(anc, // new source
4116
e.getID(),
4117                                             e.getWhen(),
4118                                             e.getModifiers(),
4119                                             newX, // x relative to new source
4120
newY, // y relative to new source
4121
e.getClickCount(),
4122                                             e.isPopupTrigger(),
4123                                             e.getScrollType(),
4124                                             e.getScrollAmount(),
4125                                             e.getWheelRotation());
4126                ((AWTEvent JavaDoc)e).copyPrivateDataInto(newMWE);
4127                anc.dispatchEventImpl(newMWE);
4128            }
4129        }
4130        return true;
4131    }
4132    
4133    boolean checkWindowClosingException() {
4134        if (windowClosingException != null) {
4135            if (this instanceof Dialog JavaDoc) {
4136                ((Dialog JavaDoc)this).interruptBlocking();
4137            } else {
4138                windowClosingException.fillInStackTrace();
4139                windowClosingException.printStackTrace();
4140                windowClosingException = null;
4141            }
4142            return true;
4143        }
4144        return false;
4145    }
4146
4147    boolean areInputMethodsEnabled() {
4148        // in 1.2, we assume input method support is required for all
4149
// components that handle key events, but components can turn off
4150
// input methods by calling enableInputMethods(false).
4151
return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
4152            ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
4153    }
4154
4155    // REMIND: remove when filtering is handled at lower level
4156
boolean eventEnabled(AWTEvent JavaDoc e) {
4157        return eventTypeEnabled(e.id);
4158    }
4159
4160    boolean eventTypeEnabled(int type) {
4161        switch(type) {
4162          case ComponentEvent.COMPONENT_MOVED:
4163          case ComponentEvent.COMPONENT_RESIZED:
4164          case ComponentEvent.COMPONENT_SHOWN:
4165          case ComponentEvent.COMPONENT_HIDDEN:
4166              if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
4167                  componentListener != null) {
4168                  return true;
4169              }
4170              break;
4171          case FocusEvent.FOCUS_GAINED:
4172          case FocusEvent.FOCUS_LOST:
4173              if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 ||
4174                  focusListener != null) {
4175                  return true;
4176              }
4177              break;
4178          case KeyEvent.KEY_PRESSED:
4179          case KeyEvent.KEY_RELEASED:
4180          case KeyEvent.KEY_TYPED:
4181              if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 ||
4182                  keyListener != null) {
4183                  return true;
4184              }
4185              break;
4186          case MouseEvent.MOUSE_PRESSED:
4187          case MouseEvent.MOUSE_RELEASED:
4188          case MouseEvent.MOUSE_ENTERED:
4189          case MouseEvent.MOUSE_EXITED:
4190          case MouseEvent.MOUSE_CLICKED:
4191              if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 ||
4192                  mouseListener != null) {
4193                  return true;
4194              }
4195              break;
4196          case MouseEvent.MOUSE_MOVED:
4197          case MouseEvent.MOUSE_DRAGGED:
4198              if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 ||
4199                  mouseMotionListener != null) {
4200                  return true;
4201              }
4202              break;
4203          case MouseEvent.MOUSE_WHEEL:
4204              if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 ||
4205                  mouseWheelListener != null) {
4206                  return true;
4207              }
4208              break;
4209          case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
4210          case InputMethodEvent.CARET_POSITION_CHANGED:
4211              if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 ||
4212                  inputMethodListener != null) {
4213                  return true;
4214              }
4215              break;
4216          case HierarchyEvent.HIERARCHY_CHANGED:
4217              if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
4218                  hierarchyListener != null) {
4219                  return true;
4220              }
4221              break;
4222          case HierarchyEvent.ANCESTOR_MOVED:
4223          case HierarchyEvent.ANCESTOR_RESIZED:
4224              if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
4225                  hierarchyBoundsListener != null) {
4226                  return true;
4227              }
4228              break;
4229          case ActionEvent.ACTION_PERFORMED:
4230              if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {
4231                  return true;
4232              }
4233              break;
4234          case TextEvent.TEXT_VALUE_CHANGED:
4235              if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {
4236                  return true;
4237              }
4238              break;
4239          case ItemEvent.ITEM_STATE_CHANGED:
4240              if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {
4241                  return true;
4242              }
4243              break;
4244          case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
4245              if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {
4246                  return true;
4247              }
4248              break;
4249          default:
4250              break;
4251        }
4252        //
4253
// Always pass on events defined by external programs.
4254
//
4255
if (type > AWTEvent.RESERVED_ID_MAX) {
4256            return true;
4257        }
4258        return false;
4259    }
4260
4261    /**
4262     * @deprecated As of JDK version 1.1,
4263     * replaced by dispatchEvent(AWTEvent).
4264     */

4265    @Deprecated JavaDoc
4266    public boolean postEvent(Event JavaDoc e) {
4267        ComponentPeer peer = this.peer;
4268
4269        if (handleEvent(e)) {
4270            e.consume();
4271            return true;
4272        }
4273
4274        Component JavaDoc parent = this.parent;
4275        int eventx = e.x;
4276        int eventy = e.y;
4277        if (parent != null) {
4278            e.translate(x, y);
4279            if (parent.postEvent(e)) {
4280                e.consume();
4281                return true;
4282            }
4283            // restore coords
4284
e.x = eventx;
4285            e.y = eventy;
4286        }
4287        return false;
4288    }
4289
4290    // Event source interfaces
4291

4292    /**
4293     * Adds the specified component listener to receive component events from
4294     * this component.
4295     * If listener <code>l</code> is <code>null</code>,
4296     * no exception is thrown and no action is performed.
4297     *
4298     * @param l the component listener
4299     * @see java.awt.event.ComponentEvent
4300     * @see java.awt.event.ComponentListener
4301     * @see #removeComponentListener
4302     * @see #getComponentListeners
4303     * @since JDK1.1
4304     */

4305    public synchronized void addComponentListener(ComponentListener l) {
4306        if (l == null) {
4307            return;
4308        }
4309        componentListener = AWTEventMulticaster.add(componentListener, l);
4310        newEventsOnly = true;
4311    }
4312
4313    /**
4314     * Removes the specified component listener so that it no longer
4315     * receives component events from this component. This method performs
4316     * no function, nor does it throw an exception, if the listener
4317     * specified by the argument was not previously added to this component.
4318     * If listener <code>l</code> is <code>null</code>,
4319     * no exception is thrown and no action is performed.
4320     * @param l the component listener
4321     * @see java.awt.event.ComponentEvent
4322     * @see java.awt.event.ComponentListener
4323     * @see #addComponentListener
4324     * @see #getComponentListeners
4325     * @since JDK1.1
4326     */

4327    public synchronized void removeComponentListener(ComponentListener l) {
4328        if (l == null) {
4329            return;
4330        }
4331        componentListener = AWTEventMulticaster.remove(componentListener, l);
4332    }
4333
4334    /**
4335     * Returns an array of all the component listeners
4336     * registered on this component.
4337     *
4338     * @return all of this comonent's <code>ComponentListener</code>s
4339     * or an empty array if no component
4340     * listeners are currently registered
4341     *
4342     * @see #addComponentListener
4343     * @see #removeComponentListener
4344     * @since 1.4
4345     */

4346    public synchronized ComponentListener[] getComponentListeners() {
4347        return (ComponentListener[]) (getListeners(ComponentListener.class));
4348    }
4349
4350    /**
4351     * Adds the specified focus listener to receive focus events from
4352     * this component when this component gains input focus.
4353     * If listener <code>l</code> is <code>null</code>,
4354     * no exception is thrown and no action is performed.
4355     *
4356     * @param l the focus listener
4357     * @see java.awt.event.FocusEvent
4358     * @see java.awt.event.FocusListener
4359     * @see #removeFocusListener
4360     * @see #getFocusListeners
4361     * @since JDK1.1
4362     */

4363    public synchronized void addFocusListener(FocusListener l) {
4364        if (l == null) {
4365            return;
4366        }
4367        focusListener = AWTEventMulticaster.add(focusListener, l);
4368        newEventsOnly = true;
4369
4370        // if this is a lightweight component, enable focus events
4371
// in the native container.
4372
if (peer instanceof LightweightPeer) {
4373            parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);
4374        }
4375    }
4376
4377    /**
4378     * Removes the specified focus listener so that it no longer
4379     * receives focus events from this component. This method performs
4380     * no function, nor does it throw an exception, if the listener
4381     * specified by the argument was not previously added to this component.
4382     * If listener <code>l</code> is <code>null</code>,
4383     * no exception is thrown and no action is performed.
4384     *
4385     * @param l the focus listener
4386     * @see java.awt.event.FocusEvent
4387     * @see java.awt.event.FocusListener
4388     * @see #addFocusListener
4389     * @see #getFocusListeners
4390     * @since JDK1.1
4391     */

4392    public synchronized void removeFocusListener(FocusListener l) {
4393        if (l == null) {
4394            return;
4395        }
4396        focusListener = AWTEventMulticaster.remove(focusListener, l);
4397    }
4398
4399    /**
4400     * Returns an array of all the focus listeners
4401     * registered on this component.
4402     *
4403     * @return all of this component's <code>FocusListener</code>s
4404     * or an empty array if no component
4405     * listeners are currently registered
4406     *
4407     * @see #addFocusListener
4408     * @see #removeFocusListener
4409     * @since 1.4
4410     */

4411    public synchronized FocusListener[] getFocusListeners() {
4412        return (FocusListener[]) (getListeners(FocusListener.class));
4413    }
4414
4415    /**
4416     * Adds the specified hierarchy listener to receive hierarchy changed
4417     * events from this component when the hierarchy to which this container
4418     * belongs changes.
4419     * If listener <code>l</code> is <code>null</code>,
4420     * no exception is thrown and no action is performed.
4421     *
4422     * @param l the hierarchy listener
4423     * @see java.awt.event.HierarchyEvent
4424     * @see java.awt.event.HierarchyListener
4425     * @see #removeHierarchyListener
4426     * @see #getHierarchyListeners
4427     * @since 1.3
4428     */

4429    public void addHierarchyListener(HierarchyListener l) {
4430        if (l == null) {
4431            return;
4432        }
4433        boolean notifyAncestors;
4434        synchronized (this) {
4435            notifyAncestors =
4436                (hierarchyListener == null &&
4437                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
4438            hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
4439            notifyAncestors = (notifyAncestors && hierarchyListener != null);
4440            newEventsOnly = true;
4441        }
4442        if (notifyAncestors) {
4443            synchronized (getTreeLock()) {
4444                adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
4445                                                1);
4446            }
4447        }
4448    }
4449
4450    /**
4451     * Removes the specified hierarchy listener so that it no longer
4452     * receives hierarchy changed events from this component. This method
4453     * performs no function, nor does it throw an exception, if the listener
4454     * specified by the argument was not previously added to this component.
4455     * If listener <code>l</code> is <code>null</code>,
4456     * no exception is thrown and no action is performed.
4457     *
4458     * @param l the hierarchy listener
4459     * @see java.awt.event.HierarchyEvent
4460     * @see java.awt.event.HierarchyListener
4461     * @see #addHierarchyListener
4462     * @see #getHierarchyListeners
4463     * @since 1.3
4464     */

4465    public void removeHierarchyListener(HierarchyListener l) {
4466        if (l == null) {
4467            return;
4468        }
4469        boolean notifyAncestors;
4470        synchronized (this) {
4471            notifyAncestors =
4472                (hierarchyListener != null &&
4473                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
4474            hierarchyListener =
4475                AWTEventMulticaster.remove(hierarchyListener, l);
4476            notifyAncestors = (notifyAncestors && hierarchyListener == null);
4477        }
4478        if (notifyAncestors) {
4479            synchronized (getTreeLock()) {
4480                adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
4481                                                -1);
4482            }
4483        }
4484    }
4485
4486    /**
4487     * Returns an array of all the hierarchy listeners
4488     * registered on this component.
4489     *
4490     * @return all of this component's <code>HierarchyListener</code>s
4491     * or an empty array if no hierarchy
4492     * listeners are currently registered
4493     *
4494     * @see #addHierarchyListener
4495     * @see #removeHierarchyListener
4496     * @since 1.4
4497     */

4498    public synchronized HierarchyListener[] getHierarchyListeners() {
4499        return (HierarchyListener[])(getListeners(HierarchyListener.class));
4500    }
4501
4502    /**
4503     * Adds the specified hierarchy bounds listener to receive hierarchy
4504     * bounds events from this component when the hierarchy to which this
4505     * container belongs changes.
4506     * If listener <code>l</code> is <code>null</code>,
4507     * no exception is thrown and no action is performed.
4508     *
4509     * @param l the hierarchy bounds listener
4510     * @see java.awt.event.HierarchyEvent
4511     * @see java.awt.event.HierarchyBoundsListener
4512     * @see #removeHierarchyBoundsListener
4513     * @see #getHierarchyBoundsListeners
4514     * @since 1.3
4515     */

4516    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
4517        if (l == null) {
4518            return;
4519        }
4520        boolean notifyAncestors;
4521        synchronized (this) {
4522            notifyAncestors =
4523                (hierarchyBoundsListener == null &&
4524                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
4525            hierarchyBoundsListener =
4526                AWTEventMulticaster.add(hierarchyBoundsListener, l);
4527            notifyAncestors = (notifyAncestors &&
4528                               hierarchyBoundsListener != null);
4529            newEventsOnly = true;
4530        }
4531        if (notifyAncestors) {
4532            synchronized (getTreeLock()) {
4533                adjustListeningChildrenOnParent(
4534                                                AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
4535            }
4536        }
4537    }
4538
4539    /**
4540     * Removes the specified hierarchy bounds listener so that it no longer
4541     * receives hierarchy bounds events from this component. This method
4542     * performs no function, nor does it throw an exception, if the listener
4543     * specified by the argument was not previously added to this component.
4544     * If listener <code>l</code> is <code>null</code>,
4545     * no exception is thrown and no action is performed.
4546     *
4547     * @param l the hierarchy bounds listener
4548     * @see java.awt.event.HierarchyEvent
4549     * @see java.awt.event.HierarchyBoundsListener
4550     * @see #addHierarchyBoundsListener
4551     * @see #getHierarchyBoundsListeners
4552     * @since 1.3
4553     */

4554    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
4555        if (l == null) {
4556            return;
4557        }
4558        boolean notifyAncestors;
4559        synchronized (this) {
4560            notifyAncestors =
4561                (hierarchyBoundsListener != null &&
4562                 (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
4563            hierarchyBoundsListener =
4564                AWTEventMulticaster.remove(hierarchyBoundsListener, l);
4565            notifyAncestors = (notifyAncestors &&
4566                               hierarchyBoundsListener == null);
4567        }
4568        if (notifyAncestors) {
4569            synchronized (getTreeLock()) {
4570                adjustListeningChildrenOnParent(
4571                                                AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);
4572            }
4573        }
4574    }
4575
4576    // Should only be called while holding the tree lock
4577
int numListening(long mask) {
4578        if (dbg.on) {
4579            // One mask or the other, but not neither or both.
4580
dbg.assertion(mask == AWTEvent.HIERARCHY_EVENT_MASK ||
4581                          mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
4582        }
4583        if ((mask == AWTEvent.HIERARCHY_EVENT_MASK &&
4584             (hierarchyListener != null ||
4585              (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) ||
4586            (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK &&
4587             (hierarchyBoundsListener != null ||
4588              (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {
4589            return 1;
4590        } else {
4591            return 0;
4592        }
4593    }
4594
4595    // Should only be called while holding tree lock
4596
int countHierarchyMembers() {
4597        return 1;
4598    }
4599    // Should only be called while holding the tree lock
4600
int createHierarchyEvents(int id, Component JavaDoc changed,
4601                              Container JavaDoc changedParent, long changeFlags,
4602                              boolean enabledOnToolkit) {
4603        switch (id) {
4604          case HierarchyEvent.HIERARCHY_CHANGED:
4605              if (hierarchyListener != null ||
4606                  (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
4607                  enabledOnToolkit) {
4608                  HierarchyEvent e = new HierarchyEvent(this, id, changed,
4609                                                        changedParent,
4610                                                        changeFlags);
4611                  dispatchEvent(e);
4612                  return 1;
4613              }
4614              break;
4615          case HierarchyEvent.ANCESTOR_MOVED:
4616          case HierarchyEvent.ANCESTOR_RESIZED:
4617              if (dbg.on) {
4618                  dbg.assertion(changeFlags == 0);
4619              }
4620              if (hierarchyBoundsListener != null ||
4621                  (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
4622                  enabledOnToolkit) {
4623                  HierarchyEvent e = new HierarchyEvent(this, id, changed,
4624                                                        changedParent);
4625                  dispatchEvent(e);
4626                  return 1;
4627              }
4628              break;
4629          default:
4630              if (dbg.on) {
4631                  dbg.assertion(false);
4632              }
4633              break;
4634        }
4635        return 0;
4636    }
4637
4638    /**
4639     * Returns an array of all the hierarchy bounds listeners
4640     * registered on this component.
4641     *
4642     * @return all of this component's <code>HierarchyBoundsListener</code>s
4643     * or an empty array if no hierarchy bounds
4644     * listeners are currently registered
4645     *
4646     * @see #addHierarchyBoundsListener
4647     * @see #removeHierarchyBoundsListener
4648     * @since 1.4
4649     */

4650    public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {
4651        return (HierarchyBoundsListener[])
4652            (getListeners(HierarchyBoundsListener.class));
4653    }
4654     
4655    /*
4656     * Should only be called while holding the tree lock.
4657     * It's added only for overriding in java.awt.Window
4658     * because parent in Window is owner.
4659     */

4660    void adjustListeningChildrenOnParent(long mask, int num) {
4661        if (parent != null) {
4662            parent.adjustListeningChildren(mask, num);
4663        }
4664    }
4665
4666    /**
4667     * Adds the specified key listener to receive key events from
4668     * this component.
4669     * If l is null, no exception is thrown and no action is performed.
4670     *
4671     * @param l the key listener.
4672     * @see java.awt.event.KeyEvent
4673     * @see java.awt.event.KeyListener
4674     * @see #removeKeyListener
4675     * @see #getKeyListeners
4676     * @since JDK1.1
4677     */

4678    public synchronized void addKeyListener(KeyListener l) {
4679        if (l == null) {
4680            return;
4681        }
4682        keyListener = AWTEventMulticaster.add(keyListener, l);
4683        newEventsOnly = true;
4684
4685        // if this is a lightweight component, enable key events
4686
// in the native container.
4687
if (peer instanceof LightweightPeer) {
4688            parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);
4689        }
4690    }
4691
4692    /**
4693     * Removes the specified key listener so that it no longer
4694     * receives key events from this component. This method performs
4695     * no function, nor does it throw an exception, if the listener
4696     * specified by the argument was not previously added to this component.
4697     * If listener <code>l</code> is <code>null</code>,
4698     * no exception is thrown and no action is performed.
4699     *
4700     * @param l the key listener
4701     * @see java.awt.event.KeyEvent
4702     * @see java.awt.event.KeyListener
4703     * @see #addKeyListener
4704     * @see #getKeyListeners
4705     * @since JDK1.1
4706     */

4707    public synchronized void removeKeyListener(KeyListener l) {
4708        if (l == null) {
4709            return;
4710        }
4711        keyListener = AWTEventMulticaster.remove(keyListener, l);
4712    }
4713
4714    /**
4715     * Returns an array of all the key listeners
4716     * registered on this component.
4717     *
4718     * @return all of this component's <code>KeyListener</code>s
4719     * or an empty array if no key
4720     * listeners are currently registered
4721     *
4722     * @see #addKeyListener
4723     * @see #removeKeyListener
4724     * @since 1.4
4725     */

4726    public synchronized KeyListener[] getKeyListeners() {
4727        return (KeyListener[]) (getListeners(KeyListener.class));
4728    }
4729
4730    /**
4731     * Adds the specified mouse listener to receive mouse events from
4732     * this component.
4733     * If listener <code>l</code> is <code>null</code>,
4734     * no exception is thrown and no action is performed.
4735     *
4736     * @param l the mouse listener
4737     * @see java.awt.event.MouseEvent
4738     * @see java.awt.event.MouseListener
4739     * @see #removeMouseListener
4740     * @see #getMouseListeners
4741     * @since JDK1.1
4742     */

4743    public synchronized void addMouseListener(MouseListener l) {
4744        if (l == null) {
4745            return;
4746        }
4747        mouseListener = AWTEventMulticaster.add(mouseListener,l);
4748        newEventsOnly = true;
4749
4750        // if this is a lightweight component, enable mouse events
4751
// in the native container.
4752
if (peer instanceof LightweightPeer) {
4753            parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);
4754        }
4755    }
4756
4757    /**
4758     * Removes the specified mouse listener so that it no longer
4759     * receives mouse events from this component. This method performs
4760     * no function, nor does it throw an exception, if the listener
4761     * specified by the argument was not previously added to this component.
4762     * If listener <code>l</code> is <code>null</code>,
4763     * no exception is thrown and no action is performed.
4764     *
4765     * @param l the mouse listener
4766     * @see java.awt.event.MouseEvent
4767     * @see java.awt.event.MouseListener
4768     * @see #addMouseListener
4769     * @see #getMouseListeners
4770     * @since JDK1.1
4771     */

4772    public synchronized void removeMouseListener(MouseListener l) {
4773        if (l == null) {
4774            return;
4775        }
4776        mouseListener = AWTEventMulticaster.remove(mouseListener, l);
4777    }
4778
4779    /**
4780     * Returns an array of all the mouse listeners
4781     * registered on this component.
4782     *
4783     * @return all of this component's <code>MouseListener</code>s
4784     * or an empty array if no mouse
4785     * listeners are currently registered
4786     *
4787     * @see #addMouseListener
4788     * @see #removeMouseListener
4789     * @since 1.4
4790     */

4791    public synchronized MouseListener[] getMouseListeners() {
4792        return (MouseListener[]) (getListeners(MouseListener.class));
4793    }
4794
4795    /**
4796     * Adds the specified mouse motion listener to receive mouse motion
4797     * events from this component.
4798     * If listener <code>l</code> is <code>null</code>,
4799     * no exception is thrown and no action is performed.
4800     *
4801     * @param l the mouse motion listener
4802     * @see java.awt.event.MouseEvent
4803     * @see java.awt.event.MouseMotionListener
4804     * @see #removeMouseMotionListener
4805     * @see #getMouseMotionListeners
4806     * @since JDK1.1
4807     */

4808    public synchronized void addMouseMotionListener(MouseMotionListener l) {
4809        if (l == null) {
4810            return;
4811        }
4812        mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l);
4813        newEventsOnly = true;
4814
4815        // if this is a lightweight component, enable mouse events
4816
// in the native container.
4817
if (peer instanceof LightweightPeer) {
4818            parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
4819        }
4820    }
4821
4822    /**
4823     * Removes the specified mouse motion listener so that it no longer
4824     * receives mouse motion events from this component. This method performs
4825     * no function, nor does it throw an exception, if the listener
4826     * specified by the argument was not previously added to this component.
4827     * If listener <code>l</code> is <code>null</code>,
4828     * no exception is thrown and no action is performed.
4829     *
4830     * @param l the mouse motion listener
4831     * @see java.awt.event.MouseEvent
4832     * @see java.awt.event.MouseMotionListener
4833     * @see #addMouseMotionListener
4834     * @see #getMouseMotionListeners
4835     * @since JDK1.1
4836     */

4837    public synchronized void removeMouseMotionListener(MouseMotionListener l) {
4838        if (l == null) {
4839            return;
4840        }
4841        mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
4842    }
4843
4844    /**
4845     * Returns an array of all the mouse motion listeners
4846     * registered on this component.
4847     *
4848     * @return all of this component's <code>MouseMotionListener</code>s
4849     * or an empty array if no mouse motion
4850     * listeners are currently registered
4851     *
4852     * @see #addMouseMotionListener
4853     * @see #removeMouseMotionListener
4854     * @since 1.4
4855     */

4856    public synchronized MouseMotionListener[] getMouseMotionListeners() {
4857        return (MouseMotionListener[]) (getListeners(MouseMotionListener.class));
4858    }
4859
4860    /**
4861     * Adds the specified mouse wheel listener to receive mouse wheel events
4862     * from this component. Containers also receive mouse wheel events from
4863     * sub-components.
4864     * <p>
4865     * For information on how mouse wheel events are dispatched, see
4866     * the class description for {@link MouseWheelEvent}.
4867     * <p>
4868     * If l is <code>null</code>, no exception is thrown and no
4869     * action is performed.
4870     *
4871     * @param l the mouse wheel listener
4872     * @see java.awt.event.MouseWheelEvent
4873     * @see java.awt.event.MouseWheelListener
4874     * @see #removeMouseWheelListener
4875     * @see #getMouseWheelListeners
4876     * @since 1.4
4877     */

4878    public synchronized void addMouseWheelListener(MouseWheelListener l) {
4879        if (l == null) {
4880            return;
4881        }
4882        mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l);
4883        newEventsOnly = true;
4884
4885        dbg.println("Component.addMouseWheelListener(): newEventsOnly = " + newEventsOnly);
4886
4887        // if this is a lightweight component, enable mouse events
4888
// in the native container.
4889
if (peer instanceof LightweightPeer) {
4890            parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
4891        }
4892    }
4893
4894    /**
4895     * Removes the specified mouse wheel listener so that it no longer
4896     * receives mouse wheel events from this component. This method performs
4897     * no function, nor does it throw an exception, if the listener
4898     * specified by the argument was not previously added to this component.
4899     * If l is null, no exception is thrown and no action is performed.
4900     *
4901     * @param l the mouse wheel listener.
4902     * @see java.awt.event.MouseWheelEvent
4903     * @see java.awt.event.MouseWheelListener
4904     * @see #addMouseWheelListener
4905     * @see #getMouseWheelListeners
4906     * @since 1.4
4907     */

4908    public synchronized void removeMouseWheelListener(MouseWheelListener l) {
4909        if (l == null) {
4910            return;
4911        }
4912        mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
4913    }
4914
4915    /**
4916     * Returns an array of all the mouse wheel listeners
4917     * registered on this component.
4918     *
4919     * @return all of this component's <code>MouseWheelListener</code>s
4920     * or an empty array if no mouse wheel
4921     * listeners are currently registered
4922     *
4923     * @see #addMouseWheelListener
4924     * @see #removeMouseWheelListener
4925     * @since 1.4
4926     */

4927    public synchronized MouseWheelListener[] getMouseWheelListeners() {
4928        return (MouseWheelListener[]) (getListeners(MouseWheelListener.class));
4929    }
4930
4931    /**
4932     * Adds the specified input method listener to receive
4933     * input method events from this component. A component will
4934     * only receive input method events from input methods
4935     * if it also overrides <code>getInputMethodRequests</code> to return an
4936     * <code>InputMethodRequests</code> instance.
4937     * If listener <code>l</code> is <code>null</code>,
4938     * no exception is thrown and no action is performed.
4939     *
4940     * @param l the input method listener
4941     * @see java.awt.event.InputMethodEvent
4942     * @see java.awt.event.InputMethodListener
4943     * @see #removeInputMethodListener
4944     * @see #getInputMethodListeners
4945     * @see #getInputMethodRequests
4946     * @since 1.2
4947     */

4948    public synchronized void addInputMethodListener(InputMethodListener JavaDoc l) {
4949        if (l == null) {
4950            return;
4951        }
4952        inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
4953        newEventsOnly = true;
4954    }
4955
4956    /**
4957     * Removes the specified input method listener so that it no longer
4958     * receives input method events from this component. This method performs
4959     * no function, nor does it throw an exception, if the listener
4960     * specified by the argument was not previously added to this component.
4961     * If listener <code>l</code> is <code>null</code>,
4962     * no exception is thrown and no action is performed.
4963     *
4964     * @param l the input method listener
4965     * @see java.awt.event.InputMethodEvent
4966     * @see java.awt.event.InputMethodListener
4967     * @see #addInputMethodListener
4968     * @see #getInputMethodListeners
4969     * @since 1.2
4970     */

4971    public synchronized void removeInputMethodListener(InputMethodListener JavaDoc l) {
4972        if (l == null) {
4973            return;
4974        }
4975        inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
4976    }
4977
4978    /**
4979     * Returns an array of all the input method listeners
4980     * registered on this component.
4981     *
4982     * @return all of this component's <code>InputMethodListener</code>s
4983     * or an empty array if no input method
4984     * listeners are currently registered
4985     *
4986     * @see #addInputMethodListener
4987     * @see #removeInputMethodListener
4988     * @since 1.4
4989     */

4990    public synchronized InputMethodListener JavaDoc[] getInputMethodListeners() {
4991        return (InputMethodListener JavaDoc[]) (getListeners(InputMethodListener JavaDoc.class));
4992    }
4993
4994    /**
4995     * Returns an array of all the objects currently registered
4996     * as <code><em>Foo</em>Listener</code>s
4997     * upon this <code>Component</code>.
4998     * <code><em>Foo</em>Listener</code>s are registered using the
4999     * <code>add<em>Foo</em>Listener</code> method.
5000     *
5001     * <p>
5002     * You can specify the <code>listenerType</code> argument
5003     * with a class literal, such as
5004     * <code><em>Foo</em>Listener.class</code>.
5005     * For example, you can query a
5006     * <code>Component</code> <code>c</code>
5007     * for its mouse listeners with the following code:
5008     *
5009     * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
5010     *
5011     * If no such listeners exist, this method returns an empty array.
5012     *
5013     * @param listenerType the type of listeners requested; this parameter
5014     * should specify an interface that descends from
5015     * <code>java.util.EventListener</code>
5016     * @return an array of all objects registered as
5017     * <code><em>Foo</em>Listener</code>s on this component,
5018     * or an empty array if no such listeners have been added
5019     * @exception ClassCastException if <code>listenerType</code>
5020     * doesn't specify a class or interface that implements
5021     * <code>java.util.EventListener</code>
5022     *
5023     * @see #getComponentListeners
5024     * @see #getFocusListeners
5025     * @see #getHierarchyListeners
5026     * @see #getHierarchyBoundsListeners
5027     * @see #getKeyListeners
5028     * @see #getMouseListeners
5029     * @see #getMouseMotionListeners
5030     * @see #getMouseWheelListeners
5031     * @see #getInputMethodListeners
5032     * @see #getPropertyChangeListeners
5033     *
5034     * @since 1.3
5035     */

5036    public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
5037        EventListener JavaDoc l = null;
5038        if (listenerType == ComponentListener.class) {
5039            l = componentListener;
5040        } else if (listenerType == FocusListener.class) {
5041            l = focusListener;
5042        } else if (listenerType == HierarchyListener.class) {
5043            l = hierarchyListener;
5044        } else if (listenerType == HierarchyBoundsListener.class) {
5045            l = hierarchyBoundsListener;
5046        } else if (listenerType == KeyListener.class) {
5047            l = keyListener;
5048        } else if (listenerType == MouseListener.class) {
5049            l = mouseListener;
5050        } else if (listenerType == MouseMotionListener.class) {
5051            l = mouseMotionListener;
5052        } else if (listenerType == MouseWheelListener.class) {
5053            l = mouseWheelListener;
5054        } else if (listenerType == InputMethodListener JavaDoc.class) {
5055            l = inputMethodListener;
5056        } else if (listenerType == PropertyChangeListener JavaDoc.class) {
5057            return (T[])getPropertyChangeListeners();
5058        }
5059        return AWTEventMulticaster.getListeners(l, listenerType);
5060    }
5061
5062    /**
5063     * Gets the input method request handler which supports
5064     * requests from input methods for this component. A component
5065     * that supports on-the-spot text input must override this
5066     * method to return an <code>InputMethodRequests</code> instance.
5067     * At the same time, it also has to handle input method events.
5068     *
5069     * @return the input method request handler for this component,
5070     * <code>null</code> by default
5071     * @see #addInputMethodListener
5072     * @since 1.2
5073     */

5074    public InputMethodRequests JavaDoc getInputMethodRequests() {
5075        return null;
5076    }
5077
5078    /**
5079     * Gets the input context used by this component for handling
5080     * the communication with input methods when text is entered
5081     * in this component. By default, the input context used for
5082     * the parent component is returned. Components may
5083     * override this to return a private input context.
5084     *
5085     * @return the input context used by this component;
5086     * <code>null</code> if no context can be determined
5087     * @since 1.2
5088     */

5089    public InputContext JavaDoc getInputContext() {
5090        Container JavaDoc parent = this.parent;
5091        if (parent == null) {
5092            return null;
5093        } else {
5094            return parent.getInputContext();
5095        }
5096    }
5097
5098    /**
5099     * Enables the events defined by the specified event mask parameter
5100     * to be delivered to this component.
5101     * <p>
5102     * Event types are automatically enabled when a listener for
5103     * that event type is added to the component.
5104     * <p>
5105     * This method only needs to be invoked by subclasses of
5106     * <code>Component</code> which desire to have the specified event
5107     * types delivered to <code>processEvent</code> regardless of whether
5108     * or not a listener is registered.
5109     * @param eventsToEnable the event mask defining the event types
5110     * @see #processEvent
5111     * @see #disableEvents
5112     * @see AWTEvent
5113     * @since JDK1.1
5114     */

5115    protected final void enableEvents(long eventsToEnable) {
5116        long notifyAncestors = 0;
5117        synchronized (this) {
5118            if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
5119                hierarchyListener == null &&
5120                (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {
5121                notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5122            }
5123            if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
5124                hierarchyBoundsListener == null &&
5125                (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {
5126                notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5127            }
5128            eventMask |= eventsToEnable;
5129            newEventsOnly = true;
5130        }
5131
5132        // if this is a lightweight component, enable mouse events
5133
// in the native container.
5134
if (peer instanceof LightweightPeer) {
5135            parent.proxyEnableEvents(eventMask);
5136        }
5137        if (notifyAncestors != 0) {
5138            synchronized (getTreeLock()) {
5139                adjustListeningChildrenOnParent(notifyAncestors, 1);
5140            }
5141        }
5142    }
5143
5144    /**
5145     * Disables the events defined by the specified event mask parameter
5146     * from being delivered to this component.
5147     * @param eventsToDisable the event mask defining the event types
5148     * @see #enableEvents
5149     * @since JDK1.1
5150     */

5151    protected final void disableEvents(long eventsToDisable) {
5152        long notifyAncestors = 0;
5153        synchronized (this) {
5154            if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
5155                hierarchyListener == null &&
5156                (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
5157                notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
5158            }
5159            if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 &&
5160                hierarchyBoundsListener == null &&
5161                (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
5162                notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
5163            }
5164            eventMask &= ~eventsToDisable;
5165        }
5166        if (notifyAncestors != 0) {
5167            synchronized (getTreeLock()) {
5168                adjustListeningChildrenOnParent(notifyAncestors, -1);
5169            }
5170        }
5171    }
5172
5173    /**
5174     * Potentially coalesce an event being posted with an existing
5175     * event. This method is called by <code>EventQueue.postEvent</code>
5176     * if an event with the same ID as the event to be posted is found in
5177     * the queue (both events must have this component as their source).
5178     * This method either returns a coalesced event which replaces
5179     * the existing event (and the new event is then discarded), or
5180     * <code>null</code> to indicate that no combining should be done
5181     * (add the second event to the end of the queue). Either event
5182     * parameter may be modified and returned, as the other one is discarded
5183     * unless <code>null</code> is returned.
5184     * <p>
5185     * This implementation of <code>coalesceEvents</code> coalesces
5186     * two event types: mouse move (and drag) events,
5187     * and paint (and update) events.
5188     * For mouse move events the last event is always returned, causing
5189     * intermediate moves to be discarded. For paint events, the new
5190     * event is coalesced into a complex <code>RepaintArea</code> in the peer.
5191     * The new <code>AWTEvent</code> is always returned.
5192     *
5193     * @param existingEvent the event already on the <code>EventQueue</code>
5194     * @param newEvent the event being posted to the
5195     * <code>EventQueue</code>
5196     * @return a coalesced event, or <code>null</code> indicating that no
5197     * coalescing was done
5198     */

5199    protected AWTEvent JavaDoc coalesceEvents(AWTEvent JavaDoc existingEvent,
5200                                      AWTEvent JavaDoc newEvent) {
5201        int id = existingEvent.getID();
5202        if (dbg.on) {
5203            dbg.assertion(id == newEvent.getID() &&
5204                          existingEvent.getSource().equals(newEvent.getSource()));
5205        }
5206
5207        switch (id) {
5208          case Event.MOUSE_MOVE:
5209          case Event.MOUSE_DRAG: {
5210              MouseEvent e = (MouseEvent)existingEvent;
5211              if (e.getModifiers() == ((MouseEvent)newEvent).getModifiers()) {
5212                  // Just return the newEvent, causing the old to be
5213
// discarded.
5214
return newEvent;
5215              }
5216              break;
5217          }
5218          case PaintEvent.PAINT:
5219          case PaintEvent.UPDATE: {
5220              if(peer != null && !(peer instanceof LightweightPeer)) {
5221                  // EventQueue.postEvent should use peer.coalescePaintEvent
5222
return newEvent;
5223              }
5224              // This approach to coalescing paint events seems to be
5225
// better than any heuristic for unioning rectangles.
5226
PaintEvent existingPaintEvent = (PaintEvent) existingEvent;
5227              PaintEvent newPaintEvent = (PaintEvent) newEvent;
5228              Rectangle JavaDoc existingRect = existingPaintEvent.getUpdateRect();
5229              Rectangle JavaDoc newRect = newPaintEvent.getUpdateRect();
5230              
5231              if (dbg.on) {
5232                  dbg.println("Component::coalesceEvents : newEvent : nullPeer : x = " +
5233                              newRect.x + " y = " + newRect.y + " width = " + newRect.width +
5234                              " height = " + newRect.height);
5235              }
5236              
5237              if (existingRect.contains(newRect)) {
5238                  return existingEvent;
5239              }
5240              if (newRect.contains(existingRect)) {
5241                  return newEvent;
5242              }
5243              
5244              break;
5245          }
5246        }
5247
5248        return null;
5249    }
5250
5251    /**
5252     * Processes events occurring on this component. By default this
5253     * method calls the appropriate
5254     * <code>process&lt;event&nbsp;type&gt;Event</code>
5255     * method for the given class of event.
5256     * <p>Note that if the event parameter is <code>null</code>
5257     * the behavior is unspecified and may result in an
5258     * exception.
5259     *
5260     * @param e the event
5261     * @see #processComponentEvent
5262     * @see #processFocusEvent
5263     * @see #processKeyEvent
5264     * @see #processMouseEvent
5265     * @see #processMouseMotionEvent
5266     * @see #processInputMethodEvent
5267     * @see #processHierarchyEvent
5268     * @see #processMouseWheelEvent
5269     * @since JDK1.1
5270     */

5271    protected void processEvent(AWTEvent JavaDoc e) {
5272        if (e instanceof FocusEvent) {
5273            processFocusEvent((FocusEvent)e);
5274
5275        } else if (e instanceof MouseEvent) {
5276            switch(e.getID()) {
5277              case MouseEvent.MOUSE_PRESSED:
5278              case MouseEvent.MOUSE_RELEASED:
5279              case MouseEvent.MOUSE_CLICKED:
5280              case MouseEvent.MOUSE_ENTERED:
5281              case MouseEvent.MOUSE_EXITED:
5282                  processMouseEvent((MouseEvent)e);
5283                  break;
5284              case MouseEvent.MOUSE_MOVED:
5285              case MouseEvent.MOUSE_DRAGGED:
5286                  processMouseMotionEvent((MouseEvent)e);
5287                  break;
5288              case MouseEvent.MOUSE_WHEEL:
5289                  processMouseWheelEvent((MouseWheelEvent)e);
5290                  break;
5291            }
5292
5293        } else if (e instanceof KeyEvent) {
5294            processKeyEvent((KeyEvent)e);
5295
5296        } else if (e instanceof ComponentEvent) {
5297            processComponentEvent((ComponentEvent)e);
5298        } else if (e instanceof InputMethodEvent JavaDoc) {
5299            processInputMethodEvent((InputMethodEvent JavaDoc)e);
5300        } else if (e instanceof HierarchyEvent) {
5301            switch (e.getID()) {
5302              case HierarchyEvent.HIERARCHY_CHANGED:
5303                  processHierarchyEvent((HierarchyEvent)e);
5304                  break;
5305              case HierarchyEvent.ANCESTOR_MOVED:
5306              case HierarchyEvent.ANCESTOR_RESIZED:
5307                  processHierarchyBoundsEvent((HierarchyEvent)e);
5308                  break;
5309            }
5310        }
5311    }
5312
5313    /**
5314     * Processes component events occurring on this component by
5315     * dispatching them to any registered
5316     * <code>ComponentListener</code> objects.
5317     * <p>
5318     * This method is not called unless component events are
5319     * enabled for this component. Component events are enabled
5320     * when one of the following occurs:
5321     * <p><ul>
5322     * <li>A <code>ComponentListener</code> object is registered
5323     * via <code>addComponentListener</code>.
5324     * <li>Component events are enabled via <code>enableEvents</code>.
5325     * </ul>
5326     * <p>Note that if the event parameter is <code>null</code>
5327     * the behavior is unspecified and may result in an
5328     * exception.
5329     *
5330     * @param e the component event
5331     * @see java.awt.event.ComponentEvent
5332     * @see java.awt.event.ComponentListener
5333     * @see #addComponentListener
5334     * @see #enableEvents
5335     * @since JDK1.1
5336     */

5337    protected void processComponentEvent(ComponentEvent e) {
5338        ComponentListener listener = componentListener;
5339        if (listener != null) {
5340            int id = e.getID();
5341            switch(id) {
5342              case ComponentEvent.COMPONENT_RESIZED:
5343                  listener.componentResized(e);
5344                  break;
5345              case ComponentEvent.COMPONENT_MOVED:
5346                  listener.componentMoved(e);
5347                  break;
5348              case ComponentEvent.COMPONENT_SHOWN:
5349                  listener.componentShown(e);
5350                  break;
5351              case ComponentEvent.COMPONENT_HIDDEN:
5352                  listener.componentHidden(e);
5353                  break;
5354            }
5355        }
5356    }
5357
5358    /**
5359     * Processes focus events occurring on this component by
5360     * dispatching them to any registered
5361     * <code>FocusListener</code> objects.
5362     * <p>
5363     * This method is not called unless focus events are
5364     * enabled for this component. Focus events are enabled
5365     * when one of the following occurs:
5366     * <p><ul>
5367     * <li>A <code>FocusListener</code> object is registered
5368     * via <code>addFocusListener</code>.
5369     * <li>Focus events are enabled via <code>enableEvents</code>.
5370     * </ul>
5371     * <p>
5372     * If focus events are enabled for a <code>Component</code>,
5373     * the current <code>KeyboardFocusManager</code> determines
5374     * whether or not a focus event should be dispatched to
5375     * registered <code>FocusListener</code> objects. If the
5376     * events are to be dispatched, the <code>KeyboardFocusManager</code>
5377     * calls the <code>Component</code>'s <code>dispatchEvent</code>
5378     * method, which results in a call to the <code>Component</code>'s
5379     * <code>processFocusEvent</code> method.
5380     * <p>
5381     * If focus events are enabled for a <code>Component</code>, calling
5382     * the <code>Component</code>'s <code>dispatchEvent</code> method
5383     * with a <code>FocusEvent</code> as the argument will result in a
5384     * call to the <code>Component</code>'s <code>processFocusEvent</code>
5385     * method regardless of the current <code>KeyboardFocusManager</code>.
5386     * <p>
5387     * <p>Note that if the event parameter is <code>null</code>
5388     * the behavior is unspecified and may result in an
5389     * exception.
5390     *
5391     * @param e the focus event
5392     * @see java.awt.event.FocusEvent
5393     * @see java.awt.event.FocusListener
5394     * @see java.awt.KeyboardFocusManager
5395     * @see #addFocusListener
5396     * @see #enableEvents
5397     * @see #dispatchEvent
5398     * @since JDK1.1
5399     */

5400    protected void processFocusEvent(FocusEvent e) {
5401        FocusListener listener = focusListener;
5402        if (listener != null) {
5403            int id = e.getID();
5404            switch(id) {
5405              case FocusEvent.FOCUS_GAINED:
5406                  listener.focusGained(e);
5407                  break;
5408              case FocusEvent.FOCUS_LOST:
5409                  listener.focusLost(e);
5410                  break;
5411            }
5412        }
5413    }
5414
5415    /**
5416     * Processes key events occurring on this component by
5417     * dispatching them to any registered
5418     * <code>KeyListener</code> objects.
5419     * <p>
5420     * This method is not called unless key events are
5421     * enabled for this component. Key events are enabled
5422     * when one of the following occurs:
5423     * <p><ul>
5424     * <li>A <code>KeyListener</code> object is registered
5425     * via <code>addKeyListener</code>.
5426     * <li>Key events are enabled via <code>enableEvents</code>.
5427     * </ul>
5428     *
5429     * <p>
5430     * If key events are enabled for a <code>Component</code>,
5431     * the current <code>KeyboardFocusManager</code> determines
5432     * whether or not a key event should be dispatched to
5433     * registered <code>KeyListener</code> objects. The
5434     * <code>DefaultKeyboardFocusManager</code> will not dispatch
5435     * key events to a <code>Component</code> that is not the focus
5436     * owner or is not showing.
5437     * <p>
5438     * As of J2SE 1.4, <code>KeyEvent</code>s are redirected to
5439     * the focus owner. Please see the
5440     * <a HREF="doc-files/FocusSpec.html">Focus Specification</a>
5441     * for further information.
5442     * <p>
5443     * Calling a <code>Component</code>'s <code>dispatchEvent</code>
5444     * method with a <code>KeyEvent</code> as the argument will
5445     * result in a call to the <code>Component</code>'s
5446     * <code>processKeyEvent</code> method regardless of the
5447     * current <code>KeyboardFocusManager</code> as long as the
5448     * component is showing, focused, and enabled, and key events
5449     * are enabled on it.
5450     * <p>If the event parameter is <code>null</code>
5451     * the behavior is unspecified and may result in an
5452     * exception.
5453     *
5454     * @param e the key event
5455     * @see java.awt.event.KeyEvent
5456     * @see java.awt.event.KeyListener
5457     * @see java.awt.KeyboardFocusManager
5458     * @see java.awt.DefaultKeyboardFocusManager
5459     * @see #processEvent
5460     * @see #dispatchEvent
5461     * @see #addKeyListener
5462     * @see #enableEvents
5463     * @see #isShowing
5464     * @since JDK1.1
5465     */

5466    protected void processKeyEvent(KeyEvent e) {
5467        KeyListener listener = keyListener;
5468        if (listener != null) {
5469            int id = e.getID();
5470            switch(id) {
5471              case KeyEvent.KEY_TYPED:
5472                  listener.keyTyped(e);
5473                  break;
5474              case KeyEvent.KEY_PRESSED:
5475                  listener.keyPressed(e);
5476                  break;
5477              case KeyEvent.KEY_RELEASED:
5478                  listener.keyReleased(e);
5479                  break;
5480            }
5481        }
5482    }
5483
5484    /**
5485     * Processes mouse events occurring on this component by
5486     * dispatching them to any registered
5487     * <code>MouseListener</code> objects.
5488     * <p>
5489     * This method is not called unless mouse events are
5490     * enabled for this component. Mouse events are enabled
5491     * when one of the following occurs:
5492     * <p><ul>
5493     * <li>A <code>MouseListener</code> object is registered
5494     * via <code>addMouseListener</code>.
5495     * <li>Mouse events are enabled via <code>enableEvents</code>.
5496     * </ul>
5497     * <p>Note that if the event parameter is <code>null</code>
5498     * the behavior is unspecified and may result in an
5499     * exception.
5500     *
5501     * @param e the mouse event
5502     * @see java.awt.event.MouseEvent
5503     * @see java.awt.event.MouseListener
5504     * @see #addMouseListener
5505     * @see #enableEvents
5506     * @since JDK1.1
5507     */

5508    protected void processMouseEvent(MouseEvent e) {
5509        MouseListener listener = mouseListener;
5510        if (listener != null) {
5511            int id = e.getID();
5512            switch(id) {
5513              case MouseEvent.MOUSE_PRESSED:
5514                  listener.mousePressed(e);
5515                  break;
5516              case MouseEvent.MOUSE_RELEASED:
5517                  listener.mouseReleased(e);
5518                  break;
5519              case MouseEvent.MOUSE_CLICKED:
5520                  listener.mouseClicked(e);
5521                  break;
5522              case MouseEvent.MOUSE_EXITED:
5523                  listener.mouseExited(e);
5524                  break;
5525              case MouseEvent.MOUSE_ENTERED:
5526                  listener.mouseEntered(e);
5527                  break;
5528            }
5529        }
5530    }
5531
5532    /**
5533     * Processes mouse motion events occurring on this component by
5534     * dispatching them to any registered
5535     * <code>MouseMotionListener</code> objects.
5536     * <p>
5537     * This method is not called unless mouse motion events are
5538     * enabled for this component. Mouse motion events are enabled
5539     * when one of the following occurs:
5540     * <p><ul>
5541     * <li>A <code>MouseMotionListener</code> object is registered
5542     * via <code>addMouseMotionListener</code>.
5543     * <li>Mouse motion events are enabled via <code>enableEvents</code>.
5544     * </ul>
5545     * <p>Note that if the event parameter is <code>null</code>
5546     * the behavior is unspecified and may result in an
5547     * exception.
5548     *
5549     * @param e the mouse motion event
5550     * @see java.awt.event.MouseEvent
5551     * @see java.awt.event.MouseMotionListener
5552     * @see #addMouseMotionListener
5553     * @see #enableEvents
5554     * @since JDK1.1
5555     */

5556    protected void processMouseMotionEvent(MouseEvent e) {
5557        MouseMotionListener listener = mouseMotionListener;
5558        if (listener != null) {
5559            int id = e.getID();
5560            switch(id) {
5561              case MouseEvent.MOUSE_MOVED:
5562                  listener.mouseMoved(e);
5563                  break;
5564              case MouseEvent.MOUSE_DRAGGED:
5565                  listener.mouseDragged(e);
5566                  break;
5567            }
5568        }
5569    }
5570
5571    /**
5572     * Processes mouse wheel events occurring on this component by
5573     * dispatching them to any registered
5574     * <code>MouseWheelListener</code> objects.
5575     * <p>
5576     * This method is not called unless mouse wheel events are
5577     * enabled for this component. Mouse wheel events are enabled
5578     * when one of the following occurs:
5579     * <p><ul>
5580     * <li>A <code>MouseWheelListener</code> object is registered
5581     * via <code>addMouseWheelListener</code>.
5582     * <li>Mouse wheel events are enabled via <code>enableEvents</code>.
5583     * </ul>
5584     * <p>
5585     * For information on how mouse wheel events are dispatched, see
5586     * the class description for {@link MouseWheelEvent}.
5587     * <p>
5588     * Note that if the event parameter is <code>null</code>
5589     * the behavior is unspecified and may result in an
5590     * exception.
5591     *
5592     * @param e the mouse wheel event
5593     * @see java.awt.event.MouseWheelEvent
5594     * @see java.awt.event.MouseWheelListener
5595     * @see #addMouseWheelListener
5596     * @see #enableEvents
5597     * @since 1.4
5598     */

5599    protected void processMouseWheelEvent(MouseWheelEvent e) {
5600        MouseWheelListener listener = mouseWheelListener;
5601        if (listener != null) {
5602            int id = e.getID();
5603            switch(id) {
5604              case MouseEvent.MOUSE_WHEEL:
5605                  listener.mouseWheelMoved(e);
5606                  break;
5607            }
5608        }
5609    }
5610
5611    boolean postsOldMouseEvents() {
5612        return false;
5613    }
5614
5615    /**
5616     * Processes input method events occurring on this component by
5617     * dispatching them to any registered
5618     * <code>InputMethodListener</code> objects.
5619     * <p>
5620     * This method is not called unless input method events
5621     * are enabled for this component. Input method events are enabled
5622     * when one of the following occurs:
5623     * <p><ul>
5624     * <li>An <code>InputMethodListener</code> object is registered
5625     * via <code>addInputMethodListener</code>.
5626     * <li>Input method events are enabled via <code>enableEvents</code>.
5627     * </ul>
5628     * <p>Note that if the event parameter is <code>null</code>
5629     * the behavior is unspecified and may result in an
5630     * exception.
5631     *
5632     * @param e the input method event
5633     * @see java.awt.event.InputMethodEvent
5634     * @see java.awt.event.InputMethodListener
5635     * @see #addInputMethodListener
5636     * @see #enableEvents
5637     * @since 1.2
5638     */

5639    protected void processInputMethodEvent(InputMethodEvent JavaDoc e) {
5640        InputMethodListener JavaDoc listener = inputMethodListener;
5641        if (listener != null) {
5642            int id = e.getID();
5643            switch (id) {
5644              case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5645                  listener.inputMethodTextChanged(e);
5646                  break;
5647              case InputMethodEvent.CARET_POSITION_CHANGED:
5648                  listener.caretPositionChanged(e);
5649                  break;
5650            }
5651        }
5652    }
5653
5654    /**
5655     * Processes hierarchy events occurring on this component by
5656     * dispatching them to any registered
5657     * <code>HierarchyListener</code> objects.
5658     * <p>
5659     * This method is not called unless hierarchy events
5660     * are enabled for this component. Hierarchy events are enabled
5661     * when one of the following occurs:
5662     * <p><ul>
5663     * <li>An <code>HierarchyListener</code> object is registered
5664     * via <code>addHierarchyListener</code>.
5665     * <li>Hierarchy events are enabled via <code>enableEvents</code>.
5666     * </ul>
5667     * <p>Note that if the event parameter is <code>null</code>
5668     * the behavior is unspecified and may result in an
5669     * exception.
5670     *
5671     * @param e the hierarchy event
5672     * @see java.awt.event.HierarchyEvent
5673     * @see java.awt.event.HierarchyListener
5674     * @see #addHierarchyListener
5675     * @see #enableEvents
5676     * @since 1.3
5677     */

5678    protected void processHierarchyEvent(HierarchyEvent e) {
5679        HierarchyListener listener = hierarchyListener;
5680        if (listener != null) {
5681            int id = e.getID();
5682            switch (id) {
5683              case HierarchyEvent.HIERARCHY_CHANGED:
5684                  listener.hierarchyChanged(e);
5685                  break;
5686            }
5687        }
5688    }
5689
5690    /**
5691     * Processes hierarchy bounds events occurring on this component by
5692     * dispatching them to any registered
5693     * <code>HierarchyBoundsListener</code> objects.
5694     * <p>
5695     * This method is not called unless hierarchy bounds events
5696     * are enabled for this component. Hierarchy bounds events are enabled
5697     * when one of the following occurs:
5698     * <p><ul>
5699     * <li>An <code>HierarchyBoundsListener</code> object is registered
5700     * via <code>addHierarchyBoundsListener</code>.
5701     * <li>Hierarchy bounds events are enabled via <code>enableEvents</code>.
5702     * </ul>
5703     * <p>Note that if the event parameter is <code>null</code>
5704     * the behavior is unspecified and may result in an
5705     * exception.
5706     *
5707     * @param e the hierarchy event
5708     * @see java.awt.event.HierarchyEvent
5709     * @see java.awt.event.HierarchyBoundsListener
5710     * @see #addHierarchyBoundsListener
5711     * @see #enableEvents
5712     * @since 1.3
5713     */

5714    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
5715        HierarchyBoundsListener listener = hierarchyBoundsListener;
5716        if (listener != null) {
5717            int id = e.getID();
5718            switch (id) {
5719              case HierarchyEvent.ANCESTOR_MOVED:
5720                  listener.ancestorMoved(e);
5721                  break;
5722              case HierarchyEvent.ANCESTOR_RESIZED:
5723                  listener.ancestorResized(e);
5724                  break;
5725            }
5726        }
5727    }
5728
5729    /**
5730     * @deprecated As of JDK version 1.1
5731     * replaced by processEvent(AWTEvent).
5732     */

5733    @Deprecated JavaDoc
5734    public boolean handleEvent(Event JavaDoc evt) {
5735        switch (evt.id) {
5736          case Event.MOUSE_ENTER:
5737              return mouseEnter(evt, evt.x, evt.y);
5738
5739          case Event.MOUSE_EXIT:
5740              return mouseExit(evt, evt.x, evt.y);
5741
5742          case Event.MOUSE_MOVE:
5743              return mouseMove(evt, evt.x, evt.y);
5744
5745          case Event.MOUSE_DOWN:
5746              return mouseDown(evt, evt.x, evt.y);
5747
5748          case Event.MOUSE_DRAG:
5749              return mouseDrag(evt, evt.x, evt.y);
5750
5751          case Event.MOUSE_UP:
5752              return mouseUp(evt, evt.x, evt.y);
5753
5754          case Event.KEY_PRESS:
5755          case Event.KEY_ACTION:
5756              return keyDown(evt, evt.key);
5757
5758          case Event.KEY_RELEASE:
5759          case Event.KEY_ACTION_RELEASE:
5760              return keyUp(evt, evt.key);
5761
5762          case Event.ACTION_EVENT:
5763              return action(evt, evt.arg);
5764          case Event.GOT_FOCUS:
5765              return gotFocus(evt, evt.arg);
5766          case Event.LOST_FOCUS:
5767              return lostFocus(evt, evt.arg);
5768        }
5769        return false;
5770    }
5771
5772    /**
5773     * @deprecated As of JDK version 1.1,
5774     * replaced by processMouseEvent(MouseEvent).
5775     */

5776    @Deprecated JavaDoc
5777    public boolean mouseDown(Event JavaDoc evt, int x, int y) {
5778        return false;
5779    }
5780
5781    /**
5782     * @deprecated As of JDK version 1.1,
5783     * replaced by processMouseMotionEvent(MouseEvent).
5784     */

5785    @Deprecated JavaDoc
5786    public boolean mouseDrag(Event JavaDoc evt, int x, int y) {
5787        return false;
5788    }
5789
5790    /**
5791     * @deprecated As of JDK version 1.1,
5792     * replaced by processMouseEvent(MouseEvent).
5793     */

5794    @Deprecated JavaDoc
5795    public boolean mouseUp(Event JavaDoc evt, int x, int y) {
5796        return false;
5797    }
5798
5799    /**
5800     * @deprecated As of JDK version 1.1,
5801     * replaced by processMouseMotionEvent(MouseEvent).
5802     */

5803    @Deprecated JavaDoc
5804    public boolean mouseMove(Event JavaDoc evt, int x, int y) {
5805        return false;
5806    }
5807
5808    /**
5809     * @deprecated As of JDK version 1.1,
5810     * replaced by processMouseEvent(MouseEvent).
5811     */

5812    @Deprecated JavaDoc
5813    public boolean mouseEnter(Event JavaDoc evt, int x, int y) {
5814        return false;
5815    }
5816
5817    /**
5818     * @deprecated As of JDK version 1.1,
5819     * replaced by processMouseEvent(MouseEvent).
5820     */

5821    @Deprecated JavaDoc
5822    public boolean mouseExit(Event JavaDoc evt, int x, int y) {
5823        return false;
5824    }
5825
5826    /**
5827     * @deprecated As of JDK version 1.1,
5828     * replaced by processKeyEvent(KeyEvent).
5829     */

5830    @Deprecated JavaDoc
5831    public boolean keyDown(Event JavaDoc evt, int key) {
5832        return false;
5833    }
5834
5835    /**
5836     * @deprecated As of JDK version 1.1,
5837     * replaced by processKeyEvent(KeyEvent).
5838     */

5839    @Deprecated JavaDoc
5840    public boolean keyUp(Event JavaDoc evt, int key) {
5841        return false;
5842    }
5843
5844    /**
5845     * @deprecated As of JDK version 1.1,
5846     * should register this component as ActionListener on component
5847     * which fires action events.
5848     */

5849    @Deprecated JavaDoc
5850    public boolean action(Event JavaDoc evt, Object JavaDoc what) {
5851        return false;
5852    }
5853
5854    /**
5855     * Makes this <code>Component</code> displayable by connecting it to a
5856     * native screen resource.
5857     * This method is called internally by the toolkit and should
5858     * not be called directly by programs.
5859     * @see #isDisplayable
5860     * @see #removeNotify
5861     * @since JDK1.0
5862     */

5863    public void addNotify() {
5864        synchronized (getTreeLock()) {
5865            ComponentPeer peer = this.peer;
5866            if (peer == null || peer instanceof LightweightPeer){
5867                if (peer == null) {
5868                    // Update both the Component's peer variable and the local
5869
// variable we use for thread safety.
5870
this.peer = peer = getToolkit().createComponent(this);
5871                }
5872
5873                // This is a lightweight component which means it won't be
5874
// able to get window-related events by itself. If any
5875
// have been enabled, then the nearest native container must
5876
// be enabled.
5877
if (parent != null) {
5878                    long mask = 0;
5879                    if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
5880                        mask |= AWTEvent.MOUSE_EVENT_MASK;
5881                    }
5882                    if ((mouseMotionListener != null) ||
5883                        ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
5884                        mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
5885                    }
5886                    if ((mouseWheelListener != null ) ||
5887                        ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
5888                        mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
5889                    }
5890                    if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
5891                        mask |= AWTEvent.FOCUS_EVENT_MASK;
5892                    }
5893                    if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
5894                        mask |= AWTEvent.KEY_EVENT_MASK;
5895                    }
5896                    if (mask != 0) {
5897                        parent.proxyEnableEvents(mask);
5898                    }
5899                }
5900            } else {
5901                // It's native. If the parent is lightweight it
5902
// will need some help.
5903
Container JavaDoc parent = this.parent;
5904                if (parent != null && parent.peer instanceof LightweightPeer) {
5905                    nativeInLightFixer = new NativeInLightFixer();
5906                }
5907            }
5908            invalidate();
5909
5910            int npopups = (popups != null? popups.size() : 0);
5911            for (int i = 0 ; i < npopups ; i++) {
5912                PopupMenu JavaDoc popup = (PopupMenu JavaDoc)popups.elementAt(i);
5913                popup.addNotify();
5914            }
5915            
5916            if (dropTarget != null) dropTarget.addNotify(peer);
5917
5918            peerFont = getFont();
5919
5920            // Update stacking order
5921
if (parent != null && parent.peer != null) {
5922                ContainerPeer parentContPeer = (ContainerPeer) parent.peer;
5923                // if our parent is lightweight and we are not
5924
// we should call restack on nearest heavyweight
5925
// container.
5926
if (parentContPeer instanceof LightweightPeer
5927                    && ! (peer instanceof LightweightPeer))
5928                {
5929                    Container JavaDoc hwParent = getNativeContainer();
5930                    if (hwParent != null && hwParent.peer != null) {
5931                        parentContPeer = (ContainerPeer) hwParent.peer;
5932                    }
5933                }
5934                if (parentContPeer.isRestackSupported()) {
5935                    parentContPeer.restack();
5936                }
5937            }
5938
5939            if (hierarchyListener != null ||
5940                (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
5941                Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
5942                HierarchyEvent e =
5943                    new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
5944                                       this, parent,
5945                                       HierarchyEvent.DISPLAYABILITY_CHANGED |
5946                                       ((isRecursivelyVisible())
5947                                        ? HierarchyEvent.SHOWING_CHANGED
5948                                        : 0));
5949                dispatchEvent(e);
5950            }
5951        }
5952    }
5953
5954    /**
5955     * Makes this <code>Component</code> undisplayable by destroying it native
5956     * screen resource.
5957     * <p>
5958     * This method is called by the toolkit internally and should
5959     * not be called directly by programs. Code overriding
5960     * this method should call <code>super.removeNotify</code> as
5961     * the first line of the overriding method.
5962     *
5963     * @see #isDisplayable
5964     * @see #addNotify
5965     * @since JDK1.0
5966     */

5967    public void removeNotify() {
5968        KeyboardFocusManager.clearMostRecentFocusOwner(this);
5969        if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
5970            getPermanentFocusOwner() == this)
5971        {
5972            KeyboardFocusManager.getCurrentKeyboardFocusManager().
5973                setGlobalPermanentFocusOwner(null);
5974        }
5975
5976        synchronized (getTreeLock()) {
5977            if (isFocusOwner() && !nextFocusHelper()) {
5978                KeyboardFocusManager.getCurrentKeyboardFocusManager().
5979                    clearGlobalFocusOwner();
5980            }
5981
5982            int npopups = (popups != null? popups.size() : 0);
5983            for (int i = 0 ; i < npopups ; i++) {
5984                PopupMenu JavaDoc popup = (PopupMenu JavaDoc)popups.elementAt(i);
5985                popup.removeNotify();
5986            }
5987            // If there is any input context for this component, notify
5988
// that this component is being removed. (This has to be done
5989
// before hiding peer.)
5990
if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
5991                InputContext JavaDoc inputContext = getInputContext();
5992                if (inputContext != null) {
5993                    inputContext.removeNotify(this);
5994                }
5995            }
5996
5997            ComponentPeer p = peer;
5998            if (p != null) {
5999
6000                if (bufferStrategy instanceof FlipBufferStrategy) {
6001                    ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
6002                }
6003
6004                if (dropTarget != null) dropTarget.removeNotify(peer);
6005
6006                // Hide peer first to stop system events such as cursor moves.
6007
if (visible) {
6008                    p.hide();
6009                }
6010
6011                peer = null; // Stop peer updates.
6012
peerFont = null;
6013
6014                Toolkit.getEventQueue().removeSourceEvents(this, false);
6015                KeyboardFocusManager.getCurrentKeyboardFocusManager().
6016                    discardKeyEvents(this);
6017
6018                p.dispose();
6019            }
6020
6021            if (hierarchyListener != null ||
6022                (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
6023                Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6024                HierarchyEvent e =
6025                    new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
6026                                       this, parent,
6027                                       HierarchyEvent.DISPLAYABILITY_CHANGED |
6028                                       ((isRecursivelyVisible())
6029                                        ? HierarchyEvent.SHOWING_CHANGED
6030                                        : 0));
6031                dispatchEvent(e);
6032            }
6033        }
6034    }
6035
6036    /**
6037     * @deprecated As of JDK version 1.1,
6038     * replaced by processFocusEvent(FocusEvent).
6039     */

6040    @Deprecated JavaDoc
6041    public boolean gotFocus(Event JavaDoc evt, Object JavaDoc what) {
6042        return false;
6043    }
6044
6045    /**
6046     * @deprecated As of JDK version 1.1,
6047     * replaced by processFocusEvent(FocusEvent).
6048     */

6049    @Deprecated JavaDoc
6050    public boolean lostFocus(Event JavaDoc evt, Object JavaDoc what) {
6051        return false;
6052    }
6053
6054    /**
6055     * Returns whether this <code>Component</code> can become the focus
6056     * owner.
6057     *
6058     * @return <code>true</code> if this <code>Component</code> is
6059     * focusable; <code>false</code> otherwise
6060     * @see #setFocusable
6061     * @since JDK1.1
6062     * @deprecated As of 1.4, replaced by <code>isFocusable()</code>.
6063     */

6064    @Deprecated JavaDoc
6065    public boolean isFocusTraversable() {
6066        if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
6067            isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
6068        }
6069        return focusable;
6070    }
6071  
6072    /**
6073     * Returns whether this Component can be focused.
6074     *
6075     * @return <code>true</code> if this Component is focusable;
6076     * <code>false</code> otherwise.
6077     * @see #setFocusable
6078     * @since 1.4
6079     */

6080    public boolean isFocusable() {
6081        return isFocusTraversable();
6082    }
6083
6084    /**
6085     * Sets the focusable state of this Component to the specified value. This
6086     * value overrides the Component's default focusability.
6087     *
6088     * @param focusable indicates whether this Component is focusable
6089     * @see #isFocusable
6090     * @since 1.4
6091     * @beaninfo
6092     * bound: true
6093     */

6094    public void setFocusable(boolean focusable) {
6095        boolean oldFocusable;
6096        synchronized (this) {
6097            oldFocusable = this.focusable;
6098            this.focusable = focusable;
6099        }
6100        isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
6101 
6102        firePropertyChange("focusable", oldFocusable, focusable);
6103        if (oldFocusable && !focusable) {
6104            if (isFocusOwner()) {
6105                autoTransferFocus(true);
6106            }
6107            KeyboardFocusManager.clearMostRecentFocusOwner(this);
6108        }
6109    }
6110
6111    final boolean isFocusTraversableOverridden() {
6112        return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
6113    }
6114
6115    /**
6116     * Sets the focus traversal keys for a given traversal operation for this
6117     * Component.
6118     * <p>
6119     * The default values for a Component's focus traversal keys are
6120     * implementation-dependent. Sun recommends that all implementations for a
6121     * particular native platform use the same default values. The
6122     * recommendations for Windows and Unix are listed below. These
6123     * recommendations are used in the Sun AWT implementations.
6124     *
6125     * <table border=1 summary="Recommended default values for a Component's focus traversal keys">
6126     * <tr>
6127     * <th>Identifier</th>
6128     * <th>Meaning</th>
6129     * <th>Default</th>
6130     * </tr>
6131     * <tr>
6132     * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
6133     * <td>Normal forward keyboard traversal</td>
6134     * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
6135     * </tr>
6136     * <tr>
6137     * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
6138     * <td>Normal reverse keyboard traversal</td>
6139     * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
6140     * </tr>
6141     * <tr>
6142     * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
6143     * <td>Go up one focus traversal cycle</td>
6144     * <td>none</td>
6145     * </tr>
6146     * </table>
6147     *
6148     * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
6149     * recommended.
6150     * <p>
6151     * Using the AWTKeyStroke API, client code can specify on which of two
6152     * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
6153     * operation will occur. Regardless of which KeyEvent is specified,
6154     * however, all KeyEvents related to the focus traversal key, including the
6155     * associated KEY_TYPED event, will be consumed, and will not be dispatched
6156     * to any Component. It is a runtime error to specify a KEY_TYPED event as
6157     * mapping to a focus traversal operation, or to map the same event to
6158     * multiple default focus traversal operations.
6159     * <p>
6160     * If a value of null is specified for the Set, this Component inherits the
6161     * Set from its parent. If all ancestors of this Component have null
6162     * specified for the Set, then the current KeyboardFocusManager's default
6163     * Set is used.
6164     *
6165     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6166     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6167     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6168     * @param keystrokes the Set of AWTKeyStroke for the specified operation
6169     * @see #getFocusTraversalKeys
6170     * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6171     * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6172     * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6173     * @throws IllegalArgumentException if id is not one of
6174     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6175     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6176     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
6177     * contains null, or if any Object in keystrokes is not an
6178     * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
6179     * or if any keystroke already maps to another focus traversal
6180     * operation for this Component
6181     * @since 1.4
6182     * @beaninfo
6183     * bound: true
6184     */

6185    public void setFocusTraversalKeys(int id,
6186                      Set JavaDoc<? extends AWTKeyStroke JavaDoc> keystrokes)
6187    {
6188        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6189            throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
6190        }
6191      
6192        setFocusTraversalKeys_NoIDCheck(id, keystrokes);
6193    }
6194
6195    /**
6196     * Returns the Set of focus traversal keys for a given traversal operation
6197     * for this Component. (See
6198     * <code>setFocusTraversalKeys</code> for a full description of each key.)
6199     * <p>
6200     * If a Set of traversal keys has not been explicitly defined for this
6201     * Component, then this Component's parent's Set is returned. If no Set
6202     * has been explicitly defined for any of this Component's ancestors, then
6203     * the current KeyboardFocusManager's default Set is returned.
6204     *
6205     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6206     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6207     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6208     * @return the Set of AWTKeyStrokes for the specified operation. The Set
6209     * will be unmodifiable, and may be empty. null will never be
6210     * returned.
6211     * @see #setFocusTraversalKeys
6212     * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
6213     * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
6214     * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
6215     * @throws IllegalArgumentException if id is not one of
6216     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6217     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6218     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6219     * @since 1.4
6220     */

6221    public Set JavaDoc<AWTKeyStroke JavaDoc> getFocusTraversalKeys(int id) {
6222        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6223            throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
6224        }
6225 
6226        return getFocusTraversalKeys_NoIDCheck(id);
6227    }
6228
6229    // We define these methods so that Container does not need to repeat this
6230
// code. Container cannot call super.<method> because Container allows
6231
// DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method
6232
// would erroneously generate an IllegalArgumentException for
6233
// DOWN_CYCLE_TRAVERSAL_KEY.
6234
final void setFocusTraversalKeys_NoIDCheck(int id, Set JavaDoc keystrokes) {
6235        Set JavaDoc oldKeys;
6236
6237        synchronized (this) {
6238            if (focusTraversalKeys == null) {
6239                initializeFocusTraversalKeys();
6240            }
6241
6242            if (keystrokes != null) {
6243                for (Iterator JavaDoc iter = keystrokes.iterator(); iter.hasNext(); ) {
6244                    Object JavaDoc obj = iter.next();
6245
6246                    if (obj == null) {
6247                        throw new IllegalArgumentException JavaDoc("cannot set null focus traversal key");
6248                    }
6249
6250                    // Generates a ClassCastException if the element is not an
6251
// AWTKeyStroke. This is desirable.
6252
AWTKeyStroke JavaDoc keystroke = (AWTKeyStroke JavaDoc)obj;
6253
6254                    if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
6255                        throw new IllegalArgumentException JavaDoc("focus traversal keys cannot map to KEY_TYPED events");
6256                    }
6257
6258                    for (int i = 0; i < focusTraversalKeys.length; i++) {
6259                        if (i == id) {
6260                            continue;
6261                        }
6262                        
6263                        if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke))
6264                        {
6265                            throw new IllegalArgumentException JavaDoc("focus traversal keys must be unique for a Component");
6266                        }
6267                    }
6268                }
6269            }
6270
6271            oldKeys = focusTraversalKeys[id];
6272            focusTraversalKeys[id] = (keystrokes != null)
6273                ? Collections.unmodifiableSet(new HashSet JavaDoc(keystrokes))
6274                : null;
6275        }
6276
6277        firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,
6278                           keystrokes);
6279    }
6280    final Set JavaDoc getFocusTraversalKeys_NoIDCheck(int id) {
6281        // Okay to return Set directly because it is an unmodifiable view
6282
Set JavaDoc keystrokes = (focusTraversalKeys != null)
6283            ? focusTraversalKeys[id]
6284            : null;
6285        
6286        if (keystrokes != null) {
6287            return keystrokes;
6288        } else {
6289            Container JavaDoc parent = this.parent;
6290            if (parent != null) {
6291                return parent.getFocusTraversalKeys(id);
6292            } else {
6293                return KeyboardFocusManager.getCurrentKeyboardFocusManager().
6294                    getDefaultFocusTraversalKeys(id);
6295            }
6296        }
6297    }
6298 
6299    /**
6300     * Returns whether the Set of focus traversal keys for the given focus
6301     * traversal operation has been explicitly defined for this Component. If
6302     * this method returns <code>false</code>, this Component is inheriting the
6303     * Set from an ancestor, or from the current KeyboardFocusManager.
6304     *
6305     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6306     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6307     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6308     * @return <code>true</code> if the the Set of focus traversal keys for the
6309     * given focus traversal operation has been explicitly defined for
6310     * this Component; <code>false</code> otherwise.
6311     * @throws IllegalArgumentException if id is not one of
6312     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
6313     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
6314     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
6315     * @since 1.4
6316     */

6317    public boolean areFocusTraversalKeysSet(int id) {
6318        if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
6319            throw new IllegalArgumentException JavaDoc("invalid focus traversal key identifier");
6320        }
6321 
6322        return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
6323    }
6324
6325    /**
6326     * Sets whether focus traversal keys are enabled for this Component.
6327     * Components for which focus traversal keys are disabled receive key
6328     * events for focus traversal keys. Components for which focus traversal
6329     * keys are enabled do not see these events; instead, the events are
6330     * automatically converted to traversal operations.
6331     *
6332     * @param focusTraversalKeysEnabled whether focus traversal keys are
6333     * enabled for this Component
6334     * @see #getFocusTraversalKeysEnabled
6335     * @see #setFocusTraversalKeys
6336     * @see #getFocusTraversalKeys
6337     * @since 1.4
6338     * @beaninfo
6339     * bound: true
6340     */

6341    public void setFocusTraversalKeysEnabled(boolean
6342                                             focusTraversalKeysEnabled) {
6343        boolean oldFocusTraversalKeysEnabled;
6344        synchronized (this) {
6345            oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled;
6346            this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
6347        }
6348        firePropertyChange("focusTraversalKeysEnabled",
6349                           oldFocusTraversalKeysEnabled,
6350                           focusTraversalKeysEnabled);
6351    }
6352
6353    /**
6354     * Returns whether focus traversal keys are enabled for this Component.
6355     * Components for which focus traversal keys are disabled receive key
6356     * events for focus traversal keys. Components for which focus traversal
6357     * keys are enabled do not see these events; instead, the events are
6358     * automatically converted to traversal operations.
6359     *
6360     * @return whether focus traversal keys are enabled for this Component
6361     * @see #setFocusTraversalKeysEnabled
6362     * @see #setFocusTraversalKeys
6363     * @see #getFocusTraversalKeys
6364     * @since 1.4
6365     */

6366    public boolean getFocusTraversalKeysEnabled() {
6367        return focusTraversalKeysEnabled;
6368    }
6369
6370    /**
6371     * Requests that this Component get the input focus, and that this
6372     * Component's top-level ancestor become the focused Window. This component
6373     * must be displayable, visible, and focusable for the request to be
6374     * granted. Every effort will be made to honor the request; however, in
6375     * some cases it may be impossible to do so. Developers must never assume
6376     * that this Component is the focus owner until this Component receives a
6377     * FOCUS_GAINED event. If this request is denied because this Component's
6378     * top-level Window cannot become the focused Window, the request will be
6379     * remembered and will be granted when the Window is later focused by the
6380     * user.
6381     * <p>
6382     * This method cannot be used to set the focus owner to no Component at
6383     * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
6384     * instead.
6385     * <p>
6386     * Because the focus behavior of this method is platform-dependent,
6387     * developers are strongly encouraged to use
6388     * <code>requestFocusInWindow</code> when possible.
6389     *
6390     * @see #requestFocusInWindow
6391     * @see java.awt.event.FocusEvent
6392     * @see #addFocusListener
6393     * @see #isFocusable
6394     * @see #isDisplayable
6395     * @see KeyboardFocusManager#clearGlobalFocusOwner
6396     * @since JDK1.0
6397     */

6398    public void requestFocus() {
6399        requestFocusHelper(false, true);
6400    }
6401
6402    /**
6403     * Requests that this <code>Component</code> get the input focus,
6404     * and that this <code>Component</code>'s top-level ancestor
6405     * become the focused <code>Window</code>. This component
6406     * must be displayable, visible, and focusable for the request to be
6407     * granted. Every effort will be made to honor the request; however, in
6408     * some cases it may be impossible to do so. Developers must never assume
6409     * that this component is the focus owner until this component receives a
6410     * FOCUS_GAINED event. If this request is denied because this component's
6411     * top-level window cannot become the focused window, the request will be
6412     * remembered and will be granted when the window is later focused by the
6413     * user.
6414     * <p>
6415     * This method returns a boolean value. If <code>false</code> is returned,
6416     * the request is <b>guaranteed to fail</b>. If <code>true</code> is
6417     * returned, the request will succeed <b>unless</b> it is vetoed, or an
6418     * extraordinary event, such as disposal of the component's peer, occurs
6419     * before the request can be granted by the native windowing system. Again,
6420     * while a return value of <code>true</code> indicates that the request is
6421     * likely to succeed, developers must never assume that this component is
6422     * the focus owner until this component receives a FOCUS_GAINED event.
6423     * <p>
6424     * This method cannot be used to set the focus owner to no component at
6425     * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
6426     * instead.
6427     * <p>
6428     * Because the focus behavior of this method is platform-dependent,
6429     * developers are strongly encouraged to use
6430     * <code>requestFocusInWindow</code> when possible.
6431     * <p>
6432     * Every effort will be made to ensure that <code>FocusEvent</code>s
6433     * generated as a
6434     * result of this request will have the specified temporary value. However,
6435     * because specifying an arbitrary temporary state may not be implementable
6436     * on all native windowing systems, correct behavior for this method can be
6437     * guaranteed only for lightweight <code>Component</code>s.
6438     * This method is not intended
6439     * for general use, but exists instead as a hook for lightweight component
6440     * libraries, such as Swing.
6441     *
6442     * @param temporary true if the focus change is temporary,
6443     * such as when the window loses the focus; for
6444     * more information on temporary focus changes see the
6445     *<a HREF="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
6446     * @return <code>false</code> if the focus change request is guaranteed to
6447     * fail; <code>true</code> if it is likely to succeed
6448     * @see java.awt.event.FocusEvent
6449     * @see #addFocusListener
6450     * @see #isFocusable
6451     * @see #isDisplayable
6452     * @see KeyboardFocusManager#clearGlobalFocusOwner
6453     * @since 1.4
6454     */

6455    protected boolean requestFocus(boolean temporary) {
6456        return requestFocusHelper(temporary, true);
6457    }
6458
6459    /**
6460     * Requests that this Component get the input focus, if this Component's
6461     * top-level ancestor is already the focused Window. This component must be
6462     * displayable, visible, and focusable for the request to be granted. Every
6463     * effort will be made to honor the request; however, in some cases it may
6464     * be impossible to do so. Developers must never assume that this Component
6465     * is the focus owner until this Component receives a FOCUS_GAINED event.
6466     * <p>
6467     * This method returns a boolean value. If <code>false</code> is returned,
6468     * the request is <b>guaranteed to fail</b>. If <code>true</code> is
6469     * returned, the request will succeed <b>unless</b> it is vetoed, or an
6470     * extraordinary event, such as disposal of the Component's peer, occurs
6471     * before the request can be granted by the native windowing system. Again,
6472     * while a return value of <code>true</code> indicates that the request is
6473     * likely to succeed, developers must never assume that this Component is
6474     * the focus owner until this Component receives a FOCUS_GAINED event.
6475     * <p>
6476     * This method cannot be used to set the focus owner to no Component at
6477     * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
6478     * instead.
6479     * <p>
6480     * The focus behavior of this method can be implemented uniformly across
6481     * platforms, and thus developers are strongly encouraged to use this
6482     * method over <code>requestFocus</code> when possible. Code which relies
6483     * on <code>requestFocus</code> may exhibit different focus behavior on
6484     * different platforms.
6485     *
6486     * @return <code>false</code> if the focus change request is guaranteed to
6487     * fail; <code>true</code> if it is likely to succeed
6488     * @see #requestFocus
6489     * @see java.awt.event.FocusEvent
6490     * @see #addFocusListener
6491     * @see #isFocusable
6492     * @see #isDisplayable
6493     * @see KeyboardFocusManager#clearGlobalFocusOwner
6494     * @since 1.4
6495     */

6496    public boolean requestFocusInWindow() {
6497        return requestFocusHelper(false, false);
6498    }
6499
6500    /**
6501     * Requests that this <code>Component</code> get the input focus,
6502     * if this <code>Component</code>'s
6503     * top-level ancestor is already the focused <code>Window</code>.
6504     * This component must be
6505     * displayable, visible, and focusable for the request to be granted. Every
6506     * effort will be made to honor the request; however, in some cases it may
6507     * be impossible to do so. Developers must never assume that this component
6508     * is the focus owner until this component receives a FOCUS_GAINED event.
6509     * <p>
6510     * This method returns a boolean value. If <code>false</code> is returned,
6511     * the request is <b>guaranteed to fail</b>. If <code>true</code> is
6512     * returned, the request will succeed <b>unless</b> it is vetoed, or an
6513     * extraordinary event, such as disposal of the component's peer, occurs
6514     * before the request can be granted by the native windowing system. Again,
6515     * while a return value of <code>true</code> indicates that the request is
6516     * likely to succeed, developers must never assume that this component is
6517     * the focus owner until this component receives a FOCUS_GAINED event.
6518     * <p>
6519     * This method cannot be used to set the focus owner to no component at
6520     * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
6521     * instead.
6522     * <p>
6523     * The focus behavior of this method can be implemented uniformly across
6524     * platforms, and thus developers are strongly encouraged to use this
6525     * method over <code>requestFocus</code> when possible. Code which relies
6526     * on <code>requestFocus</code> may exhibit different focus behavior on
6527     * different platforms.
6528     * <p>
6529     * Every effort will be made to ensure that <code>FocusEvent</code>s
6530     * generated as a
6531     * result of this request will have the specified temporary value. However,
6532     * because specifying an arbitrary temporary state may not be implementable
6533     * on all native windowing systems, correct behavior for this method can be
6534     * guaranteed only for lightweight components. This method is not intended
6535     * for general use, but exists instead as a hook for lightweight component
6536     * libraries, such as Swing.
6537     *
6538     * @param temporary true if the focus change is temporary,
6539     * such as when the window loses the focus; for
6540     * more information on temporary focus changes see the
6541     *<a HREF="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
6542     * @return <code>false</code> if the focus change request is guaranteed to
6543     * fail; <code>true</code> if it is likely to succeed
6544     * @see #requestFocus
6545     * @see java.awt.event.FocusEvent
6546     * @see #addFocusListener
6547     * @see #isFocusable
6548     * @see #isDisplayable
6549     * @see KeyboardFocusManager#clearGlobalFocusOwner
6550     * @since 1.4
6551     */

6552    protected boolean requestFocusInWindow(boolean temporary) {
6553        return requestFocusHelper(temporary, false);
6554    }
6555
6556    final boolean requestFocusHelper(boolean temporary,
6557                                     boolean focusedWindowChangeAllowed) {
6558        if (isFocusable() && isVisible()) {
6559            ComponentPeer peer = this.peer;
6560            if (peer != null) {
6561                boolean recursivelyInvisible = false;
6562                Component JavaDoc window = this;
6563                while (!(window instanceof Window JavaDoc)) {
6564                    if (!window.isVisible()) {
6565                        recursivelyInvisible = true;
6566                    }
6567                    window = window.parent;
6568                }
6569                if (window == null || !((Window JavaDoc)window).isFocusableWindow()) {
6570                    focusLog.finest("FAIL 1");
6571                    return false;
6572                }
6573
6574                // Update most-recent map
6575
KeyboardFocusManager.setMostRecentFocusOwner(this);
6576                
6577                if (recursivelyInvisible) {
6578                    focusLog.finest("FAIL 1.5");
6579                    return false;
6580                }
6581
6582                Component JavaDoc heavyweight = (peer instanceof LightweightPeer)
6583                    ? getNativeContainer() : this;
6584                if (heavyweight == null || !heavyweight.isVisible()) {
6585                    focusLog.finest("FAIL 2");
6586                    return false;
6587                }
6588                peer = heavyweight.peer;
6589                if (peer == null) {
6590                    focusLog.finest("FAIL 3");
6591                    return false;
6592                }
6593
6594                // Focus this Component
6595
long time = EventQueue.getMostRecentEventTime();
6596                boolean success = peer.requestFocus
6597                    (this, temporary, focusedWindowChangeAllowed, time);
6598                if (!success) {
6599                    KeyboardFocusManager.getCurrentKeyboardFocusManager
6600                        (appContext).dequeueKeyEvents(time, this);
6601                    focusLog.finest("FAIL 4");
6602                } else {
6603                    if (focusLog.isLoggable(Level.FINEST)) focusLog.finest("Pass for " + this);
6604                }
6605                return success;
6606            }
6607        }
6608        focusLog.finest("FAIL 5");
6609        return false;
6610    }
6611
6612    final void autoTransferFocus(boolean clearOnFailure) {
6613        Component JavaDoc toTest = KeyboardFocusManager.
6614            getCurrentKeyboardFocusManager().getFocusOwner();
6615        if (toTest != this) {
6616            if (toTest != null) {
6617                toTest.autoTransferFocus(clearOnFailure);
6618            }
6619            return;
6620        }
6621
6622        if ( KeyboardFocusManager.hasFocusRequests() ){
6623             return;
6624        }
6625 
6626        // the following code will execute only if this Component is the focus
6627
// owner
6628

6629        if (!(isDisplayable() && isVisible() && isEnabled() && isFocusable())) {
6630            doAutoTransfer(clearOnFailure);
6631            return;
6632        }
6633
6634        toTest = getParent();
6635
6636        while (toTest != null && !(toTest instanceof Window JavaDoc)) {
6637            if (!(toTest.isDisplayable() && toTest.isVisible() &&
6638                  (toTest.isEnabled() || toTest.isLightweight()))) {
6639                doAutoTransfer(clearOnFailure);
6640                return;
6641            }
6642            toTest = toTest.getParent();
6643        }
6644    }
6645    private void doAutoTransfer(boolean clearOnFailure) {
6646        if (clearOnFailure) {
6647            if (!nextFocusHelper()) {
6648                KeyboardFocusManager.getCurrentKeyboardFocusManager().
6649                    clearGlobalFocusOwner();
6650            }
6651        } else {
6652            transferFocus();
6653        }
6654    }
6655  
6656    /**
6657     * Transfers the focus to the next component, as though this Component were
6658     * the focus owner.
6659     * @see #requestFocus()
6660     * @since JDK1.1
6661     */

6662    public void transferFocus() {
6663        nextFocus();
6664    }
6665  
6666    /**
6667     * Returns the Container which is the focus cycle root of this Component's
6668     * focus traversal cycle. Each focus traversal cycle has only a single
6669     * focus cycle root and each Component which is not a Container belongs to
6670     * only a single focus traversal cycle. Containers which are focus cycle
6671     * roots belong to two cycles: one rooted at the Container itself, and one
6672     * rooted at the Container's nearest focus-cycle-root ancestor. For such
6673     * Containers, this method will return the Container's nearest focus-cycle-
6674     * root ancestor.
6675     *
6676     * @return this Component's nearest focus-cycle-root ancestor
6677     * @see Container#isFocusCycleRoot()
6678     * @since 1.4
6679     */

6680    public Container JavaDoc getFocusCycleRootAncestor() {
6681        Container JavaDoc rootAncestor = this.parent;
6682        while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
6683            rootAncestor = rootAncestor.parent;
6684        }
6685        return rootAncestor;
6686    }
6687 
6688    /**
6689     * Returns whether the specified Container is the focus cycle root of this
6690     * Component's focus traversal cycle. Each focus traversal cycle has only
6691     * a single focus cycle root and each Component which is not a Container
6692     * belongs to only a single focus traversal cycle.
6693     *
6694     * @param container the Container to be tested
6695     * @return <code>true</code> if the specified Container is a focus-cycle-
6696     * root of this Component; <code>false</code> otherwise
6697     * @see Container#isFocusCycleRoot()
6698     * @since 1.4
6699     */

6700    public boolean isFocusCycleRoot(Container JavaDoc container) {
6701        Container JavaDoc rootAncestor = getFocusCycleRootAncestor();
6702        return (rootAncestor == container);
6703    }
6704 
6705    /**
6706     * @deprecated As of JDK version 1.1,
6707     * replaced by transferFocus().
6708     */

6709    @Deprecated JavaDoc
6710    public void nextFocus() {
6711        nextFocusHelper();
6712    }
6713  
6714    boolean nextFocusHelper() {
6715        Container JavaDoc rootAncestor = getFocusCycleRootAncestor();
6716        Component JavaDoc comp = this;
6717        while (rootAncestor != null &&
6718               !(rootAncestor.isShowing() &&
6719                 rootAncestor.isFocusable() &&
6720                 rootAncestor.isEnabled()))
6721        {
6722            comp = rootAncestor;
6723            rootAncestor = comp.getFocusCycleRootAncestor();
6724        }
6725        if (rootAncestor != null) {
6726            FocusTraversalPolicy JavaDoc policy =
6727                rootAncestor.getFocusTraversalPolicy();
6728            Component JavaDoc toFocus = policy.getComponentAfter(rootAncestor, comp);
6729            if (toFocus == null) {
6730                toFocus = policy.getDefaultComponent(rootAncestor);
6731            }
6732            if (toFocus != null) {
6733                if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Next component " + toFocus);
6734                boolean res = toFocus.requestFocus(false);
6735                if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Request focus returned " + res);
6736                return res;
6737            }
6738        }
6739        return false;
6740    }
6741
6742    /**
6743     * Transfers the focus to the previous component, as though this Component
6744     * were the focus owner.
6745     * @see #requestFocus()
6746     * @since 1.4
6747     */

6748    public void transferFocusBackward() {
6749        Container JavaDoc rootAncestor = getFocusCycleRootAncestor();
6750        Component JavaDoc comp = this;
6751        while (rootAncestor != null &&
6752               !(rootAncestor.isShowing() &&
6753                 rootAncestor.isFocusable() &&
6754                 rootAncestor.isEnabled()))
6755        {
6756            comp = rootAncestor;
6757            rootAncestor = comp.getFocusCycleRootAncestor();
6758        }
6759        if (rootAncestor != null) {
6760            FocusTraversalPolicy JavaDoc policy =
6761                rootAncestor.getFocusTraversalPolicy();
6762            Component JavaDoc toFocus = policy.getComponentBefore(rootAncestor, comp);
6763            if (toFocus == null) {
6764                toFocus = policy.getDefaultComponent(rootAncestor);
6765            }
6766            if (toFocus != null) {
6767                toFocus.requestFocus();
6768            }
6769        }
6770    }
6771
6772    /**
6773     * Transfers the focus up one focus traversal cycle. Typically, the focus
6774     * owner is set to this Component's focus cycle root, and the current focus
6775     * cycle root is set to the new focus owner's focus cycle root. If,
6776     * however, this Component's focus cycle root is a Window, then the focus
6777     * owner is set to the focus cycle root's default Component to focus, and
6778     * the current focus cycle root is unchanged.
6779     *
6780     * @see #requestFocus()
6781     * @see Container#isFocusCycleRoot()
6782     * @see Container#setFocusCycleRoot(boolean)
6783     * @since 1.4
6784     */

6785    public void transferFocusUpCycle() {
6786        Container JavaDoc rootAncestor;
6787        for (rootAncestor = getFocusCycleRootAncestor();
6788             rootAncestor != null && !(rootAncestor.isShowing() &&
6789                                       rootAncestor.isFocusable() &&
6790                                       rootAncestor.isEnabled());
6791             rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
6792        }
6793        
6794        if (rootAncestor != null) {
6795            Container JavaDoc rootAncestorRootAncestor =
6796                rootAncestor.getFocusCycleRootAncestor();
6797            KeyboardFocusManager.getCurrentKeyboardFocusManager().
6798                setGlobalCurrentFocusCycleRoot(
6799                                               (rootAncestorRootAncestor != null)
6800                                               ? rootAncestorRootAncestor
6801                                               : rootAncestor);
6802            rootAncestor.requestFocus();
6803        } else {
6804            Container JavaDoc window =
6805                (this instanceof Container JavaDoc) ? ((Container JavaDoc)this) : getParent();
6806            while (window != null && !(window instanceof Window JavaDoc)) {
6807                window = window.getParent();
6808            }
6809            if (window != null) {
6810                Component JavaDoc toFocus = window.getFocusTraversalPolicy().
6811                    getDefaultComponent(window);
6812                if (toFocus != null) {
6813                    KeyboardFocusManager.getCurrentKeyboardFocusManager().
6814                        setGlobalCurrentFocusCycleRoot(window);
6815                    toFocus.requestFocus();
6816                }
6817            }
6818        }
6819    }
6820
6821    /**
6822     * Returns <code>true</code> if this <code>Component</code> is the
6823     * focus owner. This method is obsolete, and has been replaced by
6824     * <code>isFocusOwner()</code>.
6825     *
6826     * @return <code>true</code> if this <code>Component</code> is the
6827     * focus owner; <code>false</code> otherwise
6828     * @since 1.2
6829     */

6830    public boolean hasFocus() {
6831        return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
6832                getFocusOwner() == this);
6833    }
6834  
6835    /**
6836     * Returns <code>true</code> if this <code>Component</code> is the
6837     * focus owner.
6838     *
6839     * @return <code>true</code> if this <code>Component</code> is the
6840     * focus owner; <code>false</code> otherwise
6841     * @since 1.4
6842     */

6843    public boolean isFocusOwner() {
6844        return hasFocus();
6845    }
6846
6847    /**
6848     * Adds the specified popup menu to the component.
6849     * @param popup the popup menu to be added to the component.
6850     * @see #remove(MenuComponent)
6851     * @since JDK1.1
6852     */

6853    public synchronized void add(PopupMenu JavaDoc popup) {
6854        if (popup.parent != null) {
6855            popup.parent.remove(popup);
6856        }
6857        if (popups == null) {
6858            popups = new Vector JavaDoc();
6859        }
6860        popups.addElement(popup);
6861        popup.parent = this;
6862
6863        if (peer != null) {
6864            if (popup.peer == null) {
6865                popup.addNotify();
6866            }
6867        }
6868    }
6869
6870    /**
6871     * Removes the specified popup menu from the component.
6872     * @param popup the popup menu to be removed
6873     * @see #add(PopupMenu)
6874     * @since JDK1.1
6875     */

6876    public synchronized void remove(MenuComponent JavaDoc popup) {
6877        if (popups != null) {
6878            int index = popups.indexOf(popup);
6879            if (index >= 0) {
6880                PopupMenu JavaDoc pmenu = (PopupMenu JavaDoc)popup;
6881                if (pmenu.peer != null) {
6882                    pmenu.removeNotify();
6883                }
6884                pmenu.parent = null;
6885                popups.removeElementAt(index);
6886                if (popups.size() == 0) {
6887                    popups = null;
6888                }
6889            }
6890        }
6891    }
6892
6893    /**
6894     * Returns a string representing the state of this component. This
6895     * method is intended to be used only for debugging purposes, and the
6896     * content and format of the returned string may vary between
6897     * implementations. The returned string may be empty but may not be
6898     * <code>null</code>.
6899     *
6900     * @return a string representation of this component's state
6901     * @since JDK1.0
6902     */

6903    protected String JavaDoc paramString() {
6904        String JavaDoc thisName = getName();
6905        String JavaDoc str = (thisName != null? thisName : "") + "," + x + "," + y + "," + width + "x" + height;
6906        if (!valid) {
6907            str += ",invalid";
6908        }
6909        if (!visible) {
6910            str += ",hidden";
6911        }
6912        if (!enabled) {
6913            str += ",disabled";
6914        }
6915        return str;
6916    }
6917
6918    /**
6919     * Returns a string representation of this component and its values.
6920     * @return a string representation of this component
6921     * @since JDK1.0
6922     */

6923    public String JavaDoc toString() {
6924        return getClass().getName() + "[" + paramString() + "]";
6925    }
6926
6927    /**
6928     * Prints a listing of this component to the standard system output
6929     * stream <code>System.out</code>.
6930     * @see java.lang.System#out
6931     * @since JDK1.0
6932     */

6933    public void list() {
6934        list(System.out, 0);
6935    }
6936
6937    /**
6938     * Prints a listing of this component to the specified output
6939     * stream.
6940     * @param out a print stream
6941     * @since JDK1.0
6942     */

6943    public void list(PrintStream JavaDoc out) {
6944        list(out, 0);
6945    }
6946
6947    /**
6948     * Prints out a list, starting at the specified indentation, to the
6949     * specified print stream.
6950     * @param out a print stream
6951     * @param indent number of spaces to indent
6952     * @see java.io.PrintStream#println(java.lang.Object)
6953     * @since JDK1.0
6954     */

6955    public void list(PrintStream JavaDoc out, int indent) {
6956        for (int i = 0 ; i < indent ; i++) {
6957            out.print(" ");
6958        }
6959        out.println(this);
6960    }
6961
6962    /**
6963     * Prints a listing to the specified print writer.
6964     * @param out the print writer to print to
6965     * @since JDK1.1
6966     */

6967    public void list(PrintWriter JavaDoc out) {
6968        list(out, 0);
6969    }
6970
6971    /**
6972     * Prints out a list, starting at the specified indentation, to
6973     * the specified print writer.
6974     * @param out the print writer to print to
6975     * @param indent the number of spaces to indent
6976     * @see java.io.PrintStream#println(java.lang.Object)
6977     * @since JDK1.1
6978     */

6979    public void list(PrintWriter JavaDoc out, int indent) {
6980        for (int i = 0 ; i < indent ; i++) {
6981            out.print(" ");
6982        }
6983        out.println(this);
6984    }
6985
6986    /*
6987     * Fetches the native container somewhere higher up in the component
6988     * tree that contains this component.
6989     */

6990    Container JavaDoc getNativeContainer() {
6991        Container JavaDoc p = parent;
6992        while (p != null && p.peer instanceof LightweightPeer) {
6993            p = p.getParent();
6994        }
6995        return p;
6996    }
6997    
6998    /**
6999     * Adds a PropertyChangeListener to the listener list. The listener is
7000     * registered for all bound properties of this class, including the
7001     * following:
7002     * <ul>
7003     * <li>this Component's font ("font")</li>
7004     * <li>this Component's background color ("background")</li>
7005     * <li>this Component's foreground color ("foreground")</li>
7006     * <li>this Component's focusability ("focusable")</li>
7007     * <li>this Component's focus traversal keys enabled state
7008     * ("focusTraversalKeysEnabled")</li>
7009     * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
7010     * ("forwardFocusTraversalKeys")</li>
7011     * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
7012     * ("backwardFocusTraversalKeys")</li>
7013     * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
7014     * ("upCycleFocusTraversalKeys")</li>
7015     * <li>this Component's preferred size ("preferredSize")</li>
7016     * <li>this Component's minimum size ("minimumSize")</li>
7017     * <li>this Component's maximum size ("maximumSize")</li>
7018     * <li>this Component's name ("name")</li>
7019     * </ul>
7020     * Note that if this <code>Component</code> is inheriting a bound property, then no
7021     * event will be fired in response to a change in the inherited property.
7022     * <p>
7023     * If <code>listener</code> is <code>null</code>,
7024     * no exception is thrown and no action is performed.
7025     *
7026     * @param listener the property change listener to be added
7027     *
7028     * @see #removePropertyChangeListener
7029     * @see #getPropertyChangeListeners
7030     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7031     */

7032    public synchronized void addPropertyChangeListener(
7033                                                       PropertyChangeListener JavaDoc listener) {
7034        if (listener == null) {
7035            return;
7036        }
7037        if (changeSupport == null) {
7038            changeSupport = new PropertyChangeSupport JavaDoc(this);
7039        }
7040        changeSupport.addPropertyChangeListener(listener);
7041    }
7042  
7043    /**
7044     * Removes a PropertyChangeListener from the listener list. This method
7045     * should be used to remove PropertyChangeListeners that were registered
7046     * for all bound properties of this class.
7047     * <p>
7048     * If listener is null, no exception is thrown and no action is performed.
7049     *
7050     * @param listener the PropertyChangeListener to be removed
7051     *
7052     * @see #addPropertyChangeListener
7053     * @see #getPropertyChangeListeners
7054     * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
7055     */

7056    public synchronized void removePropertyChangeListener(
7057                                                          PropertyChangeListener JavaDoc listener) {
7058        if (listener == null || changeSupport == null) {
7059            return;
7060        }
7061        changeSupport.removePropertyChangeListener(listener);
7062    }
7063
7064    /**
7065     * Returns an array of all the property change listeners
7066     * registered on this component.
7067     *
7068     * @return all of this component's <code>PropertyChangeListener</code>s
7069     * or an empty array if no property change
7070     * listeners are currently registered
7071     *
7072     * @see #addPropertyChangeListener
7073     * @see #removePropertyChangeListener
7074     * @see #getPropertyChangeListeners(java.lang.String)
7075     * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
7076     * @since 1.4
7077     */

7078    public synchronized PropertyChangeListener JavaDoc[] getPropertyChangeListeners() {
7079        if (changeSupport == null) {
7080            return new PropertyChangeListener JavaDoc[0];
7081        }
7082        return changeSupport.getPropertyChangeListeners();
7083    }
7084  
7085    /**
7086     * Adds a PropertyChangeListener to the listener list for a specific
7087     * property. The specified property may be user-defined, or one of the
7088     * following:
7089     * <ul>
7090     * <li>this Component's font ("font")</li>
7091     * <li>this Component's background color ("background")</li>
7092     * <li>this Component's foreground color ("foreground")</li>
7093     * <li>this Component's focusability ("focusable")</li>
7094     * <li>this Component's focus traversal keys enabled state
7095     * ("focusTraversalKeysEnabled")</li>
7096     * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
7097     * ("forwardFocusTraversalKeys")</li>
7098     * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
7099     * ("backwardFocusTraversalKeys")</li>
7100     * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
7101     * ("upCycleFocusTraversalKeys")</li>
7102     * </ul>
7103     * Note that if this <code>Component</code> is inheriting a bound property, then no
7104     * event will be fired in response to a change in the inherited property.
7105     * <p>
7106     * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
7107     * no exception is thrown and no action is taken.
7108     *
7109     * @param propertyName one of the property names listed above
7110     * @param listener the property change listener to be added
7111     *
7112     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7113     * @see #getPropertyChangeListeners(java.lang.String)
7114     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7115     */

7116    public synchronized void addPropertyChangeListener(
7117                                                       String JavaDoc propertyName,
7118                                                       PropertyChangeListener JavaDoc listener) {
7119        if (listener == null) {
7120            return;
7121        }
7122        if (changeSupport == null) {
7123            changeSupport = new PropertyChangeSupport JavaDoc(this);
7124        }
7125        changeSupport.addPropertyChangeListener(propertyName, listener);
7126    }
7127
7128    /**
7129     * Removes a <code>PropertyChangeListener</code> from the listener
7130     * list for a specific property. This method should be used to remove
7131     * <code>PropertyChangeListener</code>s
7132     * that were registered for a specific bound property.
7133     * <p>
7134     * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
7135     * no exception is thrown and no action is taken.
7136     *
7137     * @param propertyName a valid property name
7138     * @param listener the PropertyChangeListener to be removed
7139     *
7140     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7141     * @see #getPropertyChangeListeners(java.lang.String)
7142     * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
7143     */

7144    public synchronized void removePropertyChangeListener(
7145                                                          String JavaDoc propertyName,
7146                                                          PropertyChangeListener JavaDoc listener) {
7147        if (listener == null || changeSupport == null) {
7148            return;
7149        }
7150        changeSupport.removePropertyChangeListener(propertyName, listener);
7151    }
7152
7153    /**
7154     * Returns an array of all the listeners which have been associated
7155     * with the named property.
7156     *
7157     * @return all of the <code>PropertyChangeListener</code>s associated with
7158     * the named property; if no such listeners have been added or
7159     * if <code>propertyName</code> is <code>null</code>, an empty
7160     * array is returned
7161     *
7162     * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7163     * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
7164     * @see #getPropertyChangeListeners
7165     * @since 1.4
7166     */

7167    public synchronized PropertyChangeListener JavaDoc[] getPropertyChangeListeners(
7168                                                                            String JavaDoc propertyName) {
7169        if (changeSupport == null) {
7170            return new PropertyChangeListener JavaDoc[0];
7171        }
7172        return changeSupport.getPropertyChangeListeners(propertyName);
7173    }
7174
7175    /**
7176     * Support for reporting bound property changes for Object properties.
7177     * This method can be called when a bound property has changed and it will
7178     * send the appropriate PropertyChangeEvent to any registered
7179     * PropertyChangeListeners.
7180     *
7181     * @param propertyName the property whose value has changed
7182     * @param oldValue the property's previous value
7183     * @param newValue the property's new value
7184     */

7185    protected void firePropertyChange(String JavaDoc propertyName,
7186                                      Object JavaDoc oldValue, Object JavaDoc newValue) {
7187        PropertyChangeSupport JavaDoc changeSupport = this.changeSupport;
7188        if (changeSupport == null ||
7189            (oldValue != null && newValue != null && oldValue.equals(newValue))) {
7190            return;
7191        }
7192        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
7193    }
7194
7195    /**
7196     * Support for reporting bound property changes for boolean properties.
7197     * This method can be called when a bound property has changed and it will
7198     * send the appropriate PropertyChangeEvent to any registered
7199     * PropertyChangeListeners.
7200     *
7201     * @param propertyName the property whose value has changed
7202     * @param oldValue the property's previous value
7203     * @param newValue the property's new value
7204     */

7205    protected void firePropertyChange(String JavaDoc propertyName,
7206                                      boolean oldValue, boolean newValue) {
7207        PropertyChangeSupport JavaDoc changeSupport = this.changeSupport;
7208        if (changeSupport == null || oldValue == newValue) {
7209            return;
7210        }
7211        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
7212    }
7213  
7214    /**
7215     * Support for reporting bound property changes for integer properties.
7216     * This method can be called when a bound property has changed and it will
7217     * send the appropriate PropertyChangeEvent to any registered
7218     * PropertyChangeListeners.
7219     *
7220     * @param propertyName the property whose value has changed
7221     * @param oldValue the property's previous value
7222     * @param newValue the property's new value
7223     */

7224    protected void firePropertyChange(String JavaDoc propertyName,
7225                                      int oldValue, int newValue) {
7226        PropertyChangeSupport JavaDoc changeSupport = this.changeSupport;
7227        if (changeSupport == null || oldValue == newValue) {
7228            return;
7229        }
7230        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
7231    }
7232
7233    /**
7234     * Reports a bound property change.
7235     *
7236     * @param propertyName the programmatic name of the property
7237     * that was changed
7238     * @param oldValue the old value of the property (as a byte)
7239     * @param newValue the new value of the property (as a byte)
7240     * @see #firePropertyChange(java.lang.String, java.lang.Object,
7241     * java.lang.Object)
7242     * @since 1.5
7243     */

7244    public void firePropertyChange(String JavaDoc propertyName, byte oldValue, byte newValue) {
7245        if (changeSupport == null || oldValue == newValue) {
7246            return;
7247        }
7248      &nb