KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JComponent


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

7 package javax.swing;
8
9
10 import java.util.Hashtable JavaDoc;
11 import java.util.Dictionary JavaDoc;
12 import java.util.Enumeration JavaDoc;
13 import java.util.Locale JavaDoc;
14 import java.util.Vector JavaDoc;
15 import java.util.EventListener JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.TreeSet JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.HashMap JavaDoc;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import java.awt.image.VolatileImage JavaDoc;
24 import java.awt.Graphics2D JavaDoc;
25 import java.awt.peer.LightweightPeer;
26 import java.awt.dnd.DropTarget JavaDoc;
27 import java.awt.font.FontRenderContext JavaDoc;
28 import java.beans.*;
29
30 import java.applet.Applet JavaDoc;
31
32 import java.io.Serializable JavaDoc;
33 import java.io.ObjectOutputStream JavaDoc;
34 import java.io.ObjectInputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.ObjectInputValidation JavaDoc;
37 import java.io.InvalidObjectException JavaDoc;
38
39 import java.lang.reflect.Method JavaDoc;
40
41 import javax.swing.border.*;
42 import javax.swing.event.*;
43 import javax.swing.plaf.*;
44 import javax.accessibility.*;
45
46 import com.sun.java.swing.SwingUtilities2;
47 import sun.font.FontDesignMetrics;
48 import sun.swing.AccessibleMethod;
49
50 /**
51  * The base class for all Swing components except top-level containers.
52  * To use a component that inherits from <code>JComponent</code>,
53  * you must place the component in a containment hierarchy
54  * whose root is a top-level Swing container.
55  * Top-level Swing containers --
56  * such as <code>JFrame</code>, <code>JDialog</code>,
57  * and <code>JApplet</code> --
58  * are specialized components
59  * that provide a place for other Swing components to paint themselves.
60  * For an explanation of containment hierarchies, see
61  * <a
62  href="http://java.sun.com/docs/books/tutorial/uiswing/overview/hierarchy.html">Swing Components and the Containment Hierarchy</a>,
63  * a section in <em>The Java Tutorial</em>.
64  *
65  * <p>
66  * The <code>JComponent</code> class provides:
67  * <ul>
68  * <li>The base class for both standard and custom components
69  * that use the Swing architecture.
70  * <li>A "pluggable look and feel" (L&F) that can be specified by the
71  * programmer or (optionally) selected by the user at runtime.
72  * The look and feel for each component is provided by a
73  * <em>UI delegate</em> -- an object that descends from
74  * {@link javax.swing.plaf.ComponentUI}.
75  * See <a
76  * HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html">How
77  * to Set the Look and Feel</a>
78  * in <em>The Java Tutorial</em>
79  * for more information.
80  * <li>Comprehensive keystroke handling.
81  * See the document <a
82  * HREF="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">Keyboard
83  * Bindings in Swing</a>,
84  * an article in <em>The Swing Connection</em>,
85  * for more information.
86  * <li>Support for tool tips --
87  * short descriptions that pop up when the cursor lingers
88  * over a component.
89  * See <a
90  * HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How
91  * to Use Tool Tips</a>
92  * in <em>The Java Tutorial</em>
93  * for more information.
94  * <li>Support for accessibility.
95  * <code>JComponent</code> contains all of the methods in the
96  * <code>Accessible</code> interface,
97  * but it doesn't actually implement the interface. That is the
98  * responsibility of the individual classes
99  * that extend <code>JComponent</code>.
100  * <li>Support for component-specific properties.
101  * With the {@link #putClientProperty}
102  * and {@link #getClientProperty} methods,
103  * you can associate name-object pairs
104  * with any object that descends from <code>JComponent</code>.
105  * <li>An infrastructure for painting
106  * that includes double buffering and support for borders.
107  * For more information see <a
108  * HREF="http://java.sun.com/docs/books/tutorial/uiswing/overview/draw.html">Painting</a> and
109  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html">How
110  * to Use Borders</a>,
111  * both of which are sections in <em>The Java Tutorial</em>.
112  * </ul>
113  * For more information on these subjects, see the
114  * <a HREF="package-summary.html#package_description">Swing package description</a>
115  * and <em>The Java Tutorial</em> section
116  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
117  * <p>
118  * <code>JComponent</code> and its subclasses document default values
119  * for certain properties. For example, <code>JTable</code> documents the
120  * default row height as 16. Each <code>JComponent</code> subclass
121  * that has a <code>ComponentUI</code> will create the
122  * <code>ComponentUI</code> as part of its constructor. In order
123  * to provide a particular look and feel each
124  * <code>ComponentUI</code> may set properties back on the
125  * <code>JComponent</code> that created it. For example, a custom
126  * look and feel may require <code>JTable</code>s to have a row
127  * height of 24. The documented defaults are the value of a property
128  * BEFORE the <code>ComponentUI</code> has been installed. If you
129  * need a specific value for a particular property you should
130  * explicitly set it.
131  * <p>
132  * In release 1.4, the focus subsystem was rearchitected.
133  * For more information, see
134  * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
135  * How to Use the Focus Subsystem</a>,
136  * a section in <em>The Java Tutorial</em>.
137  * <p>
138  * <strong>Warning:</strong>
139  * Serialized objects of this class will not be compatible with
140  * future Swing releases. The current serialization support is
141  * appropriate for short term storage or RMI between applications running
142  * the same version of Swing. As of 1.4, support for long term storage
143  * of all JavaBeans<sup><font size="-2">TM</font></sup>
144  * has been added to the <code>java.beans</code> package.
145  * Please see {@link java.beans.XMLEncoder}.
146  *
147  * @see KeyStroke
148  * @see Action
149  * @see #setBorder
150  * @see #registerKeyboardAction
151  * @see JOptionPane
152  * @see #setDebugGraphicsOptions
153  * @see #setToolTipText
154  * @see #setAutoscrolls
155  *
156  * @version 2.130 07/09/99
157  * @author Hans Muller
158  * @author Arnaud Weber
159  */

160 public abstract class JComponent extends Container implements Serializable JavaDoc
161 {
162     /**
163      * @see #getUIClassID
164      * @see #writeObject
165      */

166     private static final String JavaDoc uiClassID = "ComponentUI";
167
168     /**
169      * Key used in client properties for the AncestorNotifier.
170      */

171     private static final StringBuffer JavaDoc ANCESTOR_NOTIFIER_KEY = new StringBuffer JavaDoc(
172                                                "AncestorNotifier");
173
174     /**
175      * Key used in client properties for the TransferHandler.
176      */

177     private static final StringBuffer JavaDoc TRANSFER_HANDLER_KEY = new StringBuffer JavaDoc(
178                                                "TransferHandler");
179
180     /**
181      * Key used in client properties for the InputVerifier.
182      */

183     private static final StringBuffer JavaDoc INPUT_VERIFIER_KEY = new StringBuffer JavaDoc(
184                                                "InputVerifier");
185
186     /**
187      * @see #readObject
188      */

189     private static final Hashtable JavaDoc readObjectCallbacks = new Hashtable JavaDoc(1);
190
191     /**
192      * Keys to use for forward focus traversal when the JComponent is
193      * managing focus.
194      */

195     private static Set JavaDoc managingFocusForwardTraversalKeys;
196
197     /**
198      * Keys to use for backward focus traversal when the JComponent is
199      * managing focus.
200      */

201     private static Set JavaDoc managingFocusBackwardTraversalKeys;
202
203     /**
204      * Indicates if we should register a <code>DropTarget</code> for a
205      * non-null <code>TransferHandler</code>. Use
206      * <code>getSuppressDropTarget</code> to check.
207      */

208     private static boolean suppressDropSupport;
209
210     /**
211      * Indiciates if we've checked the system property for suppressing
212      * drop support.
213      */

214     private static boolean checkedSuppressDropSupport;
215
216     // Following are the possible return values from getObscuredState.
217
private static final int NOT_OBSCURED = 0;
218     private static final int PARTIALLY_OBSCURED = 1;
219     private static final int COMPLETELY_OBSCURED = 2;
220
221     /**
222      * Set to true when DebugGraphics has been loaded.
223      */

224     static boolean DEBUG_GRAPHICS_LOADED;
225
226     /**
227      * Anti-aliased FontMetrics.
228      */

229     private static final Map JavaDoc<Font,FontMetrics> aaFontMap;
230
231     /* The following fields support set methods for the corresponding
232      * java.awt.Component properties.
233      */

234     private boolean isAlignmentXSet;
235     private float alignmentX;
236     private boolean isAlignmentYSet;
237     private float alignmentY;
238
239     /**
240      * Backing store for JComponent properties and listeners
241      */

242
243     /** The look and feel delegate for this component. */
244     protected transient ComponentUI ui;
245     /** A list of event listeners for this component. */
246     protected EventListenerList listenerList = new EventListenerList();
247
248     private transient ArrayTable JavaDoc clientProperties;
249     private VetoableChangeSupport vetoableChangeSupport;
250     /**
251      * Whether or not autoscroll has been enabled.
252      */

253     private boolean autoscrolls;
254     private Border border;
255     private int flags;
256
257     /* Input verifier for this component */
258     private InputVerifier JavaDoc inputVerifier = null;
259
260     private boolean verifyInputWhenFocusTarget = true;
261
262     /**
263      * Set in <code>_paintImmediately</code>.
264      * Will indicate the child that initiated the painting operation.
265      * If <code>paintingChild</code> is opaque, no need to paint
266      * any child components after <code>paintingChild</code>.
267      * Test used in <code>paintChildren</code>.
268      */

269     transient Component paintingChild;
270
271     /**
272      * Constant used for <code>registerKeyboardAction</code> that
273      * means that the command should be invoked when
274      * the component has the focus.
275      */

276     public static final int WHEN_FOCUSED = 0;
277
278     /**
279      * Constant used for <code>registerKeyboardAction</code> that
280      * means that the command should be invoked when the receiving
281      * component is an ancestor of the focused component or is
282      * itself the focused component.
283      */

284     public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
285
286     /**
287      * Constant used for <code>registerKeyboardAction</code> that
288      * means that the command should be invoked when
289      * the receiving component is in the window that has the focus
290      * or is itself the focused component.
291      */

292     public static final int WHEN_IN_FOCUSED_WINDOW = 2;
293
294     /**
295      * Constant used by some of the APIs to mean that no condition is defined.
296      */

297     public static final int UNDEFINED_CONDITION = -1;
298
299     /**
300      * The key used by <code>JComponent</code> to access keyboard bindings.
301      */

302     private static final String JavaDoc KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
303
304     /**
305      * An array of <code>KeyStroke</code>s used for
306      * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
307      * in the client properties under this string.
308      */

309     private static final String JavaDoc WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
310
311     /**
312      * The comment to display when the cursor is over the component,
313      * also known as a "value tip", "flyover help", or "flyover label".
314      */

315     public static final String JavaDoc TOOL_TIP_TEXT_KEY = "ToolTipText";
316
317     private static final String JavaDoc NEXT_FOCUS = "nextFocus";
318
319     /**
320      * <code>JPopupMenu<code> assigned to this component
321      * and all of its childrens
322      */

323     private JPopupMenu JavaDoc popupMenu;
324
325     /** Private flags **/
326     private static final int IS_DOUBLE_BUFFERED = 0;
327     private static final int ANCESTOR_USING_BUFFER = 1;
328     private static final int IS_PAINTING_TILE = 2;
329     private static final int IS_OPAQUE = 3;
330     private static final int KEY_EVENTS_ENABLED = 4;
331     private static final int FOCUS_INPUTMAP_CREATED = 5;
332     private static final int ANCESTOR_INPUTMAP_CREATED = 6;
333     private static final int WIF_INPUTMAP_CREATED = 7;
334     private static final int ACTIONMAP_CREATED = 8;
335     private static final int CREATED_DOUBLE_BUFFER = 9;
336     // bit 10 is free
337
private static final int IS_PRINTING = 11;
338     private static final int IS_PRINTING_ALL = 12;
339     private static final int IS_REPAINTING = 13;
340     /** Bits 14-21 are used to handle nested writeObject calls. **/
341     private static final int WRITE_OBJ_COUNTER_FIRST = 14;
342     private static final int RESERVED_1 = 15;
343     private static final int RESERVED_2 = 16;
344     private static final int RESERVED_3 = 17;
345     private static final int RESERVED_4 = 18;
346     private static final int RESERVED_5 = 19;
347     private static final int RESERVED_6 = 20;
348     private static final int WRITE_OBJ_COUNTER_LAST = 21;
349     
350     private static final int REQUEST_FOCUS_DISABLED = 22;
351     private static final int INHERITS_POPUP_MENU = 23;
352     private static final int OPAQUE_SET = 24;
353     private static final int AUTOSCROLLS_SET = 25;
354     private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26;
355     private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27;
356
357     /**
358      * Whether or not some JComponent is calling into an InputVerifier.
359      */

360     private static boolean inInputVerifier;
361
362     /**
363      * Temporary rectangles.
364      */

365     private static java.util.List JavaDoc tempRectangles = new java.util.ArrayList JavaDoc(11);
366
367     /** Used for <code>WHEN_FOCUSED</code> bindings. */
368     private InputMap JavaDoc focusInputMap;
369     /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
370     private InputMap JavaDoc ancestorInputMap;
371     /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
372     private ComponentInputMap JavaDoc windowInputMap;
373
374     /** ActionMap. */
375     private ActionMap JavaDoc actionMap;
376
377     /** Key used to store the default locale in an AppContext **/
378     private static final String JavaDoc defaultLocale = "JComponent.defaultLocale";
379
380     /**
381      * Whether or not this component should turn on anti-aliased text
382      * rendering.
383      */

384     private boolean aaText;
385
386     static {
387         aaFontMap = new HashMap JavaDoc<Font,FontMetrics>();
388     }
389
390     /**
391      * Returns the Set of <code>KeyStroke</code>s to use if the component
392      * is managing focus for forward focus traversal.
393      */

394     static Set JavaDoc<KeyStroke JavaDoc> getManagingFocusForwardTraversalKeys() {
395         if (managingFocusForwardTraversalKeys == null) {
396             managingFocusForwardTraversalKeys = new TreeSet JavaDoc();
397             managingFocusForwardTraversalKeys.add(
398                 KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_MASK));
399         }
400         return managingFocusForwardTraversalKeys;
401     }
402
403     /**
404      * Returns the Set of <code>KeyStroke</code>s to use if the component
405      * is managing focus for backward focus traversal.
406      */

407     static Set JavaDoc<KeyStroke JavaDoc> getManagingFocusBackwardTraversalKeys() {
408         if (managingFocusBackwardTraversalKeys == null) {
409             managingFocusBackwardTraversalKeys = new TreeSet JavaDoc();
410             managingFocusBackwardTraversalKeys.add(
411                 KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
412                                        InputEvent.SHIFT_MASK |
413                                        InputEvent.CTRL_MASK));
414         }
415         return managingFocusBackwardTraversalKeys;
416     }
417
418
419     /**
420      * Returns true if <code>setTransferHandler</code> should install
421      * a <code>DropTarget</code>.
422      */

423     private static boolean getSuppressDropTarget() {
424         if (!checkedSuppressDropSupport) {
425             Boolean JavaDoc b = (Boolean JavaDoc)java.security.AccessController.doPrivileged(
426                 new java.security.PrivilegedAction JavaDoc() {
427                     public Object JavaDoc run() {
428                         String JavaDoc value = System.getProperty(
429                                               "suppressSwingDropSupport");
430
431                         if (value != null) {
432                             return Boolean.valueOf(value);
433                         }
434                         return Boolean.FALSE;
435                     }
436                 }
437                 );
438             suppressDropSupport = b.booleanValue();
439             checkedSuppressDropSupport = true;
440         }
441         return suppressDropSupport;
442     }
443
444     private static Rectangle fetchRectangle() {
445         synchronized(tempRectangles) {
446             Rectangle rect;
447             int size = tempRectangles.size();
448             if (size > 0) {
449                 rect = (Rectangle)tempRectangles.remove(size - 1);
450             }
451             else {
452                 rect = new Rectangle(0, 0, 0, 0);
453             }
454             return rect;
455         }
456     }
457
458     private static void recycleRectangle(Rectangle rect) {
459         synchronized(tempRectangles) {
460             tempRectangles.add(rect);
461         }
462     }
463
464     /**
465      * Sets whether or not <code>getComponentPopupMenu</code> should delegate
466      * to the parent if this component does not have a <code>JPopupMenu</code>
467      * assigned to it.
468      * <p>
469      * The default value for this is false, but some <code>JComponent</code>
470      * subclasses that are implemented as a number of <code>JComponent</code>s
471      * may set this to true.
472      * <p>
473      * This is a bound property.
474      *
475      * @param value whether or not the JPopupMenu is inherited
476      * @see #setComponentPopupMenu
477      * @beaninfo
478      * bound: true
479      * description: Whether or not the JPopupMenu is inherited
480      * @since 1.5
481      */

482     public void setInheritsPopupMenu(boolean value) {
483         setFlag(INHERITS_POPUP_MENU, value);
484     }
485
486     /**
487      * Returns true if the JPopupMenu should be inherited from the parent.
488      *
489      * @see #setComponentPopupMenu
490      * @since 1.5
491      */

492     public boolean getInheritsPopupMenu() {
493         return getFlag(INHERITS_POPUP_MENU);
494     }
495
496     /**
497      * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
498      * The UI is responsible for registering bindings and adding the necessary
499      * listeners such that the <code>JPopupMenu</code> will be shown at
500      * the appropriate time. When the <code>JPopupMenu</code> is shown
501      * depends upon the look and feel: some may show it on a mouse event,
502      * some may enable a key binding.
503      * <p>
504      * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
505      * returns true, then <code>getComponentPopupMenu</code> will be delegated
506      * to the parent. This provides for a way to make all child components
507      * inherit the popupmenu of the parent.
508      * <p>
509      * This is a bound property.
510      *
511      * @param popup - the popup that will be assigned to this component
512      * may be null
513      * @see #getComponentPopupMenu
514      * @beaninfo
515      * bound: true
516      * preferred: true
517      * description: Popup to show
518      * @since 1.5
519      */

520     public void setComponentPopupMenu(JPopupMenu JavaDoc popup) {
521         if(popup != null && isLightweight()) {
522             enableEvents(AWTEvent.MOUSE_EVENT_MASK);
523         }
524         this.popupMenu = popup;
525     }
526
527     /**
528      * Returns <code>JPopupMenu</code> that assigned for this component.
529      * If this component does not have a <code>JPopupMenu</code> assigned
530      * to it and <code>getInheritsPopupMenu</code> is true, this
531      * will return <code>getParent().getComponentPopupMenu()</code> (assuming
532      * the parent is valid.)
533      *
534      * @return <code>JPopupMenu</code> assigned for this component
535      * or <code>null</code> if no popup assigned
536      * @see #setComponentPopupMenu
537      * @since 1.5
538      */

539     public JPopupMenu JavaDoc getComponentPopupMenu() {
540
541         if(!getInheritsPopupMenu()) {
542             return popupMenu;
543         }
544
545         if(popupMenu == null) {
546             // Search parents for its popup
547
Container parent = getParent();
548             while (parent != null) {
549                 if(parent instanceof JComponent JavaDoc) {
550                     return ((JComponent JavaDoc)parent).getComponentPopupMenu();
551                 }
552                 if(parent instanceof Window ||
553                    parent instanceof Applet JavaDoc) {
554                     // Reached toplevel, break and return null
555
break;
556                 }
557                 parent = parent.getParent();
558             }
559             return null;
560         }
561
562         return popupMenu;
563     }
564
565     /**
566      * Default <code>JComponent</code> constructor. This constructor does
567      * very little initialization beyond calling the <code>Container</code>
568      * constructor. For example, the initial layout manager is
569      * <code>null</code>. It does, however, set the component's locale
570      * property to the value returned by
571      * <code>JComponent.getDefaultLocale</code>.
572      *
573      * @see #getDefaultLocale
574      */

575     public JComponent() {
576         super();
577     // We enable key events on all JComponents so that accessibility
578
// bindings will work everywhere. This is a partial fix to BugID
579
// 4282211.
580
enableEvents(AWTEvent.KEY_EVENT_MASK);
581     if (isManagingFocus()) {
582             LookAndFeel.installProperty(this,
583                                         "focusTraversalKeysForward",
584                   getManagingFocusForwardTraversalKeys());
585             LookAndFeel.installProperty(this,
586                                         "focusTraversalKeysBackward",
587                   getManagingFocusBackwardTraversalKeys());
588     }
589
590         super.setLocale( JComponent.getDefaultLocale() );
591     }
592
593
594     /**
595      * Resets the UI property to a value from the current look and feel.
596      * <code>JComponent</code> subclasses must override this method
597      * like this:
598      * <pre>
599      * public void updateUI() {
600      * setUI((SliderUI)UIManager.getUI(this);
601      * }
602      * </pre>
603      *
604      * @see #setUI
605      * @see UIManager#getLookAndFeel
606      * @see UIManager#getUI
607      */

608     public void updateUI() {}
609
610
611     /**
612      * Sets the look and feel delegate for this component.
613      * <code>JComponent</code> subclasses generally override this method
614      * to narrow the argument type. For example, in <code>JSlider</code>:
615      * <pre>
616      * public void setUI(SliderUI newUI) {
617      * super.setUI(newUI);
618      * }
619      * </pre>
620      * <p>
621      * Additionally <code>JComponent</code> subclasses must provide a
622      * <code>getUI</code> method that returns the correct type. For example:
623      * <pre>
624      * public SliderUI getUI() {
625      * return (SliderUI)ui;
626      * }
627      * </pre>
628      *
629      * @param newUI the new UI delegate
630      * @see #updateUI
631      * @see UIManager#getLookAndFeel
632      * @see UIManager#getUI
633      * @beaninfo
634      * bound: true
635      * hidden: true
636      * attribute: visualUpdate true
637      * description: The component's look and feel delegate.
638      */

639     protected void setUI(ComponentUI newUI) {
640         /* We do not check that the UI instance is different
641          * before allowing the switch in order to enable the
642          * same UI instance *with different default settings*
643          * to be installed.
644          */

645         if (ui != null) {
646             ui.uninstallUI(this);
647         }
648         // aaText shouldn't persist between look and feels, reset it.
649
aaText = false;
650         ComponentUI oldUI = ui;
651         ui = newUI;
652         if (ui != null) {
653             ui.installUI(this);
654         }
655
656         firePropertyChange("UI", oldUI, newUI);
657         revalidate();
658         repaint();
659     }
660
661
662     /**
663      * Returns the <code>UIDefaults</code> key used to
664      * look up the name of the <code>swing.plaf.ComponentUI</code>
665      * class that defines the look and feel
666      * for this component. Most applications will never need to
667      * call this method. Subclasses of <code>JComponent</code> that support
668      * pluggable look and feel should override this method to
669      * return a <code>UIDefaults</code> key that maps to the
670      * <code>ComponentUI</code> subclass that defines their look and feel.
671      *
672      * @return the <code>UIDefaults</code> key for a
673      * <code>ComponentUI</code> subclass
674      * @see UIDefaults#getUI
675      * @beaninfo
676      * expert: true
677      * description: UIClassID
678      */

