OSDN Git Service

Imported GNU Classpath 0.90
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JComponent.java
1 /* JComponent.java -- Every component in swing inherits from this class.
2    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing;
40
41 import java.applet.Applet;
42 import java.awt.AWTEvent;
43 import java.awt.Color;
44 import java.awt.Component;
45 import java.awt.Container;
46 import java.awt.Dimension;
47 import java.awt.EventQueue;
48 import java.awt.FocusTraversalPolicy;
49 import java.awt.Font;
50 import java.awt.Graphics;
51 import java.awt.Graphics2D;
52 import java.awt.Image;
53 import java.awt.Insets;
54 import java.awt.Point;
55 import java.awt.Rectangle;
56 import java.awt.Shape;
57 import java.awt.Window;
58 import java.awt.dnd.DropTarget;
59 import java.awt.event.ActionEvent;
60 import java.awt.event.ActionListener;
61 import java.awt.event.ContainerEvent;
62 import java.awt.event.ContainerListener;
63 import java.awt.event.FocusEvent;
64 import java.awt.event.FocusListener;
65 import java.awt.event.KeyEvent;
66 import java.awt.event.MouseEvent;
67 import java.awt.peer.LightweightPeer;
68 import java.beans.PropertyChangeEvent;
69 import java.beans.PropertyChangeListener;
70 import java.beans.PropertyVetoException;
71 import java.beans.VetoableChangeListener;
72 import java.io.Serializable;
73 import java.util.ArrayList;
74 import java.util.EventListener;
75 import java.util.Hashtable;
76 import java.util.Locale;
77 import java.util.Set;
78
79 import javax.accessibility.Accessible;
80 import javax.accessibility.AccessibleContext;
81 import javax.accessibility.AccessibleExtendedComponent;
82 import javax.accessibility.AccessibleKeyBinding;
83 import javax.accessibility.AccessibleRole;
84 import javax.accessibility.AccessibleState;
85 import javax.accessibility.AccessibleStateSet;
86 import javax.swing.border.Border;
87 import javax.swing.border.CompoundBorder;
88 import javax.swing.border.TitledBorder;
89 import javax.swing.event.AncestorEvent;
90 import javax.swing.event.AncestorListener;
91 import javax.swing.event.EventListenerList;
92 import javax.swing.plaf.ComponentUI;
93
94 /**
95  * The base class of all Swing components.
96  * It contains generic methods to manage events, properties and sizes. Actual
97  * drawing of the component is channeled to a look-and-feel class that is
98  * implemented elsewhere.
99  *
100  * @author Ronald Veldema (rveldema&064;cs.vu.nl)
101  * @author Graydon Hoare (graydon&064;redhat.com)
102  */
103 public abstract class JComponent extends Container implements Serializable
104 {
105   private static final long serialVersionUID = -7908749299918704233L;
106
107   /** 
108    * The accessible context of this <code>JComponent</code>.
109    */
110   protected AccessibleContext accessibleContext;
111
112   /**
113    * Basic accessibility support for <code>JComponent</code> derived
114    * widgets.
115    */
116   public abstract class AccessibleJComponent 
117     extends AccessibleAWTContainer
118     implements AccessibleExtendedComponent
119   {
120     /**
121      * Receives notification if the focus on the JComponent changes and
122      * fires appropriate PropertyChangeEvents to listeners registered with
123      * the AccessibleJComponent.
124      */
125     protected class AccessibleFocusHandler 
126       implements FocusListener
127     {
128       /**
129        * Creates a new AccessibleFocusHandler.
130        */
131       protected AccessibleFocusHandler()
132       {
133         // Nothing to do here.
134       }
135
136       /**
137        * Receives notification when the JComponent gained focus and fires
138        * a PropertyChangeEvent to listeners registered on the
139        * AccessibleJComponent with a property name of
140        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and a new value
141        * of {@link AccessibleState#FOCUSED}.
142        */
143       public void focusGained(FocusEvent event)
144       {
145         AccessibleJComponent.this.firePropertyChange
146           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
147            AccessibleState.FOCUSED);
148       }
149
150       /**
151        * Receives notification when the JComponent lost focus and fires
152        * a PropertyChangeEvent to listeners registered on the
153        * AccessibleJComponent with a property name of
154        * {@link AccessibleContext#ACCESSIBLE_STATE_PROPERTY} and an old value
155        * of {@link AccessibleState#FOCUSED}.
156        */
157       public void focusLost(FocusEvent valevent)
158       {
159         AccessibleJComponent.this.firePropertyChange
160           (AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
161            AccessibleState.FOCUSED, null);
162       }
163     }
164
165     /**
166      * Receives notification if there are child components are added or removed
167      * from the JComponent and fires appropriate PropertyChangeEvents to
168      * interested listeners on the AccessibleJComponent.
169      */
170     protected class AccessibleContainerHandler 
171       implements ContainerListener
172     {
173       /**
174        * Creates a new AccessibleContainerHandler.
175        */
176       protected AccessibleContainerHandler()
177       {
178         // Nothing to do here.
179       }
180
181       /**
182        * Receives notification when a child component is added to the
183        * JComponent and fires a PropertyChangeEvent on listeners registered
184        * with the AccessibleJComponent with a property name of
185        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
186        *
187        * @param event the container event
188        */
189       public void componentAdded(ContainerEvent event)
190       {
191         Component c = event.getChild();
192         if (c != null && c instanceof Accessible)
193           {
194             AccessibleContext childCtx = c.getAccessibleContext();
195             AccessibleJComponent.this.firePropertyChange
196               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, null, childCtx);
197           }
198       }
199
200       /**
201        * Receives notification when a child component is removed from the
202        * JComponent and fires a PropertyChangeEvent on listeners registered
203        * with the AccessibleJComponent with a property name of
204        * {@link AccessibleContext#ACCESSIBLE_CHILD_PROPERTY}.
205        *
206        * @param event the container event
207        */
208       public void componentRemoved(ContainerEvent event)
209       {
210         Component c = event.getChild();
211         if (c != null && c instanceof Accessible)
212           {
213             AccessibleContext childCtx = c.getAccessibleContext();
214             AccessibleJComponent.this.firePropertyChange
215               (AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, childCtx, null);
216           }
217       }
218     }
219
220     private static final long serialVersionUID = -7047089700479897799L;
221
222     /**
223      * Receives notification when a child component is added to the
224      * JComponent and fires a PropertyChangeEvent on listeners registered
225      * with the AccessibleJComponent.
226      *
227      * @specnote AccessibleAWTContainer has a protected field with the same
228      *           name. Looks like a bug or nasty misdesign to me.
229      */
230     protected ContainerListener accessibleContainerHandler;
231
232     /**
233      * Receives notification if the focus on the JComponent changes and
234      * fires appropriate PropertyChangeEvents to listeners registered with
235      * the AccessibleJComponent.
236      *
237      * @specnote AccessibleAWTComponent has a protected field
238      *           accessibleAWTFocusHandler. Looks like a bug or nasty misdesign
239      *           to me.
240      */
241     protected FocusListener accessibleFocusHandler;
242
243     /**
244      * Creates a new AccessibleJComponent.
245      */
246     protected AccessibleJComponent()
247     {
248       // Nothing to do here.
249     }
250
251     /**
252      * Adds a property change listener to the list of registered listeners.
253      *
254      * This sets up the {@link #accessibleContainerHandler} and
255      * {@link #accessibleFocusHandler} fields and calls
256      * <code>super.addPropertyChangeListener(listener)</code>.
257      *
258      * @param listener the listener to add
259      */
260     public void addPropertyChangeListener(PropertyChangeListener listener)
261     {
262       // Tests seem to indicate that this method also sets up the other two
263       // handlers.
264       if (accessibleContainerHandler == null)
265         {
266           accessibleContainerHandler = new AccessibleContainerHandler();
267           addContainerListener(accessibleContainerHandler);
268         }
269       if (accessibleFocusHandler == null)
270         {
271           accessibleFocusHandler = new AccessibleFocusHandler();
272           addFocusListener(accessibleFocusHandler);
273         }
274       super.addPropertyChangeListener(listener);
275     }
276
277     /**
278      * Removes a property change listener from the list of registered listeners.
279      *
280      * This uninstalls the {@link #accessibleContainerHandler} and
281      * {@link #accessibleFocusHandler} fields and calls
282      * <code>super.removePropertyChangeListener(listener)</code>.
283      *
284      * @param listener the listener to remove
285      */
286     public void removePropertyChangeListener(PropertyChangeListener listener)
287     {
288       // Tests seem to indicate that this method also resets the other two
289       // handlers.
290       if (accessibleContainerHandler != null)
291         {
292           removeContainerListener(accessibleContainerHandler);
293           accessibleContainerHandler = null;
294         }
295       if (accessibleFocusHandler != null)
296         {
297           removeFocusListener(accessibleFocusHandler);
298           accessibleFocusHandler = null;
299         }
300       super.removePropertyChangeListener(listener);
301     }
302
303     /**
304      * Returns the number of accessible children of this object.
305      *
306      * @return  the number of accessible children of this object
307      */
308     public int getAccessibleChildrenCount()
309     {
310       // TODO: The functionality should be performed in the superclass.
311       // Find out why this is overridden. However, it is very well possible
312       // that this is left over from times when there was no such superclass
313       // method.
314       return super.getAccessibleChildrenCount();
315     }
316
317     /**
318      * Returns the accessible child component at index <code>i</code>.
319      *
320      * @param i the index of the accessible child to return
321      *
322      * @return the accessible child component at index <code>i</code>
323      */
324     public Accessible getAccessibleChild(int i)
325     {
326       // TODO: The functionality should be performed in the superclass.
327       // Find out why this is overridden. However, it is very well possible
328       // that this is left over from times when there was no such superclass
329       // method.
330       return super.getAccessibleChild(i);
331     }
332
333     /**
334      * Returns the accessible state set of this component.
335      *
336      * @return the accessible state set of this component
337      */
338     public AccessibleStateSet getAccessibleStateSet()
339     {
340       // Note: While the java.awt.Component has an 'opaque' property, it
341       // seems that it is not added to the accessible state set there, even
342       // if this property is true. However, it is handled for JComponent, so
343       // we add it here.
344       AccessibleStateSet state = super.getAccessibleStateSet();
345       if (isOpaque())
346         state.add(AccessibleState.OPAQUE);
347       return state;
348     }
349
350     /**
351      * Returns the localized name for this object. Generally this should
352      * almost never return {@link Component#getName()} since that is not
353      * a localized name. If the object is some kind of text component (like
354      * a menu item), then the value of the object may be returned. Also, if
355      * the object has a tooltip, the value of the tooltip may also be
356      * appropriate.
357      *
358      * @return the localized name for this object or <code>null</code> if this
359      *         object has no name
360      */
361     public String getAccessibleName()
362     {
363       String name = super.getAccessibleName();
364
365       // There are two fallbacks provided by the JComponent in the case the
366       // superclass returns null:
367       // - If the component is inside a titled border, then it inherits the
368       //   name from the border title.
369       // - If the component is not inside a titled border but has a label
370       //   (via JLabel.setLabelFor()), then it gets the name from the label's
371       //   accessible context.
372
373       if (name == null)
374         {
375           name = getTitledBorderText();
376         }
377
378       if (name == null)
379         {
380           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
381           if (l instanceof Accessible)
382             {
383               AccessibleContext labelCtx =
384                 ((Accessible) l).getAccessibleContext();
385               name = labelCtx.getAccessibleName();
386             }
387         }
388
389       return name;
390     }
391
392     /**
393      * Returns the localized description of this object.
394      *
395      * @return the localized description of this object or <code>null</code>
396      *         if this object has no description
397      */
398     public String getAccessibleDescription()
399     {
400       // There are two fallbacks provided by the JComponent in the case the
401       // superclass returns null:
402       // - If the component has a tooltip, then inherit the description from
403       //   the tooltip.
404       // - If the component is not inside a titled border but has a label
405       //   (via JLabel.setLabelFor()), then it gets the name from the label's
406       //   accessible context.
407       String descr = super.getAccessibleDescription();
408
409       if (descr == null)
410         {
411           descr = getToolTipText();
412         }
413
414       if (descr == null)
415         {
416           Object l = getClientProperty(JLabel.LABEL_PROPERTY);
417           if (l instanceof Accessible)
418             {
419               AccessibleContext labelCtx =
420                 ((Accessible) l).getAccessibleContext();
421               descr = labelCtx.getAccessibleName();
422             }
423         }
424
425       return descr;
426     }
427
428     /**
429      * Returns the accessible role of this component.
430      *
431      * @return the accessible role of this component
432      *
433      * @see AccessibleRole
434      */
435     public AccessibleRole getAccessibleRole()
436     {
437       return AccessibleRole.SWING_COMPONENT;
438     }
439
440     /**
441      * Recursivly searches a border hierarchy (starting at <code>border) for
442      * a titled border and returns the title if one is found, <code>null</code>
443      * otherwise.
444      *
445      * @param border the border to start search from
446      *
447      * @return the border title of a possibly found titled border
448      */
449     protected String getBorderTitle(Border border)
450     {
451       String title = null;
452       if (border instanceof CompoundBorder)
453         {
454           CompoundBorder compound = (CompoundBorder) border;
455           Border inner = compound.getInsideBorder();
456           title = getBorderTitle(inner);
457           if (title == null)
458             {
459               Border outer = compound.getOutsideBorder();
460               title = getBorderTitle(outer);
461             }
462         }
463       else if (border instanceof TitledBorder)
464         {
465           TitledBorder titled = (TitledBorder) border;
466           title = titled.getTitle(); 
467         }
468       return title;
469     }
470
471     /**
472      * Returns the tooltip text for this accessible component.
473      *
474      * @return the tooltip text for this accessible component
475      */
476     public String getToolTipText()
477     {
478       return JComponent.this.getToolTipText();
479     }
480
481     /**
482      * Returns the title of the border of this accessible component if
483      * this component has a titled border, otherwise returns <code>null</code>.
484      *
485      * @return the title of the border of this accessible component if
486      *         this component has a titled border, otherwise returns
487      *         <code>null</code>
488      */
489     public String getTitledBorderText()
490     {
491       return getBorderTitle(getBorder()); 
492     }
493
494     /**
495      * Returns the keybindings associated with this accessible component or
496      * <code>null</code> if the component does not support key bindings.
497      *
498      * @return the keybindings associated with this accessible component
499      */
500     public AccessibleKeyBinding getAccessibleKeyBinding()
501     {
502       // The reference implementation seems to always return null here,
503       // independent of the key bindings of the JComponent. So do we.
504       return null;
505     }
506   }
507
508   /** 
509    * An explicit value for the component's preferred size; if not set by a
510    * user, this is calculated on the fly by delegating to the {@link
511    * ComponentUI#getPreferredSize} method on the {@link #ui} property. 
512    */
513   Dimension preferredSize;
514
515   /** 
516    * An explicit value for the component's minimum size; if not set by a
517    * user, this is calculated on the fly by delegating to the {@link
518    * ComponentUI#getMinimumSize} method on the {@link #ui} property. 
519    */
520   Dimension minimumSize;
521
522   /** 
523    * An explicit value for the component's maximum size; if not set by a
524    * user, this is calculated on the fly by delegating to the {@link
525    * ComponentUI#getMaximumSize} method on the {@link #ui} property.
526    */
527   Dimension maximumSize;
528
529   /**
530    * A value between 0.0 and 1.0 indicating the preferred horizontal
531    * alignment of the component, relative to its siblings. The values
532    * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
533    * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
534    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
535    * managers use this property.
536    *
537    * @see #getAlignmentX
538    * @see #setAlignmentX
539    * @see javax.swing.OverlayLayout
540    * @see javax.swing.BoxLayout
541    */
542   float alignmentX = -1.0F;
543
544   /**
545    * A value between 0.0 and 1.0 indicating the preferred vertical
546    * alignment of the component, relative to its siblings. The values
547    * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
548    * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
549    * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
550    * managers use this property.
551    *
552    * @see #getAlignmentY
553    * @see #setAlignmentY
554    * @see javax.swing.OverlayLayout
555    * @see javax.swing.BoxLayout
556    */
557   float alignmentY = -1.0F;
558
559   /** 
560    * The border painted around this component.
561    * 
562    * @see #paintBorder
563    */
564   Border border;
565
566   /** 
567    * The text to show in the tooltip associated with this component.
568    * 
569    * @see #setToolTipText
570    * @see #getToolTipText()
571    */
572    String toolTipText;
573
574   /** 
575    * <p>Whether to double buffer this component when painting. This flag
576    * should generally be <code>true</code>, to ensure good painting
577    * performance.</p>
578    *
579    * <p>All children of a double buffered component are painted into the
580    * double buffer automatically, so only the top widget in a window needs
581    * to be double buffered.</p>
582    *
583    * @see #setDoubleBuffered
584    * @see #isDoubleBuffered
585    * @see #paint
586    */
587   boolean doubleBuffered = true;
588
589   /**
590    * A set of flags indicating which debugging graphics facilities should
591    * be enabled on this component. The values should be a combination of
592    * {@link DebugGraphics#NONE_OPTION}, {@link DebugGraphics#LOG_OPTION},
593    * {@link DebugGraphics#FLASH_OPTION}, or {@link
594    * DebugGraphics#BUFFERED_OPTION}.
595    *
596    * @see #setDebugGraphicsOptions
597    * @see #getDebugGraphicsOptions
598    * @see DebugGraphics
599    * @see #getComponentGraphics
600    */
601   int debugGraphicsOptions;
602
603   /** 
604    * <p>This property controls two independent behaviors simultaneously.</p>
605    *
606    * <p>First, it controls whether to fill the background of this widget
607    * when painting its body. This affects calls to {@link
608    * JComponent#paintComponent}, which in turn calls {@link
609    * ComponentUI#update} on the component's {@link #ui} property. If the
610    * component is opaque during this call, the background will be filled
611    * before calling {@link ComponentUI#paint}. This happens merely as a
612    * convenience; you may fill the component's background yourself too,
613    * but there is no need to do so if you will be filling with the same
614    * color.</p>
615    *
616    * <p>Second, it the opaque property informs swing's repaint system
617    * whether it will be necessary to paint the components "underneath" this
618    * component, in Z-order. If the component is opaque, it is considered to
619    * completely occlude components "underneath" it, so they will not be
620    * repainted along with the opaque component.</p>
621    *
622    * <p>The default value for this property is <code>false</code>, but most
623    * components will want to set it to <code>true</code> when installing UI
624    * defaults in {@link ComponentUI#installUI}.</p>
625    *
626    * @see #setOpaque
627    * @see #isOpaque
628    * @see #paintComponent
629    */
630   boolean opaque = false;
631
632   /** 
633    * The user interface delegate for this component. Event delivery and
634    * repainting of the component are usually delegated to this object. 
635    *
636    * @see #setUI
637    * @see #getUIClassID
638    * @see #updateUI
639    */
640   protected ComponentUI ui;
641
642   /**
643    * A hint to the focus system that this component should or should not
644    * get focus. If this is <code>false</code>, swing will not try to
645    * request focus on this component; if <code>true</code>, swing might
646    * try to request focus, but the request might fail. Thus it is only 
647    * a hint guiding swing's behavior.
648    *
649    * @see #requestFocus()
650    * @see #isRequestFocusEnabled
651    * @see #setRequestFocusEnabled
652    */
653   boolean requestFocusEnabled;
654
655   /**
656    * Flag indicating behavior of this component when the mouse is dragged
657    * outside the component and the mouse <em>stops moving</em>. If
658    * <code>true</code>, synthetic mouse events will be delivered on regular
659    * timed intervals, continuing off in the direction the mouse exited the
660    * component, until the mouse is released or re-enters the component.
661    *
662    * @see #setAutoscrolls
663    * @see #getAutoscrolls
664    */
665   boolean autoscrolls = false;
666
667   /**
668    * Indicates whether the current paint call is already double buffered or
669    * not. 
670    */
671   static boolean isPaintingDoubleBuffered = false;
672
673   /**
674    * Listeners for events other than {@link PropertyChangeEvent} are
675    * handled by this listener list. PropertyChangeEvents are handled in
676    * {@link #changeSupport}.
677    */
678   protected EventListenerList listenerList = new EventListenerList();
679
680   /** 
681    * Storage for "client properties", which are key/value pairs associated
682    * with this component by a "client", such as a user application or a
683    * layout manager. This is lazily constructed when the component gets its
684    * first client property.
685    */
686   private Hashtable clientProperties;
687   
688   private InputMap inputMap_whenFocused;
689   private InputMap inputMap_whenAncestorOfFocused;
690   private ComponentInputMap inputMap_whenInFocusedWindow;
691   private ActionMap actionMap;
692   /** @since 1.3 */
693   private boolean verifyInputWhenFocusTarget;
694   private InputVerifier inputVerifier;
695
696   private TransferHandler transferHandler;
697
698   /**
699    * Indicates if this component is currently painting a tile or not.
700    */
701   private boolean paintingTile;
702
703   /**
704    * A temporary buffer used for fast dragging of components.
705    */
706   private Image dragBuffer;
707
708   /**
709    * Indicates if the dragBuffer is already initialized.
710    */
711   private boolean dragBufferInitialized;
712
713   /**
714    * A cached Rectangle object to be reused. Be careful when you use that,
715    * so that it doesn't get modified in another context within the same
716    * method call chain.
717    */
718   private static transient Rectangle rectCache;
719
720   /**
721    * The default locale of the component.
722    * 
723    * @see #getDefaultLocale
724    * @see #setDefaultLocale
725    */
726   private static Locale defaultLocale;
727   
728   public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
729
730   /**
731    * Constant used to indicate that no condition has been assigned to a
732    * particular action.
733    *
734    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
735    */
736   public static final int UNDEFINED_CONDITION = -1;
737
738   /**
739    * Constant used to indicate that an action should be performed only when 
740    * the component has focus.
741    *
742    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
743    */
744   public static final int WHEN_FOCUSED = 0;
745
746   /**
747    * Constant used to indicate that an action should be performed only when 
748    * the component is an ancestor of the component which has focus.
749    *
750    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
751    */
752   public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
753
754   /**
755    * Constant used to indicate that an action should be performed only when 
756    * the component is in the window which has focus.
757    *
758    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
759    */
760   public static final int WHEN_IN_FOCUSED_WINDOW = 2;
761
762   /**
763    * Indicates if this component is completely dirty or not. This is used
764    * by the RepaintManager's
765    * {@link RepaintManager#isCompletelyDirty(JComponent)} method.
766    */
767   boolean isCompletelyDirty = false;
768
769   /**
770    * Indicates if the opaque property has been set by a client program or by
771    * the UI.
772    *
773    * @see #setUIProperty(String, Object)
774    * @see LookAndFeel#installProperty(JComponent, String, Object)
775    */
776   private boolean clientOpaqueSet = false;
777
778   /**
779    * Indicates if the autoscrolls property has been set by a client program or
780    * by the UI.
781    *
782    * @see #setUIProperty(String, Object)
783    * @see LookAndFeel#installProperty(JComponent, String, Object)
784    */
785   private boolean clientAutoscrollsSet = false;
786
787   /**
788    * Creates a new <code>JComponent</code> instance.
789    */
790   public JComponent()
791   {
792     super();
793     setDropTarget(new DropTarget());
794     defaultLocale = Locale.getDefault();
795     debugGraphicsOptions = DebugGraphics.NONE_OPTION;
796     setRequestFocusEnabled(true);
797   }
798
799   /**
800    * Helper to lazily construct and return the client properties table.
801    * 
802    * @return The current client properties table
803    *
804    * @see #clientProperties
805    * @see #getClientProperty
806    * @see #putClientProperty
807    */
808   private Hashtable getClientProperties()
809   {
810     if (clientProperties == null)
811       clientProperties = new Hashtable();
812     return clientProperties;
813   }
814
815   /**
816    * Get a client property associated with this component and a particular
817    * key.
818    *
819    * @param key The key with which to look up the client property
820    *
821    * @return A client property associated with this object and key
822    *
823    * @see #clientProperties
824    * @see #getClientProperties
825    * @see #putClientProperty
826    */
827   public final Object getClientProperty(Object key)
828   {
829     return getClientProperties().get(key);
830   }
831
832   /**
833    * Add a client property <code>value</code> to this component, associated
834    * with <code>key</code>. If there is an existing client property
835    * associated with <code>key</code>, it will be replaced.  A
836    * {@link PropertyChangeEvent} is sent to registered listeners (with the
837    * name of the property being <code>key.toString()</code>).
838    *
839    * @param key The key of the client property association to add
840    * @param value The value of the client property association to add
841    *
842    * @see #clientProperties
843    * @see #getClientProperties
844    * @see #getClientProperty
845    */
846   public final void putClientProperty(Object key, Object value)
847   {
848     Hashtable t = getClientProperties();
849     Object old = t.get(key);
850     if (value != null)
851       t.put(key, value);
852     else
853       t.remove(key);
854     firePropertyChange(key.toString(), old, value);
855   }
856
857   /**
858    * Unregister an <code>AncestorListener</code>.
859    *
860    * @param listener The listener to unregister
861    * 
862    * @see #addAncestorListener
863    */
864   public void removeAncestorListener(AncestorListener listener)
865   {
866     listenerList.remove(AncestorListener.class, listener);
867   }
868
869   /**
870    * Unregister a <code>VetoableChangeChangeListener</code>.
871    *
872    * @param listener The listener to unregister
873    *
874    * @see #addVetoableChangeListener
875    */
876   public void removeVetoableChangeListener(VetoableChangeListener listener)
877   {
878     listenerList.remove(VetoableChangeListener.class, listener);
879   }
880
881   /**
882    * Register an <code>AncestorListener</code>.
883    *
884    * @param listener The listener to register
885    *
886    * @see #removeVetoableChangeListener
887    */
888   public void addAncestorListener(AncestorListener listener)
889   {
890     listenerList.add(AncestorListener.class, listener);
891   }
892
893   /**
894    * Register a <code>PropertyChangeListener</code> for a specific, named
895    * property. To listen to all property changes, regardless of name, use
896    * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
897    *
898    * @param propertyName The property name to listen to
899    * @param listener The listener to register
900    *
901    * @see #removePropertyChangeListener(String, PropertyChangeListener)
902    * @see #changeSupport
903    */
904   public void addPropertyChangeListener(String propertyName,
905                                         PropertyChangeListener listener)
906   {
907     listenerList.add(PropertyChangeListener.class, listener);
908   }
909
910   /**
911    * Register a <code>VetoableChangeListener</code>.
912    *
913    * @param listener The listener to register
914    *
915    * @see #removeVetoableChangeListener
916    * @see #listenerList
917    */
918   public void addVetoableChangeListener(VetoableChangeListener listener)
919   {
920     listenerList.add(VetoableChangeListener.class, listener);
921   }
922
923   /**
924    * Returns all registered {@link EventListener}s of the given 
925    * <code>listenerType</code>.
926    *
927    * @param listenerType the class of listeners to filter (<code>null</code> 
928    *                     not permitted).
929    *                     
930    * @return An array of registered listeners.
931    * 
932    * @throws ClassCastException if <code>listenerType</code> does not implement
933    *                            the {@link EventListener} interface.
934    * @throws NullPointerException if <code>listenerType</code> is 
935    *                              <code>null</code>.
936    *                            
937    * @see #getAncestorListeners()
938    * @see #listenerList
939    * 
940    * @since 1.3
941    */
942   public EventListener[] getListeners(Class listenerType)
943   {
944     if (listenerType == PropertyChangeListener.class)
945       return getPropertyChangeListeners();
946     else
947       return listenerList.getListeners(listenerType);
948   }
949
950   /**
951    * Return all registered <code>AncestorListener</code> objects.
952    *
953    * @return The set of <code>AncestorListener</code> objects in {@link
954    * #listenerList}
955    */
956   public AncestorListener[] getAncestorListeners()
957   {
958     return (AncestorListener[]) getListeners(AncestorListener.class);
959   }
960
961   /**
962    * Return all registered <code>VetoableChangeListener</code> objects.
963    *
964    * @return The set of <code>VetoableChangeListener</code> objects in {@link
965    * #listenerList}
966    */
967   public VetoableChangeListener[] getVetoableChangeListeners()
968   {
969     return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
970   }
971
972   /**
973    * A variant of {@link #firePropertyChange(String,Object,Object)} 
974    * for properties with <code>boolean</code> values.
975    *
976    * @specnote It seems that in JDK1.5 all property related methods have been 
977    *           moved to java.awt.Component, except this and 2 others. We call
978    *           super here. I guess this will also be removed in one of the next
979    *           releases.
980    */
981   public void firePropertyChange(String propertyName, boolean oldValue,
982                                  boolean newValue)
983   {
984     super.firePropertyChange(propertyName, oldValue, newValue);
985   }
986
987   /**
988    * A variant of {@link #firePropertyChange(String,Object,Object)} 
989    * for properties with <code>char</code> values.
990    *
991    * @specnote It seems that in JDK1.5 all property related methods have been 
992    *           moved to java.awt.Component, except this and 2 others. We call
993    *           super here. I guess this will also be removed in one of the next
994    *           releases.
995    */
996   public void firePropertyChange(String propertyName, char oldValue,
997                                  char newValue)
998   {
999     super.firePropertyChange(propertyName, oldValue, newValue);
1000   }
1001
1002   /**
1003    * A variant of {@link #firePropertyChange(String,Object,Object)} 
1004    * for properties with <code>int</code> values.
1005    *
1006    * @specnote It seems that in JDK1.5 all property related methods have been 
1007    *           moved to java.awt.Component, except this and 2 others. We call
1008    *           super here. I guess this will also be removed in one of the next
1009    *           releases.
1010    */
1011   public void firePropertyChange(String propertyName, int oldValue,
1012                                  int newValue)
1013   {
1014     super.firePropertyChange(propertyName, oldValue, newValue);
1015   }
1016
1017   /**
1018    * Call {@link VetoableChangeListener#vetoableChange} on all listeners
1019    * registered to listen to a given property. Any method which changes
1020    * the specified property of this component should call this method.
1021    *
1022    * @param propertyName The property which changed
1023    * @param oldValue The old value of the property
1024    * @param newValue The new value of the property
1025    *
1026    * @throws PropertyVetoException if the change was vetoed by a listener
1027    *
1028    * @see #addVetoableChangeListener
1029    * @see #removeVetoableChangeListener
1030    */
1031   protected void fireVetoableChange(String propertyName, Object oldValue,
1032                                     Object newValue)
1033     throws PropertyVetoException
1034   {
1035     VetoableChangeListener[] listeners = getVetoableChangeListeners();
1036
1037     PropertyChangeEvent evt = 
1038       new PropertyChangeEvent(this, propertyName, oldValue, newValue);
1039
1040     for (int i = 0; i < listeners.length; i++)
1041       listeners[i].vetoableChange(evt);
1042   }
1043
1044   /**
1045    * Get the value of the accessibleContext property for this component.
1046    *
1047    * @return the current value of the property
1048    */
1049   public AccessibleContext getAccessibleContext()
1050   {
1051     return null;
1052   }
1053
1054   /**
1055    * Get the value of the {@link #alignmentX} property.
1056    *
1057    * @return The current value of the property.
1058    *
1059    * @see #setAlignmentX
1060    * @see #alignmentY
1061    */
1062   public float getAlignmentX()
1063   {
1064     float ret = alignmentX;
1065     if (alignmentX < 0)
1066       // alignment has not been set explicitly.
1067       ret = super.getAlignmentX();
1068
1069     return ret;
1070   }
1071
1072   /**
1073    * Get the value of the {@link #alignmentY} property.
1074    *
1075    * @return The current value of the property.
1076    *
1077    * @see #setAlignmentY
1078    * @see #alignmentX
1079    */
1080   public float getAlignmentY()
1081   {
1082     float ret = alignmentY;
1083     if (alignmentY < 0)
1084       // alignment has not been set explicitly.
1085       ret = super.getAlignmentY();
1086
1087     return ret;
1088   }
1089
1090   /**
1091    * Get the current value of the {@link #autoscrolls} property.
1092    *
1093    * @return The current value of the property
1094    */
1095   public boolean getAutoscrolls()
1096   {
1097     return autoscrolls;
1098   }
1099
1100   /**
1101    * Set the value of the {@link #border} property.
1102    *   
1103    * @param newBorder The new value of the property
1104    *
1105    * @see #getBorder
1106    */
1107   public void setBorder(Border newBorder)
1108   {
1109     Border oldBorder = getBorder();
1110     if (oldBorder == newBorder)
1111       return;
1112
1113     border = newBorder;
1114     firePropertyChange("border", oldBorder, newBorder);
1115     repaint();
1116   }
1117
1118   /**
1119    * Get the value of the {@link #border} property.
1120    *
1121    * @return The property's current value
1122    *
1123    * @see #setBorder
1124    */
1125   public Border getBorder()
1126   {
1127     return border;
1128   }
1129
1130   /**
1131    * Get the component's current bounding box. If a rectangle is provided,
1132    * use this as the return value (adjusting its fields in place);
1133    * otherwise (of <code>null</code> is provided) return a new {@link
1134    * Rectangle}.
1135    *
1136    * @param rv Optional return value to use
1137    *
1138    * @return A rectangle bounding the component
1139    */
1140   public Rectangle getBounds(Rectangle rv)
1141   {
1142     if (rv == null)
1143       return new Rectangle(getX(), getY(), getWidth(), getHeight());
1144     else
1145       {
1146         rv.setBounds(getX(), getY(), getWidth(), getHeight());
1147         return rv;
1148       }
1149   }
1150
1151   /**
1152    * Prepares a graphics context for painting this object. If {@link
1153    * #debugGraphicsOptions} is not equal to {@link
1154    * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
1155    * wrapping the parameter. Otherwise configure the parameter with this
1156    * component's foreground color and font.
1157    *
1158    * @param g The graphics context to wrap or configure
1159    *
1160    * @return A graphics context to paint this object with
1161    *
1162    * @see #debugGraphicsOptions
1163    * @see #paint
1164    */
1165   protected Graphics getComponentGraphics(Graphics g)
1166   {
1167     Graphics g2 = g;
1168     int options = getDebugGraphicsOptions();
1169     if (options != DebugGraphics.NONE_OPTION)
1170       {
1171         if (!(g2 instanceof DebugGraphics))
1172           g2 = new DebugGraphics(g);
1173         DebugGraphics dg = (DebugGraphics) g2;
1174         dg.setDebugOptions(dg.getDebugOptions() | options);
1175       }
1176     g2.setFont(this.getFont());
1177     g2.setColor(this.getForeground());
1178     return g2;
1179   }
1180
1181   /**
1182    * Get the value of the {@link #debugGraphicsOptions} property.
1183    *
1184    * @return The current value of the property.
1185    *
1186    * @see #setDebugGraphicsOptions
1187    * @see #debugGraphicsOptions
1188    */
1189   public int getDebugGraphicsOptions()
1190   {
1191     String option = System.getProperty("gnu.javax.swing.DebugGraphics");
1192     int options = debugGraphicsOptions;
1193     if (option != null && option.length() != 0)
1194       {
1195         if (options < 0)
1196           options = 0;
1197
1198         if (option.equals("LOG"))
1199           options |= DebugGraphics.LOG_OPTION;
1200         else if (option.equals("FLASH"))
1201           options |= DebugGraphics.FLASH_OPTION;
1202       }
1203     return options;
1204   }
1205
1206   /**
1207    * Get the component's insets, which are calculated from
1208    * the {@link #border} property. If the border is <code>null</code>,
1209    * calls {@link Container#getInsets}.
1210    *
1211    * @return The component's current insets
1212    */
1213   public Insets getInsets()
1214   {
1215     if (border == null)
1216       return super.getInsets();
1217     return getBorder().getBorderInsets(this);
1218   }
1219
1220   /**
1221    * Get the component's insets, which are calculated from the {@link
1222    * #border} property. If the border is <code>null</code>, calls {@link
1223    * Container#getInsets}. The passed-in {@link Insets} value will be
1224    * used as the return value, if possible.
1225    *
1226    * @param insets Return value object to reuse, if possible
1227    *
1228    * @return The component's current insets
1229    */
1230   public Insets getInsets(Insets insets)
1231   {
1232     Insets t = getInsets();
1233
1234     if (insets == null)
1235       return t;
1236
1237     insets.left = t.left;
1238     insets.right = t.right;
1239     insets.top = t.top;
1240     insets.bottom = t.bottom;
1241     return insets;
1242   }
1243
1244   /**
1245    * Get the component's location. The passed-in {@link Point} value
1246    * will be used as the return value, if possible.
1247    *
1248    * @param rv Return value object to reuse, if possible
1249    *
1250    * @return The component's current location
1251    */
1252   public Point getLocation(Point rv)
1253   {
1254     if (rv == null)
1255       return new Point(getX(), getY());
1256
1257     rv.setLocation(getX(), getY());
1258     return rv;
1259   }
1260
1261   /**
1262    * Get the component's maximum size. If the {@link #maximumSize} property
1263    * has been explicitly set, it is returned. If the {@link #maximumSize}
1264    * property has not been set but the {@link #ui} property has been, the
1265    * result of {@link ComponentUI#getMaximumSize} is returned. If neither
1266    * property has been set, the result of {@link Container#getMaximumSize}
1267    * is returned.
1268    *
1269    * @return The maximum size of the component
1270    *
1271    * @see #maximumSize
1272    * @see #setMaximumSize
1273    */
1274   public Dimension getMaximumSize()
1275   {
1276     if (maximumSize != null)
1277       return maximumSize;
1278
1279     if (ui != null)
1280       {
1281         Dimension s = ui.getMaximumSize(this);
1282         if (s != null)
1283           return s;
1284       }
1285
1286     Dimension p = super.getMaximumSize();
1287     return p;
1288   }
1289
1290   /**
1291    * Get the component's minimum size. If the {@link #minimumSize} property
1292    * has been explicitly set, it is returned. If the {@link #minimumSize}
1293    * property has not been set but the {@link #ui} property has been, the
1294    * result of {@link ComponentUI#getMinimumSize} is returned. If neither
1295    * property has been set, the result of {@link Container#getMinimumSize}
1296    * is returned.
1297    *
1298    * @return The minimum size of the component
1299    *
1300    * @see #minimumSize
1301    * @see #setMinimumSize
1302    */
1303   public Dimension getMinimumSize()
1304   {
1305     if (minimumSize != null)
1306       return minimumSize;
1307
1308     if (ui != null)
1309       {
1310         Dimension s = ui.getMinimumSize(this);
1311         if (s != null)
1312           return s;
1313       }
1314
1315     Dimension p = super.getMinimumSize();
1316     return p;
1317   }
1318
1319   /**
1320    * Get the component's preferred size. If the {@link #preferredSize}
1321    * property has been explicitly set, it is returned. If the {@link
1322    * #preferredSize} property has not been set but the {@link #ui} property
1323    * has been, the result of {@link ComponentUI#getPreferredSize} is
1324    * returned. If neither property has been set, the result of {@link
1325    * Container#getPreferredSize} is returned.
1326    *
1327    * @return The preferred size of the component
1328    *
1329    * @see #preferredSize
1330    * @see #setPreferredSize
1331    */
1332   public Dimension getPreferredSize()
1333   {
1334     Dimension prefSize = null;
1335     if (preferredSize != null)
1336       prefSize = new Dimension(preferredSize);
1337
1338     else if (ui != null)
1339       {
1340         Dimension s = ui.getPreferredSize(this);
1341         if (s != null)
1342           prefSize = s;
1343       }
1344
1345     if (prefSize == null)
1346       prefSize = super.getPreferredSize();
1347
1348     return prefSize;
1349   }
1350
1351   /**
1352    * Checks if a maximum size was explicitely set on the component.
1353    *
1354    * @return <code>true</code> if a maximum size was set,
1355    * <code>false</code> otherwise
1356    * 
1357    * @since 1.3
1358    */
1359   public boolean isMaximumSizeSet()
1360   {
1361     return maximumSize != null;
1362   }
1363
1364   /**
1365    * Checks if a minimum size was explicitely set on the component.
1366    *
1367    * @return <code>true</code> if a minimum size was set,
1368    * <code>false</code> otherwise
1369    * 
1370    * @since 1.3
1371    */
1372   public boolean isMinimumSizeSet()
1373   {
1374     return minimumSize != null;
1375   }
1376
1377   /**
1378    * Checks if a preferred size was explicitely set on the component.
1379    *
1380    * @return <code>true</code> if a preferred size was set,
1381    * <code>false</code> otherwise
1382    * 
1383    * @since 1.3
1384    */
1385   public boolean isPreferredSizeSet()
1386   {
1387     return preferredSize != null;
1388   }
1389   
1390   /**
1391    * Return the value of the <code>nextFocusableComponent</code> property.
1392    *
1393    * @return The current value of the property, or <code>null</code>
1394    * if none has been set.
1395    * 
1396    * @deprecated See {@link java.awt.FocusTraversalPolicy}
1397    */
1398   public Component getNextFocusableComponent()
1399   {
1400     Container focusRoot = this;
1401     if (! this.isFocusCycleRoot())
1402       focusRoot = getFocusCycleRootAncestor();
1403
1404     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
1405     return policy.getComponentAfter(focusRoot, this);
1406   }
1407
1408   /**
1409    * Return the set of {@link KeyStroke} objects which are registered
1410    * to initiate actions on this component.
1411    *
1412    * @return An array of the registered keystrokes
1413    */
1414   public KeyStroke[] getRegisteredKeyStrokes()
1415   {
1416     return null;
1417   }
1418
1419   /**
1420    * Returns the first ancestor of this component which is a {@link JRootPane}.
1421    * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
1422    *
1423    * @return An ancestral JRootPane, or <code>null</code> if none exists.
1424    */
1425   public JRootPane getRootPane()
1426   {
1427     JRootPane p = SwingUtilities.getRootPane(this);
1428     return p;
1429   }
1430
1431   /**
1432    * Get the component's size. The passed-in {@link Dimension} value
1433    * will be used as the return value, if possible.
1434    *
1435    * @param rv Return value object to reuse, if possible
1436    *
1437    * @return The component's current size
1438    */
1439   public Dimension getSize(Dimension rv)
1440   {
1441     if (rv == null)
1442       return new Dimension(getWidth(), getHeight());
1443     else
1444       {
1445         rv.setSize(getWidth(), getHeight());
1446         return rv;
1447       }
1448   }
1449
1450   /**
1451    * Return the <code>toolTip</code> property of this component, creating it and
1452    * setting it if it is currently <code>null</code>. This method can be
1453    * overridden in subclasses which wish to control the exact form of
1454    * tooltip created.
1455    *
1456    * @return The current toolTip
1457    */
1458   public JToolTip createToolTip()
1459   {
1460     JToolTip toolTip = new JToolTip();
1461     toolTip.setComponent(this);
1462     toolTip.setTipText(toolTipText);
1463
1464     return toolTip;
1465   }
1466
1467   /**
1468    * Return the location at which the {@link #toolTipText} property should be
1469    * displayed, when triggered by a particular mouse event. 
1470    *
1471    * @param event The event the tooltip is being presented in response to
1472    *
1473    * @return The point at which to display a tooltip, or <code>null</code>
1474    *     if swing is to choose a default location.
1475    */
1476   public Point getToolTipLocation(MouseEvent event)
1477   {
1478     return null;
1479   }
1480
1481   /**
1482    * Set the value of the {@link #toolTipText} property.
1483    *
1484    * @param text The new property value
1485    *
1486    * @see #getToolTipText()
1487    */
1488   public void setToolTipText(String text)
1489   {
1490     if (text == null)
1491     {
1492       ToolTipManager.sharedInstance().unregisterComponent(this);
1493       toolTipText = null;
1494       return;
1495     }
1496
1497     // XXX: The tip text doesn't get updated unless you set it to null
1498     // and then to something not-null. This is consistent with the behaviour
1499     // of Sun's ToolTipManager.
1500
1501     String oldText = toolTipText;
1502     toolTipText = text;
1503
1504     if (oldText == null)
1505       ToolTipManager.sharedInstance().registerComponent(this);
1506   }
1507
1508   /**
1509    * Get the value of the {@link #toolTipText} property.
1510    *
1511    * @return The current property value
1512    *
1513    * @see #setToolTipText
1514    */
1515   public String getToolTipText()
1516   {
1517     return toolTipText;
1518   }
1519
1520   /**
1521    * Get the value of the {@link #toolTipText} property, in response to a
1522    * particular mouse event.
1523    *
1524    * @param event The mouse event which triggered the tooltip
1525    *
1526    * @return The current property value
1527    *
1528    * @see #setToolTipText
1529    */
1530   public String getToolTipText(MouseEvent event)
1531   {
1532     return getToolTipText();
1533   }
1534
1535   /**
1536    * Return the top level ancestral container (usually a {@link
1537    * java.awt.Window} or {@link java.applet.Applet}) which this component is
1538    * contained within, or <code>null</code> if no ancestors exist.
1539    *
1540    * @return The top level container, if it exists
1541    */
1542   public Container getTopLevelAncestor()
1543   {
1544     Container c = getParent();
1545     for (Container peek = c; peek != null; peek = peek.getParent())
1546       c = peek;
1547     return c;
1548   }
1549
1550   /**
1551    * Compute the component's visible rectangle, which is defined
1552    * recursively as either the component's bounds, if it has no parent, or
1553    * the intersection of the component's bounds with the visible rectangle
1554    * of its parent.
1555    *
1556    * @param rect The return value slot to place the visible rectangle in
1557    */
1558   public void computeVisibleRect(Rectangle rect)
1559   {
1560     Component c = getParent();
1561     if (c != null && c instanceof JComponent)
1562       {
1563         ((JComponent) c).computeVisibleRect(rect);
1564         rect.translate(-getX(), -getY());
1565         rect = SwingUtilities.computeIntersection(0, 0, getWidth(),
1566                                                   getHeight(), rect);
1567       }
1568     else
1569       rect.setRect(0, 0, getWidth(), getHeight());
1570   }
1571
1572   /**
1573    * Return the component's visible rectangle in a new {@link Rectangle},
1574    * rather than via a return slot.
1575    *
1576    * @return the component's visible rectangle
1577    *
1578    * @see #computeVisibleRect(Rectangle)
1579    */
1580   public Rectangle getVisibleRect()
1581   {
1582     Rectangle r = new Rectangle();
1583     computeVisibleRect(r);
1584     return r;
1585   }
1586
1587   /**
1588    * <p>Requests that this component receive input focus, giving window
1589    * focus to the top level ancestor of this component. Only works on
1590    * displayable, focusable, visible components.</p>
1591    *
1592    * <p>This method should not be called by clients; it is intended for
1593    * focus implementations. Use {@link Component#requestFocus()} instead.</p>
1594    *
1595    * @see Component#requestFocus()
1596    */
1597   public void grabFocus()
1598   {
1599     requestFocus();
1600   }
1601
1602   /**
1603    * Get the value of the {@link #doubleBuffered} property.
1604    *
1605    * @return The property's current value
1606    */
1607   public boolean isDoubleBuffered()
1608   {
1609     return doubleBuffered;
1610   }
1611
1612   /**
1613    * Return <code>true</code> if the provided component has no native peer;
1614    * in other words, if it is a "lightweight component".
1615    *
1616    * @param c The component to test for lightweight-ness
1617    *
1618    * @return Whether or not the component is lightweight
1619    */
1620   public static boolean isLightweightComponent(Component c)
1621   {
1622     return c.getPeer() instanceof LightweightPeer;
1623   }
1624
1625   /**
1626    * Return <code>true</code> if you wish this component to manage its own
1627    * focus. In particular: if you want this component to be sent
1628    * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
1629    * have its children considered as focus transfer targets. If
1630    * <code>true</code>, focus traversal around this component changes to
1631    * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
1632    *
1633    * @return <code>true</code> if you want this component to manage its own
1634    *     focus, otherwise (by default) <code>false</code>
1635    *
1636    * @deprecated 1.4 Use {@link Component#setFocusTraversalKeys(int, Set)} and
1637    *     {@link Container#setFocusCycleRoot(boolean)} instead
1638    */
1639   public boolean isManagingFocus()
1640   {
1641     return false;
1642   }
1643
1644   /**
1645    * Return the current value of the {@link #opaque} property. 
1646    *
1647    * @return The current property value
1648    */
1649   public boolean isOpaque()
1650   {
1651     return opaque;
1652   }
1653
1654   /**
1655    * Return <code>true</code> if the component can guarantee that none of its
1656    * children will overlap in Z-order. This is a hint to the painting system.
1657    * The default is to return <code>true</code>, but some components such as
1658    * {@link JLayeredPane} should override this to return <code>false</code>.
1659    *
1660    * @return Whether the component tiles its children
1661    */
1662   public boolean isOptimizedDrawingEnabled()
1663   {
1664     return true;
1665   }
1666
1667   /**
1668    * Return <code>true</code> if this component is currently painting a tile,
1669    * this means that paint() is called again on another child component. This
1670    * method returns <code>false</code> if this component does not paint a tile
1671    * or if the last tile is currently painted.
1672    *
1673    * @return whether the component is painting a tile
1674    */
1675   public boolean isPaintingTile()
1676   {
1677     return paintingTile;
1678   }
1679
1680   /**
1681    * Get the value of the {@link #requestFocusEnabled} property.
1682    *
1683    * @return The current value of the property
1684    */
1685   public boolean isRequestFocusEnabled()
1686   {
1687     return requestFocusEnabled;
1688   }
1689
1690   /**
1691    * Return <code>true</code> if this component is a validation root; this
1692    * will cause calls to {@link #invalidate()} in this component's children
1693    * to be "captured" at this component, and not propagate to its parents.
1694    * For most components this should return <code>false</code>, but some
1695    * components such as {@link JViewport} will want to return
1696    * <code>true</code>.
1697    *
1698    * @return Whether this component is a validation root
1699    */
1700   public boolean isValidateRoot()
1701   {
1702     return false;
1703   }
1704
1705   /**
1706    * <p>Paint the component. This is a delicate process, and should only be
1707    * called from the repaint thread, under control of the {@link
1708    * RepaintManager}. Client code should usually call {@link #repaint()} to
1709    * trigger painting.</p>
1710    *
1711    * <p>The body of the <code>paint</code> call involves calling {@link
1712    * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
1713    * order. If you want to customize painting behavior, you should override
1714    * one of these methods rather than <code>paint</code>.</p>
1715    *
1716    * <p>For more details on the painting sequence, see <a
1717    * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">
1718    * this article</a>.</p>
1719    *
1720    * @param g The graphics context to paint with
1721    *
1722    * @see #paintImmediately(Rectangle)
1723    */
1724   public void paint(Graphics g)
1725   {
1726     RepaintManager rm = RepaintManager.currentManager(this);
1727     // We do a little stunt act here to switch on double buffering if it's
1728     // not already on. If we are not already doublebuffered, then we jump
1729     // into the method paintDoubleBuffered, which turns on the double buffer
1730     // and then calls paint(g) again. In the second call we go into the else
1731     // branch of this if statement and actually paint things to the double
1732     // buffer. When this method completes, the call stack unwinds back to
1733     // paintDoubleBuffered, where the buffer contents is finally drawn to the
1734     // screen.
1735     if (!isPaintingDoubleBuffered && isDoubleBuffered()
1736         && rm.isDoubleBufferingEnabled())
1737       {
1738         Rectangle clip = g.getClipBounds();
1739         paintDoubleBuffered(clip);
1740       }
1741     else
1742       {
1743         if (getClientProperty("bufferedDragging") != null
1744             && dragBuffer == null)
1745           {
1746             initializeDragBuffer();
1747           }
1748         else if (getClientProperty("bufferedDragging") == null
1749             && dragBuffer != null)
1750           {
1751             dragBuffer = null;
1752           }
1753
1754         if (g.getClip() == null)
1755           g.setClip(0, 0, getWidth(), getHeight());
1756         if (dragBuffer != null && dragBufferInitialized)
1757           {
1758             g.drawImage(dragBuffer, 0, 0, this);
1759           }
1760         else
1761           {
1762             Graphics g2 = getComponentGraphics(g);
1763             paintComponent(g2);
1764             paintBorder(g2);
1765             paintChildren(g2);
1766             Rectangle clip = g2.getClipBounds();
1767             if (clip == null
1768                 || (clip.x == 0 && clip.y == 0 && clip.width == getWidth()
1769                 && clip.height == getHeight()))
1770               RepaintManager.currentManager(this).markCompletelyClean(this);
1771           }
1772       }
1773   }
1774
1775   /**
1776    * Initializes the drag buffer by creating a new image and painting this
1777    * component into it.
1778    */
1779   private void initializeDragBuffer()
1780   {
1781     dragBufferInitialized = false;
1782     // Allocate new dragBuffer if the current one is too small.
1783     if (dragBuffer == null || dragBuffer.getWidth(this) < getWidth()
1784         || dragBuffer.getHeight(this) < getHeight())
1785       {
1786         dragBuffer = createImage(getWidth(), getHeight());
1787       }
1788     Graphics g = dragBuffer.getGraphics();
1789     paint(g);
1790     g.dispose();
1791     dragBufferInitialized = true;
1792   }
1793
1794   /**
1795    * Paint the component's border. This usually means calling {@link
1796    * Border#paintBorder} on the {@link #border} property, if it is
1797    * non-<code>null</code>. You may override this if you wish to customize
1798    * border painting behavior. The border is painted after the component's
1799    * body, but before the component's children.
1800    *
1801    * @param g The graphics context with which to paint the border
1802    *
1803    * @see #paint
1804    * @see #paintChildren
1805    * @see #paintComponent
1806    */
1807   protected void paintBorder(Graphics g)
1808   {
1809     if (getBorder() != null)
1810       getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
1811   }
1812
1813   /**
1814    * Paint the component's children. This usually means calling {@link
1815    * Container#paint}, which recursively calls {@link #paint} on any of the
1816    * component's children, with appropriate changes to coordinate space and
1817    * clipping region. You may override this if you wish to customize
1818    * children painting behavior. The children are painted after the
1819    * component's body and border.
1820    *
1821    * @param g The graphics context with which to paint the children
1822    *
1823    * @see #paint
1824    * @see #paintBorder
1825    * @see #paintComponent
1826    */
1827   protected void paintChildren(Graphics g)
1828   {
1829     if (getComponentCount() > 0)
1830       {
1831         if (isOptimizedDrawingEnabled())
1832           paintChildrenOptimized(g);
1833         else
1834           paintChildrenWithOverlap(g);
1835       }
1836   }
1837
1838   /**
1839    * Paints the children of this JComponent in the case when the component
1840    * is not marked as optimizedDrawingEnabled, that means the container cannot
1841    * guarantee that it's children are tiled. For this case we must
1842    * perform a more complex optimization to determine the minimal rectangle
1843    * to be painted for each child component.
1844    *
1845    * @param g the graphics context to use
1846    */
1847   private void paintChildrenWithOverlap(Graphics g)
1848   {
1849     Shape originalClip = g.getClip();
1850     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
1851     g.clipRect(inner.x, inner.y, inner.width, inner.height);
1852     Component[] children = getComponents();
1853
1854     // Find the rectangles that need to be painted for each child component.
1855     // We push on this list arrays that have the Rectangles to be painted as
1856     // the first elements and the component to be painted as the last one.
1857     // Later we go through that list in reverse order and paint the rectangles.
1858     ArrayList paintRegions = new ArrayList(children.length);
1859     ArrayList paintRectangles = new ArrayList();
1860     ArrayList newPaintRects = new ArrayList();
1861     paintRectangles.add(g.getClipBounds());
1862     ArrayList componentRectangles = new ArrayList();
1863
1864     // Go through children from top to bottom and find out their paint
1865     // rectangles.
1866     for (int index = 0; paintRectangles.size() > 0 &&
1867       index < children.length; index++)
1868       {
1869         Component comp = children[index];
1870         if (! comp.isVisible())
1871           continue;
1872
1873         Rectangle compBounds = comp.getBounds();
1874         boolean isOpaque = comp instanceof JComponent
1875                            && ((JComponent) comp).isOpaque();
1876
1877         // Add all the current paint rectangles that intersect with the
1878         // component to the component's paint rectangle array.
1879         for (int i = paintRectangles.size() - 1; i >= 0; i--)
1880           {
1881             Rectangle r = (Rectangle) paintRectangles.get(i);
1882             if (r.intersects(compBounds))
1883               {
1884                 Rectangle compRect = r.intersection(compBounds);
1885                 componentRectangles.add(compRect);
1886                 // If the component is opaque, split up each paint rect and
1887                 // add paintRect - compBounds to the newPaintRects array.
1888                 if (isOpaque)
1889                   {
1890                     int x, y, w, h;
1891                     Rectangle rect = new Rectangle();
1892
1893                     // The north retangle.
1894                     x = Math.max(compBounds.x, r.x);
1895                     y = r.y;
1896                     w = Math.min(compBounds.width, r.width + r.x - x);
1897                     h = compBounds.y - r.y;
1898                     rect.setBounds(x, y, w, h);
1899                     if (! rect.isEmpty())
1900                       {
1901                         newPaintRects.add(rect);
1902                         rect = new Rectangle();
1903                       }
1904
1905                     // The south rectangle.
1906                     x = Math.max(compBounds.x, r.x);
1907                     y = compBounds.y + compBounds.height;
1908                     w = Math.min(compBounds.width, r.width + r.x - x);
1909                     h = r.height - (compBounds.y - r.y) - compBounds.height;
1910                     rect.setBounds(x, y, w, h);
1911                     if (! rect.isEmpty())
1912                       {
1913                         newPaintRects.add(rect);
1914                         rect = new Rectangle();
1915                       }
1916
1917                     // The west rectangle.
1918                     x = r.x;
1919                     y = r.y;
1920                     w = compBounds.x - r.x;
1921                     h = r.height;
1922                     rect.setBounds(x, y, w, h);
1923                     if (! rect.isEmpty())
1924                       {
1925                         newPaintRects.add(rect);
1926                         rect = new Rectangle();
1927                       }
1928
1929                     // The east rectangle.
1930                     x = compBounds.x + compBounds.width;
1931                     y = r.y;
1932                     w = r.width - (compBounds.x - r.x) - compBounds.width;
1933                     h = r.height;
1934                     rect.setBounds(x, y, w, h);
1935                     if (! rect.isEmpty())
1936                       {
1937                         newPaintRects.add(rect);
1938                       }
1939                   }
1940                 else
1941                   {
1942                     // Not opaque, need to reuse the current paint rectangles
1943                     // for the next component.
1944                     newPaintRects.add(r);
1945                   }
1946                 
1947               }
1948             else
1949               {
1950                 newPaintRects.add(r);
1951               }
1952           }
1953
1954         // Replace the paintRectangles with the new split up
1955         // paintRectangles.
1956         paintRectangles.clear();
1957         paintRectangles.addAll(newPaintRects);
1958         newPaintRects.clear();
1959
1960         // Store paint rectangles if there are any for the current component.
1961         int compRectsSize = componentRectangles.size();
1962         if (compRectsSize > 0)
1963           {
1964             componentRectangles.add(comp);
1965             paintRegions.add(componentRectangles);
1966             componentRectangles = new ArrayList();
1967           }
1968       }
1969
1970     // paintingTile becomes true just before we start painting the component's
1971     // children.
1972     paintingTile = true;
1973
1974     // We must go through the painting regions backwards, because the
1975     // topmost components have been added first, followed by the components
1976     // below.
1977     int prEndIndex = paintRegions.size() - 1;
1978     for (int i = prEndIndex; i >= 0; i--)
1979       {
1980         // paintingTile must be set to false before we begin to start painting
1981         // the last tile.
1982         if (i == 0)
1983           paintingTile = false;
1984
1985         ArrayList paintingRects = (ArrayList) paintRegions.get(i);
1986         // The last element is always the component.
1987         Component c = (Component) paintingRects.get(paintingRects.size() - 1);
1988         int endIndex = paintingRects.size() - 2;
1989         for (int j = 0; j <= endIndex; j++)
1990           {
1991             Rectangle cBounds = c.getBounds();
1992             Rectangle bounds = (Rectangle) paintingRects.get(j);
1993             Rectangle oldClip = g.getClipBounds();
1994             if (oldClip == null)
1995               oldClip = bounds;
1996
1997             boolean translated = false;
1998             try
1999               {
2000                 g.setClip(bounds);
2001                 g.translate(cBounds.x, cBounds.y);
2002                 translated = true;
2003                 c.paint(g);
2004               }
2005             finally
2006               {
2007                 if (translated)
2008                   g.translate(-cBounds.x, -cBounds.y);
2009                 g.setClip(oldClip);
2010               }
2011           }
2012       }
2013     g.setClip(originalClip);
2014   }
2015
2016   /**
2017    * Paints the children of this container when it is marked as
2018    * optimizedDrawingEnabled. In this case the container can guarantee that
2019    * it's children are tiled, which allows for a much more efficient
2020    * algorithm to determine the minimum rectangles to be painted for
2021    * each child.
2022    *
2023    * @param g the graphics context to use
2024    */
2025   private void paintChildrenOptimized(Graphics g)
2026   {
2027     Shape originalClip = g.getClip();
2028     Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
2029     g.clipRect(inner.x, inner.y, inner.width, inner.height);
2030     Component[] children = getComponents();
2031
2032     // paintingTile becomes true just before we start painting the component's
2033     // children.
2034     paintingTile = true;
2035     for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
2036       {
2037         // paintingTile must be set to false before we begin to start painting
2038         // the last tile.
2039         if (i == children.length - 1)
2040           paintingTile = false;
2041
2042         if (!children[i].isVisible())
2043           continue;
2044
2045         Rectangle bounds = children[i].getBounds(rectCache);
2046         Rectangle oldClip = g.getClipBounds();
2047         if (oldClip == null)
2048           oldClip = bounds;
2049
2050         if (!g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height))
2051           continue;
2052
2053         boolean translated = false;
2054         try
2055           {
2056             g.clipRect(bounds.x, bounds.y, bounds.width, bounds.height);
2057             g.translate(bounds.x, bounds.y);
2058             translated = true;
2059             children[i].paint(g);
2060           }
2061         finally
2062           {
2063             if (translated)
2064               g.translate(-bounds.x, -bounds.y);
2065             g.setClip(oldClip);
2066           }
2067       }
2068     g.setClip(originalClip);
2069   }
2070
2071   /**
2072    * Paint the component's body. This usually means calling {@link
2073    * ComponentUI#update} on the {@link #ui} property of the component, if
2074    * it is non-<code>null</code>. You may override this if you wish to
2075    * customize the component's body-painting behavior. The component's body
2076    * is painted first, before the border and children.
2077    *
2078    * @param g The graphics context with which to paint the body
2079    *
2080    * @see #paint
2081    * @see #paintBorder
2082    * @see #paintChildren
2083    */
2084   protected void paintComponent(Graphics g)
2085   {
2086     if (ui != null)
2087       {
2088         Graphics g2 = g;
2089         if (!(g instanceof Graphics2D))
2090           g2 = g.create();
2091         ui.update(g2, this);
2092         if (!(g instanceof Graphics2D))
2093           g2.dispose();
2094       }
2095   }
2096
2097   /**
2098    * A variant of {@link #paintImmediately(Rectangle)} which takes
2099    * integer parameters.
2100    *
2101    * @param x The left x coordinate of the dirty region
2102    * @param y The top y coordinate of the dirty region
2103    * @param w The width of the dirty region
2104    * @param h The height of the dirty region
2105    */
2106   public void paintImmediately(int x, int y, int w, int h)
2107   {
2108     paintImmediately(new Rectangle(x, y, w, h));
2109   }
2110
2111   /**
2112    * Transform the provided dirty rectangle for this component into the
2113    * appropriate ancestral {@link JRootPane} and call {@link #paint} on
2114    * that root pane. This method is called from the {@link RepaintManager}
2115    * and should always be called within the painting thread.
2116    *
2117    * <p>This method will acquire a double buffer from the {@link
2118    * RepaintManager} if the component's {@link #doubleBuffered} property is
2119    * <code>true</code> and the <code>paint</code> call is the
2120    * <em>first</em> recursive <code>paint</code> call inside swing.</p>
2121    *
2122    * <p>The method will also modify the provided {@link Graphics} context
2123    * via the {@link #getComponentGraphics} method. If you want to customize
2124    * the graphics object used for painting, you should override that method
2125    * rather than <code>paint</code>.</p>
2126    *
2127    * @param r The dirty rectangle to paint
2128    */
2129   public void paintImmediately(Rectangle r)
2130   {
2131     // Try to find a root pane for this component.
2132     //Component root = findPaintRoot(r);
2133     Component root = findPaintRoot(r);
2134     // If no paint root is found, then this component is completely overlapped
2135     // by another component and we don't need repainting.
2136     if (root == null)
2137       return;
2138     if (root == null || !root.isShowing())
2139       return;
2140
2141     Rectangle rootClip = SwingUtilities.convertRectangle(this, r, root);
2142     if (root instanceof JComponent)
2143       ((JComponent) root).paintImmediately2(rootClip);
2144     else
2145       root.repaint(rootClip.x, rootClip.y, rootClip.width, rootClip.height);
2146   }
2147
2148   /**
2149    * Performs the actual work of paintImmediatly on the repaint root.
2150    *
2151    * @param r the area to be repainted
2152    */
2153   void paintImmediately2(Rectangle r)
2154   {
2155     RepaintManager rm = RepaintManager.currentManager(this);
2156     if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
2157       paintDoubleBuffered(r);
2158     else
2159       paintSimple(r);
2160   }
2161
2162   /**
2163    * Gets the root of the component given. If a parent of the 
2164    * component is an instance of Applet, then the applet is 
2165    * returned. The applet is considered the root for painting
2166    * and adding/removing components. Otherwise, the root Window
2167    * is returned if it exists.
2168    * 
2169    * @param comp - The component to get the root for.
2170    * @return the parent root. An applet if it is a parent,
2171    * or the root window. If neither exist, null is returned.
2172    */
2173   private Component getRoot(Component comp)
2174   {
2175       Applet app = null;
2176       
2177       while (comp != null)
2178         {
2179           if (app == null && comp instanceof Window)
2180             return comp;
2181           else if (comp instanceof Applet)
2182             app = (Applet) comp;
2183           comp = comp.getParent();
2184         }
2185       
2186       return app;
2187   }
2188   
2189   /**
2190    * Performs double buffered repainting.
2191    */
2192   private void paintDoubleBuffered(Rectangle r)
2193   {
2194     RepaintManager rm = RepaintManager.currentManager(this);
2195
2196     // Paint on the offscreen buffer.
2197     Component root = getRoot(this);
2198     Image buffer = rm.getOffscreenBuffer(this, root.getWidth(),
2199                                          root.getHeight());
2200     //Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
2201     Point translation = SwingUtilities.convertPoint(this, 0, 0, root);
2202     Graphics g2 = buffer.getGraphics();
2203     g2.translate(translation.x, translation.y);
2204     g2.setClip(r.x, r.y, r.width, r.height);
2205     g2 = getComponentGraphics(g2);
2206     isPaintingDoubleBuffered = true;
2207     try
2208       {
2209         paint(g2);
2210       }
2211     finally
2212       {
2213         isPaintingDoubleBuffered = false;
2214         g2.dispose();
2215       }
2216
2217     // Paint the buffer contents on screen.
2218     rm.commitBuffer(root, new Rectangle(translation.x + r.x,
2219                                         translation.y + r.y, r.width,
2220                                         r.height));
2221   }
2222
2223   /**
2224    * Performs normal painting without double buffering.
2225    *
2226    * @param r the area that should be repainted
2227    */
2228   void paintSimple(Rectangle r)
2229   {
2230     Graphics g = getGraphics();
2231     Graphics g2 = getComponentGraphics(g);
2232     g2.setClip(r);
2233     paint(g2);
2234     g2.dispose();
2235     if (g != g2)
2236       g.dispose();
2237   }
2238
2239   /**
2240    * Return a string representation for this component, for use in
2241    * debugging.
2242    *
2243    * @return A string describing this component.
2244    */
2245   protected String paramString()
2246   {
2247     StringBuffer sb = new StringBuffer();
2248     sb.append(super.paramString());
2249     sb.append(",alignmentX=").append(getAlignmentX());
2250     sb.append(",alignmentY=").append(getAlignmentY());
2251     sb.append(",border=");
2252     if (getBorder() != null)
2253       sb.append(getBorder());
2254     sb.append(",maximumSize=");
2255     if (getMaximumSize() != null)
2256       sb.append(getMaximumSize());
2257     sb.append(",minimumSize=");
2258     if (getMinimumSize() != null)
2259       sb.append(getMinimumSize());
2260     sb.append(",preferredSize=");
2261     if (getPreferredSize() != null)
2262       sb.append(getPreferredSize());
2263     return sb.toString();
2264   }
2265
2266   /**
2267    * A variant of {@link
2268    * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
2269    * provides <code>null</code> for the command name.   
2270    */
2271   public void registerKeyboardAction(ActionListener act,
2272                                      KeyStroke stroke, 
2273                                      int cond)
2274   {
2275     registerKeyboardAction(act, null, stroke, cond);
2276   }
2277
2278   /* 
2279    * There is some charmingly undocumented behavior sun seems to be using
2280    * to simulate the old register/unregister keyboard binding API. It's not
2281    * clear to me why this matters, but we shall endeavour to follow suit.
2282    *
2283    * Two main thing seem to be happening when you do registerKeyboardAction():
2284    * 
2285    *  - no actionMap() entry gets created, just an entry in inputMap()
2286    *
2287    *  - the inputMap() entry is a proxy class which invokes the the
2288    *  binding's actionListener as a target, and which clobbers the command
2289    *  name sent in the ActionEvent, providing the binding command name
2290    *  instead.
2291    *
2292    * This much you can work out just by asking the input and action maps
2293    * what they contain after making bindings, and watching the event which
2294    * gets delivered to the recipient. Beyond that, it seems to be a
2295    * sun-private solution so I will only immitate it as much as it matters
2296    * to external observers.
2297    */
2298   private static class ActionListenerProxy
2299     extends AbstractAction
2300   {
2301     ActionListener target;
2302     String bindingCommandName;
2303
2304     public ActionListenerProxy(ActionListener li, 
2305                                String cmd)
2306     {
2307       target = li;
2308       bindingCommandName = cmd;
2309     }
2310
2311     public void actionPerformed(ActionEvent e)
2312     {
2313       ActionEvent derivedEvent = new ActionEvent(e.getSource(),
2314                                                  e.getID(),
2315                                                  bindingCommandName,
2316                                                  e.getModifiers());
2317       target.actionPerformed(derivedEvent);
2318     }
2319   }
2320
2321   
2322   /**
2323    * An obsolete method to register a keyboard action on this component.
2324    * You should use <code>getInputMap</code> and <code>getActionMap</code>
2325    * to fetch mapping tables from keystrokes to commands, and commands to
2326    * actions, respectively, and modify those mappings directly.
2327    *
2328    * @param act The action to be registered
2329    * @param cmd The command to deliver in the delivered {@link
2330    *     java.awt.event.ActionEvent}
2331    * @param stroke The keystroke to register on
2332    * @param cond One of the values {@link #UNDEFINED_CONDITION},
2333    *     {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
2334    *     {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
2335    *     be met for the action to be fired
2336    *
2337    * @see #unregisterKeyboardAction
2338    * @see #getConditionForKeyStroke
2339    * @see #resetKeyboardActions
2340    */
2341   public void registerKeyboardAction(ActionListener act, 
2342                                      String cmd,
2343                                      KeyStroke stroke, 
2344                                      int cond)
2345   {
2346     getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
2347   }
2348
2349   public final void setInputMap(int condition, InputMap map)
2350   {
2351     enableEvents(AWTEvent.KEY_EVENT_MASK);
2352     switch (condition)
2353       {
2354       case WHEN_FOCUSED:
2355         inputMap_whenFocused = map;
2356         break;
2357
2358       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2359         inputMap_whenAncestorOfFocused = map;
2360         break;
2361
2362       case WHEN_IN_FOCUSED_WINDOW:
2363         if (map != null && !(map instanceof ComponentInputMap))
2364             throw new 
2365               IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW " + 
2366                                        "InputMap must be a ComponentInputMap");
2367         inputMap_whenInFocusedWindow = (ComponentInputMap)map;
2368         break;
2369         
2370       case UNDEFINED_CONDITION:
2371       default:
2372         throw new IllegalArgumentException();
2373       }
2374   }
2375
2376   public final InputMap getInputMap(int condition)
2377   {
2378     enableEvents(AWTEvent.KEY_EVENT_MASK);
2379     switch (condition)
2380       {
2381       case WHEN_FOCUSED:
2382         if (inputMap_whenFocused == null)
2383           inputMap_whenFocused = new InputMap();
2384         return inputMap_whenFocused;
2385
2386       case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2387         if (inputMap_whenAncestorOfFocused == null)
2388           inputMap_whenAncestorOfFocused = new InputMap();
2389         return inputMap_whenAncestorOfFocused;
2390
2391       case WHEN_IN_FOCUSED_WINDOW:
2392         if (inputMap_whenInFocusedWindow == null)
2393           inputMap_whenInFocusedWindow = new ComponentInputMap(this);
2394         return inputMap_whenInFocusedWindow;
2395
2396       case UNDEFINED_CONDITION:
2397       default:
2398         return null;
2399       }
2400   }
2401
2402   public final InputMap getInputMap()
2403   {
2404     return getInputMap(WHEN_FOCUSED);
2405   }
2406
2407   public final ActionMap getActionMap()
2408   {
2409     if (actionMap == null)
2410       actionMap = new ActionMap();
2411     return actionMap;
2412   }
2413
2414   public final void setActionMap(ActionMap map)
2415   {
2416     actionMap = map;
2417   }
2418
2419   /**
2420    * Return the condition that determines whether a registered action
2421    * occurs in response to the specified keystroke.
2422    *
2423    * As of 1.3 KeyStrokes can be registered with multiple simultaneous
2424    * conditions.
2425    *
2426    * @param ks The keystroke to return the condition of
2427    *
2428    * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
2429    *     #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
2430    *     #WHEN_IN_FOCUSED_WINDOW}
2431    *
2432    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)   
2433    * @see #unregisterKeyboardAction   
2434    * @see #resetKeyboardActions
2435    */
2436   public int getConditionForKeyStroke(KeyStroke ks)
2437   {
2438     if (inputMap_whenFocused != null 
2439         && inputMap_whenFocused.get(ks) != null)
2440       return WHEN_FOCUSED;
2441     else if (inputMap_whenAncestorOfFocused != null 
2442              && inputMap_whenAncestorOfFocused.get(ks) != null)
2443       return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
2444     else if (inputMap_whenInFocusedWindow != null 
2445              && inputMap_whenInFocusedWindow.get(ks) != null)
2446       return WHEN_IN_FOCUSED_WINDOW;
2447     else
2448       return UNDEFINED_CONDITION;
2449   }
2450
2451   /**
2452    * Get the ActionListener (typically an {@link Action} object) which is
2453    * associated with a particular keystroke. 
2454    *
2455    * @param ks The keystroke to retrieve the action of
2456    *
2457    * @return The action associated with the specified keystroke
2458    */
2459   public ActionListener getActionForKeyStroke(KeyStroke ks)
2460   {
2461     Object cmd = getInputMap().get(ks);
2462     if (cmd != null)
2463       {
2464         if (cmd instanceof ActionListenerProxy)
2465           return (ActionListenerProxy) cmd;
2466         else if (cmd instanceof String)
2467           return getActionMap().get(cmd);
2468       }
2469     return null;
2470   }
2471
2472   /**
2473    * A hook for subclasses which want to customize event processing.
2474    */
2475   protected void processComponentKeyEvent(KeyEvent e)
2476   {
2477     // This method does nothing, it is meant to be overridden by subclasses.
2478   }
2479
2480   /**
2481    * Override the default key dispatch system from Component to hook into
2482    * the swing {@link InputMap} / {@link ActionMap} system.
2483    *
2484    * See <a
2485    * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">
2486    * this report</a> for more details, it's somewhat complex.
2487    */
2488   protected void processKeyEvent(KeyEvent e)
2489   {
2490     // let the AWT event processing send KeyEvents to registered listeners
2491     super.processKeyEvent(e);
2492     processComponentKeyEvent(e);
2493
2494     if (e.isConsumed())
2495       return;
2496
2497     // Input maps are checked in this order:
2498     // 1. The focused component's WHEN_FOCUSED map is checked.
2499     // 2. The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map.
2500     // 3. The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps of the focused
2501     //    component's parent, then its parent's parent, and so on.
2502     //    Note: Input maps for disabled components are skipped.
2503     // 4. The WHEN_IN_FOCUSED_WINDOW maps of all the enabled components in
2504     //    the focused window are searched.
2505     
2506     KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
2507     boolean pressed = e.getID() == KeyEvent.KEY_PRESSED;
2508     
2509     if (processKeyBinding(keyStroke, e, WHEN_FOCUSED, pressed))
2510       {
2511         // This is step 1 from above comment.
2512         e.consume();
2513         return;
2514       }
2515     else if (processKeyBinding
2516              (keyStroke, e, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2517       {
2518         // This is step 2 from above comment.
2519         e.consume();
2520         return;
2521       }
2522     
2523     // This is step 3 from above comment.
2524     Container current = getParent();    
2525     while (current != null)
2526       { 
2527         // If current is a JComponent, see if it handles the event in its
2528         // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT maps.
2529         if ((current instanceof JComponent) && 
2530             ((JComponent)current).processKeyBinding 
2531             (keyStroke, e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2532           {
2533             e.consume();
2534             return;
2535           }     
2536         
2537         // Stop when we've tried a top-level container and it didn't handle it
2538         if (current instanceof Window || current instanceof Applet)
2539           break;        
2540         
2541         // Move up the hierarchy
2542         current = current.getParent();
2543       }
2544     
2545     // Current being null means the JComponent does not currently have a
2546     // top-level ancestor, in which case we don't need to check 
2547     // WHEN_IN_FOCUSED_WINDOW bindings.
2548     if (current == null || e.isConsumed())
2549       return;
2550     
2551     // This is step 4 from above comment.  KeyboardManager maintains mappings
2552     // related to WHEN_IN_FOCUSED_WINDOW bindings so that we don't have to 
2553     // traverse the containment hierarchy each time.
2554     if (KeyboardManager.getManager().processKeyStroke(current, keyStroke, e))
2555       e.consume();
2556   }
2557
2558   protected boolean processKeyBinding(KeyStroke ks,
2559                                       KeyEvent e,
2560                                       int condition,
2561                                       boolean pressed)
2562   { 
2563     if (isEnabled())
2564       {
2565         Action act = null;
2566         InputMap map = getInputMap(condition);
2567         if (map != null)
2568           {
2569             Object cmd = map.get(ks);
2570             if (cmd != null)
2571               {
2572                 if (cmd instanceof ActionListenerProxy)
2573                   act = (Action) cmd;
2574                 else 
2575                   act = (Action) getActionMap().get(cmd);
2576               }
2577           }
2578         if (act != null && act.isEnabled())
2579           return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
2580       }
2581     return false;
2582   }
2583   
2584   /**
2585    * Remove a keyboard action registry.
2586    *
2587    * @param aKeyStroke The keystroke to unregister
2588    *
2589    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2590    * @see #getConditionForKeyStroke
2591    * @see #resetKeyboardActions
2592    */
2593   public void unregisterKeyboardAction(KeyStroke aKeyStroke)
2594   {
2595     ActionMap am = getActionMap();
2596     // This loops through the conditions WHEN_FOCUSED,
2597     // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT and WHEN_IN_FOCUSED_WINDOW.
2598     for (int cond = 0; cond < 3; cond++)
2599       {
2600         InputMap im = getInputMap(cond);
2601         if (im != null)
2602           {
2603             Object action = im.get(aKeyStroke);
2604             if (action != null && am != null)
2605               am.remove(action);
2606             im.remove(aKeyStroke);
2607           }
2608       }
2609   }
2610
2611
2612   /**
2613    * Reset all keyboard action registries.
2614    *
2615    * @see #registerKeyboardAction(ActionListener, KeyStroke, int)
2616    * @see #unregisterKeyboardAction
2617    * @see #getConditionForKeyStroke
2618    */
2619   public void resetKeyboardActions()
2620   {
2621     if (inputMap_whenFocused != null)
2622       inputMap_whenFocused.clear();
2623     if (inputMap_whenAncestorOfFocused != null)
2624       inputMap_whenAncestorOfFocused.clear();
2625     if (inputMap_whenInFocusedWindow != null)
2626       inputMap_whenInFocusedWindow.clear();
2627     if (actionMap != null)
2628       actionMap.clear();
2629   }
2630
2631   /**
2632    * Mark the described region of this component as dirty in the current
2633    * {@link RepaintManager}. This will queue an asynchronous repaint using
2634    * the system painting thread in the near future.
2635    *
2636    * @param tm ignored
2637    * @param x coordinate of the region to mark as dirty
2638    * @param y coordinate of the region to mark as dirty
2639    * @param width dimension of the region to mark as dirty
2640    * @param height dimension of the region to mark as dirty
2641    */
2642   public void repaint(long tm, int x, int y, int width, int height)
2643   {
2644      RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width,
2645                                                         height);
2646   }
2647
2648   /**
2649    * Mark the described region of this component as dirty in the current
2650    * {@link RepaintManager}. This will queue an asynchronous repaint using
2651    * the system painting thread in the near future.
2652    *
2653    * @param r The rectangle to mark as dirty
2654    */
2655   public void repaint(Rectangle r)
2656   {
2657     RepaintManager.currentManager(this).addDirtyRegion(this, r.x, r.y, r.width,
2658                                                        r.height);
2659   }
2660
2661   /**
2662    * Request focus on the default component of this component's {@link
2663    * FocusTraversalPolicy}.
2664    *
2665    * @return The result of {@link #requestFocus()}
2666    *
2667    * @deprecated Use {@link #requestFocus()} on the default component provided
2668    *     from the {@link FocusTraversalPolicy} instead.
2669    */
2670   public boolean requestDefaultFocus()
2671   {
2672     return false;
2673   }
2674
2675   /**
2676    * Queue a an invalidation and revalidation of this component, using 
2677    * {@link RepaintManager#addInvalidComponent}.
2678    */
2679   public void revalidate()
2680   {
2681     if (! EventQueue.isDispatchThread())
2682       SwingUtilities.invokeLater(new Runnable()
2683         {
2684           public void run()
2685           {
2686             revalidate();
2687           }
2688         });
2689     else
2690       {
2691         invalidate();
2692         RepaintManager.currentManager(this).addInvalidComponent(this);
2693       }
2694   }
2695
2696   /**
2697    * Calls <code>scrollRectToVisible</code> on the component's parent. 
2698    * Components which can service this call should override.
2699    *
2700    * @param r The rectangle to make visible
2701    */
2702   public void scrollRectToVisible(Rectangle r)
2703   {
2704     Component p = getParent();
2705     if (p instanceof JComponent)
2706       ((JComponent) p).scrollRectToVisible(r);
2707   }
2708
2709   /**
2710    * Set the value of the {@link #alignmentX} property.
2711    *
2712    * @param a The new value of the property
2713    */
2714   public void setAlignmentX(float a)
2715   {
2716     if (a < 0.0F)
2717       alignmentX = 0.0F;
2718     else if (a > 1.0)
2719       alignmentX = 1.0F;
2720     else
2721       alignmentX = a;
2722   }
2723
2724   /**
2725    * Set the value of the {@link #alignmentY} property.
2726    *
2727    * @param a The new value of the property
2728    */
2729   public void setAlignmentY(float a)
2730   {
2731     if (a < 0.0F)
2732       alignmentY = 0.0F;
2733     else if (a > 1.0)
2734       alignmentY = 1.0F;
2735     else
2736       alignmentY = a;
2737   }
2738
2739   /**
2740    * Set the value of the {@link #autoscrolls} property.
2741    *
2742    * @param a The new value of the property
2743    */
2744   public void setAutoscrolls(boolean a)
2745   {
2746     autoscrolls = a;
2747     clientAutoscrollsSet = true;
2748   }
2749
2750   /**
2751    * Set the value of the {@link #debugGraphicsOptions} property.
2752    *
2753    * @param debugOptions The new value of the property
2754    */
2755   public void setDebugGraphicsOptions(int debugOptions)
2756   {
2757     debugGraphicsOptions = debugOptions;
2758   }
2759
2760   /**
2761    * Set the value of the {@link #doubleBuffered} property.
2762    *
2763    * @param db The new value of the property
2764    */
2765   public void setDoubleBuffered(boolean db)
2766   {
2767     doubleBuffered = db;
2768   }
2769
2770   /**
2771    * Set the value of the <code>enabled</code> property.
2772    *
2773    * @param enable The new value of the property
2774    */
2775   public void setEnabled(boolean enable)
2776   {
2777     if (enable == isEnabled())
2778       return;
2779     super.setEnabled(enable);
2780     firePropertyChange("enabled", !enable, enable);
2781     repaint();
2782   }
2783
2784   /**
2785    * Set the value of the <code>font</code> property.
2786    *
2787    * @param f The new value of the property
2788    */
2789   public void setFont(Font f)
2790   {
2791     if (f == getFont())
2792       return;
2793     super.setFont(f);
2794     revalidate();
2795     repaint();
2796   }
2797
2798   /**
2799    * Set the value of the <code>background</code> property.
2800    *
2801    * @param bg The new value of the property
2802    */
2803   public void setBackground(Color bg)
2804   {
2805     if (bg == getBackground())
2806       return;
2807     super.setBackground(bg);
2808     repaint();
2809   }
2810
2811   /**
2812    * Set the value of the <code>foreground</code> property.
2813    *
2814    * @param fg The new value of the property
2815    */
2816   public void setForeground(Color fg)
2817   {
2818     if (fg == getForeground())
2819       return;
2820     super.setForeground(fg);
2821     repaint();
2822   }
2823
2824   /**
2825    * Set the value of the {@link #maximumSize} property. The passed value is
2826    * copied, the later direct changes on the argument have no effect on the
2827    * property value.
2828    *
2829    * @param max The new value of the property
2830    */
2831   public void setMaximumSize(Dimension max)
2832   {
2833     Dimension oldMaximumSize = maximumSize;
2834     if (max != null) 
2835       maximumSize = new Dimension(max);
2836     else
2837       maximumSize = null;
2838     firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
2839   }
2840
2841   /**
2842    * Set the value of the {@link #minimumSize} property. The passed value is
2843    * copied, the later direct changes on the argument have no effect on the
2844    * property value.
2845    *
2846    * @param min The new value of the property
2847    */
2848   public void setMinimumSize(Dimension min)
2849   {
2850     Dimension oldMinimumSize = minimumSize;
2851     if (min != null)
2852       minimumSize = new Dimension(min);
2853     else
2854       minimumSize = null;
2855     firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
2856   }
2857
2858   /**
2859    * Set the value of the {@link #preferredSize} property. The passed value is
2860    * copied, the later direct changes on the argument have no effect on the
2861    * property value.
2862    *
2863    * @param pref The new value of the property
2864    */
2865   public void setPreferredSize(Dimension pref)
2866   {
2867     Dimension oldPreferredSize = preferredSize;
2868     if (pref != null)
2869       preferredSize = new Dimension(pref);
2870     else
2871       preferredSize = null;
2872     firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
2873   }
2874
2875   /**
2876    * Set the specified component to be the next component in the 
2877    * focus cycle, overriding the {@link FocusTraversalPolicy} for
2878    * this component.
2879    *
2880    * @param aComponent The component to set as the next focusable
2881    *
2882    * @deprecated Use FocusTraversalPolicy instead
2883    */
2884   public void setNextFocusableComponent(Component aComponent)
2885   {
2886     Container focusRoot = this;
2887     if (! this.isFocusCycleRoot())
2888       focusRoot = getFocusCycleRootAncestor();
2889
2890     FocusTraversalPolicy policy  = focusRoot.getFocusTraversalPolicy();
2891     if (policy instanceof CompatibilityFocusTraversalPolicy)
2892       {
2893         policy = new CompatibilityFocusTraversalPolicy(policy);
2894         focusRoot.setFocusTraversalPolicy(policy);
2895       }
2896     CompatibilityFocusTraversalPolicy p =
2897       (CompatibilityFocusTraversalPolicy) policy;
2898
2899     Component old = getNextFocusableComponent();
2900     if (old != null)
2901       {
2902         p.removeNextFocusableComponent(this, old);
2903       }
2904
2905     if (aComponent != null)
2906       {
2907         p.addNextFocusableComponent(this, aComponent);
2908       }
2909   }
2910
2911   /**
2912    * Set the value of the {@link #requestFocusEnabled} property.
2913    *
2914    * @param e The new value of the property
2915    */
2916   public void setRequestFocusEnabled(boolean e)
2917   {
2918     requestFocusEnabled = e;
2919   }
2920
2921   /**
2922    * Get the value of the {@link #transferHandler} property.
2923    *
2924    * @return The current value of the property
2925    *
2926    * @see #setTransferHandler
2927    */
2928
2929   public TransferHandler getTransferHandler()
2930   {
2931     return transferHandler;
2932   }
2933
2934   /**
2935    * Set the value of the {@link #transferHandler} property.
2936    *
2937    * @param newHandler The new value of the property
2938    *
2939    * @see #getTransferHandler
2940    */
2941
2942   public void setTransferHandler(TransferHandler newHandler)
2943   {
2944     if (transferHandler == newHandler)
2945       return;
2946
2947     TransferHandler oldHandler = transferHandler;
2948     transferHandler = newHandler;
2949     firePropertyChange("transferHandler", oldHandler, newHandler);
2950   }
2951
2952   /**
2953    * Set if the component should paint all pixels withing its bounds.
2954    * If this property is set to false, the component expects the cleared
2955    * background.
2956    *
2957    * @param isOpaque if true, paint all pixels. If false, expect the clean
2958    * background. 
2959    *
2960    * @see ComponentUI#update
2961    */
2962   public void setOpaque(boolean isOpaque)
2963   {
2964     boolean oldOpaque = opaque;
2965     opaque = isOpaque;
2966     clientOpaqueSet = true;
2967     firePropertyChange("opaque", oldOpaque, opaque);
2968   }
2969
2970   /**
2971    * Set the value of the visible property.
2972    *
2973    * If the value is changed, then the AncestorListeners of this component
2974    * and all its children (recursivly) are notified.
2975    *
2976    * @param v The new value of the property
2977    */
2978   public void setVisible(boolean v)
2979   {
2980     // No need to do anything if the actual value doesn't change.
2981     if (isVisible() == v)
2982       return;
2983
2984     super.setVisible(v);
2985
2986     // Notify AncestorListeners.
2987     if (v == true)
2988       fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
2989     else
2990       fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
2991
2992     Container parent = getParent();
2993     if (parent != null)
2994       parent.repaint(getX(), getY(), getWidth(), getHeight());
2995     revalidate();
2996   }
2997
2998   /**
2999    * Call {@link #paint}. 
3000    * 
3001    * @param g The graphics context to paint into
3002    */
3003   public void update(Graphics g)
3004   {
3005     paint(g);
3006   }
3007
3008   /**
3009    * Get the value of the UIClassID property. This property should be a key
3010    * in the {@link UIDefaults} table managed by {@link UIManager}, the
3011    * value of which is the name of a class to load for the component's
3012    * {@link #ui} property.
3013    *
3014    * @return A "symbolic" name which will map to a class to use for the
3015    * component's UI, such as <code>"ComponentUI"</code>
3016    *
3017    * @see #setUI
3018    * @see #updateUI
3019    */
3020   public String getUIClassID()
3021   {
3022     return "ComponentUI";
3023   }
3024
3025   /**
3026    * Install a new UI delegate as the component's {@link #ui} property. In
3027    * the process, this will call {@link ComponentUI#uninstallUI} on any
3028    * existing value for the {@link #ui} property, and {@link
3029    * ComponentUI#installUI} on the new UI delegate.
3030    *
3031    * @param newUI The new UI delegate to install
3032    *
3033    * @see #updateUI
3034    * @see #getUIClassID
3035    */
3036   protected void setUI(ComponentUI newUI)
3037   {
3038     if (ui != null)
3039       ui.uninstallUI(this);
3040
3041     ComponentUI oldUI = ui;
3042     ui = newUI;
3043
3044     if (ui != null)
3045       ui.installUI(this);
3046
3047     firePropertyChange("UI", oldUI, newUI);
3048     revalidate();
3049     repaint();
3050   }
3051
3052   /**
3053    * This method should be overridden in subclasses. In JComponent, the
3054    * method does nothing. In subclasses, it should a UI delegate
3055    * (corresponding to the symbolic name returned from {@link
3056    * #getUIClassID}) from the {@link UIManager}, and calls {@link #setUI}
3057    * with the new delegate.
3058    */
3059   public void updateUI()
3060   {
3061     // Nothing to do here.
3062   }
3063
3064   public static Locale getDefaultLocale()
3065   {
3066     return defaultLocale;
3067   }
3068   
3069   public static void setDefaultLocale(Locale l)
3070   {
3071     defaultLocale = l;
3072   }
3073   
3074   /**
3075    * Returns the currently set input verifier for this component.
3076    *
3077    * @return the input verifier, or <code>null</code> if none
3078    */
3079   public InputVerifier getInputVerifier()
3080   {
3081     return inputVerifier;
3082   }
3083
3084   /**
3085    * Sets the input verifier to use by this component.
3086    *
3087    * @param verifier the input verifier, or <code>null</code>
3088    */
3089   public void setInputVerifier(InputVerifier verifier)
3090   {
3091     InputVerifier oldVerifier = inputVerifier;
3092     inputVerifier = verifier;
3093     firePropertyChange("inputVerifier", oldVerifier, verifier);
3094   }
3095
3096   /**
3097    * @since 1.3
3098    */
3099   public boolean getVerifyInputWhenFocusTarget()
3100   {
3101     return verifyInputWhenFocusTarget;
3102   }
3103
3104   /**
3105    * @since 1.3
3106    */
3107   public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
3108   {
3109     if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
3110       return;
3111
3112     this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
3113     firePropertyChange("verifyInputWhenFocusTarget",
3114                        ! verifyInputWhenFocusTarget,
3115                        verifyInputWhenFocusTarget);
3116   }
3117
3118   /**
3119    * Requests that this component gets the input focus if the
3120    * requestFocusEnabled property is set to <code>true</code>.
3121    * This also means that this component's top-level window becomes
3122    * the focused window, if that is not already the case.
3123    *
3124    * The preconditions that have to be met to become a focus owner is that
3125    * the component must be displayable, visible and focusable.
3126    *
3127    * Note that this signals only a request for becoming focused. There are
3128    * situations in which it is not possible to get the focus. So developers
3129    * should not assume that the component has the focus until it receives
3130    * a {@link java.awt.event.FocusEvent} with a value of
3131    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3132    *
3133    * @see Component#requestFocus()
3134    */
3135   public void requestFocus()
3136   {
3137     if (isRequestFocusEnabled())
3138       super.requestFocus();
3139   }
3140
3141   /**
3142    * This method is overridden to make it public so that it can be used
3143    * by look and feel implementations.
3144    *
3145    * You should not use this method directly. Instead you are strongly
3146    * encouraged to call {@link #requestFocus()} or 
3147    * {@link #requestFocusInWindow()} instead.
3148    *
3149    * @param temporary if the focus change is temporary
3150    *
3151    * @return <code>false</code> if the focus change request will definitly
3152    *     fail, <code>true</code> if it will likely succeed
3153    *
3154    * @see Component#requestFocus(boolean)
3155    *
3156    * @since 1.4
3157    */
3158   public boolean requestFocus(boolean temporary)
3159   {
3160     return super.requestFocus(temporary);
3161   }
3162
3163   /**
3164    * Requests that this component gets the input focus if the top level
3165    * window that contains this component has the focus and the
3166    * requestFocusEnabled property is set to <code>true</code>.
3167    *
3168    * The preconditions that have to be met to become a focus owner is that
3169    * the component must be displayable, visible and focusable.
3170    *
3171    * Note that this signals only a request for becoming focused. There are
3172    * situations in which it is not possible to get the focus. So developers
3173    * should not assume that the component has the focus until it receives
3174    * a {@link java.awt.event.FocusEvent} with a value of
3175    * {@link java.awt.event.FocusEvent#FOCUS_GAINED}.
3176    *
3177    * @return <code>false</code> if the focus change request will definitly
3178    *     fail, <code>true</code> if it will likely succeed
3179    *
3180    * @see Component#requestFocusInWindow()
3181    */
3182   public boolean requestFocusInWindow()
3183   {
3184     if (isRequestFocusEnabled())
3185       return super.requestFocusInWindow();
3186     else
3187       return false;
3188   }
3189
3190   /**
3191    * This method is overridden to make it public so that it can be used
3192    * by look and feel implementations.
3193    *
3194    * You should not use this method directly. Instead you are strongly
3195    * encouraged to call {@link #requestFocus()} or 
3196    * {@link #requestFocusInWindow()} instead.
3197    *
3198    * @param temporary if the focus change is temporary
3199    *
3200    * @return <code>false</code> if the focus change request will definitly
3201    *     fail, <code>true</code> if it will likely succeed
3202    *
3203    * @see Component#requestFocus(boolean)
3204    *
3205    * @since 1.4
3206    */
3207   protected boolean requestFocusInWindow(boolean temporary)
3208   {
3209     return super.requestFocusInWindow(temporary);
3210   }
3211
3212   /**
3213    * Receives notification if this component is added to a parent component.
3214    *
3215    * Notification is sent to all registered AncestorListeners about the
3216    * new parent.
3217    *
3218    * This method sets up ActionListeners for all registered KeyStrokes of
3219    * this component in the chain of parent components.
3220    *
3221    * A PropertyChange event is fired to indicate that the ancestor property
3222    * has changed.
3223    *
3224    * This method is used internally and should not be used in applications.
3225    */
3226   public void addNotify()
3227   {
3228     // Register the WHEN_IN_FOCUSED_WINDOW keyboard bindings
3229     // Note that here we unregister all bindings associated with
3230     // this component and then re-register them.  This may be more than
3231     // necessary if the top-level ancestor hasn't changed.  Should
3232     // maybe improve this.
3233     KeyboardManager km = KeyboardManager.getManager();
3234     km.clearBindingsForComp(this);
3235     km.registerEntireMap((ComponentInputMap)
3236                          this.getInputMap(WHEN_IN_FOCUSED_WINDOW));
3237     super.addNotify();
3238
3239     // Notify AncestorListeners.
3240     fireAncestorEvent(this, AncestorEvent.ANCESTOR_ADDED);
3241
3242     // fire property change event for 'ancestor'
3243     firePropertyChange("ancestor", null, getParent());
3244   }
3245
3246   /**
3247    * Receives notification that this component no longer has a parent.
3248    *
3249    * This method sends an AncestorEvent to all registered AncestorListeners,
3250    * notifying them that the parent is gone.
3251    *
3252    * The keybord actions of this component are removed from the parent and
3253    * its ancestors.
3254    *
3255    * A PropertyChangeEvent is fired to indicate that the 'ancestor' property
3256    * has changed.
3257    *
3258    * This method is called before the component is actually removed from
3259    * its parent, so the parent is still visible through 
3260    * {@link Component#getParent}.
3261    */
3262   public void removeNotify()
3263   {
3264     super.removeNotify();
3265
3266     KeyboardManager.getManager().clearBindingsForComp(this);
3267     
3268     // Notify ancestor listeners.
3269     fireAncestorEvent(this, AncestorEvent.ANCESTOR_REMOVED);
3270
3271     // fire property change event for 'ancestor'
3272     firePropertyChange("ancestor", getParent(), null);
3273   }
3274
3275   /**
3276    * Returns <code>true</code> if the coordinates (x, y) lie within
3277    * the bounds of this component and <code>false</code> otherwise.
3278    * x and y are relative to the coordinate space of the component.
3279    *
3280    * @param x the X coordinate of the point to check
3281    * @param y the Y coordinate of the point to check
3282    *
3283    * @return <code>true</code> if the specified point lies within the bounds
3284    *     of this component, <code>false</code> otherwise
3285    */
3286   public boolean contains(int x, int y)
3287   {
3288     if (ui == null)
3289       return super.contains(x, y);
3290     else
3291       return ui.contains(this, x, y);
3292   }
3293
3294   /**
3295    * Disables this component.
3296    *
3297    * @deprecated replaced by {@link #setEnabled(boolean)}
3298    */
3299   public void disable()
3300   {
3301     super.disable();
3302   }
3303
3304   /**
3305    * Enables this component.
3306    *
3307    * @deprecated replaced by {@link #setEnabled(boolean)}
3308    */
3309   public void enable()
3310   {
3311     super.enable();
3312   }
3313
3314   /**
3315    * Returns the Graphics context for this component. This can be used
3316    * to draw on a component.
3317    *
3318    * @return the Graphics context for this component
3319    */
3320   public Graphics getGraphics()
3321   {
3322     return super.getGraphics();
3323   }
3324
3325   /**
3326    * Returns the X coordinate of the upper left corner of this component.
3327    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3328    * because it does not cause any heap allocation.
3329    *
3330    * @return the X coordinate of the upper left corner of the component
3331    */
3332   public int getX()
3333   {
3334     return super.getX();
3335   }
3336
3337   /**
3338    * Returns the Y coordinate of the upper left corner of this component.
3339    * Prefer this method over {@link #getBounds} or {@link #getLocation}
3340    * because it does not cause any heap allocation.
3341    *
3342    * @return the Y coordinate of the upper left corner of the component
3343    */
3344   public int getY()
3345   {
3346     return super.getY();
3347   }
3348
3349   /**
3350    * Returns the height of this component. Prefer this method over
3351    * {@link #getBounds} or {@link #getSize} because it does not cause
3352    * any heap allocation.
3353    *
3354    * @return the height of the component
3355    */
3356   public int getHeight()
3357   {
3358     return super.getHeight();
3359   }
3360
3361   /**
3362    * Returns the width of this component. Prefer this method over
3363    * {@link #getBounds} or {@link #getSize} because it does not cause
3364    * any heap allocation.
3365    *
3366    * @return the width of the component
3367    */
3368   public int getWidth()
3369   {
3370     return super.getWidth();
3371   }
3372
3373   /**
3374    * Prints this component to the given Graphics context. A call to this
3375    * method results in calls to the methods {@link #printComponent},
3376    * {@link #printBorder} and {@link #printChildren} in this order.
3377    *
3378    * Double buffering is temporarily turned off so the painting goes directly
3379    * to the supplied Graphics context.
3380    *
3381    * @param g the Graphics context to print onto
3382    */
3383   public void print(Graphics g)
3384   {
3385     boolean doubleBufferState = isDoubleBuffered();
3386     setDoubleBuffered(false);
3387     printComponent(g);
3388     printBorder(g);
3389     printChildren(g);
3390     setDoubleBuffered(doubleBufferState);
3391   }
3392
3393   /**
3394    * Prints this component to the given Graphics context. This invokes
3395    * {@link #print}.
3396    *
3397    * @param g the Graphics context to print onto
3398    */
3399   public void printAll(Graphics g)
3400   {
3401     print(g);
3402   }
3403
3404   /**
3405    * Prints this component to the specified Graphics context. The default
3406    * behaviour is to invoke {@link #paintComponent}. Override this
3407    * if you want special behaviour for printing.
3408    *
3409    * @param g the Graphics context to print onto
3410    *
3411    * @since 1.3
3412    */
3413   protected void printComponent(Graphics g)
3414   {
3415     paintComponent(g);
3416   }
3417
3418   /**
3419    * Print this component's children to the specified Graphics context.
3420    * The default behaviour is to invoke {@link #paintChildren}. Override this
3421    * if you want special behaviour for printing.
3422    *
3423    * @param g the Graphics context to print onto
3424    *
3425    * @since 1.3
3426    */
3427   protected void printChildren(Graphics g)
3428   {
3429     paintChildren(g);
3430   }
3431
3432   /**
3433    * Print this component's border to the specified Graphics context.
3434    * The default behaviour is to invoke {@link #paintBorder}. Override this
3435    * if you want special behaviour for printing.
3436    *
3437    * @param g the Graphics context to print onto
3438    *
3439    * @since 1.3
3440    */
3441   protected void printBorder(Graphics g)
3442   {
3443     paintBorder(g);
3444   }
3445
3446   /**
3447    * Processes mouse motion event, like dragging and moving.
3448    *
3449    * @param ev the MouseEvent describing the mouse motion
3450    */
3451   protected void processMouseMotionEvent(MouseEvent ev)
3452   {
3453     super.processMouseMotionEvent(ev);
3454   }
3455
3456   /**
3457    * Moves and resizes the component.
3458    *
3459    * @param x the new horizontal location
3460    * @param y the new vertial location
3461    * @param w the new width
3462    * @param h the new height
3463    */
3464   public void reshape(int x, int y, int w, int h)
3465   {
3466     int oldX = getX();
3467     int oldY = getY();
3468     super.reshape(x, y, w, h);
3469     // Notify AncestorListeners.
3470     if (oldX != getX() || oldY != getY())
3471       fireAncestorEvent(this, AncestorEvent.ANCESTOR_MOVED);
3472   }
3473
3474   /**
3475    * Fires an AncestorEvent to this component's and all of its child
3476    * component's AncestorListeners.
3477    *
3478    * @param ancestor the component that triggered the event
3479    * @param id the kind of ancestor event that should be fired
3480    */
3481   void fireAncestorEvent(JComponent ancestor, int id)
3482   {
3483     // Fire event for registered ancestor listeners of this component.
3484     AncestorListener[] listeners = getAncestorListeners();
3485     if (listeners.length > 0)
3486       {
3487         AncestorEvent ev = new AncestorEvent(this, id,
3488                                              ancestor, ancestor.getParent());
3489         for (int i = 0; i < listeners.length; i++)
3490           {
3491             switch (id)
3492               {
3493               case AncestorEvent.ANCESTOR_MOVED:
3494                 listeners[i].ancestorMoved(ev);
3495                 break;
3496               case AncestorEvent.ANCESTOR_ADDED:
3497                 listeners[i].ancestorAdded(ev);
3498                 break;
3499               case AncestorEvent.ANCESTOR_REMOVED:
3500                 listeners[i].ancestorRemoved(ev);
3501                 break;
3502               }
3503           }
3504       }
3505     // Dispatch event to all children.
3506     Component[] children = getComponents();
3507     for (int i = 0; i < children.length; i++)
3508       {
3509         if (!(children[i] instanceof JComponent))
3510           continue;
3511         JComponent jc = (JComponent) children[i];
3512         jc.fireAncestorEvent(ancestor, id);
3513       }
3514   }
3515
3516   /**
3517    * Finds a suitable paint root for painting this component. This method first
3518    * checks if this component is overlapped using
3519    * {@link #findOverlapFreeParent(Rectangle)}. The returned paint root is then
3520    * feeded to {@link #findOpaqueParent(Component)} to find the nearest opaque
3521    * component for this paint root. If no paint is necessary, then we return
3522    * <code>null</code>.
3523    *
3524    * @param c the clip of this component
3525    *
3526    * @return the paint root or <code>null</code> if no painting is necessary
3527    */
3528   private Component findPaintRoot(Rectangle c)
3529   {
3530     Component p = findOverlapFreeParent(c);
3531     if (p == null)
3532       return null;
3533     Component root = findOpaqueParent(p);
3534     return root;
3535   }
3536
3537   /**
3538    * Scans the containment hierarchy upwards for components that overlap the
3539    * this component in the specified clip. This method returns
3540    * <code>this</code>, if no component overlaps this component. It returns
3541    * <code>null</code> if another component completely covers this component
3542    * in the specified clip (no repaint necessary). If another component partly
3543    * overlaps this component in the specified clip, then the parent of this
3544    * component is returned (this is the component that must be used as repaint
3545    * root). For efficient lookup, the method
3546    * {@link #isOptimizedDrawingEnabled()} is used.
3547    *
3548    * @param clip the clip of this component
3549    *
3550    * @return the paint root, or <code>null</code> if no paint is necessary
3551    */
3552   private Component findOverlapFreeParent(Rectangle clip)
3553   {
3554     Rectangle currentClip = clip;
3555     Component found = this;
3556     Container parent = this; 
3557     while (parent != null && !(parent instanceof Window))
3558       {
3559         Container newParent = parent.getParent();
3560         if (newParent == null || newParent instanceof Window)
3561           break;
3562         // If the parent is optimizedDrawingEnabled, then its children are
3563         // tiled and cannot have an overlapping child. Go directly to next
3564         // parent.
3565         if ((newParent instanceof JComponent
3566             && ((JComponent) newParent).isOptimizedDrawingEnabled()))
3567           
3568           {
3569             parent = newParent;
3570             continue;
3571           }
3572         // If the parent is not optimizedDrawingEnabled, we must paint the
3573         // parent.
3574         Rectangle target = SwingUtilities.convertRectangle(found,
3575                                                            currentClip,
3576                                                            newParent);
3577         found = newParent;
3578         currentClip = target;
3579         parent = newParent;
3580       }
3581     return found;
3582   }
3583
3584   /**
3585    * Finds the nearest component to <code>c</code> (upwards in the containment
3586    * hierarchy), that is opaque. If <code>c</code> itself is opaque,
3587    * this returns <code>c</code> itself.
3588    *
3589    * @param c the start component for the search
3590    * @return the nearest component to <code>c</code> (upwards in the containment
3591    *         hierarchy), that is opaque; If <code>c</code> itself is opaque,
3592    *         this returns <code>c</code> itself
3593    */
3594   private Component findOpaqueParent(Component c)
3595   {
3596     Component found = c;
3597     while (true)
3598       {
3599         if ((found instanceof JComponent) && ((JComponent) found).isOpaque())
3600           break;
3601         else if (!(found instanceof JComponent))
3602           break;
3603         Container p = found.getParent();
3604         if (p == null)
3605           break;
3606         else
3607           found = p;
3608       }
3609     return found;
3610   }
3611   
3612   /**
3613    * This is the method that gets called when the WHEN_IN_FOCUSED_WINDOW map
3614    * is changed.
3615    *
3616    * @param changed the JComponent associated with the WHEN_IN_FOCUSED_WINDOW
3617    *        map
3618    */
3619   void updateComponentInputMap(ComponentInputMap changed)
3620   {
3621     // Since you can change a component's input map via
3622     // setInputMap, we have to check if <code>changed</code>
3623     // is still in our WHEN_IN_FOCUSED_WINDOW map hierarchy
3624     InputMap curr = getInputMap(WHEN_IN_FOCUSED_WINDOW);
3625     while (curr != null && curr != changed)
3626       curr = curr.getParent();
3627     
3628     // If curr is null then changed is not in the hierarchy
3629     if (curr == null)
3630       return;
3631     
3632     // Now we have to update the keyboard manager's hashtable
3633     KeyboardManager km = KeyboardManager.getManager();
3634     
3635     // This is a poor strategy, should be improved.  We currently 
3636     // delete all the old bindings for the component and then register
3637     // the current bindings.
3638     km.clearBindingsForComp(changed.getComponent());
3639     km.registerEntireMap((ComponentInputMap) 
3640                          getInputMap(WHEN_IN_FOCUSED_WINDOW));
3641   }
3642
3643   /**
3644    * Helper method for
3645    * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
3646    * 
3647    * @param propertyName the name of the property
3648    * @param value the value of the property
3649    *
3650    * @throws IllegalArgumentException if the specified property cannot be set
3651    *         by this method
3652    * @throws ClassCastException if the property value does not match the
3653    *         property type
3654    * @throws NullPointerException if <code>c</code> or
3655    *         <code>propertyValue</code> is <code>null</code>
3656    */
3657   void setUIProperty(String propertyName, Object value)
3658   {
3659     if (propertyName.equals("opaque"))
3660       {
3661         if (! clientOpaqueSet)
3662           {
3663             setOpaque(((Boolean) value).booleanValue());
3664             clientOpaqueSet = false;
3665           }
3666       }
3667     else if (propertyName.equals("autoscrolls"))
3668       {
3669         if (! clientAutoscrollsSet)
3670           {
3671             setAutoscrolls(((Boolean) value).booleanValue());
3672             clientAutoscrollsSet = false;
3673           }
3674       }
3675     else
3676       {
3677         throw new IllegalArgumentException
3678             ("Unsupported property for LookAndFeel.installProperty(): "
3679              + propertyName);
3680       }
3681   }
3682 }