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