679     public String JavaDoc getUIClassID() {
680         return uiClassID;
681     }
682
683
684     /**
685      * Returns the graphics object used to paint this component.
686      * If <code>DebugGraphics</code> is turned on we create a new
687      * <code>DebugGraphics</code> object if necessary.
688      * Otherwise we just configure the
689      * specified graphics object's foreground and font.
690      *
691      * @param g the original <code>Graphics</code> object
692      * @return a <code>Graphics</code> object configured for this component
693      */

694     protected Graphics getComponentGraphics(Graphics g) {
695         Graphics componentGraphics = g;
696         if (ui != null && DEBUG_GRAPHICS_LOADED) {
697             if ((DebugGraphics.debugComponentCount() != 0) &&
698                     (shouldDebugGraphics() != 0) &&
699                     !(g instanceof DebugGraphics JavaDoc)) {
700                 componentGraphics = new DebugGraphics JavaDoc(g,this);
701             }
702         }
703         componentGraphics.setColor(getForeground());
704         componentGraphics.setFont(getFont());
705
706         return componentGraphics;
707     }
708
709
710     /**
711      * Calls the UI delegate's paint method, if the UI delegate
712      * is non-<code>null</code>. We pass the delegate a copy of the
713      * <code>Graphics</code> object to protect the rest of the
714      * paint code from irrevocable changes
715      * (for example, <code>Graphics.translate</code>).
716      * <p>
717      * If you override this in a subclass you should not make permanent
718      * changes to the passed in <code>Graphics</code>. For example, you
719      * should not alter the clip <code>Rectangle</code> or modify the
720      * transform. If you need to do these operations you may find it
721      * easier to create a new <code>Graphics</code> from the passed in
722      * <code>Graphics</code> and manipulate it. Further, if you do not
723      * invoker super's implementation you must honor the opaque property,
724      * that is
725      * if this component is opaque, you must completely fill in the background
726      * in a non-opaque color. If you do not honor the opaque property you
727      * will likely see visual artifacts.
728      * <p>
729      * The passed in <code>Graphics</code> object might
730      * have a transform other than the identify transform
731      * installed on it. In this case, you might get
732      * unexpected results if you cumulatively apply
733      * another transform.
734      *
735      * @param g the <code>Graphics</code> object to protect
736      * @see #paint
737      * @see ComponentUI
738      */

739     protected void paintComponent(Graphics g) {
740         if (ui != null) {
741             Graphics scratchGraphics = (g == null) ? null : g.create();
742             try {
743                 ui.update(scratchGraphics, this);
744             }
745             finally {
746                 scratchGraphics.dispose();
747             }
748         }
749     }
750
751     /**
752      * Paints this component's children.
753      * If <code>shouldUseBuffer</code> is true,
754      * no component ancestor has a buffer and
755      * the component children can use a buffer if they have one.
756      * Otherwise, one ancestor has a buffer currently in use and children
757      * should not use a buffer to paint.
758      * @param g the <code>Graphics</code> context in which to paint
759      * @see #paint
760      * @see java.awt.Container#paint
761      */

762     protected void paintChildren(Graphics g) {
763         boolean isJComponent;
764     Graphics sg = null;
765
766         try {
767             synchronized(getTreeLock()) {
768         int i = getComponentCount() - 1;
769         if (i < 0) {
770             return;
771         }
772         sg = (g == null) ? null : g.create();
773         // If we are only to paint to a specific child, determine
774
// its index.
775
if (paintingChild != null &&
776             (paintingChild instanceof JComponent JavaDoc) &&
777             ((JComponent JavaDoc)paintingChild).isOpaque()) {
778             for (; i >= 0; i--) {
779             if (getComponent(i) == paintingChild){
780                 break;
781             }
782             }
783         }
784                 Rectangle tmpRect = fetchRectangle();
785         boolean checkSiblings = (!isOptimizedDrawingEnabled() &&
786                      checkIfChildObscuredBySibling());
787         Rectangle clipBounds = null;
788                 if (checkSiblings) {
789             clipBounds = sg.getClipBounds();
790             if (clipBounds == null) {
791                 clipBounds = new Rectangle(0, 0, getWidth(),
792                                                    getHeight());
793             }
794                 }
795         boolean printing = getFlag(IS_PRINTING);
796                 for (; i >= 0 ; i--) {
797                     Component comp = getComponent(i);
798                     if (comp != null &&
799                         (printing || isLightweightComponent(comp)) &&
800                         (comp.isVisible() == true)) {
801                         Rectangle cr;
802                         isJComponent = (comp instanceof JComponent JavaDoc);
803
804                         cr = comp.getBounds(tmpRect);
805
806             boolean hitClip = g.hitClip(cr.x, cr.y, cr.width, cr.height);
807
808                         if (hitClip) {
809                 if (checkSiblings && i > 0) {
810                 int x = cr.x;
811                 int y = cr.y;
812                 int width = cr.width;
813                 int height = cr.height;
814                 SwingUtilities.computeIntersection
815                      (clipBounds.x, clipBounds.y,
816                       clipBounds.width, clipBounds.height, cr);
817
818                 if(getObscuredState(i, cr.x, cr.y, cr.width,
819                                          cr.height) == COMPLETELY_OBSCURED) {
820                     continue;
821                 }
822                 cr.x = x;
823                 cr.y = y;
824                 cr.width = width;
825                 cr.height = height;
826                 }
827                             Graphics cg = sg.create(cr.x, cr.y, cr.width,
828                                                     cr.height);
829                 cg.setColor(comp.getForeground());
830                 cg.setFont(comp.getFont());
831                             boolean shouldSetFlagBack = false;
832                             try {
833                                 if(isJComponent) {
834                                     if(getFlag(ANCESTOR_USING_BUFFER)) {
835                                         ((JComponent JavaDoc)comp).setFlag(ANCESTOR_USING_BUFFER,true);
836                                         shouldSetFlagBack = true;
837                                     }
838                                     if(getFlag(IS_PAINTING_TILE)) {
839                                         ((JComponent JavaDoc)comp).setFlag(IS_PAINTING_TILE,true);
840                                         shouldSetFlagBack = true;
841                                     }
842                     if(!printing) {
843                     ((JComponent JavaDoc)comp).paint(cg);
844                     }
845                     else {
846                     if (!getFlag(IS_PRINTING_ALL)) {
847                         comp.print(cg);
848                     }
849                     else {
850                         comp.printAll(cg);
851                     }
852                     }
853                                 } else {
854                     if (!printing) {
855                     comp.paint(cg);
856                     }
857                     else {
858                     if (!getFlag(IS_PRINTING_ALL)) {
859                         comp.print(cg);
860                     }
861                     else {
862                         comp.printAll(cg);
863                     }
864                     }
865                 }
866                             } finally {
867                                 cg.dispose();
868                                 if(shouldSetFlagBack) {
869                                     ((JComponent JavaDoc)comp).setFlag(ANCESTOR_USING_BUFFER,false);
870                                     ((JComponent JavaDoc)comp).setFlag(IS_PAINTING_TILE,false);
871                                 }
872                             }
873                         }
874                     }
875
876                 }
877                 recycleRectangle(tmpRect);
878             }
879         } finally {
880         if (sg != null) {
881         sg.dispose();
882         }
883         }
884     }
885
886     /**
887      * Paints the component's border.
888      * <p>
889      * If you override this in a subclass you should not make permanent
890      * changes to the passed in <code>Graphics</code>. For example, you
891      * should not alter the clip <code>Rectangle</code> or modify the
892      * transform. If you need to do these operations you may find it
893      * easier to create a new <code>Graphics</code> from the passed in
894      * <code>Graphics</code> and manipulate it.
895      *
896      * @param g the <code>Graphics</code> context in which to paint
897      *
898      * @see #paint
899      * @see #setBorder
900      */

901     protected void paintBorder(Graphics g) {
902         Border border = getBorder();
903         if (border != null) {
904             border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
905         }
906     }
907
908
909     /**
910      * Calls <code>paint</code>. Doesn't clear the background but see
911      * <code>ComponentUI.update</code>, which is called by
912      * <code>paintComponent</code>.
913      *
914      * @param g the <code>Graphics</code> context in which to paint
915      * @see #paint
916      * @see #paintComponent
917      * @see javax.swing.plaf.ComponentUI
918      */

919     public void update(Graphics g) {
920         paint(g);
921     }
922
923
924     /**
925      * Invoked by Swing to draw components.
926      * Applications should not invoke <code>paint</code> directly,
927      * but should instead use the <code>repaint</code> method to
928      * schedule the component for redrawing.
929      * <p>
930      * This method actually delegates the work of painting to three
931      * protected methods: <code>paintComponent</code>,
932      * <code>paintBorder</code>,
933      * and <code>paintChildren</code>. They're called in the order
934      * listed to ensure that children appear on top of component itself.
935      * Generally speaking, the component and its children should not
936      * paint in the insets area allocated to the border. Subclasses can
937      * just override this method, as always. A subclass that just
938      * wants to specialize the UI (look and feel) delegate's
939      * <code>paint</code> method should just override
940      * <code>paintComponent</code>.
941      *
942      * @param g the <code>Graphics</code> context in which to paint
943      * @see #paintComponent
944      * @see #paintBorder
945      * @see #paintChildren
946      * @see #getComponentGraphics
947      * @see #repaint
948      */

949     public void paint(Graphics g) {
950     boolean shouldClearPaintFlags = false;
951     boolean paintCompleted = false;
952
953         if ((getWidth() <= 0) || (getHeight() <= 0)) {
954             return;
955         }
956
957         Graphics componentGraphics = getComponentGraphics(g);
958         Graphics co = (componentGraphics == null) ? null :
959                       componentGraphics.create();
960         try {
961             RepaintManager JavaDoc repaintManager = RepaintManager.currentManager(this);
962         Rectangle clipRect = co.getClipBounds();
963             int clipX;
964             int clipY;
965             int clipW;
966             int clipH;
967         if (clipRect == null) {
968                 clipX = clipY = 0;
969         clipW = getWidth();
970         clipH = getHeight();
971             }
972         else {
973             clipX = clipRect.x;
974         clipY = clipRect.y;
975         clipW = clipRect.width;
976         clipH = clipRect.height;
977             }
978
979             if(clipW > getWidth()) {
980                 clipW = getWidth();
981             }
982             if(clipH > getHeight()) {
983                 clipH = getHeight();
984             }
985
986             if(getParent() != null && !(getParent() instanceof JComponent JavaDoc)) {
987                 adjustPaintFlags();
988                 shouldClearPaintFlags = true;
989             }
990
991         int bw,bh;
992         boolean printing = getFlag(IS_PRINTING);
993             if(!printing && repaintManager.isDoubleBufferingEnabled() &&
994                !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
995
996         paintCompleted = paintDoubleBuffered(this, this, co, clipX, clipY, clipW, clipH);
997             }
998         if (!paintCompleted) {
999         // Will ocassionaly happen in 1.2, especially when printing.
1000
if (clipRect == null) {
1001            co.setClip(clipX, clipY, clipW, clipH);
1002        }
1003
1004                if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
1005            if (!printing) {
1006            paintComponent(co);
1007            paintBorder(co);
1008            }
1009            else {
1010            printComponent(co);
1011            printBorder(co);
1012            }
1013                }
1014        if (!printing) {
1015            paintChildren(co);
1016        }
1017        else {
1018            printChildren(co);
1019        }
1020            }
1021        } finally {
1022            co.dispose();
1023            if(shouldClearPaintFlags) {
1024                setFlag(ANCESTOR_USING_BUFFER,false);
1025                setFlag(IS_PAINTING_TILE,false);
1026                setFlag(IS_PRINTING,false);
1027                setFlag(IS_PRINTING_ALL,false);
1028            }
1029        }
1030    }
1031
1032    /**
1033     * Returns true if this component, or any of it's ancestors, are in
1034     * the processing of painting.
1035     */

1036    boolean isPainting() {
1037        Container component = this;
1038        while (component != null) {
1039            if (component instanceof JComponent JavaDoc &&
1040                   ((JComponent JavaDoc)component).getFlag(ANCESTOR_USING_BUFFER)) {
1041                return true;
1042            }
1043            component = component.getParent();
1044        }
1045        return false;
1046    }
1047    
1048    private void adjustPaintFlags() {
1049    JComponent JavaDoc jparent = null;
1050    Container parent;
1051    for(parent = getParent() ; parent != null ; parent =
1052        parent.getParent()) {
1053        if(parent instanceof JComponent JavaDoc) {
1054        jparent = (JComponent JavaDoc) parent;
1055        if(jparent.getFlag(ANCESTOR_USING_BUFFER))
1056          setFlag(ANCESTOR_USING_BUFFER, true);
1057        if(jparent.getFlag(IS_PAINTING_TILE))
1058          setFlag(IS_PAINTING_TILE, true);
1059        if(jparent.getFlag(IS_PRINTING))
1060          setFlag(IS_PRINTING, true);
1061        if(jparent.getFlag(IS_PRINTING_ALL))
1062          setFlag(IS_PRINTING_ALL, true);
1063        break;
1064        }
1065    }
1066    }
1067
1068    /**
1069     * Invoke this method to print the component. This method invokes
1070     * <code>print</code> on the component.
1071     *
1072     * @param g the <code>Graphics</code> context in which to paint
1073     * @see #print
1074     * @see #printComponent
1075     * @see #printBorder
1076     * @see #printChildren
1077     */

1078    public void printAll(Graphics g) {
1079    setFlag(IS_PRINTING_ALL, true);
1080    try {
1081        print(g);
1082    }
1083    finally {
1084        setFlag(IS_PRINTING_ALL, false);
1085    }
1086    }
1087
1088    /**
1089     * Invoke this method to print the component. This method will
1090     * result in invocations to <code>printComponent</code>,
1091     * <code>printBorder</code> and <code>printChildren</code>. It is
1092     * not recommended that you override this method, instead override
1093     * one of the previously mentioned methods. This method sets the
1094     * component's state such that the double buffer will not be used, eg
1095     * painting will be done directly on the passed in <code>Graphics</code>.
1096     *
1097     * @param g the <code>Graphics</code> context in which to paint
1098     * @see #printComponent
1099     * @see #printBorder
1100     * @see #printChildren
1101     */

1102    public void print(Graphics g) {
1103    setFlag(IS_PRINTING, true);
1104    try {
1105        paint(g);
1106    }
1107    finally {
1108        setFlag(IS_PRINTING, false);
1109    }
1110    }
1111    
1112    /**
1113     * This is invoked during a printing operation. This is implemented to
1114     * invoke <code>paintComponent</code> on the component. Override this
1115     * if you wish to add special painting behavior when printing.
1116     *
1117     * @param g the <code>Graphics</code> context in which to paint
1118     * @see #print
1119     * @since 1.3
1120     */

1121    protected void printComponent(Graphics g) {
1122    paintComponent(g);
1123    }
1124
1125    /**
1126     * Prints this component's children. This is implemented to invoke
1127     * <code>paintChildren</code> on the component. Override this if you
1128     * wish to print the children differently than painting.
1129     *
1130     * @param g the <code>Graphics</code> context in which to paint
1131     * @see #print
1132     * @since 1.3
1133     */

1134    protected void printChildren(Graphics g) {
1135    paintChildren(g);
1136    }
1137
1138    /**
1139     * Prints the component's border. This is implemented to invoke
1140     * <code>paintBorder</code> on the component. Override this if you
1141     * wish to print the border differently that it is painted.
1142     *
1143     * @param g the <code>Graphics</code> context in which to paint
1144     * @see #print
1145     * @since 1.3
1146     */

1147    protected void printBorder(Graphics g) {
1148    paintBorder(g);
1149    }
1150
1151    /**
1152     * Returns true if the component is currently painting a tile.
1153     * If this method returns true, paint will be called again for another
1154     * tile. This method returns false if you are not painting a tile or
1155     * if the last tile is painted.
1156     * Use this method to keep some state you might need between tiles.
1157     *
1158     * @return true if the component is currently painting a tile,
1159     * false otherwise
1160     */

1161    public boolean isPaintingTile() {
1162        return getFlag(IS_PAINTING_TILE);
1163    }
1164
1165    /**
1166     * In release 1.4, the focus subsystem was rearchitected.
1167     * For more information, see
1168     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1169     * How to Use the Focus Subsystem</a>,
1170     * a section in <em>The Java Tutorial</em>.
1171     * <p>
1172     * Changes this <code>JComponent</code>'s focus traversal keys to
1173     * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
1174     * <code>SortingFocusTraversalPolicy</code> from considering descendants
1175     * of this JComponent when computing a focus traversal cycle.
1176     *
1177     * @see java.awt.Component#setFocusTraversalKeys
1178     * @see SortingFocusTraversalPolicy
1179     * @deprecated As of 1.4, replaced by
1180     * <code>Component.setFocusTraversalKeys(int, Set)</code> and
1181     * <code>Container.setFocusCycleRoot(boolean)</code>.
1182     */

