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();<