1183    @Deprecated JavaDoc
1184    public boolean isManagingFocus() {
1185    return false;
1186    }
1187  
1188    private void registerNextFocusableComponent() {
1189    registerNextFocusableComponent(getNextFocusableComponent());
1190    }
1191
1192    private void registerNextFocusableComponent(Component
1193                        nextFocusableComponent) {
1194    if (nextFocusableComponent == null) {
1195        return;
1196    }
1197  
1198    Container nearestRoot =
1199        (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1200    FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1201    if (!(policy instanceof LegacyGlueFocusTraversalPolicy JavaDoc)) {
1202        policy = new LegacyGlueFocusTraversalPolicy JavaDoc(policy);
1203        nearestRoot.setFocusTraversalPolicy(policy);
1204    }
1205    ((LegacyGlueFocusTraversalPolicy JavaDoc)policy).
1206        setNextFocusableComponent(this, nextFocusableComponent);
1207    }
1208
1209    private void deregisterNextFocusableComponent() {
1210    Component nextFocusableComponent = getNextFocusableComponent();
1211    if (nextFocusableComponent == null) {
1212        return;
1213    }
1214
1215    Container nearestRoot =
1216        (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1217    if (nearestRoot == null) {
1218        return;
1219    }
1220    FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1221    if (policy instanceof LegacyGlueFocusTraversalPolicy JavaDoc) {
1222        ((LegacyGlueFocusTraversalPolicy JavaDoc)policy).
1223        unsetNextFocusableComponent(this, nextFocusableComponent);
1224    }
1225    }
1226
1227    /**
1228     * In release 1.4, the focus subsystem was rearchitected.
1229     * For more information, see
1230     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1231     * How to Use the Focus Subsystem</a>,
1232     * a section in <em>The Java Tutorial</em>.
1233     * <p>
1234     * Overrides the default <code>FocusTraversalPolicy</code> for this
1235     * <code>JComponent</code>'s focus traversal cycle by unconditionally
1236     * setting the specified <code>Component</code> as the next
1237     * <code>Component</code> in the cycle, and this <code>JComponent</code>
1238     * as the specified <code>Component</code>'s previous
1239     * <code>Component</code> in the cycle.
1240     *
1241     * @param aComponent the <code>Component</code> that should follow this
1242     * <code>JComponent</code> in the focus traversal cycle
1243     *
1244     * @see #getNextFocusableComponent
1245     * @see java.awt.FocusTraversalPolicy
1246     * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
1247     */

1248    @Deprecated JavaDoc
1249    public void setNextFocusableComponent(Component aComponent) {
1250    boolean displayable = isDisplayable();
1251    if (displayable) {
1252        deregisterNextFocusableComponent();
1253    }
1254    putClientProperty(NEXT_FOCUS, aComponent);
1255    if (displayable) {
1256        registerNextFocusableComponent(aComponent);
1257    }
1258    }
1259  
1260    /**
1261     * In release 1.4, the focus subsystem was rearchitected.
1262     * For more information, see
1263     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1264     * How to Use the Focus Subsystem</a>,
1265     * a section in <em>The Java Tutorial</em>.
1266     * <p>
1267     * Returns the <code>Component</code> set by a prior call to
1268     * <code>setNextFocusableComponent(Component)</code> on this
1269     * <code>JComponent</code>.
1270     *
1271     * @return the <code>Component</code> that will follow this
1272     * <code>JComponent</code> in the focus traversal cycle, or
1273     * <code>null</code> if none has been explicitly specified
1274     *
1275     * @see #setNextFocusableComponent
1276     * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
1277     */

1278    @Deprecated JavaDoc
1279    public Component getNextFocusableComponent() {
1280    return (Component)getClientProperty(NEXT_FOCUS);
1281    }
1282  
1283    /**
1284     * Provides a hint as to whether or not this <code>JComponent</code>
1285     * should get focus. This is only a hint, and it is up to consumers that
1286     * are requesting focus to honor this property. This is typically honored
1287     * for mouse operations, but not keyboard operations. For example, look
1288     * and feels could verify this property is true before requesting focus
1289     * during a mouse operation. This would often times be used if you did
1290     * not want a mouse press on a <code>JComponent</code> to steal focus,
1291     * but did want the <code>JComponent</code> to be traversable via the
1292     * keyboard. If you do not want this <code>JComponent</code> focusable at
1293     * all, use the <code>setFocusable</code> method instead.
1294     * <p>
1295     * Please see
1296     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1297     * How to Use the Focus Subsystem</a>,
1298     * a section in <em>The Java Tutorial</em>,
1299     * for more information.
1300     *
1301     * @param requestFocusEnabled indicates whether you want this
1302     * <code>JComponent</code> to be focusable or not
1303     * @see <a HREF="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
1304     * @see java.awt.Component#setFocusable
1305     */

1306    public void setRequestFocusEnabled(boolean requestFocusEnabled) {
1307        setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
1308    }
1309  
1310    /**
1311     * Returns <code>true</code> if this <code>JComponent</code> should
1312     * get focus; otherwise returns <code>false</code>.
1313     * <p>
1314     * Please see
1315     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1316     * How to Use the Focus Subsystem</a>,
1317     * a section in <em>The Java Tutorial</em>,
1318     * for more information.
1319     *
1320     * @return <code>true</code> if this component should get focus,
1321     * otherwise returns <code>false</code>
1322     * @see #setRequestFocusEnabled
1323     * @see <a HREF="../../java/awt/doc-files/FocusSpec.html">Focus
1324     * Specification</a>
1325     * @see java.awt.Component#isFocusable
1326     */

1327    public boolean isRequestFocusEnabled() {
1328        return !getFlag(REQUEST_FOCUS_DISABLED);
1329    }
1330  
1331    private boolean runInputVerifier() {
1332        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
1333        boolean inActivation;
1334        try {
1335            AccessibleMethod accessibleMethod
1336                = new AccessibleMethod(KeyboardFocusManager.class,
1337                                       "isInActivation");
1338            inActivation = (Boolean JavaDoc) (accessibleMethod.invokeNoChecked(kfm));
1339        } catch (NoSuchMethodException JavaDoc e) {
1340            throw new AssertionError JavaDoc(
1341                "Couldn't locate method KeyboardFocusManager.isInActivation()");
1342        }
1343
1344        if (inActivation) {
1345            // Focus automatically returned back from another window
1346
// no need to process input verifier again
1347
return true;
1348        }
1349
1350        if (inInputVerifier) {
1351            // We're already running the InputVerifier, assume the
1352
// developer knows what they're doing.
1353
return true;
1354        }
1355        Component focusOwner = kfm.getFocusOwner();
1356
1357        if (focusOwner == null) {
1358            // If we are moving focus from another window, we should detect
1359
// what element was in focus in the window that will be focused now.
1360
// To do this, static package private method
1361
// KeyboardFocusManager.getMostRecentFocusOwner() will be called.
1362
// We will use AccessController.doPrivileged() to make package
1363
// private method accessible.
1364
Window window = SwingUtilities.getWindowAncestor(this);
1365            if (window != null) {
1366                try {
1367                    AccessibleMethod accessibleMethod
1368                        = new AccessibleMethod(KeyboardFocusManager.class,
1369                                               "getMostRecentFocusOwner",
1370                                               Window.class);
1371                    focusOwner = (Component) (accessibleMethod.invokeNoChecked(null,
1372                                                                               window));
1373                } catch (NoSuchMethodException JavaDoc e) {
1374                    throw new AssertionError JavaDoc("Couldn't locate method " +
1375                            "KeyboardFocusManager.getMostRecentFocusOwner()");
1376                }
1377            }
1378        }
1379
1380        if (focusOwner == this) {
1381            return true;
1382        }
1383
1384    if (!getVerifyInputWhenFocusTarget()) {
1385        return true;
1386    }
1387  
1388    if (focusOwner == null || !(focusOwner instanceof JComponent JavaDoc)) {
1389        return true;
1390    }
1391  
1392    JComponent JavaDoc jFocusOwner = (JComponent JavaDoc)focusOwner;
1393    InputVerifier JavaDoc iv = jFocusOwner.getInputVerifier();
1394    
1395    if (iv == null) {
1396        return true;
1397    } else {
1398            inInputVerifier = true;
1399            try {
1400                return iv.shouldYieldFocus(jFocusOwner);
1401            } finally {
1402                inInputVerifier = false;
1403            }
1404    }
1405    }
1406  
1407    /**
1408     * Requests that this <code>Component</code> gets the input focus.
1409     * Refer to {@link java.awt.Component#requestFocus()
1410     * Component.requestFocus()} for a complete description of
1411     * this method.
1412     * <p>
1413     * Note that the use of this method is discouraged because
1414     * its behavior is platform dependent. Instead we recommend the
1415     * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
1416     * If you would like more information on focus, see
1417     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1418     *
1419     * @see java.awt.Component#requestFocusInWindow()
1420     * @see java.awt.Component#requestFocusInWindow(boolean)
1421     * @since 1.4
1422     */

1423    public void requestFocus() {
1424        if (runInputVerifier()) {
1425        super.requestFocus();
1426    }
1427    }
1428
1429    /**
1430     * Requests that this <code>Component</code> gets the input focus.
1431     * Refer to {@link java.awt.Component#requestFocus(boolean)
1432     * Component.requestFocus(boolean)} for a complete description of
1433     * this method.
1434     * <p>
1435     * Note that the use of this method is discouraged because
1436     * its behavior is platform dependent. Instead we recommend the
1437     * use of {@link #requestFocusInWindow(boolean)
1438     * requestFocusInWindow(boolean)}.
1439     * If you would like more information on focus, see
1440     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1441     * How to Use the Focus Subsystem</a>,
1442     * a section in <em>The Java Tutorial</em>.
1443     *
1444     * @param temporary boolean indicating if the focus change is temporary
1445     * @return <code>false</code> if the focus change request is guaranteed to
1446     * fail; <code>true</code> if it is likely to succeed
1447     * @see java.awt.Component#requestFocusInWindow()
1448     * @see java.awt.Component#requestFocusInWindow(boolean)
1449     * @since 1.4
1450     */

1451    public boolean requestFocus(boolean temporary) {
1452    return (runInputVerifier())
1453        ? super.requestFocus(temporary)
1454        : false;
1455    }
1456
1457    /**
1458     * Requests that this <code>Component</code> gets the input focus.
1459     * Refer to {@link java.awt.Component#requestFocusInWindow()
1460     * Component.requestFocusInWindow()} for a complete description of
1461     * this method.
1462     * <p>
1463     * If you would like more information on focus, see
1464     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1465     * How to Use the Focus Subsystem</a>,
1466     * a section in <em>The Java Tutorial</em>.
1467     *
1468     * @return <code>false</code> if the focus change request is guaranteed to
1469     * fail; <code>true</code> if it is likely to succeed
1470     * @see java.awt.Component#requestFocusInWindow()
1471     * @see java.awt.Component#requestFocusInWindow(boolean)
1472     * @since 1.4
1473     */

1474    public boolean requestFocusInWindow() {
1475    return (runInputVerifier())
1476        ? super.requestFocusInWindow()
1477        : false;
1478    }
1479
1480    /**
1481     * Requests that this <code>Component</code> gets the input focus.
1482     * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
1483     * Component.requestFocusInWindow(boolean)} for a complete description of
1484     * this method.
1485     * <p>
1486     * If you would like more information on focus, see
1487     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1488     *
1489     * @param temporary boolean indicating if the focus change is temporary
1490     * @return <code>false</code> if the focus change request is guaranteed to
1491     * fail; <code>true</code> if it is likely to succeed
1492     * @see java.awt.Component#requestFocusInWindow()
1493     * @see java.awt.Component#requestFocusInWindow(boolean)
1494     * @since 1.4
1495     */

1496    protected boolean requestFocusInWindow(boolean temporary) {
1497    return (runInputVerifier())
1498        ? super.requestFocusInWindow(temporary)
1499        : false;
1500    }
1501
1502    /**
1503     * Requests that this Component get the input focus, and that this
1504     * Component's top-level ancestor become the focused Window. This component
1505     * must be displayable, visible, and focusable for the request to be
1506     * granted.
1507     * <p>
1508     * This method is intended for use by focus implementations. Client code
1509     * should not use this method; instead, it should use
1510     * <code>requestFocusInWindow()</code>.
1511     *
1512     * @see #requestFocusInWindow()
1513     */

1514    public void grabFocus() {
1515    requestFocus();
1516    }
1517  
1518    /**
1519     * Sets the value to indicate whether input verifier for the
1520     * current focus owner will be called before this component requests
1521     * focus. The default is true. Set to false on components such as a
1522     * Cancel button or a scrollbar, which should activate even if the
1523     * input in the current focus owner is not "passed" by the input
1524     * verifier for that component.
1525     *
1526     * @param verifyInputWhenFocusTarget value for the
1527     * <code>verifyInputWhenFocusTarget</code> property
1528     * @see InputVerifier
1529     * @see #setInputVerifier
1530     * @see #getInputVerifier
1531     * @see #getVerifyInputWhenFocusTarget
1532     *
1533     * @since 1.3
1534     * @beaninfo
1535     * bound: true
1536     * description: Whether the Component verifies input before accepting
1537     * focus.
1538     */

1539    public void setVerifyInputWhenFocusTarget(boolean
1540                          verifyInputWhenFocusTarget) {
1541    boolean oldVerifyInputWhenFocusTarget =
1542        this.verifyInputWhenFocusTarget;
1543        this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
1544    firePropertyChange("verifyInputWhenFocusTarget",
1545               oldVerifyInputWhenFocusTarget,
1546               verifyInputWhenFocusTarget);
1547    }
1548
1549    /**
1550     * Returns the value that indicates whether the input verifier for the
1551     * current focus owner will be called before this component requests
1552     * focus.
1553     *
1554     * @return value of the <code>verifyInputWhenFocusTarget</code> property
1555     *
1556     * @see InputVerifier
1557     * @see #setInputVerifier
1558     * @see #getInputVerifier
1559     * @see #setVerifyInputWhenFocusTarget
1560     *
1561     * @since 1.3
1562     */

1563    public boolean getVerifyInputWhenFocusTarget() {
1564        return verifyInputWhenFocusTarget;
1565    }
1566
1567
1568    /**
1569     * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
1570     *
1571     * @param font the font for which font metrics is to be
1572     * obtained
1573     * @return the font metrics for <code>font</code>
1574     * @throws NullPointerException if <code>font</code> is null
1575     * @since 1.5
1576     */

1577    public FontMetrics getFontMetrics(Font font) {
1578        if (font != null && SwingUtilities2.drawTextAntialiased(aaText)) {
1579            synchronized(aaFontMap) {
1580                FontMetrics aaMetrics = aaFontMap.get(font);
1581                if (aaMetrics == null) {
1582                    aaMetrics = new FontDesignMetrics(
1583                             font, SwingUtilities2.AA_FRC);
1584                    aaFontMap.put(font, aaMetrics);
1585                }
1586                return aaMetrics;
1587            }
1588        }
1589        return super.getFontMetrics(font);
1590    }
1591 
1592
1593    /**
1594     * Sets the preferred size of this component.
1595     * If <code>preferredSize</code> is <code>null</code>, the UI will
1596     * be asked for the preferred size.
1597     * @beaninfo
1598     * preferred: true
1599     * bound: true
1600     * description: The preferred size of the component.
1601     */

1602    public void setPreferredSize(Dimension preferredSize) {
1603        super.setPreferredSize(preferredSize);
1604    }
1605
1606
1607    /**
1608     * If the <code>preferredSize</code> has been set to a
1609     * non-<code>null</code> value just returns it.
1610     * If the UI delegate's <code>getPreferredSize</code>
1611     * method returns a non <code>null</code> value then return that;
1612     * otherwise defer to the component's layout manager.
1613     *
1614     * @return the value of the <code>preferredSize</code> property
1615     * @see #setPreferredSize
1616     * @see ComponentUI
1617     */

1618    public Dimension getPreferredSize() {
1619        if (isPreferredSizeSet()) {
1620            return super.getPreferredSize();
1621        }
1622        Dimension size = null;
1623        if (ui != null) {
1624            size = ui.getPreferredSize(this);
1625        }
1626        return (size != null) ? size : super.getPreferredSize();
1627    }
1628
1629
1630    /**
1631     * Sets the maximum size of this component to a constant
1632     * value. Subsequent calls to <code>getMaximumSize</code> will always
1633     * return this value; the component's UI will not be asked
1634     * to compute it. Setting the maximum size to <code>null</code>
1635     * restores the default behavior.
1636     *
1637     * @param maximumSize a <code>Dimension</code> containing the
1638     * desired maximum allowable size
1639     * @see #getMaximumSize
1640     * @beaninfo
1641     * bound: true
1642     * description: The maximum size of the component.
1643     */

1644    public void setMaximumSize(Dimension maximumSize) {
1645        super.setMaximumSize(maximumSize);
1646    }
1647
1648
1649    /**
1650     * If the maximum size has been set to a non-<code>null</code> value
1651     * just returns it. If the UI delegate's <code>getMaximumSize</code>
1652     * method returns a non-<code>null</code> value then return that;
1653     * otherwise defer to the component's layout manager.
1654     *
1655     * @return the value of the <code>maximumSize</code> property
1656     * @see #setMaximumSize
1657     * @see ComponentUI
1658     */

1659    public Dimension getMaximumSize() {
1660        if (isMaximumSizeSet()) {
1661            return super.getMaximumSize();
1662        }
1663        Dimension size = null;
1664        if (ui != null) {
1665            size = ui.getMaximumSize(this);
1666        }
1667        return (size != null) ? size : super.getMaximumSize();
1668    }
1669
1670
1671    /**
1672     * Sets the minimum size of this component to a constant
1673     * value. Subsequent calls to <code>getMinimumSize</code> will always
1674     * return this value; the component's UI will not be asked
1675     * to compute it. Setting the minimum size to <code>null</code>
1676     * restores the default behavior.
1677     *
1678     * @param minimumSize the new minimum size of this component
1679     * @see #getMinimumSize
1680     * @beaninfo
1681     * bound: true
1682     * description: The minimum size of the component.
1683     */

1684    public void setMinimumSize(Dimension minimumSize) {
1685        super.setMinimumSize(minimumSize);
1686    }
1687
1688    /**
1689     * If the minimum size has been set to a non-<code>null</code> value
1690     * just returns it. If the UI delegate's <code>getMinimumSize</code>
1691     * method returns a non-<code>null</code> value then return that; otherwise
1692     * defer to the component's layout manager.
1693     *
1694     * @return the value of the <code>minimumSize</code> property
1695     * @see #setMinimumSize
1696     * @see ComponentUI
1697     */

1698    public Dimension getMinimumSize() {
1699        if (isMinimumSizeSet()) {
1700            return super.getMinimumSize();
1701        }
1702        Dimension size = null;
1703        if (ui != null) {
1704            size = ui.getMinimumSize(this);
1705        }
1706        return (size != null) ? size : super.getMinimumSize();
1707    }
1708
1709    /**
1710     * Gives the UI delegate an opportunity to define the precise
1711     * shape of this component for the sake of mouse processing.
1712     *
1713     * @return true if this component logically contains x,y
1714     * @see java.awt.Component#contains(int, int)
1715     * @see ComponentUI
1716     */

1717    public boolean contains(int x, int y) {
1718        return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
1719    }
1720
1721    /**
1722     * Sets the border of this component. The <code>Border</code> object is
1723     * responsible for defining the insets for the component
1724     * (overriding any insets set directly on the component) and
1725     * for optionally rendering any border decorations within the
1726     * bounds of those insets. Borders should be used (rather
1727     * than insets) for creating both decorative and non-decorative
1728     * (such as margins and padding) regions for a swing component.
1729     * Compound borders can be used to nest multiple borders within a
1730     * single component.
1731     * <p>
1732     * Although technically you can set the border on any object
1733     * that inherits from <code>JComponent</ocde>, the look and
1734     * feel implementation of many standard Swing components
1735     * doesn't work well with user-set borders. In general,
1736     * when you want to set a border on a standard Swing
1737     * component other than <code>JPanel</code> or <code>JLabel</code>,
1738     * we recommend that you put the component in a <code>JPanel</code>
1739     * and set the border on the <code>JPanel</code>.
1740     * <p>
1741     * This is a bound property.
1742     *
1743     * @param border the border to be rendered for this component
1744     * @see Border
1745     * @see CompoundBorder
1746     * @beaninfo
1747     * bound: true
1748     * preferred: true
1749     * attribute: visualUpdate true
1750     * description: The component's border.
1751     */

1752    public void setBorder(Border border) {
1753        Border oldBorder = this.border;
1754
1755        this.border = border;
1756        firePropertyChange("border", oldBorder, border);
1757        if (border != oldBorder) {
1758            if (border == null || oldBorder == null ||
1759                !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
1760                revalidate();
1761            }
1762            repaint();
1763        }
1764    }
1765
1766    /**
1767     * Returns the border of this component or <code>null</code> if no
1768     * border is currently set.
1769     *
1770     * @return the border object for this component
1771     * @see #setBorder
1772     */

1773    public Border getBorder() {
1774        return border;
1775    }
1776
1777    /**
1778     * If a border has been set on this component, returns the
1779     * border's insets; otherwise calls <code>super.getInsets</code>.
1780     *
1781     * @return the value of the insets property
1782     * @see #setBorder
1783     */

1784    public Insets getInsets() {
1785        if (border != null) {
1786            return border.getBorderInsets(this);
1787        }
1788        return super.getInsets();
1789    }
1790
1791    /**
1792     * Returns an <code>Insets</code> object containing this component's inset
1793     * values. The passed-in <code>Insets</code> object will be reused
1794     * if possible.
1795     * Calling methods cannot assume that the same object will be returned,
1796     * however. All existing values within this object are overwritten.
1797     * If <code>insets</code> is null, this will allocate a new one.
1798     *
1799     * @param insets the <code>Insets</code> object, which can be reused
1800     * @return the <code>Insets</code> object
1801     * @see #getInsets
1802     * @beaninfo
1803     * expert: true
1804     */

1805    public Insets getInsets(Insets insets) {
1806        if (insets == null) {
1807            insets = new Insets(0, 0, 0, 0);
1808        }
1809        if (border != null) {
1810            if (border instanceof AbstractBorder) {
1811                return ((AbstractBorder)border).getBorderInsets(this, insets);
1812            } else {
1813                // Can't reuse border insets because the Border interface
1814
// can't be enhanced.
1815
return border.getBorderInsets(this);
1816            }
1817        } else {
1818            // super.getInsets() always returns an Insets object with
1819
// all of its value zeroed. No need for a new object here.
1820
insets.left = insets.top = insets.right = insets.bottom = 0;
1821            return insets;
1822        }
1823    }
1824
1825    /**
1826     * Overrides <code>Container.getAlignmentY</code> to return
1827     * the horizontal alignment.
1828     *
1829     * @return the value of the <code>alignmentY</code> property
1830     * @see #setAlignmentY
1831     * @see java.awt.Component#getAlignmentY
1832     */

1833    public float getAlignmentY() {
1834        if (isAlignmentYSet) {
1835            return alignmentY;
1836        }
1837        return super.getAlignmentY();
1838    }
1839
1840    /**
1841     * Sets the the horizontal alignment.
1842     *
1843     * @param alignmentY the new horizontal alignment
1844     * @see #getAlignmentY
1845     * @beaninfo
1846     * description: The preferred vertical alignment of the component.
1847     */

1848    public void setAlignmentY(float alignmentY) {
1849        this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
1850        isAlignmentYSet = true;
1851    }
1852
1853
1854    /**
1855     * Overrides <code>Container.getAlignmentX</code> to return
1856     * the vertical alignment.
1857     *
1858     * @return the value of the <code>alignmentX</code> property
1859     * @see #setAlignmentX
1860     * @see java.awt.Component#getAlignmentX
1861     */

1862    public float getAlignmentX() {
1863        if (isAlignmentXSet) {
1864            return alignmentX;
1865        }
1866        return super.getAlignmentX();
1867    }
1868
1869    /**
1870     * Sets the the vertical alignment.
1871     *
1872     * @param alignmentX the new vertical alignment
1873     * @see #getAlignmentX
1874     * @beaninfo
1875     * description: The preferred horizontal alignment of the component.
1876     */

1877    public void setAlignmentX(float alignmentX) {
1878        this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
1879        isAlignmentXSet = true;
1880    }
1881
1882    /**
1883     * Sets the input verifier for this component.
1884     *
1885     * @param inputVerifier the new input verifier
1886     * @since 1.3
1887     * @see InputVerifier
1888     * @beaninfo
1889     * bound: true
1890     * description: The component's input verifier.
1891     */

1892    public void setInputVerifier(InputVerifier JavaDoc inputVerifier) {
1893    InputVerifier JavaDoc oldInputVerifier = (InputVerifier JavaDoc)getClientProperty(
1894                                         INPUT_VERIFIER_KEY);
1895        putClientProperty(INPUT_VERIFIER_KEY, inputVerifier);
1896    firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
1897    }
1898
1899    /**
1900     * Returns the input verifier for this component.
1901     *
1902     * @return the <code>inputVerifier</code> property
1903     * @since 1.3
1904     * @see InputVerifier
1905     */

1906    public InputVerifier JavaDoc getInputVerifier() {
1907        return (InputVerifier JavaDoc)getClientProperty(INPUT_VERIFIER_KEY);
1908    }
1909
1910    /**
1911     * Returns this component's graphics context, which lets you draw
1912     * on a component. Use this method get a <code>Graphics</code> object and
1913     * then invoke operations on that object to draw on the component.
1914     * @return this components graphics context
1915     */

1916    public Graphics getGraphics() {
1917        if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
1918            DebugGraphics JavaDoc graphics = new DebugGraphics JavaDoc(super.getGraphics(),
1919                                                       this);
1920            return graphics;
1921        }
1922        return super.getGraphics();
1923    }
1924
1925
1926    /** Enables or disables diagnostic information about every graphics
1927      * operation performed within the component or one of its children.
1928      *
1929      * @param debugOptions determines how the component should display
1930      * the information; one of the following options:
1931      * <ul>
1932      * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1933      * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1934      * times.
1935      * <li>DebugGraphics.BUFFERED_OPTION - creates an
1936      * <code>ExternalWindow</code> that displays the operations
1937      * performed on the View's offscreen buffer.
1938      * <li>DebugGraphics.NONE_OPTION disables debugging.
1939      * <li>A value of 0 causes no changes to the debugging options.
1940      * </ul>
1941      * <code>debugOptions</code> is bitwise OR'd into the current value
1942      *
1943      * @beaninfo
1944      * preferred: true
1945      * enum: NONE_OPTION DebugGraphics.NONE_OPTION
1946      * LOG_OPTION DebugGraphics.LOG_OPTION
1947      * FLASH_OPTION DebugGraphics.FLASH_OPTION
1948      * BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
1949      * description: Diagnostic options for graphics operations.
1950      */

1951    public void setDebugGraphicsOptions(int debugOptions) {
1952        DebugGraphics.setDebugOptions(this, debugOptions);
1953    }
1954
1955    /** Returns the state of graphics debugging.
1956      *
1957      * @return a bitwise OR'd flag of zero or more of the following options:
1958      * <ul>
1959      * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1960      * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1961      * times.
1962      * <li>DebugGraphics.BUFFERED_OPTION - creates an
1963      * <code>ExternalWindow</code> that displays the operations
1964      * performed on the View's offscreen buffer.
1965      * <li>DebugGraphics.NONE_OPTION disables debugging.
1966      * <li>A value of 0 causes no changes to the debugging options.
1967      * </ul>
1968      * @see #setDebugGraphicsOptions
1969      */

1970    public int getDebugGraphicsOptions() {
1971        return DebugGraphics.getDebugOptions(this);
1972    }
1973
1974
1975    /**
1976     * Returns true if debug information is enabled for this
1977     * <code>JComponent</code> or one of its parents.
1978     */

1979    int shouldDebugGraphics() {
1980        return DebugGraphics.shouldComponentDebug(this);
1981    }
1982
1983    /**
1984     * This method is now obsolete, please use a combination of
1985     * <code>getActionMap()</code> and <code>getInputMap()</code> for
1986     * similiar behavior. For example, to bind the <code>KeyStroke</code>
1987     * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
1988     * now use:
1989     * <pre>
1990     * component.getInputMap().put(aKeyStroke, aCommand);
1991     * component.getActionMap().put(aCommmand, anAction);
1992     * </pre>
1993     * The above assumes you want the binding to be applicable for
1994     * <code>WHEN_FOCUSED</code>. To register bindings for other focus
1995     * states use the <code>getInputMap</code> method that takes an integer.
1996     * <p>
1997     * Register a new keyboard action.
1998     * <code>anAction</code> will be invoked if a key event matching
1999     * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
2000     * The <code>KeyStroke</code> object defines a
2001     * particular combination of a keyboard key and one or more modifiers
2002     * (alt, shift, ctrl, meta).
2003     * <p>
2004     * The <code>aCommand</code> will be set in the delivered event if
2005     * specified.
2006     * <p>
2007     * The <code>aCondition</code> can be one of:
2008     * <blockquote>
2009     * <DL>
2010     * <DT>WHEN_FOCUSED
2011     * <DD>The action will be invoked only when the keystroke occurs
2012     * while the component has the focus.
2013     * <DT>WHEN_IN_FOCUSED_WINDOW
2014     * <DD>The action will be invoked when the keystroke occurs while
2015     * the component has the focus or if the component is in the
2016     * window that has the focus. Note that the component need not
2017     * be an immediate descendent of the window -- it can be
2018     * anywhere in the window's containment hierarchy. In other
2019     * words, whenever <em>any</em> component in the window has the focus,
2020     * the action registered with this component is invoked.
2021     * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2022     * <DD>The action will be invoked when the keystroke occurs while the
2023     * component has the focus or if the component is an ancestor of
2024     * the component that has the focus.
2025     * </DL>
2026     * </blockquote>
2027     * <p>
2028     * The combination of keystrokes and conditions lets you define high
2029     * level (semantic) action events for a specified keystroke+modifier
2030     * combination (using the KeyStroke class) and direct to a parent or
2031     * child of a component that has the focus, or to the component itself.
2032     * In other words, in any hierarchical structure of components, an
2033     * arbitrary key-combination can be immediately directed to the
2034     * appropriate component in the hierarchy, and cause a specific method
2035     * to be invoked (usually by way of adapter objects).
2036     * <p>
2037     * If an action has already been registered for the receiving
2038     * container, with the same charCode and the same modifiers,
2039     * <code>anAction</code> will replace the action.
2040     *
2041     * @param anAction the <code>Action</code> to be registered
2042     * @param aCommand the command to be set in the delivered event
2043     * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
2044     * @param aCondition the condition that needs to be met, see above
2045     * @see KeyStroke
2046     */

2047    public void registerKeyboardAction(ActionListener anAction,String JavaDoc aCommand,KeyStroke JavaDoc aKeyStroke,int aCondition) {
2048
2049    InputMap JavaDoc inputMap = getInputMap(aCondition, true);
2050
2051    if (inputMap != null) {
2052        ActionMap JavaDoc actionMap = getActionMap(true);
2053        ActionStandin action = new ActionStandin(anAction, aCommand);
2054        inputMap.put(aKeyStroke, action);
2055        if (actionMap != null) {
2056        actionMap.put(action, action);
2057        }
2058    }
2059    }
2060
2061    /**
2062     * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
2063     * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
2064     * is true only actions that haven't been registered are pushed
2065     * to the <code>KeyboardManager</code>;
2066     * otherwise all actions are pushed to the <code>KeyboardManager</code>.
2067     *
2068     * @param onlyIfNew if true, only actions that haven't been registered
2069     * are pushed to the <code>KeyboardManager</code>
2070     */

2071    private void registerWithKeyboardManager(boolean onlyIfNew) {
2072    InputMap JavaDoc inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2073    KeyStroke JavaDoc[] strokes;
2074    Hashtable JavaDoc registered = (Hashtable JavaDoc)getClientProperty
2075                            (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2076
2077    if (inputMap != null) {
2078        // Push any new KeyStrokes to the KeyboardManager.
2079
strokes = inputMap.allKeys();
2080        if (strokes != null) {
2081        for (int counter = strokes.length - 1; counter >= 0;
2082             counter--) {
2083            if (!onlyIfNew || registered == null ||
2084            registered.get(strokes[counter]) == null) {
2085            registerWithKeyboardManager(strokes[counter]);
2086            }
2087            if (registered != null) {
2088            registered.remove(strokes[counter]);
2089            }
2090        }
2091        }
2092    }
2093    else {
2094        strokes = null;
2095    }
2096    // Remove any old ones.
2097
if (registered != null && registered.size() > 0) {
2098        Enumeration JavaDoc keys = registered.keys();
2099
2100        while (keys.hasMoreElements()) {
2101        KeyStroke JavaDoc ks = (KeyStroke JavaDoc)keys.nextElement();
2102        unregisterWithKeyboardManager(ks);
2103        }
2104        registered.clear();
2105    }
2106    // Updated the registered Hashtable.
2107
if (strokes != null && strokes.length > 0) {
2108        if (registered == null) {
2109        registered = new Hashtable JavaDoc(strokes.length);
2110        putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
2111        }
2112        for (int counter = strokes.length - 1; counter >= 0; counter--) {
2113        registered.put(strokes[counter], strokes[counter]);
2114        }
2115    }
2116    else {
2117        putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2118    }
2119    }
2120
2121    /**
2122     * Unregisters all the previously registered
2123     * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
2124     */

2125    private void unregisterWithKeyboardManager() {
2126    Hashtable JavaDoc registered = (Hashtable JavaDoc)getClientProperty
2127                            (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2128
2129    if (registered != null && registered.size() > 0) {
2130        Enumeration JavaDoc keys = registered.keys();
2131
2132        while (keys.hasMoreElements()) {
2133        KeyStroke JavaDoc ks = (KeyStroke JavaDoc)keys.nextElement();
2134        unregisterWithKeyboardManager(ks);
2135        }
2136    }
2137    putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2138    }
2139
2140    /**
2141     * Invoked from <code>ComponentInputMap</code> when its bindings change.
2142     * If <code>inputMap</code> is the current <code>windowInputMap</code>
2143     * (or a parent of the window <code>InputMap</code>)
2144     * the <code>KeyboardManager</code> is notified of the new bindings.
2145     *
2146     * @param inputMap the map containing the new bindings
2147     */

2148    void componentInputMapChanged(ComponentInputMap JavaDoc inputMap) {
2149    InputMap JavaDoc km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2150
2151    while (km != inputMap && km != null) {
2152        km = (ComponentInputMap JavaDoc)km.getParent();
2153    }
2154    if (km != null) {
2155        registerWithKeyboardManager(false);
2156    }
2157    }
2158
2159    private void registerWithKeyboardManager(KeyStroke JavaDoc aKeyStroke) {
2160    KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
2161    }
2162
2163    private void unregisterWithKeyboardManager(KeyStroke JavaDoc aKeyStroke) {
2164    KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
2165                                this);
2166    }
2167
2168    /**
2169     * This method is now obsolete, please use a combination of
2170     * <code>getActionMap()</code> and <code>getInputMap()</code> for
2171     * similiar behavior.
2172     */

2173    public void registerKeyboardAction(ActionListener anAction,KeyStroke JavaDoc aKeyStroke,int aCondition) {
2174        registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
2175    }
2176
2177    /**
2178     * This method is now obsolete. To unregister an existing binding
2179     * you can either remove the binding from the
2180     * <code>ActionMap/InputMap</code>, or place a dummy binding the
2181     * <code>InputMap</code>. Removing the binding from the
2182     * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
2183     * to be active, whereas putting a dummy binding in the
2184     * <code>InputMap</code> effectively disables
2185     * the binding from ever happening.
2186     * <p>
2187     * Unregisters a keyboard action.
2188     * This will remove the binding from the <code>ActionMap</code>
2189     * (if it exists) as well as the <code>InputMap</code>s.
2190     */

2191    public void unregisterKeyboardAction(KeyStroke JavaDoc aKeyStroke) {
2192    ActionMap JavaDoc am = getActionMap(false);
2193    for (int counter = 0; counter < 3; counter++) {
2194        InputMap JavaDoc km = getInputMap(counter, false);
2195        if (km != null) {
2196        Object JavaDoc actionID = km.get(aKeyStroke);
2197
2198        if (am != null && actionID != null) {
2199            am.remove(actionID);
2200        }
2201        km.remove(aKeyStroke);
2202        }
2203    }
2204    }
2205
2206    /**
2207     * Returns the <code>KeyStrokes</code> that will initiate
2208     * registered actions.
2209     *
2210     * @return an array of <code>KeyStroke</code> objects
2211     * @see #registerKeyboardAction
2212     */

2213    public KeyStroke JavaDoc[] getRegisteredKeyStrokes() {
2214    int[] counts = new int[3];
2215    KeyStroke JavaDoc[][] strokes = new KeyStroke JavaDoc[3][];
2216
2217    for (int counter = 0; counter < 3; counter++) {
2218        InputMap JavaDoc km = getInputMap(counter, false);
2219        strokes[counter] = (km != null) ? km.allKeys() : null;
2220        counts[counter] = (strokes[counter] != null) ?
2221                       strokes[counter].length : 0;
2222    }
2223    KeyStroke JavaDoc[] retValue = new KeyStroke JavaDoc[counts[0] + counts[1] +
2224                        counts[2]];
2225    for (int counter = 0, last = 0; counter < 3; counter++) {
2226        if (counts[counter] > 0) {
2227        System.arraycopy(strokes[counter], 0, retValue, last,
2228                 counts[counter]);
2229        last += counts[counter];
2230        }
2231    }
2232    return retValue;
2233    }
2234
2235    /**
2236     * Returns the condition that determines whether a registered action
2237     * occurs in response to the specified keystroke.
2238     * <p>
2239     * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
2240     * with more than one condition.
2241     * For example, 'a' could be bound for the two
2242     * conditions <code>WHEN_FOCUSED</code> and
2243     * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
2244     *
2245     * @return the action-keystroke condition
2246     */

2247    public int getConditionForKeyStroke(KeyStroke JavaDoc aKeyStroke) {
2248    for (int counter = 0; counter < 3; counter++) {
2249        InputMap JavaDoc inputMap = getInputMap(counter, false);
2250        if (inputMap != null && inputMap.get(aKeyStroke) != null) {
2251        return counter;
2252        }
2253    }
2254    return UNDEFINED_CONDITION;
2255    }
2256
2257    /**
2258     * Returns the object that will perform the action registered for a
2259     * given keystroke.
2260     *
2261     * @return the <code>ActionListener</code>
2262     * object invoked when the keystroke occurs
2263     */

2264    public ActionListener getActionForKeyStroke(KeyStroke JavaDoc aKeyStroke) {
2265    ActionMap JavaDoc am = getActionMap(false);
2266
2267    if (am == null) {
2268        return null;
2269    }
2270    for (int counter = 0; counter < 3; counter++) {
2271        InputMap JavaDoc inputMap = getInputMap(counter, false);
2272        if (inputMap != null) {
2273        Object JavaDoc actionBinding = inputMap.get(aKeyStroke);
2274
2275        if (actionBinding != null) {
2276            Action JavaDoc action = am.get(actionBinding);
2277            if (action instanceof ActionStandin) {
2278            return ((ActionStandin)action).actionListener;
2279            }
2280            return action;
2281        }
2282        }
2283    }
2284    return null;
2285    }
2286
2287    /**
2288     * Unregisters all the bindings in the first tier <code>InputMaps</code>
2289     * and <code>ActionMap</code>. This has the effect of removing any
2290     * local bindings, and allowing the bindings defined in parent
2291     * <code>InputMap/ActionMaps</code>
2292     * (the UI is usually defined in the second tier) to persist.
2293     */

2294    public void resetKeyboardActions() {
2295    // Keys
2296
for (int counter = 0; counter < 3; counter++) {
2297        InputMap JavaDoc inputMap = getInputMap(counter, false);
2298
2299        if (inputMap != null) {
2300        inputMap.clear();
2301        }
2302    }
2303
2304    // Actions
2305
ActionMap JavaDoc am = getActionMap(false);
2306
2307    if (am != null) {
2308        am.clear();
2309    }
2310    }
2311
2312    /**
2313     * Sets the <code>InputMap</code> to use under the condition
2314     * <code>condition</code> to
2315     * <code>map</code>. A <code>null</code> value implies you
2316     * do not want any bindings to be used, even from the UI. This will
2317     * not reinstall the UI <code>InputMap</code> (if there was one).
2318     * <code>condition</code> has one of the following values:
2319     * <ul>
2320     * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
2321     * <li><code>WHEN_FOCUSED</code>
2322     * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
2323     * </ul>
2324     * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code>
2325     * and <code>map</code> is not a <code>ComponentInputMap</code>, an
2326     * <code>IllegalArgumentException</code> will be thrown.
2327     * Similarly, if <code>condition</code> is not one of the values
2328     * listed, an <code>IllegalArgumentException</code> will be thrown.
2329     *
2330     * @param condition one of the values listed above
2331     * @param map the <code>InputMap</code> to use for the given condition
2332     * @exception IllegalArgumentException if <code>condition</code> is
2333     * <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
2334     * is not an instance of <code>ComponentInputMap</code>; or
2335     * if <code>condition</code> is not one of the legal values
2336     * specified above
2337     * @since 1.3
2338     */

2339    public final void setInputMap(int condition, InputMap JavaDoc map) {
2340    switch (condition) {
2341    case WHEN_IN_FOCUSED_WINDOW:
2342        if (map != null && !(map instanceof ComponentInputMap JavaDoc)) {
2343        throw new IllegalArgumentException JavaDoc("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
2344        }
2345        windowInputMap = (ComponentInputMap JavaDoc)map;
2346        setFlag(WIF_INPUTMAP_CREATED, true);
2347        registerWithKeyboardManager(false);
2348        break;
2349    case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2350        ancestorInputMap = map;
2351        setFlag(ANCESTOR_INPUTMAP_CREATED, true);
2352        break;
2353    case WHEN_FOCUSED:
2354        focusInputMap = map;
2355        setFlag(FOCUS_INPUTMAP_CREATED, true);
2356        break;
2357    default:
2358        throw new IllegalArgumentException JavaDoc("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2359    }
2360    }
2361
2362    /**
2363     * Returns the <code>InputMap</code> that is used during
2364     * <code>condition</code>.
2365     *
2366     * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
2367     * WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2368     * @return the <code>InputMap</code> for the specified
2369     * <code>condition</code>
2370     * @since 1.3
2371     */

2372    public final InputMap JavaDoc getInputMap(int condition) {
2373    return getInputMap(condition, true);
2374    }
2375
2376    /**
2377     * Returns the <code>InputMap</code> that is used when the
2378     * component has focus.
2379     * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
2380     *
2381     * @return the <code>InputMap</code> used when the component has focus
2382     * @since JDK1.3
2383     */

2384    public final InputMap JavaDoc getInputMap() {
2385    return getInputMap(WHEN_FOCUSED, true);
2386    }
2387
2388    /**
2389     * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
2390     * the parent of the <code>am</code> to be the <code>ActionMap</code>
2391     * from the UI (if there was one), it is up to the caller to have done this.
2392     *
2393     * @param am the new <code>ActionMap</code>
2394     * @since 1.3
2395     */

2396    public final void setActionMap(ActionMap JavaDoc am) {
2397    actionMap = am;
2398    setFlag(ACTIONMAP_CREATED, true);
2399    }
2400
2401    /**
2402     * Returns the <code>ActionMap</code> used to determine what
2403     * <code>Action</code> to fire for particular <code>KeyStroke</code>
2404     * binding. The returned <code>ActionMap</code>, unless otherwise
2405     * set, will have the <code>ActionMap</code> from the UI set as the parent.
2406     *
2407     * @return the <code>ActionMap</code> containing the key/action bindings
2408     * @since 1.3
2409     */

2410    public final ActionMap JavaDoc getActionMap() {
2411    return getActionMap(true);
2412    }
2413
2414    /**
2415     * Returns the <code>InputMap</code> to use for condition
2416     * <code>condition</code>. If the <code>InputMap</code> hasn't
2417     * been created, and <code>create</code> is
2418     * true, it will be created.
2419     *
2420     * @param condition one of the following values:
2421     * <ul>
2422     * <li>JComponent.FOCUS_INPUTMAP_CREATED
2423     * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2424     * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2425     * </ul>
2426     * @param create if true, create the <code>InputMap</code> if it
2427     * is not already created
2428     * @return the <code>InputMap</code> for the given <code>condition</code>;
2429     * if <code>create</code> is false and the <code>InputMap</code>
2430     * hasn't been created, returns <code>null</code>
2431     * @exception IllegalArgumentException if <code>condition</code>
2432     * is not one of the legal values listed above
2433     */

2434    final InputMap JavaDoc getInputMap(int condition, boolean create) {
2435    switch (condition) {
2436    case WHEN_FOCUSED:
2437        if (getFlag(FOCUS_INPUTMAP_CREATED)) {
2438        return focusInputMap;
2439        }
2440        // Hasn't been created yet.
2441
if (create) {
2442        InputMap JavaDoc km = new InputMap JavaDoc();
2443        setInputMap(condition, km);
2444        return km;
2445        }
2446        break;
2447    case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2448        if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
2449        return ancestorInputMap;
2450        }
2451        // Hasn't been created yet.
2452
if (create) {
2453        InputMap JavaDoc km = new InputMap JavaDoc();
2454        setInputMap(condition, km);
2455        return km;
2456        }
2457        break;
2458    case WHEN_IN_FOCUSED_WINDOW:
2459        if (getFlag(WIF_INPUTMAP_CREATED)) {
2460        return windowInputMap;
2461        }
2462        // Hasn't been created yet.
2463
if (create) {
2464        ComponentInputMap JavaDoc km = new ComponentInputMap JavaDoc(this);
2465        setInputMap(condition, km);
2466        return km;
2467        }
2468        break;
2469    default:
2470        throw new IllegalArgumentException JavaDoc("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2471    }
2472    return null;
2473    }
2474
2475    /**
2476     * Finds and returns the appropriate <code>ActionMap</code>.
2477     *
2478     * @param create if true, create the <code>ActionMap</code> if it
2479     * is not already created
2480     * @return the <code>ActionMap</code> for this component; if the
2481     * <code>create</code> flag is false and there is no
2482     * current <code>ActionMap</code>, returns <code>null</code>
2483     */

2484    final ActionMap JavaDoc getActionMap(boolean create) {
2485    if (getFlag(ACTIONMAP_CREATED)) {
2486        return actionMap;
2487    }
2488    // Hasn't been created.
2489
if (create) {
2490        ActionMap JavaDoc am = new ActionMap JavaDoc();
2491        setActionMap(am);
2492        return am;
2493    }
2494    return null;
2495    }
2496
2497    /**
2498     * In release 1.4, the focus subsystem was rearchitected.
2499     * For more information, see
2500     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
2501     * How to Use the Focus Subsystem</a>,
2502     * a section in <em>The Java Tutorial</em>.
2503     * <p>
2504     * Requests focus on this <code>JComponent</code>'s
2505     * <code>FocusTraversalPolicy</code>'s default <code>Component</code>.
2506     * If this <code>JComponent</code> is a focus cycle root, then its
2507     * <code>FocusTraversalPolicy</code> is used. Otherwise, the
2508     * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
2509     * focus-cycle-root ancestor is used.
2510     *
2511     * @see java.awt.FocusTraversalPolicy#getDefaultComponent
2512     * @deprecated As of 1.4, replaced by
2513     * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
2514     */

2515    @Deprecated JavaDoc
2516    public boolean requestDefaultFocus() {
2517    Container nearestRoot =
2518        (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
2519    if (nearestRoot == null) {
2520        return false;
2521    }
2522    Component comp = nearestRoot.getFocusTraversalPolicy().
2523        getDefaultComponent(nearestRoot);
2524    if (comp != null) {
2525        comp.requestFocus();
2526        return true;
2527    } else {
2528        return false;
2529    }
2530    }
2531
2532    /**
2533     * Makes the component visible or invisible.
2534     * Overrides <code>Component.setVisible</code>.
2535     *
2536     * @param aFlag true to make the component visible; false to
2537     * make it invisible
2538     *
2539     * @beaninfo
2540     * attribute: visualUpdate true
2541     */

2542    public void setVisible(boolean aFlag) {
2543        if(aFlag != isVisible()) {
2544            super.setVisible(aFlag);
2545            Container parent = getParent();
2546            if(parent != null) {
2547                Rectangle r = getBounds();
2548                parent.repaint(r.x,r.y,r.width,r.height);
2549            }
2550        // Some (all should) LayoutManagers do not consider components
2551
// that are not visible. As such we need to revalidate when the
2552
// visible bit changes.
2553
revalidate();
2554        }
2555    }
2556
2557    /**
2558     * Sets whether or not this component is enabled.
2559     * A component that is enabled may respond to user input,
2560     * while a component that is not enabled cannot respond to
2561     * user input. Some components may alter their visual
2562     * representation when they are disabled in order to
2563     * provide feedback to the user that they cannot take input.
2564     * <p>Note: Disabling a component does not disable it's children.
2565     *
2566     * <p>Note: Disabling a lightweight component does not prevent it from
2567     * receiving MouseEvents.
2568     *
2569     * @param enabled true if this component should be enabled, false otherwise
2570     * @see java.awt.Component#isEnabled
2571     * @see java.awt.Component#isLightweight
2572     *
2573     * @beaninfo
2574     * preferred: true
2575     * bound: true
2576     * attribute: visualUpdate true
2577     * description: The enabled state of the component.
2578     */

2579    public void setEnabled(boolean enabled) {
2580        boolean oldEnabled = isEnabled();
2581        super.setEnabled(enabled);
2582        firePropertyChange("enabled", oldEnabled, enabled);
2583        if (enabled != oldEnabled) {
2584            repaint();
2585        }
2586    }
2587
2588    /**
2589     * Sets the foreground color of this component.
2590     *
2591     * @param fg the desired foreground <code>Color</code>
2592     * @see java.awt.Component#getForeground
2593     *
2594     * @beaninfo
2595     * preferred: true
2596     * bound: true
2597     * attribute: visualUpdate true
2598     * description: The foreground color of the component.
2599     */

2600    public void setForeground(Color fg) {
2601        Color oldFg = getForeground();
2602    super.setForeground(fg);
2603    if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
2604        // foreground already bound in AWT1.2
2605
repaint();
2606    }
2607    }
2608
2609    /**
2610     * Sets the background color of this component.
2611     *
2612     * @param bg the desired background <code>Color</code>
2613     * @see java.awt.Component#getBackground
2614     *
2615     * @beaninfo
2616     * preferred: true
2617     * bound: true
2618     * attribute: visualUpdate true
2619     * description: The background color of the component.
2620     */

2621    public void setBackground(Color bg) {
2622    Color oldBg = getBackground();
2623    super.setBackground(bg);
2624    if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) {
2625        // background already bound in AWT1.2
2626
repaint();
2627    }
2628    }
2629
2630    /**
2631     * Sets the font for this component.
2632     *
2633     * @param font the desired <code>Font</code> for this component
2634     * @see java.awt.Component#getFont
2635     *
2636     * @beaninfo
2637     * preferred: true
2638     * bound: true
2639     * attribute: visualUpdate true
2640     * description: The font for the component.
2641     */

2642    public void setFont(Font font) {
2643        Font oldFont = getFont();
2644        super.setFont(font);
2645        // font already bound in AWT1.2
2646
if (font != oldFont) {
2647            revalidate();
2648        repaint();
2649        }
2650    }
2651        
2652    /**
2653     * Returns the default locale used to initialize each JComponent's
2654     * locale property upon creation.
2655     *
2656     * The default locale has "AppContext" scope so that applets (and
2657     * potentially multiple lightweight applications running in a single VM)
2658     * can have their own setting. An applet can safely alter its default
2659     * locale because it will have no affect on other applets (or the browser).
2660     *
2661     * @return the default <code>Locale</code>.
2662     * @see #setDefaultLocale
2663     * @see java.awt.Component#getLocale
2664     * @see #setLocale
2665     * @since 1.4
2666     */

2667    static public Locale JavaDoc getDefaultLocale() {
2668        Locale JavaDoc l = (Locale JavaDoc) SwingUtilities.appContextGet(defaultLocale);
2669        if( l == null ) {
2670            //REMIND(bcb) choosing the default value is more complicated
2671
//than this.
2672
l = Locale.getDefault();
2673            JComponent.setDefaultLocale( l );
2674        }
2675        return l;
2676    }
2677
2678
2679    /**
2680     * Sets the default locale used to initialize each JComponent's locale
2681     * property upon creation. The initial value is the VM's default locale.
2682     *
2683     * The default locale has "AppContext" scope so that applets (and
2684     * potentially multiple lightweight applications running in a single VM)
2685     * can have their own setting. An applet can safely alter its default
2686     * locale because it will have no affect on other applets (or the browser).
2687     *
2688     * @param l the desired default <code>Locale</code> for new components.
2689     * @see #getDefaultLocale
2690     * @see java.awt.Component#getLocale
2691     * @see #setLocale
2692     * @since 1.4
2693     */

2694    static public void setDefaultLocale( Locale JavaDoc l ) {
2695        SwingUtilities.appContextPut(defaultLocale, l);
2696    }
2697
2698
2699    /**
2700     * Processes any key events that the component itself
2701     * recognizes. This is called after the focus
2702     * manager and any interested listeners have been
2703     * given a chance to steal away the event. This
2704     * method is called only if the event has not
2705     * yet been consumed. This method is called prior
2706     * to the keyboard UI logic.
2707     * <p>
2708     * This method is implemented to do nothing. Subclasses would
2709     * normally override this method if they process some
2710     * key events themselves. If the event is processed,
2711     * it should be consumed.
2712     */

2713    protected void processComponentKeyEvent(KeyEvent e) {
2714    }
2715
2716    /** Overrides <code>processKeyEvent</code> to process events. **/
2717    protected void processKeyEvent(KeyEvent e) {
2718      boolean result;
2719      boolean shouldProcessKey;
2720
2721      // This gives the key event listeners a crack at the event
2722
super.processKeyEvent(e);
2723
2724      // give the component itself a crack at the event
2725
if (! e.isConsumed()) {
2726          processComponentKeyEvent(e);
2727      }
2728
2729      shouldProcessKey = KeyboardState.shouldProcess(e);
2730
2731      if(e.isConsumed()) {
2732        return;
2733      }
2734
2735      if (shouldProcessKey && processKeyBindings(e, e.getID() ==
2736                                                 KeyEvent.KEY_PRESSED)) {
2737          e.consume();
2738      }
2739    }
2740
2741    /**
2742     * Invoked to process the key bindings for <code>ks</code> as the result
2743     * of the <code>KeyEvent</code> <code>e</code>. This obtains
2744     * the appropriate <code>InputMap</code>,
2745     * gets the binding, gets the action from the <code>ActionMap</code>,
2746     * and then (if the action is found and the component
2747     * is enabled) invokes <code>notifyAction</code> to notify the action.
2748     *
2749     * @param ks the <code>KeyStroke</code> queried
2750     * @param e the <code>KeyEvent</code>
2751     * @param condition one of the following values:
2752     * <ul>
2753     * <li>JComponent.WHEN_FOCUSED
2754     * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2755     * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2756     * </ul>
2757     * @param pressed true if the key is pressed
2758     * @return true if there was a binding to an action, and the action
2759     * was enabled
2760     *
2761     * @since 1.3
2762     */

2763    protected boolean processKeyBinding(KeyStroke JavaDoc ks, KeyEvent e,
2764                    int condition, boolean pressed) {
2765    InputMap JavaDoc map = getInputMap(condition, false);
2766    ActionMap JavaDoc am = getActionMap(false);
2767
2768        if(map != null && am != null && isEnabled()) {
2769        Object JavaDoc binding = map.get(ks);
2770        Action JavaDoc action = (binding == null) ? null : am.get(binding);
2771        if (action != null) {
2772        return SwingUtilities.notifyAction(action, ks, e, this,
2773                           e.getModifiers());
2774        }
2775    }
2776        return false;
2777    }
2778
2779    /**
2780     * This is invoked as the result of a <code>KeyEvent</code>
2781     * that was not consumed by the <code>FocusManager</code>,
2782     * <code>KeyListeners</code>, or the component. It will first try
2783     * <code>WHEN_FOCUSED</code> bindings,
2784     * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
2785     * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
2786     *
2787     * @param e the unconsumed <code>KeyEvent</code>
2788     * @param pressed true if the key is pressed
2789     * @return true if there is a key binding for <code>e</code>
2790     */

2791    boolean processKeyBindings(KeyEvent e, boolean pressed) {
2792      if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
2793          return false;
2794      }
2795      // Get the KeyStroke
2796
KeyStroke JavaDoc ks;
2797
2798      if (e.getID() == KeyEvent.KEY_TYPED) {
2799          ks = KeyStroke.getKeyStroke(e.getKeyChar());
2800      }
2801      else {
2802      ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
2803                    (pressed ? false:true));
2804      }
2805
2806      /* Do we have a key binding for e? */
2807      if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
2808      return true;
2809
2810      /* We have no key binding. Let's try the path from our parent to the
2811       * window excluded. We store the path components so we can avoid
2812       * asking the same component twice.
2813       */

2814      Container parent = this;
2815      while (parent != null && !(parent instanceof Window) &&
2816         !(parent instanceof Applet JavaDoc)) {
2817      if(parent instanceof JComponent JavaDoc) {
2818          if(((JComponent JavaDoc)parent).processKeyBinding(ks, e,
2819                   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2820          return true;
2821      }
2822      // This is done so that the children of a JInternalFrame are
2823
// given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
2824
// other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
2825
// more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
2826
// JInternalFrame's children vs the
2827
// WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
2828
// maybe generalize from JInternalFrame (like isFocusCycleRoot).
2829
if ((parent instanceof JInternalFrame JavaDoc) &&
2830          JComponent.processKeyBindingsForAllComponents(e,parent,pressed)){
2831          return true;
2832      }
2833      parent = parent.getParent();
2834      }
2835
2836      /* No components between the focused component and the window is
2837       * actually interested by the key event. Let's try the other
2838       * JComponent in this window.
2839       */

2840      if(parent != null) {
2841        return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
2842      }
2843      return false;
2844    }
2845
2846    static boolean processKeyBindingsForAllComponents(KeyEvent e,
2847                      Container container, boolean pressed) {
2848        while (true) {
2849            if (KeyboardManager.getCurrentManager().fireKeyboardAction(
2850                                e, pressed, container)) {
2851                return true;
2852            }
2853            if (container instanceof Popup.HeavyWeightWindow JavaDoc) {
2854                container = ((Window)container).getOwner();
2855            }
2856            else {
2857                return false;
2858            }
2859        }
2860    }
2861
2862    /**
2863     * Registers the text to display in a tool tip.
2864     * The text displays when the cursor lingers over the component.
2865     * <p>
2866     * See <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
2867     * in <em>The Java Tutorial</em>
2868     * for further documentation.
2869     *
2870     * @param text the string to display; if the text is <code>null</code>,
2871     * the tool tip is turned off for this component
2872     * @see #TOOL_TIP_TEXT_KEY
2873     * @beaninfo
2874     * preferred: true
2875     * description: The text to display in a tool tip.
2876     */

2877    public void setToolTipText(String JavaDoc text) {
2878        String JavaDoc oldText = getToolTipText();
2879        putClientProperty(TOOL_TIP_TEXT_KEY, text);
2880        ToolTipManager JavaDoc toolTipManager = ToolTipManager.sharedInstance();
2881        if (text != null) {
2882        if (oldText == null) {
2883                toolTipManager.registerComponent(this);
2884        }
2885        } else {
2886            toolTipManager.unregisterComponent(this);
2887        }
2888    }
2889
2890    /**
2891     * Returns the tooltip string that has been set with
2892     * <code>setToolTipText</code>.
2893     *
2894     * @return the text of the tool tip
2895     * @see #TOOL_TIP_TEXT_KEY
2896     */

2897    public String JavaDoc getToolTipText() {
2898        return (String JavaDoc)getClientProperty(TOOL_TIP_TEXT_KEY);
2899    }
2900
2901
2902    /**
2903     * Returns the string to be used as the tooltip for <i>event</i>.
2904     * By default this returns any string set using
2905     * <code>setToolTipText</code>. If a component provides
2906     * more extensive API to support differing tooltips at different locations,
2907     * this method should be overridden.
2908     */

2909    public String JavaDoc getToolTipText(MouseEvent event) {
2910        return getToolTipText();
2911    }
2912
2913    /**
2914     * Returns the tooltip location in this component's coordinate system.
2915     * If <code>null</code> is returned, Swing will choose a location.
2916     * The default implementation returns <code>null</code>.
2917     *
2918     * @param event the <code>MouseEvent</code> that caused the
2919     * <code>ToolTipManager</code> to show the tooltip
2920     * @return always returns <code>null</code>
2921     */

2922    public Point getToolTipLocation(MouseEvent event) {
2923        return null;
2924    }
2925
2926    /**
2927     * Returns the preferred location to display the popup menu in this
2928     * component's coordinate system. It is up to the look and feel to
2929     * honor this propery, some may choose to ignore it. If <code>null</code>
2930     * is truend the look and feel will choose a suitable location.
2931     *
2932     * @param event the <code>MouseEvent</code> that triggered the popup
2933     * to be shown, or null if popup was is not being shown as the
2934     * result of a mouse event
2935     * @return Locatino to display the JPopupMenu.
2936     * @since 1.5
2937     */

2938    public Point getPopupLocation(MouseEvent event) {
2939        return null;
2940    }
2941
2942
2943    /**
2944     * Returns the instance of <code>JToolTip</code> that should be used
2945     * to display the tooltip.
2946     * Components typically would not override this method,
2947     * but it can be used to
2948     * cause different tooltips to be displayed differently.
2949     *
2950     * @return the <code>JToolTip</code> used to display this toolTip
2951     */

2952    public JToolTip JavaDoc createToolTip() {
2953        JToolTip JavaDoc tip = new JToolTip JavaDoc();
2954        tip.setComponent(this);
2955        return tip;
2956    }
2957
2958    /**
2959     * Forwards the <code>scrollRectToVisible()</code> message to the
2960     * <code>JComponent</code>'s parent. Components that can service
2961     * the request, such as <code>JViewport</code>,
2962     * override this method and perform the scrolling.
2963     *
2964     * @param aRect the visible <code>Rectangle</code>
2965     * @see JViewport
2966     */

2967    public void scrollRectToVisible(Rectangle aRect) {
2968        Container parent;
2969        int dx = getX(), dy = getY();
2970
2971        for (parent = getParent();
2972                 !(parent == null) &&
2973                 !(parent instanceof JComponent JavaDoc) &&
2974                 !(parent instanceof CellRendererPane JavaDoc);
2975             parent = parent.getParent()) {
2976             Rectangle bounds = parent.getBounds();
2977
2978             dx += bounds.x;
2979             dy += bounds.y;
2980        }
2981
2982        if (!(parent == null) && !(parent instanceof CellRendererPane JavaDoc)) {
2983            aRect.x += dx;
2984            aRect.y += dy;
2985
2986            ((JComponent JavaDoc)parent).scrollRectToVisible(aRect);
2987            aRect.x -= dx;
2988            aRect.y -= dy;
2989        }
2990    }
2991
2992    /**
2993     * Sets the <code>autoscrolls</code> property.
2994     * If <code>true</code> mouse dragged events will be
2995     * synthetically generated when the mouse is dragged
2996     * outside of the component's bounds and mouse motion
2997     * has paused (while the button continues to be held
2998     * down). The synthetic events make it appear that the
2999     * drag gesture has resumed in the direction established when
3000     * the component's boundary was crossed. Components that
3001     * support autoscrolling must handle <code>mouseDragged</code>
3002     * events by calling <code>scrollRectToVisible</code> with a
3003     * rectangle that contains the mouse event's location. All of
3004     * the Swing components that support item selection and are
3005     * typically displayed in a <code>JScrollPane</code>
3006     * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
3007     * <code>JTextArea</code>, and <code>JEditorPane</code>)
3008     * already handle mouse dragged events in this way. To enable
3009     * autoscrolling in any other component, add a mouse motion
3010     * listener that calls <code>scrollRectToVisible</code>.
3011     * For example, given a <code>JPanel</code>, <code>myPanel</code>:
3012     * <pre>
3013     * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
3014     * public void mouseDragged(MouseEvent e) {
3015     * Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
3016     * ((JPanel)e.getSource()).scrollRectToVisible(r);
3017     * }
3018     * };
3019     * myPanel.addMouseMotionListener(doScrollRectToVisible);
3020     * </pre>
3021     * The default value of the <code>autoScrolls</code>
3022     * property is <code>false</code>.
3023     *
3024     * @param autoscrolls if true, synthetic mouse dragged events
3025     * are generated when the mouse is dragged outside of a component's
3026     * bounds and the mouse button continues to be held down; otherwise
3027     * false
3028     * @see #getAutoscrolls
3029     * @see JViewport
3030     * @see JScrollPane
3031     *
3032     * @beaninfo
3033     * expert: true
3034     * description: Determines if this component automatically scrolls its contents when dragged.
3035     */

3036    public void setAutoscrolls(boolean autoscrolls) {
3037        setFlag(AUTOSCROLLS_SET, true);
3038        if (this.autoscrolls != autoscrolls) {
3039            this.autoscrolls = autoscrolls;
3040            if (autoscrolls) {
3041                enableEvents(AWTEvent.MOUSE_EVENT_MASK);
3042                enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
3043            }
3044            else {
3045                Autoscroller.stop(this);
3046            }
3047        }
3048    }
3049
3050    /**
3051     * Gets the <code>autoscrolls</code> property.
3052     *
3053     * @return the value of the <code>autoscrolls</code> property
3054     * @see JViewport
3055     * @see #setAutoscrolls
3056     */

3057    public boolean getAutoscrolls() {
3058        return autoscrolls;
3059    }
3060
3061    /**
3062     * Sets the <code>transferHandler</code> property,
3063     * which is <code>null</code> if the component does
3064     * not support data transfer operations.
3065     * <p>
3066     * If <code>newHandler</code> is not <code>null</code>,
3067     * and the system property
3068     * <code>suppressSwingDropSupport</code> is not true, this will
3069     * install a <code>DropTarget</code> on the <code>JComponent</code>.
3070     * The default for the system property is false, so that a
3071     * <code>DropTarget</code> will be added.
3072     * <p>
3073     * Please see
3074     * <a HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
3075     * How to Use Drag and Drop and Data Transfer</a>,
3076     * a section in <em>The Java Tutorial</em>, for more information.
3077     *
3078     * @param newHandler mechanism for transfer of data to
3079     * and from the component
3080     *
3081     * @see TransferHandler
3082     * @see #getTransferHandler
3083     * @since 1.4
3084     * @beaninfo
3085     * bound: true
3086     * hidden: true
3087     * description: Mechanism for transfer of data to and from the component
3088     */

3089    public void setTransferHandler(TransferHandler JavaDoc newHandler) {
3090    TransferHandler JavaDoc oldHandler = (TransferHandler JavaDoc)getClientProperty(
3091                                      TRANSFER_HANDLER_KEY);
3092        putClientProperty(TRANSFER_HANDLER_KEY, newHandler);
3093
3094    if (! getSuppressDropTarget()) {
3095        DropTarget JavaDoc dropHandler = getDropTarget();
3096        if ((dropHandler == null) || (dropHandler instanceof UIResource)) {
3097        if (newHandler == null) {
3098            setDropTarget(null);
3099        } else if (!GraphicsEnvironment.isHeadless()) {
3100            setDropTarget(new TransferHandler.SwingDropTarget JavaDoc(this));
3101        }
3102        }
3103    }
3104        firePropertyChange("transferHandler", oldHandler, newHandler);
3105    }
3106
3107    /**
3108     * Gets the <code>transferHandler</code> property.
3109     *
3110     * @return the value of the <code>transferHandler</code> property
3111     *
3112     * @see TransferHandler
3113     * @see #setTransferHandler
3114     * @since 1.4
3115     */

3116    public TransferHandler JavaDoc getTransferHandler() {
3117    return (TransferHandler JavaDoc)getClientProperty(TRANSFER_HANDLER_KEY);
3118    }
3119
3120    /**
3121     * Processes mouse events occurring on this component by
3122     * dispatching them to any registered
3123     * <code>MouseListener</code> objects, refer to
3124     * {@link java.awt.Component#processMouseEvent(MouseEvent)}
3125     * for a complete description of this method.
3126     *
3127     * @param e the mouse event
3128     * @see java.awt.Component#processMouseEvent
3129     * @since 1.5
3130     */

3131    protected void processMouseEvent(MouseEvent e) {
3132        if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
3133            Autoscroller.stop(this);
3134        }
3135        super.processMouseEvent(e);
3136    }
3137    
3138    /**
3139     * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
3140     *
3141     * @param e the <code>MouseEvent</code>
3142     * @see MouseEvent
3143     */

3144    protected void processMouseMotionEvent(MouseEvent e) {
3145        boolean dispatch = true;
3146        if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
3147            // We don't want to do the drags when the mouse moves if we're
3148
// autoscrolling. It makes it feel spastic.
3149
dispatch = !Autoscroller.isRunning(this);
3150            Autoscroller.processMouseDragged(e);
3151        }
3152        if (dispatch) {
3153            super.processMouseMotionEvent(e);
3154        }
3155    }
3156
3157    // Inner classes can't get at this method from a super class
3158
void superProcessMouseMotionEvent(MouseEvent e) {
3159        super.processMouseMotionEvent(e);
3160    }
3161
3162    /**
3163     * This is invoked by the <code>RepaintManager</code> if
3164     * <code>createImage</code> is called on the component.
3165     *
3166     * @param newValue true if the double buffer image was created from this component
3167     */

3168    void setCreatedDoubleBuffer(boolean newValue) {
3169    setFlag(CREATED_DOUBLE_BUFFER, newValue);
3170    }
3171
3172    /**
3173     * Returns true if the <code>RepaintManager</code>
3174     * created the double buffer image from the component.
3175     *
3176     * @return true if this component had a double buffer image, false otherwise
3177     */

3178    boolean getCreatedDoubleBuffer() {
3179    return getFlag(CREATED_DOUBLE_BUFFER);
3180    }
3181
3182    /**
3183     * <code>ActionStandin</code> is used as a standin for
3184     * <code>ActionListeners</code> that are
3185     * added via <code>registerKeyboardAction</code>.
3186     */

3187    final class ActionStandin implements Action JavaDoc {
3188    private final ActionListener actionListener;
3189    private final String JavaDoc command;
3190    // This will be non-null if actionListener is an Action.
3191
private final Action JavaDoc action;
3192
3193    ActionStandin(ActionListener actionListener, String JavaDoc command) {
3194        this.actionListener = actionListener;
3195        if (actionListener instanceof Action JavaDoc) {
3196        this.action = (Action JavaDoc)actionListener;
3197        }
3198        else {
3199        this.action = null;
3200        }
3201        this.command = command;
3202    }
3203
3204    public Object JavaDoc getValue(String JavaDoc key) {
3205        if (key != null) {
3206        if (key.equals(Action.ACTION_COMMAND_KEY)) {
3207            return command;
3208        }
3209        if (action != null) {
3210            return action.getValue(key);
3211        }
3212        if (key.equals(NAME)) {
3213            return "ActionStandin";
3214        }
3215        }
3216        return null;
3217    }
3218
3219    public boolean isEnabled() {
3220            if (actionListener == null) {
3221                // This keeps the old semantics where
3222
// registerKeyboardAction(null) would essentialy remove
3223
// the binding. We don't remove the binding from the
3224
// InputMap as that would still allow parent InputMaps
3225
// bindings to be accessed.
3226
return false;
3227            }
3228        if (action == null) {
3229        return true;
3230        }
3231        return action.isEnabled();
3232    }
3233
3234    public void actionPerformed(ActionEvent ae) {
3235            if (actionListener != null) {
3236                actionListener.actionPerformed(ae);
3237            }
3238    }
3239
3240    // We don't allow any values to be added.
3241
public void putValue(String JavaDoc key, Object JavaDoc value) {}
3242
3243    // Does nothing, our enabledness is determiend from our asociated
3244
// action.
3245
public void setEnabled(boolean b) { }
3246
3247    public void addPropertyChangeListener
3248                    (PropertyChangeListener listener) {}
3249    public void removePropertyChangeListener
3250                      (PropertyChangeListener listener) {}
3251    }
3252
3253
3254    // This class is used by the KeyboardState class to provide a single
3255
// instance that can be stored in the AppContext.
3256
static final class IntVector {
3257        int array[] = null;
3258        int count = 0;
3259        int capacity = 0;
3260
3261        int size() {
3262            return count;
3263        }
3264
3265        int elementAt(int index) {
3266            return array[index];
3267        }
3268
3269        void addElement(int value) {
3270            if (count == capacity) {
3271                capacity = (capacity + 2) * 2;
3272                int[] newarray = new int[capacity];
3273                if (count > 0) {
3274                    System.arraycopy(array, 0, newarray, 0, count);
3275                }
3276                array = newarray;
3277            }
3278            array[count++] = value;
3279        }
3280
3281        void setElementAt(int value, int index) {
3282            array[index] = value;
3283        }
3284    }
3285
3286    static class KeyboardState implements Serializable JavaDoc {
3287        private static final Object JavaDoc keyCodesKey =
3288            JComponent.KeyboardState JavaDoc.class;
3289
3290        // Get the array of key codes from the AppContext.
3291
static IntVector getKeyCodeArray() {
3292            IntVector iv =
3293                (IntVector)SwingUtilities.appContextGet(keyCodesKey);
3294            if (iv == null) {
3295                iv = new IntVector();
3296                SwingUtilities.appContextPut(keyCodesKey, iv);
3297            }
3298            return iv;
3299        }
3300
3301        static void registerKeyPressed(int keyCode) {
3302            IntVector kca = getKeyCodeArray();
3303            int count = kca.size();
3304            int i;
3305            for(i=0;i<count;i++) {
3306                if(kca.elementAt(i) == -1){
3307                    kca.setElementAt(keyCode, i);
3308                    return;
3309                }
3310            }
3311            kca.addElement(keyCode);
3312        }
3313
3314        static void registerKeyReleased(int keyCode) {
3315            IntVector kca = getKeyCodeArray();
3316            int count = kca.size();
3317            int i;
3318            for(i=0;i<count;i++) {
3319                if(kca.elementAt(i) == keyCode) {
3320                    kca.setElementAt(-1, i);
3321                    return;
3322                }
3323            }
3324        }
3325
3326        static boolean keyIsPressed(int keyCode) {
3327            IntVector kca = getKeyCodeArray();
3328            int count = kca.size();
3329            int i;
3330            for(i=0;i<count;i++) {
3331                if(kca.elementAt(i) == keyCode) {
3332                    return true;
3333                }
3334            }
3335            return false;
3336        }
3337
3338        /**
3339         * Updates internal state of the KeyboardState and returns true
3340         * if the event should be processed further.
3341         */

3342        static boolean shouldProcess(KeyEvent e) {
3343            switch (e.getID()) {
3344            case KeyEvent.KEY_PRESSED:
3345                if (!keyIsPressed(e.getKeyCode())) {
3346                    registerKeyPressed(e.getKeyCode());
3347                }
3348                return true;
3349            case KeyEvent.KEY_RELEASED:
3350        // We are forced to process VK_PRINTSCREEN separately because
3351
// the Windows doesn't generate the key pressed event for
3352
// printscreen and it block the processing of key release
3353
// event for printscreen.
3354
if (keyIsPressed(e.getKeyCode()) || e.getKeyCode()==KeyEvent.VK_PRINTSCREEN) {
3355                    registerKeyReleased(e.getKeyCode());
3356                    return true;
3357                }
3358                return false;
3359            case KeyEvent.KEY_TYPED:
3360                return true;
3361            default:
3362                // Not a known KeyEvent type, bail.
3363
return false;
3364            }
3365      }
3366    }
3367
3368
3369    /*
3370     * --- Accessibility Support ---
3371     */

3372
3373    /**
3374     * @deprecated As of JDK version 1.1,
3375     * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3376     */

3377    @Deprecated JavaDoc
3378    public void enable() {
3379        if (isEnabled() != true) {
3380            super.enable();
3381            if (accessibleContext != null) {
3382                accessibleContext.firePropertyChange(
3383                    AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3384                    null, AccessibleState.ENABLED);
3385            }
3386        }
3387    }
3388
3389    /**
3390     * @deprecated As of JDK version 1.1,
3391     * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3392     */

3393    @Deprecated JavaDoc
3394    public void disable() {
3395        if (isEnabled() != false) {
3396            super.disable();
3397            if (accessibleContext != null) {
3398                accessibleContext.firePropertyChange(
3399                    AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3400                    AccessibleState.ENABLED, null);
3401            }
3402        }
3403    }
3404
3405    /**
3406     * The <code>AccessibleContext</code> associated with this
3407     * <code>JComponent</code>.
3408     */

3409    protected AccessibleContext accessibleContext = null;
3410
3411    /**
3412     * Returns the <code>AccessibleContext</code> associated with this
3413     * <code>JComponent</code>. The method implemented by this base
3414     * class returns null. Classes that extend <code>JComponent</code>
3415     * should implement this method to return the
3416     * <code>AccessibleContext</code> associated with the subclass.
3417     *
3418     * @return the <code>AccessibleContext</code> of this
3419     * <code>JComponent</code>
3420     */

3421    public AccessibleContext getAccessibleContext() {
3422        return accessibleContext;
3423    }
3424
3425    /**
3426     * Inner class of JComponent used to provide default support for
3427     * accessibility. This class is not meant to be used directly by
3428     * application developers, but is instead meant only to be
3429     * subclassed by component developers.
3430     * <p>
3431     * <strong>Warning:</strong>
3432     * Serialized objects of this class will not be compatible with
3433     * future Swing releases. The current serialization support is
3434     * appropriate for short term storage or RMI between applications running
3435     * the same version of Swing. As of 1.4, support for long term storage
3436     * of all JavaBeans<sup><font size="-2">TM</font></sup>
3437     * has been added to the <code>java.beans</code> package.
3438     * Please see {@link java.beans.XMLEncoder}.
3439     */

3440    public abstract class AccessibleJComponent extends AccessibleAWTContainer
3441       implements AccessibleExtendedComponent
3442    {
3443    /**
3444     * Though the class is abstract, this should be called by
3445     * all sub-classes.
3446     */

3447    protected AccessibleJComponent() {
3448            super();
3449        }
3450
3451    protected ContainerListener accessibleContainerHandler = null;
3452        protected FocusListener accessibleFocusHandler = null;
3453
3454    /**
3455     * Fire PropertyChange listener, if one is registered,
3456     * when children added/removed.
3457     */

3458    protected class AccessibleContainerHandler
3459        implements ContainerListener {
3460        public void componentAdded(ContainerEvent e) {
3461        Component c = e.getChild();
3462        if (c != null && c instanceof Accessible) {
3463            AccessibleJComponent.this.firePropertyChange(
3464            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3465            null, ((Accessible) c).getAccessibleContext());
3466        }
3467        }
3468        public void componentRemoved(ContainerEvent e) {
3469        Component c = e.getChild();
3470        if (c != null && c instanceof Accessible) {
3471            AccessibleJComponent.this.firePropertyChange(
3472            AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3473            ((Accessible) c).getAccessibleContext(), null);
3474        }
3475        }
3476    }
3477
3478    /**
3479     * Fire PropertyChange listener, if one is registered,
3480     * when focus events happen
3481     */

3482    protected class AccessibleFocusHandler implements FocusListener {
3483       public void focusGained(FocusEvent event) {
3484           if (accessibleContext != null) {
3485            accessibleContext.firePropertyChange(
3486            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3487            null, AccessibleState.FOCUSED);
3488        }
3489        }
3490        public void focusLost(FocusEvent event) {
3491        if (accessibleContext != null) {
3492            accessibleContext.firePropertyChange(
3493            AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3494            AccessibleState.FOCUSED, null);
3495        }
3496        }
3497    } // inner class AccessibleFocusHandler
3498

3499
3500    /**
3501     * Adds a PropertyChangeListener to the listener list.
3502     *
3503     * @param listener the PropertyChangeListener to be added
3504     */

3505    public void addPropertyChangeListener(PropertyChangeListener listener) {
3506        if (accessibleFocusHandler == null) {
3507        accessibleFocusHandler = new AccessibleFocusHandler();
3508        JComponent.this.addFocusListener(accessibleFocusHandler);
3509        }
3510        if (accessibleContainerHandler == null) {
3511        accessibleContainerHandler = new AccessibleContainerHandler();
3512        JComponent.this.addContainerListener(accessibleContainerHandler);
3513        }
3514        super.addPropertyChangeListener(listener);
3515    }
3516
3517    /**
3518     * Removes a PropertyChangeListener from the listener list.
3519     * This removes a PropertyChangeListener that was registered
3520     * for all properties.
3521     *
3522     * @param listener the PropertyChangeListener to be removed
3523     */

3524    public void removePropertyChangeListener(PropertyChangeListener listener) {
3525        if (accessibleFocusHandler != null) {
3526        JComponent.this.removeFocusListener(accessibleFocusHandler);
3527        accessibleFocusHandler = null;
3528        }
3529        super.removePropertyChangeListener(listener);
3530    }
3531
3532
3533
3534    /**
3535         * Recursively search through the border hierarchy (if it exists)
3536     * for a TitledBorder with a non-null title. This does a depth
3537         * first search on first the inside borders then the outside borders.
3538         * The assumption is that titles make really pretty inside borders
3539         * but not very pretty outside borders in compound border situations.
3540     * It's rather arbitrary, but hopefully decent UI programmers will
3541         * not create multiple titled borders for the same component.
3542     */

3543        protected String JavaDoc getBorderTitle(Border b) {
3544        String JavaDoc s;
3545        if (b instanceof TitledBorder) {
3546            return ((TitledBorder) b).getTitle();
3547        } else if (b instanceof CompoundBorder) {
3548            s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
3549        if (s == null) {
3550            s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
3551        }
3552        return s;
3553        } else {
3554            return null;
3555        }
3556    }
3557            
3558        // AccessibleContext methods
3559
//
3560
/**
3561         * Gets the accessible name of this object. This should almost never
3562         * return java.awt.Component.getName(), as that generally isn't
3563         * a localized name, and doesn't have meaning for the user. If the
3564         * object is fundamentally a text object (such as a menu item), the
3565         * accessible name should be the text of the object (for example,
3566         * "save").
3567         * If the object has a tooltip, the tooltip text may also be an
3568         * appropriate String to return.
3569         *
3570         * @return the localized name of the object -- can be null if this
3571         * object does not have a name
3572         * @see AccessibleContext#setAccessibleName
3573         */

3574        public String JavaDoc getAccessibleName() {
3575        String JavaDoc name = accessibleName;
3576
3577        // fallback to the titled border if it exists
3578
//
3579
if (name == null) {
3580        name = getBorderTitle(getBorder());
3581            }
3582
3583        // fallback to the label labeling us if it exists
3584
//
3585
if (name == null) {
3586        Object JavaDoc o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3587        if (o instanceof Accessible) {
3588            AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3589            if (ac != null) {
3590            name = ac.getAccessibleName();
3591            }
3592        }
3593        }
3594        return name;
3595        }
3596
3597        /**
3598         * Gets the accessible description of this object. This should be
3599         * a concise, localized description of what this object is - what
3600         * is its meaning to the user. If the object has a tooltip, the
3601         * tooltip text may be an appropriate string to return, assuming
3602         * it contains a concise description of the object (instead of just
3603         * the name of the object - for example a "Save" icon on a toolbar that
3604         * had "save" as the tooltip text shouldn't return the tooltip
3605         * text as the description, but something like "Saves the current
3606         * text document" instead).
3607         *
3608         * @return the localized description of the object -- can be null if
3609         * this object does not have a description
3610         * @see AccessibleContext#setAccessibleDescription
3611         */

3612        public String JavaDoc getAccessibleDescription() {
3613        String JavaDoc description = accessibleDescription;
3614
3615        // fallback to the tool tip text if it exists
3616
//
3617
if (description == null) {
3618                try {
3619                    description = getToolTipText();
3620                } catch (Exception JavaDoc e) {
3621                    // Just in case the subclass overrode the
3622
// getToolTipText method and actually
3623
// requires a MouseEvent.
3624
// [[[FIXME: WDW - we probably should require this
3625
// method to take a MouseEvent and just pass it on
3626
// to getToolTipText. The swing-feedback traffic
3627
// leads me to believe getToolTipText might change,
3628
// though, so I was hesitant to make this change at
3629
// this time.]]]
3630
}
3631            }
3632
3633        // fallback to the label labeling us if it exists
3634
//
3635
if (description == null) {
3636        Object JavaDoc o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3637        if (o instanceof Accessible) {
3638            AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3639            if (ac != null) {
3640            description = ac.getAccessibleDescription();
3641            }
3642        }
3643        }
3644
3645        return description;
3646        }
3647
3648        /**
3649         * Gets the role of this object.
3650         *
3651         * @return an instance of AccessibleRole describing the role of the
3652         * object
3653         * @see AccessibleRole
3654         */

3655        public AccessibleRole getAccessibleRole() {
3656            return AccessibleRole.SWING_COMPONENT;
3657        }
3658
3659        /**
3660         * Gets the state of this object.
3661         *
3662         * @return an instance of AccessibleStateSet containing the current
3663         * state set of the object
3664         * @see AccessibleState
3665         */

3666        public AccessibleStateSet getAccessibleStateSet() {
3667        AccessibleStateSet states = super.getAccessibleStateSet();
3668        if (JComponent.this.isOpaque()) {
3669        states.add(AccessibleState.OPAQUE);
3670        }
3671        return states;
3672        }
3673
3674        /**
3675         * Returns the number of accessible children in the object. If all
3676         * of the children of this object implement Accessible, than this
3677         * method should return the number of children of this object.
3678         *
3679         * @return the number of accessible children in the object.
3680         */

3681        public int getAccessibleChildrenCount() {
3682            return super.getAccessibleChildrenCount();
3683        }
3684
3685        /**
3686         * Returns the nth Accessible child of the object.
3687         *
3688         * @param i zero-based index of child
3689         * @return the nth Accessible child of the object
3690         */

3691        public Accessible getAccessibleChild(int i) {
3692            return super.getAccessibleChild(i);
3693        }
3694
3695    // ----- AccessibleExtendedComponent
3696

3697    /**
3698     * Returns the AccessibleExtendedComponent
3699     *
3700     * @return the AccessibleExtendedComponent
3701     */

3702    AccessibleExtendedComponent getAccessibleExtendedComponent() {
3703        return this;
3704    }
3705
3706    /**
3707     * Returns the tool tip text
3708     *
3709     * @return the tool tip text, if supported, of the object;
3710     * otherwise, null
3711     */

3712    public String JavaDoc getToolTipText() {
3713        return null;
3714    }
3715    
3716    /**
3717     * Returns the titled border text
3718     *
3719     * @return the titled border text, if supported, of the object;
3720     * otherwise, null
3721     */

3722    public String JavaDoc getTitledBorderText() {
3723        Border border = JComponent.this.getBorder();
3724        if (border instanceof TitledBorder) {
3725        return ((TitledBorder)border).getTitle();
3726        } else {
3727        return null;
3728        }
3729    }
3730        
3731    /**
3732     * Returns key bindings associated with this object
3733     *
3734     * @return the key bindings, if supported, of the object;
3735     * otherwise, null
3736     * @see AccessibleKeyBinding
3737     */

3738    public AccessibleKeyBinding getAccessibleKeyBinding() {
3739        return null;
3740    }
3741    } // inner class AccessibleJComponent
3742

3743
3744    
3745    /**
3746     * Returns an <code>ArrayTable</code> used for
3747     * key/value "client properties" for this component. If the
3748     * <code>clientProperties</code> table doesn't exist, an empty one
3749     * will be created.
3750     *
3751     * @return an ArrayTable
3752     * @see #putClientProperty
3753     * @see #getClientProperty
3754     */

3755    private ArrayTable JavaDoc getClientProperties() {
3756        if (clientProperties == null) {
3757            clientProperties = new ArrayTable JavaDoc();
3758        }
3759        return clientProperties;
3760    }
3761
3762
3763    /**
3764     * Returns the value of the property with the specified key. Only
3765     * properties added with <code>putClientProperty</code> will return
3766     * a non-<code>null</code> value.
3767     *
3768     * @param key the being queried
3769     * @return the value of this property or <code>null</code>
3770     * @see #putClientProperty
3771     */

3772    public final Object JavaDoc getClientProperty(Object JavaDoc key) {
3773        if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
3774            return Boolean.valueOf(aaText);
3775        }
3776         if(clientProperties == null) {
3777        return null;
3778    } else {
3779            synchronized(clientProperties) {
3780                return clientProperties.get(key);
3781            }
3782    }
3783    }
3784    
3785    /**
3786     * Adds an arbitrary key/value "client property" to this component.
3787     * <p>
3788     * The <code>get/putClientProperty</code> methods provide access to
3789     * a small per-instance hashtable. Callers can use get/putClientProperty
3790     * to annotate components that were created by another module.
3791     * For example, a
3792     * layout manager might store per child constraints this way. For example:
3793     * <pre>
3794     * componentA.putClientProperty("to the left of", componentB);
3795     * </pre>
3796     * If value is <code>null</code> this method will remove the property.
3797     * Changes to client properties are reported with
3798     * <code>PropertyChange</code> events.
3799     * The name of the property (for the sake of PropertyChange
3800     * events) is <code>key.toString()</code>.
3801     * <p>
3802     * The <code>clientProperty</code> dictionary is not intended to
3803     * support large
3804     * scale extensions to JComponent nor should be it considered an
3805     * alternative to subclassing when designing a new component.
3806     *
3807     * @param key the new client property key
3808     * @param value the new client property value; if <code>null</code>
3809     * this method will remove the property
3810     * @see #getClientProperty
3811     * @see #addPropertyChangeListener
3812     */

3813    public final void putClientProperty(Object JavaDoc key, Object JavaDoc value) {
3814        if (value == null && clientProperties == null) {
3815            // Both the value and ArrayTable are null, implying we don't
3816
// have to do anything.
3817
return;
3818        }
3819        if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
3820            if (value instanceof Boolean JavaDoc) {
3821                aaText = ((Boolean JavaDoc)value).booleanValue();
3822            }
3823            return;
3824        }
3825        ArrayTable JavaDoc clientProperties = getClientProperties();
3826        Object JavaDoc oldValue;
3827        synchronized(clientProperties) {
3828            oldValue = clientProperties.get(key);
3829            if (value != null) {
3830                clientProperties.put(key, value);
3831            } else if (oldValue != null) {
3832                clientProperties.remove(key);
3833            } else {
3834                // old == new == null
3835
return;
3836            }
3837        }
3838        firePropertyChange(key.toString(), oldValue, value);
3839    }
3840
3841
3842    /*
3843     * Sets the property with the specified name to the specified value if
3844     * the property has not already been set by the client program.
3845     * This method is used primarily to set UI defaults for properties
3846     * with primitive types, where the values cannot be marked with
3847     * UIResource.
3848     * @see LookAndFeel#installProperty
3849     * @param propertyName String containing the name of the property
3850     * @param value Object containing the property value
3851     */

3852    void setUIProperty(String JavaDoc propertyName, Object JavaDoc value) {
3853        if (propertyName == "opaque") {
3854            if (!getFlag(OPAQUE_SET)) {
3855                setOpaque(((Boolean JavaDoc)value).booleanValue());
3856                setFlag(OPAQUE_SET, false);
3857            }
3858        } else if (propertyName == "autoscrolls") {
3859            if (!getFlag(AUTOSCROLLS_SET)) {
3860                setAutoscrolls(((Boolean JavaDoc)value).booleanValue());
3861                setFlag(AUTOSCROLLS_SET, false);
3862            }
3863        } else if (propertyName == "focusTraversalKeysForward") {
3864            if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
3865                super.setFocusTraversalKeys(KeyboardFocusManager.
3866                                            FORWARD_TRAVERSAL_KEYS,
3867                                            (Set JavaDoc)value);
3868            }
3869        } else if (propertyName == "focusTraversalKeysBackward") {
3870            if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
3871                super.setFocusTraversalKeys(KeyboardFocusManager.
3872                                            BACKWARD_TRAVERSAL_KEYS,
3873                                            (Set JavaDoc)value);
3874            }
3875        } else {
3876            throw new IllegalArgumentException JavaDoc("property \""+
3877                                               propertyName+ "\" cannot be set using this method");
3878        }
3879    }
3880
3881
3882    /**
3883     * Sets the focus traversal keys for a given traversal operation for this
3884     * Component.
3885     * Refer to
3886     * {@link java.awt.Component#setFocusTraversalKeys}
3887     * for a complete description of this method.
3888     *
3889     * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3890     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
3891     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
3892     * @param keystrokes the Set of AWTKeyStroke for the specified operation
3893     * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
3894     * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
3895     * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
3896     * @throws IllegalArgumentException if id is not one of
3897     * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
3898     * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
3899     * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
3900     * contains null, or if any Object in keystrokes is not an
3901     * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
3902     * or if any keystroke already maps to another focus traversal
3903     * operation for this Component
3904     * @since 1.5
3905     * @beaninfo
3906     * bound: true
3907     */

3908    public void
3909    setFocusTraversalKeys(int id, Set JavaDoc<? extends AWTKeyStroke> keystrokes)
3910    {
3911        if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
3912            setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET,true);
3913        } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
3914            setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET,true);
3915        }
3916        super.setFocusTraversalKeys(id,keystrokes);
3917    }
3918
3919    /* --- Transitional java.awt.Component Support ---
3920     * The methods and fields in this section will migrate to
3921     * java.awt.Component in the next JDK release.
3922     */

3923
3924    /**
3925     * Returns true if this component is lightweight, that is, if it doesn't
3926     * have a native window system peer.
3927     *
3928     * @return true if this component is lightweight
3929     */

3930    public static boolean isLightweightComponent(Component c) {
3931        return c.getPeer() instanceof LightweightPeer;
3932    }
3933
3934
3935    /**
3936     * @deprecated As of JDK 5,
3937     * replaced by <code>Component.setBounds(int, int, int, int)</code>.
3938     * <p>
3939     * Moves and resizes this component.
3940     *
3941     * @param x the new horizontal location
3942     * @param y the new vertical location
3943     * @param w the new width
3944     * @param h the new height
3945     * @see java.awt.Component#setBounds
3946     */

3947    @Deprecated JavaDoc
3948    public void reshape(int x, int y, int w, int h) {
3949        super.reshape(x, y, w, h);
3950    }
3951
3952
3953    /**
3954     * Stores the bounds of this component into "return value"
3955     * <code>rv</code> and returns <code>rv</code>.
3956     * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
3957     * is allocated. This version of <code>getBounds</code> is useful
3958     * if the caller wants to avoid allocating a new <code>Rectangle</code>
3959     * object on the heap.
3960     *
3961     * @param rv the return value, modified to the component's bounds
3962     * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
3963     * return a newly created <code>Rectangle</code> with this
3964     * component's bounds
3965     */

3966    public Rectangle getBounds(Rectangle rv) {
3967        if (rv == null) {
3968            return new Rectangle(getX(), getY(), getWidth(), getHeight());
3969        }
3970        else {
3971            rv.setBounds(getX(), getY(), getWidth(), getHeight());
3972            return rv;
3973        }
3974    }
3975
3976
3977    /**
3978     * Stores the width/height of this component into "return value"
3979     * <code>rv</code> and returns <code>rv</code>.
3980     * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
3981     * object is allocated. This version of <code>getSize</code>
3982     * is useful if the caller wants to avoid allocating a new
3983     * <code>Dimension</code> object on the heap.
3984     *
3985     * @param rv the return value, modified to the component's size
3986     * @return <code>rv</code>
3987     */

3988    public Dimension getSize(Dimension rv) {
3989        if (rv == null) {
3990            return new Dimension(getWidth(), getHeight());
3991        }
3992        else {
3993            rv.setSize(getWidth(), getHeight());
3994            return rv;
3995        }
3996    }
3997
3998
3999    /**
4000     * Stores the x,y origin of this component into "return value"
4001     * <code>rv</code> and returns <code>rv</code>.
4002     * If <code>rv</code> is <code>null</code> a new <code>Point</code>
4003     * is allocated. This version of <code>getLocation</code> is useful
4004     * if the caller wants to avoid allocating a new <code>Point</code>
4005     * object on the heap.
4006     *
4007     * @param rv the return value, modified to the component's location
4008     * @return <code>rv</code>
4009     */

4010    public Point getLocation(Point rv) {
4011        if (rv == null) {
4012            return new Point(getX(), getY());
4013        }
4014        else {
4015            rv.setLocation(getX(), getY());
4016            return rv;
4017        }
4018    }
4019
4020
4021    /**
4022     * Returns the current x coordinate of the component's origin.
4023     * This method is preferable to writing
4024     * <code>component.getBounds().x</code>, or
4025     * <code>component.getLocation().x</code> because it doesn't cause any
4026     * heap allocations.
4027     *
4028     * @return the current x coordinate of the component's origin
4029     */

4030    public int getX() { return super.getX(); }
4031
4032
4033    /**
4034     * Returns the current y coordinate of the component's origin.
4035     * This method is preferable to writing
4036     * <code>component.getBounds().y</code>, or
4037     * <code>component.getLocation().y</code> because it doesn't cause any
4038     * heap allocations.
4039     *
4040     * @return the current y coordinate of the component's origin
4041     */

4042    public int getY() { return super.getY(); }
4043
4044
4045    /**
4046     * Returns the current width of this component.
4047     * This method is preferable to writing
4048     * <code>component.getBounds().width</code>, or
4049     * <code>component.getSize().width</code> because it doesn't cause any
4050     * heap allocations.
4051     *
4052     * @return the current width of this component
4053     */

4054    public int getWidth() { return super.getWidth(); }
4055
4056
4057    /**
4058     * Returns the current height of this component.
4059     * This method is preferable to writing
4060     * <code>component.getBounds().height</code>, or
4061     * <code>component.getSize().height</code> because it doesn't cause any
4062     * heap allocations.
4063     *
4064     * @return the current height of this component
4065     */

4066    public int getHeight() { return super.getHeight(); }
4067
4068    /**
4069     * Returns true if this component is completely opaque.
4070     * <p>
4071     * An opaque component paints every pixel within its
4072     * rectangular bounds. A non-opaque component paints only a subset of
4073     * its pixels or none at all, allowing the pixels underneath it to
4074     * "show through". Therefore, a component that does not fully paint
4075     * its pixels provides a degree of transparency.
4076     * <p>
4077     * Subclasses that guarantee to always completely paint their contents
4078     * should override this method and return true.
4079     *
4080     * @return true if this component is completely opaque
4081     * @see #setOpaque
4082     */

4083    public boolean isOpaque() {
4084        return getFlag(IS_OPAQUE);
4085    }
4086
4087    /**
4088     * If true the component paints every pixel within its bounds.
4089     * Otherwise, the component may not paint some or all of its
4090     * pixels, allowing the underlying pixels to show through.
4091     * <p>
4092     * The default value of this property is false for <code>JComponent</code>.
4093     * However, the default value for this property on most standard
4094     * <code>JComponent</code> subclasses (such as <code>JButton</code> and
4095     * <code>JTree</code>) is look-and-feel dependent.
4096     *
4097     * @param isOpaque true if this component should be opaque
4098     * @see #isOpaque
4099     * @beaninfo
4100     * bound: true
4101     * expert: true
4102     * description: The component's opacity
4103     */

4104    public void setOpaque(boolean isOpaque) {
4105        boolean oldValue = getFlag(IS_OPAQUE);
4106        setFlag(IS_OPAQUE, isOpaque);
4107        setFlag(OPAQUE_SET, true);
4108        firePropertyChange("opaque", oldValue, isOpaque);
4109    }
4110
4111
4112    /**
4113     * If the specified rectangle is completely obscured by any of this
4114     * component's opaque children then returns true. Only direct children
4115     * are considered, more distant descendants are ignored. A
4116     * <code>JComponent</code> is opaque if
4117     * <code>JComponent.isOpaque()</code> returns true, other lightweight
4118     * components are always considered transparent, and heavyweight components
4119     * are always considered opaque.
4120     *
4121     * @param x x value of specified rectangle
4122     * @param y y value of specified rectangle
4123     * @param width width of specified rectangle
4124     * @param height height of specified rectangle
4125     * @return true if the specified rectangle is obscured by an opaque child
4126     */

4127    boolean rectangleIsObscured(int x,int y,int width,int height)
4128    {
4129        int numChildren = getComponentCount();
4130
4131        for(int i = 0; i < numChildren; i++) {
4132            Component child = getComponent(i);
4133            int cx, cy, cw, ch;
4134
4135            cx = child.getX();
4136            cy = child.getY();
4137            cw = child.getWidth();
4138            ch = child.getHeight();
4139
4140            if (x >= cx && (x + width) <= (cx + cw) &&
4141                y >= cy && (y + height) <= (cy + ch) && child.isVisible()) {
4142
4143                if(child instanceof JComponent JavaDoc) {
4144// System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child);
4145
// System.out.print("B) ");
4146
// Thread.dumpStack();
4147
return ((JComponent JavaDoc)child).isOpaque();
4148                } else {
4149                    /** Sometimes a heavy weight can have a bound larger than its peer size
4150                     * so we should always draw under heavy weights
4151                     */

4152                    return false;
4153                }
4154            }
4155        }
4156
4157        return false;
4158    }
4159
4160
4161    /**
4162     * Returns the <code>Component</code>'s "visible rect rectangle" - the
4163     * intersection of the visible rectangles for the component <code>c</code>
4164     * and all of its ancestors. The return value is stored in
4165     * <code>visibleRect</code>.
4166     *
4167     * @param c the component
4168     * @param visibleRect a <code>Rectangle</code> computed as the
4169     * intersection of all visible rectangles for the component
4170     * <code>c</code> and all of its ancestors -- this is the
4171     * return value for this method
4172     * @see #getVisibleRect
4173     */

4174    static final void computeVisibleRect(Component c, Rectangle visibleRect) {
4175        Container p = c.getParent();
4176        Rectangle bounds = c.getBounds();
4177
4178        if (p == null || p instanceof Window || p instanceof Applet JavaDoc) {
4179            visibleRect.setBounds(0, 0, bounds.width, bounds.height);
4180        } else {
4181            computeVisibleRect(p, visibleRect);
4182            visibleRect.x -= bounds.x;
4183            visibleRect.y -= bounds.y;
4184            SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
4185        }
4186    }
4187
4188
4189    /**
4190     * Returns the <code>Component</code>'s "visible rect rectangle" - the
4191     * intersection of the visible rectangles for this component
4192     * and all of its ancestors. The return value is stored in
4193     * <code>visibleRect</code>.
4194     *
4195     * @param visibleRect a <code>Rectangle</code> computed as the
4196     * intersection of all visible rectangles for this
4197     * component and all of its ancestors -- this is the return
4198     * value for this method
4199     * @see #getVisibleRect
4200     */

4201    public void computeVisibleRect(Rectangle visibleRect) {
4202        computeVisibleRect(this, visibleRect);
4203    }
4204
4205
4206    /**
4207     * Returns the <code>Component</code>'s "visible rectangle" - the
4208     * intersection of this component's visible rectangle,
4209     * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
4210     * and all of its ancestors' visible rectangles.
4211     *
4212     * @return the visible rectangle
4213     */

4214    public Rectangle getVisibleRect() {
4215        Rectangle visibleRect = new Rectangle();
4216
4217        computeVisibleRect(visibleRect);
4218        return visibleRect;
4219    }
4220
4221    /**
4222     * Support for reporting bound property changes for boolean properties.
4223     * This method can be called when a bound property has changed and it will
4224     * send the appropriate PropertyChangeEvent to any registered
4225     * PropertyChangeListeners.
4226     *
4227     * @param propertyName the property whose value has changed
4228     * @param oldValue the property's previous value
4229     * @param newValue the property's new value
4230     */

4231    public void firePropertyChange(String JavaDoc propertyName,
4232                   boolean oldValue, boolean newValue) {
4233    super.firePropertyChange(propertyName, oldValue, newValue);
4234    }
4235    
4236
4237    /**
4238     * Support for reporting bound property changes for integer properties.
4239     * This method can be called when a bound property has changed and it will
4240     * send the appropriate PropertyChangeEvent to any registered
4241     * PropertyChangeListeners.
4242     *
4243     * @param propertyName the property whose value has changed
4244     * @param oldValue the property's previous value
4245     * @param newValue the property's new value
4246     */

4247    public void firePropertyChange(String JavaDoc propertyName,
4248                      int oldValue, int newValue) {
4249    super.firePropertyChange(propertyName, oldValue, newValue);
4250    }
4251
4252    // XXX This method is implemented as a workaround to a JLS issue with ambiguous
4253
// methods. This should be removed once 4758654 is resolved.
4254
public void firePropertyChange(String JavaDoc propertyName, char oldValue, char newValue) {
4255    super.firePropertyChange(propertyName, oldValue, newValue);
4256    }
4257
4258    /**
4259     * Supports reporting constrained property changes.
4260     * This method can be called when a constrained property has changed
4261     * and it will send the appropriate <code>PropertyChangeEvent</code>
4262     * to any registered <code>VetoableChangeListeners</code>.
4263     *
4264     * @param propertyName the name of the property that was listened on
4265     * @param oldValue the old value of the property
4266     * @param newValue the new value of the property
4267     * @exception PropertyVetoException when the attempt to set the
4268     * property is vetoed by the component
4269     */

4270    protected void fireVetoableChange(String JavaDoc propertyName, Object JavaDoc oldValue, Object JavaDoc newValue)
4271        throws java.beans.PropertyVetoException JavaDoc
4272    {
4273        if (vetoableChangeSupport == null) {
4274            return;
4275        }
4276        vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
4277    }
4278
4279
4280    /**
4281     * Adds a <code>VetoableChangeListener</code> to the listener list.
4282     * The listener is registered for all properties.
4283     *
4284     * @param listener the <code>VetoableChangeListener</code> to be added
4285     */

4286    public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
4287        if (vetoableChangeSupport == null) {
4288            vetoableChangeSupport = new java.beans.VetoableChangeSupport JavaDoc(this);
4289        }
4290        vetoableChangeSupport.addVetoableChangeListener(listener);
4291    }
4292
4293
4294    /**
4295     * Removes a <code>VetoableChangeListener</code> from the listener list.
4296     * This removes a <code>VetoableChangeListener</code> that was registered
4297     * for all properties.
4298     *
4299     * @param listener the <code>VetoableChangeListener</code> to be removed
4300     */

4301    public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
4302        if (vetoableChangeSupport == null) {
4303            return;
4304        }
4305        vetoableChangeSupport.removeVetoableChangeListener(listener);
4306    }
4307
4308
4309    /**
4310     * Returns an array of all the vetoable change listeners
4311     * registered on this component.
4312     *
4313     * @return all of the component's <code>VetoableChangeListener</code>s
4314     * or an empty
4315     * array if no vetoable change listeners are currently registered
4316     *
4317     * @see #addVetoableChangeListener
4318     * @see #removeVetoableChangeListener
4319     *
4320     * @since 1.4
4321     */

4322    public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
4323        if (vetoableChangeSupport == null) {
4324            return new VetoableChangeListener[0];
4325        }
4326        return vetoableChangeSupport.getVetoableChangeListeners();
4327    }
4328
4329
4330    /**
4331     * Returns the top-level ancestor of this component (either the
4332     * containing <code>Window</code> or <code>Applet</code>),
4333     * or <code>null</code> if this component has not
4334     * been added to any container.
4335     *
4336     * @return the top-level <code>Container</code> that this component is in,
4337     * or <code>null</code> if not in any container
4338     */

4339    public Container getTopLevelAncestor() {
4340        for(Container p = this; p != null; p = p.getParent()) {
4341            if(p instanceof Window || p instanceof Applet JavaDoc) {
4342                return p;
4343            }
4344        }
4345        return null;
4346    }
4347
4348    private AncestorNotifier JavaDoc getAncestorNotifier() {
4349        return (AncestorNotifier JavaDoc)getClientProperty(ANCESTOR_NOTIFIER_KEY);
4350    }
4351
4352    /**
4353     * Registers <code>listener</code> so that it will receive
4354     * <code>AncestorEvents</code> when it or any of its ancestors
4355     * move or are made visible or invisible.
4356     * Events are also sent when the component or its ancestors are added
4357     * or removed from the containment hierarchy.
4358     *
4359     * @param listener the <code>AncestorListener</code> to register
4360     * @see AncestorEvent
4361     */

4362    public void addAncestorListener(AncestorListener listener) {
4363        AncestorNotifier JavaDoc ancestorNotifier = getAncestorNotifier();
4364        if (ancestorNotifier == null) {
4365            ancestorNotifier = new AncestorNotifier JavaDoc(this);
4366            putClientProperty(ANCESTOR_NOTIFIER_KEY, ancestorNotifier);
4367        }
4368        ancestorNotifier.addAncestorListener(listener);
4369    }
4370
4371    /**
4372     * Unregisters <code>listener</code> so that it will no longer receive
4373     * <code>AncestorEvents</code>.
4374     *
4375     * @param listener the <code>AncestorListener</code> to be removed
4376     * @see #addAncestorListener
4377     */

4378    public void removeAncestorListener(AncestorListener listener) {
4379        AncestorNotifier JavaDoc ancestorNotifier = getAncestorNotifier();
4380        if (ancestorNotifier == null) {
4381            return;
4382        }
4383        ancestorNotifier.removeAncestorListener(listener);
4384        if (ancestorNotifier.listenerList.getListenerList().length == 0) {
4385            ancestorNotifier.removeAllListeners();
4386            putClientProperty(ANCESTOR_NOTIFIER_KEY, null);
4387        }
4388    }
4389
4390    /**
4391     * Returns an array of all the ancestor listeners
4392     * registered on this component.
4393     *
4394     * @return all of the component's <code>AncestorListener</code>s
4395     * or an empty
4396     * array if no ancestor listeners are currently registered
4397     *
4398     * @see #addAncestorListener
4399     * @see #removeAncestorListener
4400     *
4401     * @since 1.4
4402     */

4403    public AncestorListener[] getAncestorListeners() {
4404        AncestorNotifier JavaDoc ancestorNotifier = getAncestorNotifier();
4405    if (ancestorNotifier == null) {
4406        return new AncestorListener[0];
4407    }
4408        return ancestorNotifier.getAncestorListeners();
4409    }
4410
4411    /**
4412     * Returns an array of all the objects currently registered
4413     * as <code><em>Foo</em>Listener</code>s
4414     * upon this <code>JComponent</code>.
4415     * <code><em>Foo</em>Listener</code>s are registered using the
4416     * <code>add<em>Foo</em>Listener</code> method.
4417     *
4418     * <p>
4419     *
4420     * You can specify the <code>listenerType</code> argument
4421     * with a class literal,
4422     * such as
4423     * <code><em>Foo</em>Listener.class</code>.
4424     * For example, you can query a
4425     * <code>JComponent</code> <code>c</code>
4426     * for its mouse listeners with the following code:
4427     * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
4428     * If no such listeners exist, this method returns an empty array.
4429     *
4430     * @param listenerType the type of listeners requested; this parameter
4431     * should specify an interface that descends from
4432     * <code>java.util.EventListener</code>
4433     * @return an array of all objects registered as
4434     * <code><em>Foo</em>Listener</code>s on this component,
4435     * or an empty array if no such
4436     * listeners have been added
4437     * @exception ClassCastException if <code>listenerType</code>
4438     * doesn't specify a class or interface that implements
4439     * <code>java.util.EventListener</code>
4440     *
4441     * @since 1.3
4442     *
4443     * @see #getVetoableChangeListeners
4444     * @see #getAncestorListeners
4445     */

4446    public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
4447    T[] result;
4448    if (listenerType == AncestorListener.class) {
4449        // AncestorListeners are handled by the AncestorNotifier
4450
result = (T[])getAncestorListeners();
4451    }
4452    else if (listenerType == VetoableChangeListener.class) {
4453        // VetoableChangeListeners are handled by VetoableChangeSupport
4454
result = (T[])getVetoableChangeListeners();
4455    }
4456    else if (listenerType == PropertyChangeListener.class) {
4457        // PropertyChangeListeners are handled by PropertyChangeSupport
4458
result = (T[])getPropertyChangeListeners();
4459    }
4460    else {
4461        result = (T[])listenerList.getListeners(listenerType);
4462    }
4463
4464    if (result.length == 0) {
4465        return super.getListeners(listenerType);
4466    }
4467    return result;
4468    }
4469
4470    /**
4471     * Notifies this component that it now has a parent component.
4472     * When this method is invoked, the chain of parent components is
4473     * set up with <code>KeyboardAction</code> event listeners.
4474     *
4475     * @see #registerKeyboardAction
4476     */

4477    public void addNotify() {
4478        super.addNotify();
4479        firePropertyChange("ancestor", null, getParent());
4480
4481    registerWithKeyboardManager(false);
4482    registerNextFocusableComponent();
4483    }
4484
4485
4486    /**
4487     * Notifies this component that it no longer has a parent component.
4488     * When this method is invoked, any <code>KeyboardAction</code>s
4489     * set up in the the chain of parent components are removed.
4490     *
4491     * @see #registerKeyboardAction
4492     */

4493    public void removeNotify() {
4494        super.removeNotify();
4495        // This isn't strictly correct. The event shouldn't be
4496
// fired until *after* the parent is set to null. But
4497
// we only get notified before that happens
4498
firePropertyChange("ancestor", getParent(), null);
4499
4500    unregisterWithKeyboardManager();
4501    deregisterNextFocusableComponent();
4502
4503    if (getCreatedDoubleBuffer()) {
4504        RepaintManager.currentManager(this).resetDoubleBuffer();
4505        setCreatedDoubleBuffer(false);
4506    }
4507        if (autoscrolls) {
4508            Autoscroller.stop(this);
4509        }
4510    }
4511
4512
4513    /**
4514     * Adds the specified region to the dirty region list if the component
4515     * is showing. The component will be repainted after all of the
4516     * currently pending events have been dispatched.
4517     *
4518     * @param tm this parameter is not used
4519     * @param x the x value of the dirty region
4520     * @param y the y value of the dirty region
4521     * @param width the width of the dirty region
4522     * @param height the height of the dirty region
4523     * @see java.awt.Component#isShowing
4524     * @see RepaintManager#addDirtyRegion
4525     */

4526    public void repaint(long tm, int x, int y, int width, int height) {
4527        RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
4528    }
4529
4530
4531    /**
4532     * Adds the specified region to the dirty region list if the component
4533     * is showing. The component will be repainted after all of the
4534     * currently pending events have been dispatched.
4535     *
4536     * @param r a <code>Rectangle</code> containing the dirty region
4537     * @see java.awt.Component#isShowing
4538     * @see RepaintManager#addDirtyRegion
4539     */

4540    public void repaint(Rectangle r) {
4541        repaint(0,r.x,r.y,r.width,r.height);
4542    }
4543
4544
4545    /**
4546     * Supports deferred automatic layout.
4547     * <p>
4548     * Calls <code>invalidate</code> and then adds this component's
4549     * <code>validateRoot</code> to a list of components that need to be
4550     * validated. Validation will occur after all currently pending
4551     * events have been dispatched. In other words after this method
4552     * is called, the first validateRoot (if any) found when walking
4553     * up the containment hierarchy of this component will be validated.
4554     * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
4555     * and <code>JTextField</code> return true
4556     * from <code>isValidateRoot</code>.
4557     * <p>
4558     * This method will automatically be called on this component
4559     * when a property value changes such that size, location, or
4560     * internal layout of this component has been affected. This automatic
4561     * updating differs from the AWT because programs generally no
4562     * longer need to invoke <code>validate</code> to get the contents of the
4563     * GUI to update.
4564     * <p>
4565     *
4566     * @see java.awt.Component#invalidate
4567     * @see java.awt.Container#validate
4568     * @see #isValidateRoot
4569     * @see RepaintManager#addInvalidComponent
4570     */

4571    public void revalidate() {
4572        if (getParent() == null) {
4573            // Note: We don't bother invalidating here as once added
4574
// to a valid parent invalidate will be invoked (addImpl
4575
// invokes addNotify which will invoke invalidate on the
4576
// new Component). Also, if we do add a check to isValid
4577
// here it can potentially be called before the constructor
4578
// which was causing some people grief.
4579
return;
4580        }
4581        if (SwingUtilities.isEventDispatchThread()) {
4582            invalidate();
4583            RepaintManager.currentManager(this).addInvalidComponent(this);
4584        }
4585        else {
4586            Runnable JavaDoc callRevalidate = new Runnable JavaDoc() {
4587                public void run() {
4588                    revalidate();
4589                }
4590            };
4591            SwingUtilities.invokeLater(callRevalidate);
4592        }
4593    }
4594
4595    /**
4596     * If this method returns true, <code>revalidate</code> calls by
4597     * descendants of this component will cause the entire tree
4598     * beginning with this root to be validated.
4599     * Returns false by default. <code>JScrollPane</code> overrides
4600     * this method and returns true.
4601     *
4602     * @return always returns false
4603     * @see #revalidate
4604     * @see java.awt.Component#invalidate
4605     * @see java.awt.Container#validate
4606     */

4607    public boolean isValidateRoot() {
4608        return false;
4609    }
4610
4611
4612    /**
4613     * Returns true if this component tiles its children -- that is, if
4614     * it can guarantee that the children will not overlap. The
4615     * repainting system is substantially more efficient in this
4616     * common case. <code>JComponent</code> subclasses that can't make this
4617     * guarantee, such as <code>JLayeredPane</code>,
4618     * should override this method to return false.
4619     *
4620     * @return always returns true
4621     */

4622    public boolean isOptimizedDrawingEnabled() {
4623        return true;
4624    }
4625
4626    /**
4627     * Returns true if a paint triggered on a child component should cause
4628     * painting to originate from this Component, or one of its ancestors.
4629     *
4630     * @return true if painting should originate from this Component or
4631     * one of its ancestors.
4632     */

4633    boolean isPaintingOrigin() {
4634        return false;
4635    }
4636
4637    /**
4638     * Paints the specified region in this component and all of its
4639     * descendants that overlap the region, immediately.
4640     * <p>
4641     * It's rarely necessary to call this method. In most cases it's
4642     * more efficient to call repaint, which defers the actual painting
4643     * and can collapse redundant requests into a single paint call.
4644     * This method is useful if one needs to update the display while
4645     * the current event is being dispatched.
4646     *
4647     * @param x the x value of the region to be painted
4648     * @param y the y value of the region to be painted
4649     * @param w the width of the region to be painted
4650     * @param h the height of the region to be painted
4651     * @see #repaint
4652     */

4653    public void paintImmediately(int x,int y,int w, int h) {
4654        Component c = this;
4655        Component parent;
4656
4657        if(!isShowing()) {
4658            return;
4659        }
4660        while(!((JComponent JavaDoc)c).isOpaque()) {
4661            parent = c.getParent();
4662            if(parent != null) {
4663                x += c.getX();
4664                y += c.getY();
4665                c = parent;
4666            } else {
4667                break;
4668            }
4669
4670            if(!(c instanceof JComponent JavaDoc)) {
4671                break;
4672            }
4673        }
4674        if(c instanceof JComponent JavaDoc) {
4675            ((JComponent JavaDoc)c)._paintImmediately(x,y,w,h);
4676        } else {
4677            c.repaint(x,y,w,h);
4678        }
4679    }
4680
4681    /**
4682     * Paints the specified region now.
4683     *
4684     * @param r a <code>Rectangle</code> containing the region to be painted
4685     */

4686    public void paintImmediately(Rectangle r) {
4687        paintImmediately(r.x,r.y,r.width,r.height);
4688    }
4689
4690    /**
4691     * Returns whether this component should be guaranteed to be on top.
4692     * For example, it would make no sense for <code>Menu</code>s to pop up
4693     * under another component, so they would always return true.
4694     * Most components will want to return false, hence that is the default.
4695     *
4696     * @return always returns false
4697     */

4698    // package private
4699
boolean alwaysOnTop() {
4700    return false;
4701    }
4702
4703    void setPaintingChild(Component paintingChild) {
4704    this.paintingChild = paintingChild;
4705    }
4706
4707    void _paintImmediately(int x, int y, int w, int h) {
4708        Graphics g;
4709        Container c;
4710        Rectangle b;
4711
4712    int tmpX, tmpY, tmpWidth, tmpHeight;
4713        int offsetX=0,offsetY=0;
4714
4715        boolean hasBuffer = false;
4716
4717        JComponent JavaDoc bufferedComponent = null;
4718        JComponent JavaDoc paintingComponent = this;
4719
4720        RepaintManager JavaDoc repaintManager = RepaintManager.currentManager(this);
4721    // parent Container's up to Window or Applet. First container is
4722
// the direct parent. Note that in testing it was faster to
4723
// alloc a new Vector vs keeping a stack of them around, and gc
4724
// seemed to have a minimal effect on this.
4725
Vector JavaDoc path = new Vector JavaDoc(7);
4726    int pIndex = -1;
4727    int pCount = 0;
4728
4729    tmpX = tmpY = tmpWidth = tmpHeight = 0;
4730
4731        Rectangle paintImmediatelyClip = fetchRectangle();
4732        paintImmediatelyClip.x = x;
4733        paintImmediatelyClip.y = y;
4734        paintImmediatelyClip.width = w;
4735        paintImmediatelyClip.height = h;
4736
4737    
4738    // System.out.println("1) ************* in _paintImmediately for " + this);
4739

4740    boolean ontop = alwaysOnTop() && isOpaque();
4741        Component child;
4742        for (c = this, child = null;
4743             c != null && !(c instanceof Window) && !(c instanceof Applet JavaDoc);
4744             child = c, c = c.getParent()) {
4745                JComponent JavaDoc jc = (c instanceof JComponent JavaDoc) ? (JComponent JavaDoc)c :
4746                                null;
4747            path.addElement(c);
4748        if(!ontop && jc != null && !jc.isOptimizedDrawingEnabled()) {
4749                    boolean resetPC;
4750
4751                    // Children of c may overlap, three possible cases for the
4752
// painting region:
4753
// . Completely obscured by an opaque sibling, in which
4754
// case there is no need to paint.
4755
// . Partially obscured by a sibling: need to start
4756
// painting from c.
4757
// . Otherwise we aren't obscured and thus don't need to
4758
// start painting from parent.
4759
if (c != this) {
4760                        if (jc.isPaintingOrigin()) {
4761                            resetPC = true;
4762                        }
4763                        else {
4764                            Component[] children = c.getComponents();
4765                            int i = 0;
4766                            for (; i<children.length; i++) {
4767                                if (children[i] == child) break;
4768                            }
4769                            switch (jc.getObscuredState(i,
4770                                            paintImmediatelyClip.x,
4771                                            paintImmediatelyClip.y,
4772                                            paintImmediatelyClip.width,
4773                                            paintImmediatelyClip.height)) {
4774                            case NOT_OBSCURED:
4775                                resetPC = false;
4776                                break;
4777                            case COMPLETELY_OBSCURED:
4778                                recycleRectangle(paintImmediatelyClip);
4779                                return;
4780                            default:
4781                                resetPC = true;
4782                                break;
4783                            }
4784                        }
4785                    }
4786                    else {
4787                        resetPC = false;
4788                    }
4789
4790                    if (resetPC) {
4791                        // Get rid of any buffer since we draw from here and
4792
// we might draw something larger
4793
paintingComponent = jc;
4794                        pIndex = pCount;
4795                        offsetX = offsetY = 0;
4796                        hasBuffer = false;
4797                    }
4798        }
4799        pCount++;
4800        
4801        // look to see if the parent (and therefor this component)
4802
// is double buffered
4803
if(repaintManager.isDoubleBufferingEnabled() && jc != null &&
4804                                  jc.isDoubleBuffered()) {
4805            hasBuffer = true;
4806            bufferedComponent = jc;
4807        }
4808
4809        // if we aren't on top, include the parent's clip
4810
if (!ontop) {
4811                    int bx = c.getX();
4812                    int by = c.getY();
4813            tmpWidth = c.getWidth();
4814            tmpHeight = c.getHeight();
4815            SwingUtilities.computeIntersection(tmpX,tmpY,tmpWidth,tmpHeight,paintImmediatelyClip);
4816            paintImmediatelyClip.x += bx;
4817            paintImmediatelyClip.y += by;
4818            offsetX += bx;
4819            offsetY += by;
4820        }
4821    }
4822    
4823    // If the clip width or height is negative, don't bother painting
4824
if(c == null || c.getPeer() == null ||
4825                        paintImmediatelyClip.width <= 0 ||
4826                        paintImmediatelyClip.height <= 0) {
4827            recycleRectangle(paintImmediatelyClip);
4828        return;
4829    }
4830
4831    paintingComponent.setFlag(IS_REPAINTING, true);
4832
4833        paintImmediatelyClip.x -= offsetX;
4834        paintImmediatelyClip.y -= offsetY;
4835    
4836    // Notify the Components that are going to be painted of the
4837
// child component to paint to.
4838
if(paintingComponent != this) {
4839        Component comp;
4840        int i = pIndex;
4841        for(; i > 0 ; i--) {
4842        comp = (Component) path.elementAt(i);
4843        if(comp instanceof JComponent JavaDoc) {
4844            ((JComponent JavaDoc)comp).setPaintingChild
4845                           ((Component)path.elementAt(i-1));
4846        }
4847        }
4848    }
4849
4850    try {
4851        try {
4852            Graphics pcg = paintingComponent.getGraphics();
4853        g = (pcg == null) ? null : pcg.create();
4854        pcg.dispose();
4855        } catch(NullPointerException JavaDoc e) {
4856        g = null;
4857        e.printStackTrace();
4858        }
4859
4860        if (g == null) {
4861        System.err.println("In paintImmediately null graphics");
4862        return;
4863        }
4864
4865        try {
4866            boolean paintCompleted = false;
4867            if (hasBuffer) {
4868            paintCompleted = paintDoubleBuffered(paintingComponent, bufferedComponent, g,
4869                              paintImmediatelyClip.x,
4870                              paintImmediatelyClip.y,
4871                              paintImmediatelyClip.width,
4872                              paintImmediatelyClip.height);
4873            }
4874            if (!paintCompleted) {
4875            //System.out.println("has no buffer");
4876
g.setClip(paintImmediatelyClip.x,paintImmediatelyClip.y,
4877               paintImmediatelyClip.width,paintImmediatelyClip.height);
4878            paintingComponent.paint(g);
4879        }
4880        } finally {
4881        g.dispose();
4882        }
4883    }
4884    finally {
4885        // Reset the painting child for the parent components.
4886
if(paintingComponent != this) {
4887        Component comp;
4888        int i = pIndex;
4889        for(; i > 0 ; i--) {
4890            comp = (Component) path.elementAt(i);
4891            if(comp instanceof JComponent JavaDoc) {
4892            ((JComponent JavaDoc)comp).setPaintingChild(null);
4893            }
4894        }
4895        }
4896        path.removeAllElements();
4897        paintingComponent.setFlag(IS_REPAINTING, false);
4898    }
4899        recycleRectangle(paintImmediatelyClip);
4900    }
4901
4902    private boolean paintDoubleBuffered(JComponent JavaDoc paintingComponent, Component bufferComponent,
4903                    Graphics g, int clipX, int clipY, int clipW, int clipH) {
4904        RepaintManager JavaDoc repaintManager = RepaintManager.currentManager(paintingComponent);
4905    boolean paintCompleted = false;
4906        Image JavaDoc offscreen = null;
4907
4908        // First attempt to use VolatileImage buffer for performance. If this fails
4909
// (which should rarely occur), fallback to a standard Image buffer.
4910
//
4911
if (repaintManager.useVolatileDoubleBuffer() &&
4912            (offscreen = repaintManager.getVolatileOffscreenBuffer(
4913                bufferComponent,clipW,clipH)) != null &&
4914            (offscreen.getWidth(null) > 0 && offscreen.getHeight(null) > 0)) {
4915    
4916       VolatileImage JavaDoc vImage = (java.awt.image.VolatileImage JavaDoc)offscreen;
4917           GraphicsConfiguration gc = bufferComponent.
4918                                            getGraphicsConfiguration();
4919       for (int i = 0; !paintCompleted && i < RepaintManager.VOLATILE_LOOP_MAX; i++) {
4920        if (vImage.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
4921            repaintManager.resetVolatileDoubleBuffer(gc);
4922            offscreen = repaintManager.getVolatileOffscreenBuffer(bufferComponent,clipW, clipH);
4923            vImage = (java.awt.image.VolatileImage JavaDoc)offscreen;
4924        }
4925            paintWithOffscreenBuffer(paintingComponent, g, clipX, clipY, clipW, clipH, offscreen);
4926            paintCompleted = !vImage.contentsLost();
4927        }
4928    }
4929    if (!paintCompleted) {
4930        // VolatileImage painting loop failed, fallback to regular offscreen buffer
4931
if ((offscreen =
4932           repaintManager.getOffscreenBuffer(bufferComponent, clipW, clipH)) != null &&
4933        (offscreen.getWidth(null) > 0 && offscreen.getHeight(null) > 0)) {
4934
4935        paintWithOffscreenBuffer(paintingComponent, g, clipX, clipY, clipW, clipH, offscreen);
4936        paintCompleted = true;
4937        }
4938    }
4939    return paintCompleted;
4940    }
4941
4942    private void paintWithOffscreenBuffer(JComponent JavaDoc paintingComponent, Graphics g,
4943                                      int clipX, int clipY, int clipW, int clipH,
4944                      Image JavaDoc offscreen) {
4945        Graphics og = offscreen.getGraphics();
4946        Graphics osg = (og == null) ? null : og.create();
4947    og.dispose();
4948        int bw = offscreen.getWidth(null);
4949        int bh = offscreen.getHeight(null);
4950        int x,y,maxx,maxy;
4951
4952        if (bw > clipW) {
4953            bw = clipW;
4954        }
4955        if (bh > clipH) {
4956            bh = clipH;
4957        }
4958        try {
4959            paintingComponent.setFlag(ANCESTOR_USING_BUFFER,true);
4960            paintingComponent.setFlag(IS_PAINTING_TILE,true);
4961            for(x = clipX, maxx = clipX+clipW; x < maxx ; x += bw ) {
4962                for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
4963                    if ((y+bh) >= maxy && (x+bw) >= maxx) {
4964                        paintingComponent.setFlag(IS_PAINTING_TILE,false);
4965                    }
4966                    osg.translate(-x,-y);
4967                    osg.setClip(x,y,bw,bh);
4968
4969            if (paintingComponent.getFlag(IS_REPAINTING)) {
4970            // Called from paintImmediately (RepaintManager) to fill
4971
// repaint request
4972
paintingComponent.paint(osg);
4973                    } else {
4974            // Called from paint() (AWT) to repair damage
4975
if(!paintingComponent.rectangleIsObscured(clipX,clipY,bw,bh)) {
4976                    paintingComponent.paintComponent(osg);
4977                paintingComponent.paintBorder(osg);
4978                }
4979                paintingComponent.paintChildren(osg);
4980                    }
4981                    g.setClip(x,y,bw,bh);
4982                    g.drawImage(offscreen,x,y,paintingComponent);
4983                    osg.translate(x,y);
4984                }
4985            }
4986        } finally {
4987            paintingComponent.setFlag(ANCESTOR_USING_BUFFER,false);
4988            paintingComponent.setFlag(IS_PAINTING_TILE,false);
4989            osg.dispose();
4990        }
4991    }
4992
4993    /**
4994     * Returns whether or not the region of the specified component is
4995     * obscured by a sibling.
4996     *
4997     * @return NOT_OBSCURED if non of the siblings above the Component obscure
4998     * it, COMPLETELY_OBSCURED if one of the siblings completely
4999     * obscures the Component or PARTIALLY_OBSCURED if the Comonent is
5000     * only partially obscured.
5001     */

5002    private int getObscuredState(int compIndex, int x, int y, int width,
5003                                 int height) {
5004        int retValue = NOT_OBSCURED;
5005        Rectangle tmpRect = fetchRectangle();
5006
5007    for (int i = compIndex - 1 ; i >= 0 ; i--) {
5008        Component sibling = getComponent(i);
5009        if (!sibling.isVisible()) {
5010        continue;
5011            }
5012            Rectangle siblingRect;
5013            boolean opaque;
5014        if (sibling instanceof JComponent JavaDoc) {
5015                opaque = ((JComponent JavaDoc)sibling).isOpaque();
5016        if (!opaque) {
5017                    if (retValue == PARTIALLY_OBSCURED) {
5018                        continue;
5019                    }
5020                }
5021        }
5022        else {
5023                opaque = true;
5024        }
5025            siblingRect = sibling.getBounds(tmpRect);
5026        if (opaque && x >= siblingRect.x && (x + width) <=
5027             (siblingRect.x + siblingRect.width) &&
5028             y >= siblingRect.y && (y + height) <=
5029             (siblingRect.y + siblingRect.height)) {
5030                recycleRectangle(tmpRect);
5031        return COMPLETELY_OBSCURED;
5032        }
5033            else if (retValue == NOT_OBSCURED &&
5034                     !((x + width <= siblingRect.x) ||
5035                       (y + height <= siblingRect.y) ||
5036                       (x >= siblingRect.x + siblingRect.width) ||
5037                       (y >= siblingRect.y + siblingRect.height))) {
5038                retValue = PARTIALLY_OBSCURED;
5039            }
5040    }
5041        recycleRectangle(tmpRect);
5042    return retValue;
5043    }
5044
5045    /**
5046     * Returns true, which implies that before checking if a child should
5047     * be painted it is first check that the child is not obscured by another
5048     * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code>
5049     * returns false.
5050     *
5051     * @return always returns true
5052     */

5053    boolean checkIfChildObscuredBySibling() {
5054    return true;
5055    }
5056
5057
5058    private void setFlag(int aFlag, boolean aValue) {
5059        if(aValue) {
5060            flags |= (1 << aFlag);
5061        } else {
5062            flags &= ~(1 << aFlag);
5063        }
5064    }
5065    private boolean getFlag(int aFlag) {
5066        int mask = (1 << aFlag);
5067        return ((flags & mask) == mask);
5068    }
5069    // These functions must be static so that they can be called from
5070
// subclasses inside the package, but whose inheritance hierarhcy includes
5071
// classes outside of the package below JComponent (e.g., JTextArea).
5072
static void setWriteObjCounter(JComponent JavaDoc comp, byte count) {
5073        comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) |
5074                     (count << WRITE_OBJ_COUNTER_FIRST);
5075    }
5076    static byte getWriteObjCounter(JComponent JavaDoc comp) {
5077        return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
5078    }
5079
5080    /** Buffering **/
5081
5082    /**
5083     * Sets whether the this component should use a buffer to paint.
5084     * If set to true, all the drawing from this component will be done
5085     * in an offscreen painting buffer. The offscreen painting buffer will
5086     * the be copied onto the screen.
5087     * Swings painting system always uses a maximum of one double buffer.
5088     * If a <code>Component</code> is buffered and one of its ancestor
5089     * is also buffered, the ancestor buffer will be used.
5090     *
5091     * @param aFlag if true, set this component to be double buffered
5092     */

5093    public void setDoubleBuffered(boolean aFlag) {
5094        setFlag(IS_DOUBLE_BUFFERED,aFlag);
5095    }
5096
5097    /**
5098     * Returns whether this component should use a buffer to paint.
5099     *
5100     * @return true if this component is double buffered, otherwise false
5101     */

5102    public boolean isDoubleBuffered() {
5103        return getFlag(IS_DOUBLE_BUFFERED);
5104    }
5105
5106    /**
5107     * Returns the <code>JRootPane</code> ancestor for this component.
5108     *
5109     * @return the <code>JRootPane</code> that contains this component,
5110     * or <code>null</code> if no <code>JRootPane</code> is found
5111     */

5112    public JRootPane JavaDoc getRootPane() {
5113        return SwingUtilities.getRootPane(this);
5114    }
5115
5116
5117    /** Serialization **/
5118
5119    /**
5120     * This is called from Component by way of reflection. Do NOT change
5121     * the name unless you change the code in Component as well.
5122     */

5123    void compWriteObjectNotify() {
5124        byte count = JComponent.getWriteObjCounter(this);
5125        JComponent.setWriteObjCounter(this, (byte)(count + 1));
5126        if (count != 0) {
5127            return;
5128        }
5129
5130        if (ui != null) {
5131        ui.uninstallUI(this);
5132    }
5133        /* JTableHeader is in a separate package, which prevents it from
5134         * being able to override this package-private method the way the
5135         * other components can. We don't want to make this method protected
5136         * because it would introduce public-api for a less-than-desirable
5137         * serialization scheme, so we compromise with this 'instanceof' hack
5138         * for now.
5139         */

5140        if (getToolTipText() != null ||
5141            this instanceof javax.swing.table.JTableHeader JavaDoc) {
5142            ToolTipManager.sharedInstance().unregisterComponent(JComponent.this);
5143        }
5144    }
5145
5146    /**
5147     * This object is the <code>ObjectInputStream</code> callback
5148     * that's called after a complete graph of objects (including at least
5149     * one <code>JComponent</code>) has been read.
5150     * It sets the UI property of each Swing component
5151     * that was read to the current default with <code>updateUI</code>.
5152     * <p>
5153     * As each component is read in we keep track of the current set of
5154     * root components here, in the roots vector. Note that there's only one
5155     * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>,
5156     * they're stored in the static <code>readObjectCallbacks</code>
5157     * hashtable.
5158     *
5159     * @see java.io.ObjectInputStream#registerValidation
5160     * @see SwingUtilities#updateComponentTreeUI
5161     */

5162    private class ReadObjectCallback implements ObjectInputValidation JavaDoc
5163    {
5164    private final Vector JavaDoc roots = new Vector JavaDoc(1);
5165    private final ObjectInputStream JavaDoc inputStream;
5166
5167    ReadObjectCallback(ObjectInputStream JavaDoc s) throws Exception JavaDoc {
5168        inputStream = s;
5169        s.registerValidation(this, 0);
5170    }
5171
5172    /**
5173     * This is the method that's called after the entire graph
5174     * of objects has been read in. It initializes
5175     * the UI property of all of the copmonents with
5176     * <code>SwingUtilities.updateComponentTreeUI</code>.
5177     */

5178    public void validateObject() throws InvalidObjectException JavaDoc {
5179        try {
5180        for(int i = 0; i < roots.size(); i++) {
5181            JComponent JavaDoc root = (JComponent JavaDoc)(roots.elementAt(i));
5182            SwingUtilities.updateComponentTreeUI(root);
5183        }
5184        }
5185        finally {
5186        readObjectCallbacks.remove(inputStream);
5187        }
5188    }
5189
5190    /**
5191     * If <code>c</code> isn't a descendant of a component we've already
5192     * seen, then add it to the roots <code>Vector</code>.
5193         *
5194         * @param c the <code>JComponent</code> to add
5195     */

5196    private void registerComponent(JComponent JavaDoc c)
5197        {
5198            /* If the Component c is a descendant of one of the
5199         * existing roots (or it IS an existing root), we're done.
5200         */

5201        for(int i = 0; i < roots.size(); i++) {
5202        JComponent JavaDoc root = (JComponent JavaDoc)roots.elementAt(i);
5203        for(Component p = c; p != null; p = p.getParent()) {
5204            if (p == root) {
5205            return;
5206            }
5207        }
5208        }
5209        
5210        /* Otherwise: if Component c is an ancestor of any of the
5211         * existing roots then remove them and add c (the "new root")
5212         * to the roots vector.
5213         */

5214        for(int i = 0; i < roots.size(); i++) {
5215        JComponent JavaDoc root = (JComponent JavaDoc)roots.elementAt(i);
5216        for(Component p = root.getParent(); p != null; p = p.getParent()) {
5217            if (p == c) {
5218            roots.removeElementAt(i--); // !!
5219
break;
5220            }
5221        }
5222        }
5223        
5224        roots.addElement(c);
5225    }
5226    }
5227
5228
5229    /**
5230     * We use the <code>ObjectInputStream</code> "registerValidation"
5231     * callback to update the UI for the entire tree of components
5232     * after they've all been read in.
5233     *
5234     * @param s the <code>ObjectInputStream</code> from which to read
5235     */

5236    private void readObject(ObjectInputStream JavaDoc s)
5237    throws IOException JavaDoc, ClassNotFoundException JavaDoc
5238    {
5239        s.defaultReadObject();
5240
5241    /* If there's no ReadObjectCallback for this stream yet, that is, if
5242     * this is the first call to JComponent.readObject() for this
5243     * graph of objects, then create a callback and stash it
5244     * in the readObjectCallbacks table. Note that the ReadObjectCallback
5245     * constructor takes care of calling s.registerValidation().
5246     */

5247    ReadObjectCallback cb = (ReadObjectCallback)(readObjectCallbacks.get(s));
5248    if (cb == null) {
5249        try {
5250        readObjectCallbacks.put(s, cb = new ReadObjectCallback(s));
5251        }
5252        catch (Exception JavaDoc e) {
5253        throw new IOException JavaDoc(e.toString());
5254        }
5255    }
5256    cb.registerComponent(this);
5257
5258        if (getToolTipText() != null) {
5259            ToolTipManager.sharedInstance().registerComponent(this);
5260        }
5261
5262        // Read back the client properties.
5263
int cpCount = s.readInt();
5264        if (cpCount > 0) {
5265            clientProperties = new ArrayTable JavaDoc();
5266            for (int counter = 0; counter < cpCount; counter++) {
5267                clientProperties.put(s.readObject(),
5268                                     s.readObject());
5269            }
5270    }
5271
5272        setWriteObjCounter(this, (byte)0);
5273    }
5274
5275
5276    /**
5277     * Before writing a <code>JComponent</code> to an
5278     * <code>ObjectOutputStream</code> we temporarily uninstall its UI.
5279     * This is tricky to do because we want to uninstall
5280     * the UI before any of the <code>JComponent</code>'s children
5281     * (or its <code>LayoutManager</code> etc.) are written,
5282     * and we don't want to restore the UI until the most derived
5283     * <code>JComponent</code> subclass has been been stored.
5284     *
5285     * @param s the <code>ObjectOutputStream</code> in which to write
5286     */

5287    private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
5288        s.defaultWriteObject();
5289        if (getUIClassID().equals(uiClassID)) {
5290            byte count = JComponent.getWriteObjCounter(this);
5291            JComponent.setWriteObjCounter(this, --count);
5292            if (count == 0 && ui != null) {
5293                ui.installUI(this);
5294            }
5295        }
5296        ArrayTable.writeArrayTable(s, clientProperties);
5297    }
5298
5299
5300    /**
5301     * Returns a string representation of this <code>JComponent</code>.
5302     * This method
5303     * is intended to be used only for debugging purposes, and the
5304     * content and format of the returned string may vary between
5305     * implementations. The returned string may be empty but may not
5306     * be <code>null</code>.
5307     *
5308     * @return a string representation of this <code>JComponent</code>
5309     */

5310    protected String JavaDoc paramString() {
5311        String JavaDoc preferredSizeString = (isPreferredSizeSet() ?
5312                      getPreferredSize().toString() : "");
5313        String JavaDoc minimumSizeString = (isMinimumSizeSet() ?
5314                    getMinimumSize().toString() : "");
5315        String JavaDoc maximumSizeString = (isMaximumSizeSet() ?
5316                    getMaximumSize().toString() : "");
5317        String JavaDoc borderString = (border != null ?
5318                   border.toString() : "");
5319
5320        return super.paramString() +
5321        ",alignmentX=" + alignmentX +
5322        ",alignmentY=" + alignmentY +
5323        ",border=" + borderString +
5324    ",flags=" + flags + // should beef this up a bit
5325
",maximumSize=" + maximumSizeString +
5326        ",minimumSize=" + minimumSizeString +
5327        ",preferredSize=" + preferredSizeString;
5328    }
5329
5330}
5331
Popular Tags