History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/JComponent.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/JComponent.java+5567−0
@@ -0,0 +1,5567 @@
1+/*
2+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+package javax.swing;
26+
27+
28+import java.util.HashSet;
29+import java.util.Hashtable;
30+import java.util.Dictionary;
31+import java.util.Enumeration;
32+import java.util.Locale;
33+import java.util.Vector;
34+import java.util.EventListener;
35+import java.util.Set;
36+import java.util.Map;
37+import java.util.HashMap;
38+
39+import java.awt.*;
40+import java.awt.event.*;
41+import java.awt.image.VolatileImage;
42+import java.awt.Graphics2D;
43+import java.awt.peer.LightweightPeer;
44+import java.awt.dnd.DropTarget;
45+import java.awt.font.FontRenderContext;
46+import java.beans.PropertyChangeListener;
47+import java.beans.VetoableChangeListener;
48+import java.beans.VetoableChangeSupport;
49+import java.beans.Transient;
50+
51+import java.applet.Applet;
52+
53+import java.io.Serializable;
54+import java.io.ObjectOutputStream;
55+import java.io.ObjectInputStream;
56+import java.io.IOException;
57+import java.io.ObjectInputValidation;
58+import java.io.InvalidObjectException;
59+
60+import javax.swing.border.*;
61+import javax.swing.event.*;
62+import javax.swing.plaf.*;
63+import static javax.swing.ClientPropertyKey.*;
64+import javax.accessibility.*;
65+
66+import sun.swing.SwingUtilities2;
67+import sun.swing.UIClientPropertyKey;
68+
69+/**
70+ * The base class for all Swing components except top-level containers.
71+ * To use a component that inherits from <code>JComponent</code>,
72+ * you must place the component in a containment hierarchy
73+ * whose root is a top-level Swing container.
74+ * Top-level Swing containers --
75+ * such as <code>JFrame</code>, <code>JDialog</code>,
76+ * and <code>JApplet</code> --
77+ * are specialized components
78+ * that provide a place for other Swing components to paint themselves.
79+ * For an explanation of containment hierarchies, see
80+ * <a
81+ href="http://java.sun.com/docs/books/tutorial/uiswing/overview/hierarchy.html">Swing Components and the Containment Hierarchy</a>,
82+ * a section in <em>The Java Tutorial</em>.
83+ *
84+ * <p>
85+ * The <code>JComponent</code> class provides:
86+ * <ul>
87+ * <li>The base class for both standard and custom components
88+ * that use the Swing architecture.
89+ * <li>A "pluggable look and feel" (L&F) that can be specified by the
90+ * programmer or (optionally) selected by the user at runtime.
91+ * The look and feel for each component is provided by a
92+ * <em>UI delegate</em> -- an object that descends from
93+ * {@link javax.swing.plaf.ComponentUI}.
94+ * See <a
95+ * href="http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html">How
96+ * to Set the Look and Feel</a>
97+ * in <em>The Java Tutorial</em>
98+ * for more information.
99+ * <li>Comprehensive keystroke handling.
100+ * See the document <a
101+ * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">Keyboard
102+ * Bindings in Swing</a>,
103+ * an article in <em>The Swing Connection</em>,
104+ * for more information.
105+ * <li>Support for tool tips --
106+ * short descriptions that pop up when the cursor lingers
107+ * over a component.
108+ * See <a
109+ * href="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How
110+ * to Use Tool Tips</a>
111+ * in <em>The Java Tutorial</em>
112+ * for more information.
113+ * <li>Support for accessibility.
114+ * <code>JComponent</code> contains all of the methods in the
115+ * <code>Accessible</code> interface,
116+ * but it doesn't actually implement the interface. That is the
117+ * responsibility of the individual classes
118+ * that extend <code>JComponent</code>.
119+ * <li>Support for component-specific properties.
120+ * With the {@link #putClientProperty}
121+ * and {@link #getClientProperty} methods,
122+ * you can associate name-object pairs
123+ * with any object that descends from <code>JComponent</code>.
124+ * <li>An infrastructure for painting
125+ * that includes double buffering and support for borders.
126+ * For more information see <a
127+ * href="http://java.sun.com/docs/books/tutorial/uiswing/overview/draw.html">Painting</a> and
128+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html">How
129+ * to Use Borders</a>,
130+ * both of which are sections in <em>The Java Tutorial</em>.
131+ * </ul>
132+ * For more information on these subjects, see the
133+ * <a href="package-summary.html#package_description">Swing package description</a>
134+ * and <em>The Java Tutorial</em> section
135+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
136+ * <p>
137+ * <code>JComponent</code> and its subclasses document default values
138+ * for certain properties. For example, <code>JTable</code> documents the
139+ * default row height as 16. Each <code>JComponent</code> subclass
140+ * that has a <code>ComponentUI</code> will create the
141+ * <code>ComponentUI</code> as part of its constructor. In order
142+ * to provide a particular look and feel each
143+ * <code>ComponentUI</code> may set properties back on the
144+ * <code>JComponent</code> that created it. For example, a custom
145+ * look and feel may require <code>JTable</code>s to have a row
146+ * height of 24. The documented defaults are the value of a property
147+ * BEFORE the <code>ComponentUI</code> has been installed. If you
148+ * need a specific value for a particular property you should
149+ * explicitly set it.
150+ * <p>
151+ * In release 1.4, the focus subsystem was rearchitected.
152+ * For more information, see
153+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
154+ * How to Use the Focus Subsystem</a>,
155+ * a section in <em>The Java Tutorial</em>.
156+ * <p>
157+ * <strong>Warning:</strong> Swing is not thread safe. For more
158+ * information see <a
159+ * href="package-summary.html#threading">Swing's Threading
160+ * Policy</a>.
161+ * <p>
162+ * <strong>Warning:</strong>
163+ * Serialized objects of this class will not be compatible with
164+ * future Swing releases. The current serialization support is
165+ * appropriate for short term storage or RMI between applications running
166+ * the same version of Swing. As of 1.4, support for long term storage
167+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
168+ * has been added to the <code>java.beans</code> package.
169+ * Please see {@link java.beans.XMLEncoder}.
170+ *
171+ * @see KeyStroke
172+ * @see Action
173+ * @see #setBorder
174+ * @see #registerKeyboardAction
175+ * @see JOptionPane
176+ * @see #setDebugGraphicsOptions
177+ * @see #setToolTipText
178+ * @see #setAutoscrolls
179+ *
180+ * @author Hans Muller
181+ * @author Arnaud Weber
182+ */
183+public abstract class JComponent extends Container implements Serializable,
184+ TransferHandler.HasGetTransferHandler
185+{
186+ /**
187+ * @see #getUIClassID
188+ * @see #writeObject
189+ */
190+ private static final String uiClassID = "ComponentUI";
191+
192+ /**
193+ * @see #readObject
194+ */
195+ private static final Hashtable<ObjectInputStream, ReadObjectCallback> readObjectCallbacks =
196+ new Hashtable<ObjectInputStream, ReadObjectCallback>(1);
197+
198+ /**
199+ * Keys to use for forward focus traversal when the JComponent is
200+ * managing focus.
201+ */
202+ private static Set<KeyStroke> managingFocusForwardTraversalKeys;
203+
204+ /**
205+ * Keys to use for backward focus traversal when the JComponent is
206+ * managing focus.
207+ */
208+ private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
209+
210+ // Following are the possible return values from getObscuredState.
211+ private static final int NOT_OBSCURED = 0;
212+ private static final int PARTIALLY_OBSCURED = 1;
213+ private static final int COMPLETELY_OBSCURED = 2;
214+
215+ /**
216+ * Set to true when DebugGraphics has been loaded.
217+ */
218+ static boolean DEBUG_GRAPHICS_LOADED;
219+
220+ /**
221+ * Key used to look up a value from the AppContext to determine the
222+ * JComponent the InputVerifier is running for. That is, if
223+ * AppContext.get(INPUT_VERIFIER_SOURCE_KEY) returns non-null, it
224+ * indicates the EDT is calling into the InputVerifier from the
225+ * returned component.
226+ */
227+ private static final Object INPUT_VERIFIER_SOURCE_KEY =
228+ new StringBuilder("InputVerifierSourceKey");
229+
230+ /* The following fields support set methods for the corresponding
231+ * java.awt.Component properties.
232+ */
233+ private boolean isAlignmentXSet;
234+ private float alignmentX;
235+ private boolean isAlignmentYSet;
236+ private float alignmentY;
237+
238+ /**
239+ * Backing store for JComponent properties and listeners
240+ */
241+
242+ /** The look and feel delegate for this component. */
243+ protected transient ComponentUI ui;
244+ /** A list of event listeners for this component. */
245+ protected EventListenerList listenerList = new EventListenerList();
246+
247+ private transient ArrayTable clientProperties;
248+ private VetoableChangeSupport vetoableChangeSupport;
249+ /**
250+ * Whether or not autoscroll has been enabled.
251+ */
252+ private boolean autoscrolls;
253+ private Border border;
254+ private int flags;
255+
256+ /* Input verifier for this component */
257+ private InputVerifier inputVerifier = null;
258+
259+ private boolean verifyInputWhenFocusTarget = true;
260+
261+ /**
262+ * Set in <code>_paintImmediately</code>.
263+ * Will indicate the child that initiated the painting operation.
264+ * If <code>paintingChild</code> is opaque, no need to paint
265+ * any child components after <code>paintingChild</code>.
266+ * Test used in <code>paintChildren</code>.
267+ */
268+ transient Component paintingChild;
269+
270+ /**
271+ * Constant used for <code>registerKeyboardAction</code> that
272+ * means that the command should be invoked when
273+ * the component has the focus.
274+ */
275+ public static final int WHEN_FOCUSED = 0;
276+
277+ /**
278+ * Constant used for <code>registerKeyboardAction</code> that
279+ * means that the command should be invoked when the receiving
280+ * component is an ancestor of the focused component or is
281+ * itself the focused component.
282+ */
283+ public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
284+
285+ /**
286+ * Constant used for <code>registerKeyboardAction</code> that
287+ * means that the command should be invoked when
288+ * the receiving component is in the window that has the focus
289+ * or is itself the focused component.
290+ */
291+ public static final int WHEN_IN_FOCUSED_WINDOW = 2;
292+
293+ /**
294+ * Constant used by some of the APIs to mean that no condition is defined.
295+ */
296+ public static final int UNDEFINED_CONDITION = -1;
297+
298+ /**
299+ * The key used by <code>JComponent</code> to access keyboard bindings.
300+ */
301+ private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
302+
303+ /**
304+ * An array of <code>KeyStroke</code>s used for
305+ * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
306+ * in the client properties under this string.
307+ */
308+ private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
309+
310+ /**
311+ * The comment to display when the cursor is over the component,
312+ * also known as a "value tip", "flyover help", or "flyover label".
313+ */
314+ public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
315+
316+ private static final String NEXT_FOCUS = "nextFocus";
317+
318+ /**
319+ * <code>JPopupMenu</code> assigned to this component
320+ * and all of its childrens
321+ */
322+ private JPopupMenu popupMenu;
323+
324+ /** Private flags **/
325+ private static final int IS_DOUBLE_BUFFERED = 0;
326+ private static final int ANCESTOR_USING_BUFFER = 1;
327+ private static final int IS_PAINTING_TILE = 2;
328+ private static final int IS_OPAQUE = 3;
329+ private static final int KEY_EVENTS_ENABLED = 4;
330+ private static final int FOCUS_INPUTMAP_CREATED = 5;
331+ private static final int ANCESTOR_INPUTMAP_CREATED = 6;
332+ private static final int WIF_INPUTMAP_CREATED = 7;
333+ private static final int ACTIONMAP_CREATED = 8;
334+ private static final int CREATED_DOUBLE_BUFFER = 9;
335+ // bit 10 is free
336+ private static final int IS_PRINTING = 11;
337+ private static final int IS_PRINTING_ALL = 12;
338+ private static final int IS_REPAINTING = 13;
339+ /** Bits 14-21 are used to handle nested writeObject calls. **/
340+ private static final int WRITE_OBJ_COUNTER_FIRST = 14;
341+ private static final int RESERVED_1 = 15;
342+ private static final int RESERVED_2 = 16;
343+ private static final int RESERVED_3 = 17;
344+ private static final int RESERVED_4 = 18;
345+ private static final int RESERVED_5 = 19;
346+ private static final int RESERVED_6 = 20;
347+ private static final int WRITE_OBJ_COUNTER_LAST = 21;
348+
349+ private static final int REQUEST_FOCUS_DISABLED = 22;
350+ private static final int INHERITS_POPUP_MENU = 23;
351+ private static final int OPAQUE_SET = 24;
352+ private static final int AUTOSCROLLS_SET = 25;
353+ private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26;
354+ private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27;
355+ private static final int REVALIDATE_RUNNABLE_SCHEDULED = 28;
356+
357+ /**
358+ * Temporary rectangles.
359+ */
360+ private static java.util.List<Rectangle> tempRectangles = new java.util.ArrayList<Rectangle>(11);
361+
362+ /** Used for <code>WHEN_FOCUSED</code> bindings. */
363+ private InputMap focusInputMap;
364+ /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
365+ private InputMap ancestorInputMap;
366+ /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
367+ private ComponentInputMap windowInputMap;
368+
369+ /** ActionMap. */
370+ private ActionMap actionMap;
371+
372+ /** Key used to store the default locale in an AppContext **/
373+ private static final String defaultLocale = "JComponent.defaultLocale";
374+
375+ private static Component componentObtainingGraphicsFrom;
376+ private static Object componentObtainingGraphicsFromLock = new
377+ StringBuilder("componentObtainingGraphicsFrom");
378+
379+ /**
380+ * AA text hints.
381+ */
382+ transient private Object aaTextInfo;
383+
384+ static Graphics safelyGetGraphics(Component c) {
385+ return safelyGetGraphics(c, SwingUtilities.getRoot(c));
386+ }
387+
388+ static Graphics safelyGetGraphics(Component c, Component root) {
389+ synchronized(componentObtainingGraphicsFromLock) {
390+ componentObtainingGraphicsFrom = root;
391+ Graphics g = c.getGraphics();
392+ componentObtainingGraphicsFrom = null;
393+ return g;
394+ }
395+ }
396+
397+ static void getGraphicsInvoked(Component root) {
398+ if (!JComponent.isComponentObtainingGraphicsFrom(root)) {
399+ JRootPane rootPane = ((RootPaneContainer)root).getRootPane();
400+ if (rootPane != null) {
401+ rootPane.disableTrueDoubleBuffering();
402+ }
403+ }
404+ }
405+
406+
407+ /**
408+ * Returns true if {@code c} is the component the graphics is being
409+ * requested of. This is intended for use when getGraphics is invoked.
410+ */
411+ private static boolean isComponentObtainingGraphicsFrom(Component c) {
412+ synchronized(componentObtainingGraphicsFromLock) {
413+ return (componentObtainingGraphicsFrom == c);
414+ }
415+ }
416+
417+ /**
418+ * Returns the Set of <code>KeyStroke</code>s to use if the component
419+ * is managing focus for forward focus traversal.
420+ */
421+ static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
422+ synchronized(JComponent.class) {
423+ if (managingFocusForwardTraversalKeys == null) {
424+ managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1);
425+ managingFocusForwardTraversalKeys.add(
426+ KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
427+ InputEvent.CTRL_MASK));
428+ }
429+ }
430+ return managingFocusForwardTraversalKeys;
431+ }
432+
433+ /**
434+ * Returns the Set of <code>KeyStroke</code>s to use if the component
435+ * is managing focus for backward focus traversal.
436+ */
437+ static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
438+ synchronized(JComponent.class) {
439+ if (managingFocusBackwardTraversalKeys == null) {
440+ managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1);
441+ managingFocusBackwardTraversalKeys.add(
442+ KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
443+ InputEvent.SHIFT_MASK |
444+ InputEvent.CTRL_MASK));
445+ }
446+ }
447+ return managingFocusBackwardTraversalKeys;
448+ }
449+
450+ private static Rectangle fetchRectangle() {
451+ synchronized(tempRectangles) {
452+ Rectangle rect;
453+ int size = tempRectangles.size();
454+ if (size > 0) {
455+ rect = tempRectangles.remove(size - 1);
456+ }
457+ else {
458+ rect = new Rectangle(0, 0, 0, 0);
459+ }
460+ return rect;
461+ }
462+ }
463+
464+ private static void recycleRectangle(Rectangle rect) {
465+ synchronized(tempRectangles) {
466+ tempRectangles.add(rect);
467+ }
468+ }
469+
470+ /**
471+ * Sets whether or not <code>getComponentPopupMenu</code> should delegate
472+ * to the parent if this component does not have a <code>JPopupMenu</code>
473+ * assigned to it.
474+ * <p>
475+ * The default value for this is false, but some <code>JComponent</code>
476+ * subclasses that are implemented as a number of <code>JComponent</code>s
477+ * may set this to true.
478+ * <p>
479+ * This is a bound property.
480+ *
481+ * @param value whether or not the JPopupMenu is inherited
482+ * @see #setComponentPopupMenu
483+ * @beaninfo
484+ * bound: true
485+ * description: Whether or not the JPopupMenu is inherited
486+ * @since 1.5
487+ */
488+ public void setInheritsPopupMenu(boolean value) {
489+ boolean oldValue = getFlag(INHERITS_POPUP_MENU);
490+ setFlag(INHERITS_POPUP_MENU, value);
491+ firePropertyChange("inheritsPopupMenu", oldValue, value);
492+ }
493+
494+ /**
495+ * Returns true if the JPopupMenu should be inherited from the parent.
496+ *
497+ * @see #setComponentPopupMenu
498+ * @since 1.5
499+ */
500+ public boolean getInheritsPopupMenu() {
501+ return getFlag(INHERITS_POPUP_MENU);
502+ }
503+
504+ /**
505+ * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
506+ * The UI is responsible for registering bindings and adding the necessary
507+ * listeners such that the <code>JPopupMenu</code> will be shown at
508+ * the appropriate time. When the <code>JPopupMenu</code> is shown
509+ * depends upon the look and feel: some may show it on a mouse event,
510+ * some may enable a key binding.
511+ * <p>
512+ * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
513+ * returns true, then <code>getComponentPopupMenu</code> will be delegated
514+ * to the parent. This provides for a way to make all child components
515+ * inherit the popupmenu of the parent.
516+ * <p>
517+ * This is a bound property.
518+ *
519+ * @param popup - the popup that will be assigned to this component
520+ * may be null
521+ * @see #getComponentPopupMenu
522+ * @beaninfo
523+ * bound: true
524+ * preferred: true
525+ * description: Popup to show
526+ * @since 1.5
527+ */
528+ public void setComponentPopupMenu(JPopupMenu popup) {
529+ if(popup != null) {
530+ enableEvents(AWTEvent.MOUSE_EVENT_MASK);
531+ }
532+ JPopupMenu oldPopup = this.popupMenu;
533+ this.popupMenu = popup;
534+ firePropertyChange("componentPopupMenu", oldPopup, popup);
535+ }
536+
537+ /**
538+ * Returns <code>JPopupMenu</code> that assigned for this component.
539+ * If this component does not have a <code>JPopupMenu</code> assigned
540+ * to it and <code>getInheritsPopupMenu</code> is true, this
541+ * will return <code>getParent().getComponentPopupMenu()</code> (assuming
542+ * the parent is valid.)
543+ *
544+ * @return <code>JPopupMenu</code> assigned for this component
545+ * or <code>null</code> if no popup assigned
546+ * @see #setComponentPopupMenu
547+ * @since 1.5
548+ */
549+ public JPopupMenu getComponentPopupMenu() {
550+
551+ if(!getInheritsPopupMenu()) {
552+ return popupMenu;
553+ }
554+
555+ if(popupMenu == null) {
556+ // Search parents for its popup
557+ Container parent = getParent();
558+ while (parent != null) {
559+ if(parent instanceof JComponent) {
560+ return ((JComponent)parent).getComponentPopupMenu();
561+ }
562+ if(parent instanceof Window ||
563+ parent instanceof Applet) {
564+ // Reached toplevel, break and return null
565+ break;
566+ }
567+ parent = parent.getParent();
568+ }
569+ return null;
570+ }
571+
572+ return popupMenu;
573+ }
574+
575+ /**
576+ * Default <code>JComponent</code> constructor. This constructor does
577+ * very little initialization beyond calling the <code>Container</code>
578+ * constructor. For example, the initial layout manager is
579+ * <code>null</code>. It does, however, set the component's locale
580+ * property to the value returned by
581+ * <code>JComponent.getDefaultLocale</code>.
582+ *
583+ * @see #getDefaultLocale
584+ */
585+ public JComponent() {
586+ super();
587+ // We enable key events on all JComponents so that accessibility
588+ // bindings will work everywhere. This is a partial fix to BugID
589+ // 4282211.
590+ enableEvents(AWTEvent.KEY_EVENT_MASK);
591+ if (isManagingFocus()) {
592+ LookAndFeel.installProperty(this,
593+ "focusTraversalKeysForward",
594+ getManagingFocusForwardTraversalKeys());
595+ LookAndFeel.installProperty(this,
596+ "focusTraversalKeysBackward",
597+ getManagingFocusBackwardTraversalKeys());
598+ }
599+
600+ super.setLocale( JComponent.getDefaultLocale() );
601+ }
602+
603+
604+ /**
605+ * Resets the UI property to a value from the current look and feel.
606+ * <code>JComponent</code> subclasses must override this method
607+ * like this:
608+ * <pre>
609+ * public void updateUI() {
610+ * setUI((SliderUI)UIManager.getUI(this);
611+ * }
612+ * </pre>
613+ *
614+ * @see #setUI
615+ * @see UIManager#getLookAndFeel
616+ * @see UIManager#getUI
617+ */
618+ public void updateUI() {}
619+
620+
621+ /**
622+ * Sets the look and feel delegate for this component.
623+ * <code>JComponent</code> subclasses generally override this method
624+ * to narrow the argument type. For example, in <code>JSlider</code>:
625+ * <pre>
626+ * public void setUI(SliderUI newUI) {
627+ * super.setUI(newUI);
628+ * }
629+ * </pre>
630+ * <p>
631+ * Additionally <code>JComponent</code> subclasses must provide a
632+ * <code>getUI</code> method that returns the correct type. For example:
633+ * <pre>
634+ * public SliderUI getUI() {
635+ * return (SliderUI)ui;
636+ * }
637+ * </pre>
638+ *
639+ * @param newUI the new UI delegate
640+ * @see #updateUI
641+ * @see UIManager#getLookAndFeel
642+ * @see UIManager#getUI
643+ * @beaninfo
644+ * bound: true
645+ * hidden: true
646+ * attribute: visualUpdate true
647+ * description: The component's look and feel delegate.
648+ */
649+ protected void setUI(ComponentUI newUI) {
650+ /* We do not check that the UI instance is different
651+ * before allowing the switch in order to enable the
652+ * same UI instance *with different default settings*
653+ * to be installed.
654+ */
655+
656+ uninstallUIAndProperties();
657+
658+ // aaText shouldn't persist between look and feels, reset it.
659+ aaTextInfo =
660+ UIManager.getDefaults().get(SwingUtilities2.AA_TEXT_PROPERTY_KEY);
661+ ComponentUI oldUI = ui;
662+ ui = newUI;
663+ if (ui != null) {
664+ ui.installUI(this);
665+ }
666+
667+ firePropertyChange("UI", oldUI, newUI);
668+ revalidate();
669+ repaint();
670+ }
671+
672+ /**
673+ * Uninstalls the UI, if any, and any client properties designated
674+ * as being specific to the installed UI - instances of
675+ * {@code UIClientPropertyKey}.
676+ */
677+ private void uninstallUIAndProperties() {
678+ if (ui != null) {
679+ ui.uninstallUI(this);
680+ //clean UIClientPropertyKeys from client properties
681+ if (clientProperties != null) {
682+ synchronized(clientProperties) {
683+ Object[] clientPropertyKeys =
684+ clientProperties.getKeys(null);
685+ if (clientPropertyKeys != null) {
686+ for (Object key : clientPropertyKeys) {
687+ if (key instanceof UIClientPropertyKey) {
688+ putClientProperty(key, null);
689+ }
690+ }
691+ }
692+ }
693+ }
694+ }
695+ }
696+
697+ /**
698+ * Returns the <code>UIDefaults</code> key used to
699+ * look up the name of the <code>swing.plaf.ComponentUI</code>
700+ * class that defines the look and feel
701+ * for this component. Most applications will never need to
702+ * call this method. Subclasses of <code>JComponent</code> that support
703+ * pluggable look and feel should override this method to
704+ * return a <code>UIDefaults</code> key that maps to the
705+ * <code>ComponentUI</code> subclass that defines their look and feel.
706+ *
707+ * @return the <code>UIDefaults</code> key for a
708+ * <code>ComponentUI</code> subclass
709+ * @see UIDefaults#getUI
710+ * @beaninfo
711+ * expert: true
712+ * description: UIClassID
713+ */
714+ public String getUIClassID() {
715+ return uiClassID;
716+ }
717+
718+
719+ /**
720+ * Returns the graphics object used to paint this component.
721+ * If <code>DebugGraphics</code> is turned on we create a new
722+ * <code>DebugGraphics</code> object if necessary.
723+ * Otherwise we just configure the
724+ * specified graphics object's foreground and font.
725+ *
726+ * @param g the original <code>Graphics</code> object
727+ * @return a <code>Graphics</code> object configured for this component
728+ */
729+ protected Graphics getComponentGraphics(Graphics g) {
730+ Graphics componentGraphics = g;
731+ if (ui != null && DEBUG_GRAPHICS_LOADED) {
732+ if ((DebugGraphics.debugComponentCount() != 0) &&
733+ (shouldDebugGraphics() != 0) &&
734+ !(g instanceof DebugGraphics)) {
735+ componentGraphics = new DebugGraphics(g,this);
736+ }
737+ }
738+ componentGraphics.setColor(getForeground());
739+ componentGraphics.setFont(getFont());
740+
741+ return componentGraphics;
742+ }
743+
744+
745+ /**
746+ * Calls the UI delegate's paint method, if the UI delegate
747+ * is non-<code>null</code>. We pass the delegate a copy of the
748+ * <code>Graphics</code> object to protect the rest of the
749+ * paint code from irrevocable changes
750+ * (for example, <code>Graphics.translate</code>).
751+ * <p>
752+ * If you override this in a subclass you should not make permanent
753+ * changes to the passed in <code>Graphics</code>. For example, you
754+ * should not alter the clip <code>Rectangle</code> or modify the
755+ * transform. If you need to do these operations you may find it
756+ * easier to create a new <code>Graphics</code> from the passed in
757+ * <code>Graphics</code> and manipulate it. Further, if you do not
758+ * invoker super's implementation you must honor the opaque property,
759+ * that is
760+ * if this component is opaque, you must completely fill in the background
761+ * in a non-opaque color. If you do not honor the opaque property you
762+ * will likely see visual artifacts.
763+ * <p>
764+ * The passed in <code>Graphics</code> object might
765+ * have a transform other than the identify transform
766+ * installed on it. In this case, you might get
767+ * unexpected results if you cumulatively apply
768+ * another transform.
769+ *
770+ * @param g the <code>Graphics</code> object to protect
771+ * @see #paint
772+ * @see ComponentUI
773+ */
774+ protected void paintComponent(Graphics g) {
775+ if (ui != null) {
776+ Graphics scratchGraphics = (g == null) ? null : g.create();
777+ try {
778+ ui.update(scratchGraphics, this);
779+ }
780+ finally {
781+ scratchGraphics.dispose();
782+ }
783+ }
784+ }
785+
786+ /**
787+ * Paints this component's children.
788+ * If <code>shouldUseBuffer</code> is true,
789+ * no component ancestor has a buffer and
790+ * the component children can use a buffer if they have one.
791+ * Otherwise, one ancestor has a buffer currently in use and children
792+ * should not use a buffer to paint.
793+ * @param g the <code>Graphics</code> context in which to paint
794+ * @see #paint
795+ * @see java.awt.Container#paint
796+ */
797+ protected void paintChildren(Graphics g) {
798+ Graphics sg = g;
799+
800+ synchronized(getTreeLock()) {
801+ int i = getComponentCount() - 1;
802+ if (i < 0) {
803+ return;
804+ }
805+ // If we are only to paint to a specific child, determine
806+ // its index.
807+ if (paintingChild != null &&
808+ (paintingChild instanceof JComponent) &&
809+ paintingChild.isOpaque()) {
810+ for (; i >= 0; i--) {
811+ if (getComponent(i) == paintingChild){
812+ break;
813+ }
814+ }
815+ }
816+ Rectangle tmpRect = fetchRectangle();
817+ boolean checkSiblings = (!isOptimizedDrawingEnabled() &&
818+ checkIfChildObscuredBySibling());
819+ Rectangle clipBounds = null;
820+ if (checkSiblings) {
821+ clipBounds = sg.getClipBounds();
822+ if (clipBounds == null) {
823+ clipBounds = new Rectangle(0, 0, getWidth(),
824+ getHeight());
825+ }
826+ }
827+ boolean printing = getFlag(IS_PRINTING);
828+ final Window window = SwingUtilities.getWindowAncestor(this);
829+ final boolean isWindowOpaque = window == null || window.isOpaque();
830+ for (; i >= 0 ; i--) {
831+ Component comp = getComponent(i);
832+ if (comp == null) {
833+ continue;
834+ }
835+
836+ final boolean isJComponent = comp instanceof JComponent;
837+
838+ // Enable painting of heavyweights in non-opaque windows.
839+ // See 6884960
840+ if ((!isWindowOpaque || isJComponent ||
841+ isLightweightComponent(comp)) && comp.isVisible())
842+ {
843+ Rectangle cr;
844+
845+ cr = comp.getBounds(tmpRect);
846+
847+ boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
848+ cr.height);
849+
850+ if (hitClip) {
851+ if (checkSiblings && i > 0) {
852+ int x = cr.x;
853+ int y = cr.y;
854+ int width = cr.width;
855+ int height = cr.height;
856+ SwingUtilities.computeIntersection
857+ (clipBounds.x, clipBounds.y,
858+ clipBounds.width, clipBounds.height, cr);
859+
860+ if(getObscuredState(i, cr.x, cr.y, cr.width,
861+ cr.height) == COMPLETELY_OBSCURED) {
862+ continue;
863+ }
864+ cr.x = x;
865+ cr.y = y;
866+ cr.width = width;
867+ cr.height = height;
868+ }
869+ Graphics cg = sg.create(cr.x, cr.y, cr.width,
870+ cr.height);
871+ cg.setColor(comp.getForeground());
872+ cg.setFont(comp.getFont());
873+ boolean shouldSetFlagBack = false;
874+ try {
875+ if(isJComponent) {
876+ if(getFlag(ANCESTOR_USING_BUFFER)) {
877+ ((JComponent)comp).setFlag(
878+ ANCESTOR_USING_BUFFER,true);
879+ shouldSetFlagBack = true;
880+ }
881+ if(getFlag(IS_PAINTING_TILE)) {
882+ ((JComponent)comp).setFlag(
883+ IS_PAINTING_TILE,true);
884+ shouldSetFlagBack = true;
885+ }
886+ if(!printing) {
887+ comp.paint(cg);
888+ }
889+ else {
890+ if (!getFlag(IS_PRINTING_ALL)) {
891+ comp.print(cg);
892+ }
893+ else {
894+ comp.printAll(cg);
895+ }
896+ }
897+ } else {
898+ // The component is either lightweight, or
899+ // heavyweight in a non-opaque window
900+ if (!printing) {
901+ comp.paint(cg);
902+ }
903+ else {
904+ if (!getFlag(IS_PRINTING_ALL)) {
905+ comp.print(cg);
906+ }
907+ else {
908+ comp.printAll(cg);
909+ }
910+ }
911+ }
912+ } finally {
913+ cg.dispose();
914+ if(shouldSetFlagBack) {
915+ ((JComponent)comp).setFlag(
916+ ANCESTOR_USING_BUFFER,false);
917+ ((JComponent)comp).setFlag(
918+ IS_PAINTING_TILE,false);
919+ }
920+ }
921+ }
922+ }
923+
924+ }
925+ recycleRectangle(tmpRect);
926+ }
927+ }
928+
929+ /**
930+ * Paints the component's border.
931+ * <p>
932+ * If you override this in a subclass you should not make permanent
933+ * changes to the passed in <code>Graphics</code>. For example, you
934+ * should not alter the clip <code>Rectangle</code> or modify the
935+ * transform. If you need to do these operations you may find it
936+ * easier to create a new <code>Graphics</code> from the passed in
937+ * <code>Graphics</code> and manipulate it.
938+ *
939+ * @param g the <code>Graphics</code> context in which to paint
940+ *
941+ * @see #paint
942+ * @see #setBorder
943+ */
944+ protected void paintBorder(Graphics g) {
945+ Border border = getBorder();
946+ if (border != null) {
947+ border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
948+ }
949+ }
950+
951+
952+ /**
953+ * Calls <code>paint</code>. Doesn't clear the background but see
954+ * <code>ComponentUI.update</code>, which is called by
955+ * <code>paintComponent</code>.
956+ *
957+ * @param g the <code>Graphics</code> context in which to paint
958+ * @see #paint
959+ * @see #paintComponent
960+ * @see javax.swing.plaf.ComponentUI
961+ */
962+ public void update(Graphics g) {
963+ paint(g);
964+ }
965+
966+
967+ /**
968+ * Invoked by Swing to draw components.
969+ * Applications should not invoke <code>paint</code> directly,
970+ * but should instead use the <code>repaint</code> method to
971+ * schedule the component for redrawing.
972+ * <p>
973+ * This method actually delegates the work of painting to three
974+ * protected methods: <code>paintComponent</code>,
975+ * <code>paintBorder</code>,
976+ * and <code>paintChildren</code>. They're called in the order
977+ * listed to ensure that children appear on top of component itself.
978+ * Generally speaking, the component and its children should not
979+ * paint in the insets area allocated to the border. Subclasses can
980+ * just override this method, as always. A subclass that just
981+ * wants to specialize the UI (look and feel) delegate's
982+ * <code>paint</code> method should just override
983+ * <code>paintComponent</code>.
984+ *
985+ * @param g the <code>Graphics</code> context in which to paint
986+ * @see #paintComponent
987+ * @see #paintBorder
988+ * @see #paintChildren
989+ * @see #getComponentGraphics
990+ * @see #repaint
991+ */
992+ public void paint(Graphics g) {
993+ boolean shouldClearPaintFlags = false;
994+
995+ if ((getWidth() <= 0) || (getHeight() <= 0)) {
996+ return;
997+ }
998+
999+ Graphics componentGraphics = getComponentGraphics(g);
1000+ Graphics co = componentGraphics.create();
1001+ try {
1002+ RepaintManager repaintManager = RepaintManager.currentManager(this);
1003+ Rectangle clipRect = co.getClipBounds();
1004+ int clipX;
1005+ int clipY;
1006+ int clipW;
1007+ int clipH;
1008+ if (clipRect == null) {
1009+ clipX = clipY = 0;
1010+ clipW = getWidth();
1011+ clipH = getHeight();
1012+ }
1013+ else {
1014+ clipX = clipRect.x;
1015+ clipY = clipRect.y;
1016+ clipW = clipRect.width;
1017+ clipH = clipRect.height;
1018+ }
1019+
1020+ if(clipW > getWidth()) {
1021+ clipW = getWidth();
1022+ }
1023+ if(clipH > getHeight()) {
1024+ clipH = getHeight();
1025+ }
1026+
1027+ if(getParent() != null && !(getParent() instanceof JComponent)) {
1028+ adjustPaintFlags();
1029+ shouldClearPaintFlags = true;
1030+ }
1031+
1032+ int bw,bh;
1033+ boolean printing = getFlag(IS_PRINTING);
1034+ if (!printing && repaintManager.isDoubleBufferingEnabled() &&
1035+ !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
1036+ (getFlag(IS_REPAINTING) || repaintManager.isPainting()))
1037+ {
1038+ repaintManager.beginPaint();
1039+ try {
1040+ repaintManager.paint(this, this, co, clipX, clipY, clipW,
1041+ clipH);
1042+ } finally {
1043+ repaintManager.endPaint();
1044+ }
1045+ }
1046+ else {
1047+ // Will ocassionaly happen in 1.2, especially when printing.
1048+ if (clipRect == null) {
1049+ co.setClip(clipX, clipY, clipW, clipH);
1050+ }
1051+
1052+ if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
1053+ if (!printing) {
1054+ paintComponent(co);
1055+ paintBorder(co);
1056+ }
1057+ else {
1058+ printComponent(co);
1059+ printBorder(co);
1060+ }
1061+ }
1062+ if (!printing) {
1063+ paintChildren(co);
1064+ }
1065+ else {
1066+ printChildren(co);
1067+ }
1068+ }
1069+ } finally {
1070+ co.dispose();
1071+ if(shouldClearPaintFlags) {
1072+ setFlag(ANCESTOR_USING_BUFFER,false);
1073+ setFlag(IS_PAINTING_TILE,false);
1074+ setFlag(IS_PRINTING,false);
1075+ setFlag(IS_PRINTING_ALL,false);
1076+ }
1077+ }
1078+ }
1079+
1080+ // paint forcing use of the double buffer. This is used for historical
1081+ // reasons: JViewport, when scrolling, previously directly invoked paint
1082+ // while turning off double buffering at the RepaintManager level, this
1083+ // codes simulates that.
1084+ void paintForceDoubleBuffered(Graphics g) {
1085+ RepaintManager rm = RepaintManager.currentManager(this);
1086+ Rectangle clip = g.getClipBounds();
1087+ rm.beginPaint();
1088+ setFlag(IS_REPAINTING, true);
1089+ try {
1090+ rm.paint(this, this, g, clip.x, clip.y, clip.width, clip.height);
1091+ } finally {
1092+ rm.endPaint();
1093+ setFlag(IS_REPAINTING, false);
1094+ }
1095+ }
1096+
1097+ /**
1098+ * Returns true if this component, or any of its ancestors, are in
1099+ * the processing of painting.
1100+ */
1101+ boolean isPainting() {
1102+ Container component = this;
1103+ while (component != null) {
1104+ if (component instanceof JComponent &&
1105+ ((JComponent)component).getFlag(ANCESTOR_USING_BUFFER)) {
1106+ return true;
1107+ }
1108+ component = component.getParent();
1109+ }
1110+ return false;
1111+ }
1112+
1113+ private void adjustPaintFlags() {
1114+ JComponent jparent;
1115+ Container parent;
1116+ for(parent = getParent() ; parent != null ; parent =
1117+ parent.getParent()) {
1118+ if(parent instanceof JComponent) {
1119+ jparent = (JComponent) parent;
1120+ if(jparent.getFlag(ANCESTOR_USING_BUFFER))
1121+ setFlag(ANCESTOR_USING_BUFFER, true);
1122+ if(jparent.getFlag(IS_PAINTING_TILE))
1123+ setFlag(IS_PAINTING_TILE, true);
1124+ if(jparent.getFlag(IS_PRINTING))
1125+ setFlag(IS_PRINTING, true);
1126+ if(jparent.getFlag(IS_PRINTING_ALL))
1127+ setFlag(IS_PRINTING_ALL, true);
1128+ break;
1129+ }
1130+ }
1131+ }
1132+
1133+ /**
1134+ * Invoke this method to print the component. This method invokes
1135+ * <code>print</code> on the component.
1136+ *
1137+ * @param g the <code>Graphics</code> context in which to paint
1138+ * @see #print
1139+ * @see #printComponent
1140+ * @see #printBorder
1141+ * @see #printChildren
1142+ */
1143+ public void printAll(Graphics g) {
1144+ setFlag(IS_PRINTING_ALL, true);
1145+ try {
1146+ print(g);
1147+ }
1148+ finally {
1149+ setFlag(IS_PRINTING_ALL, false);
1150+ }
1151+ }
1152+
1153+ /**
1154+ * Invoke this method to print the component to the specified
1155+ * <code>Graphics</code>. This method will result in invocations
1156+ * of <code>printComponent</code>, <code>printBorder</code> and
1157+ * <code>printChildren</code>. It is recommended that you override
1158+ * one of the previously mentioned methods rather than this one if
1159+ * your intention is to customize the way printing looks. However,
1160+ * it can be useful to override this method should you want to prepare
1161+ * state before invoking the superclass behavior. As an example,
1162+ * if you wanted to change the component's background color before
1163+ * printing, you could do the following:
1164+ * <pre>
1165+ * public void print(Graphics g) {
1166+ * Color orig = getBackground();
1167+ * setBackground(Color.WHITE);
1168+ *
1169+ * // wrap in try/finally so that we always restore the state
1170+ * try {
1171+ * super.print(g);
1172+ * } finally {
1173+ * setBackground(orig);
1174+ * }
1175+ * }
1176+ * </pre>
1177+ * <p>
1178+ * Alternatively, or for components that delegate painting to other objects,
1179+ * you can query during painting whether or not the component is in the
1180+ * midst of a print operation. The <code>isPaintingForPrint</code> method provides
1181+ * this ability and its return value will be changed by this method: to
1182+ * <code>true</code> immediately before rendering and to <code>false</code>
1183+ * immediately after. With each change a property change event is fired on
1184+ * this component with the name <code>"paintingForPrint"</code>.
1185+ * <p>
1186+ * This method sets the component's state such that the double buffer
1187+ * will not be used: painting will be done directly on the passed in
1188+ * <code>Graphics</code>.
1189+ *
1190+ * @param g the <code>Graphics</code> context in which to paint
1191+ * @see #printComponent
1192+ * @see #printBorder
1193+ * @see #printChildren
1194+ * @see #isPaintingForPrint
1195+ */
1196+ public void print(Graphics g) {
1197+ setFlag(IS_PRINTING, true);
1198+ firePropertyChange("paintingForPrint", false, true);
1199+ try {
1200+ paint(g);
1201+ }
1202+ finally {
1203+ setFlag(IS_PRINTING, false);
1204+ firePropertyChange("paintingForPrint", true, false);
1205+ }
1206+ }
1207+
1208+ /**
1209+ * This is invoked during a printing operation. This is implemented to
1210+ * invoke <code>paintComponent</code> on the component. Override this
1211+ * if you wish to add special painting behavior when printing.
1212+ *
1213+ * @param g the <code>Graphics</code> context in which to paint
1214+ * @see #print
1215+ * @since 1.3
1216+ */
1217+ protected void printComponent(Graphics g) {
1218+ paintComponent(g);
1219+ }
1220+
1221+ /**
1222+ * Prints this component's children. This is implemented to invoke
1223+ * <code>paintChildren</code> on the component. Override this if you
1224+ * wish to print the children differently than painting.
1225+ *
1226+ * @param g the <code>Graphics</code> context in which to paint
1227+ * @see #print
1228+ * @since 1.3
1229+ */
1230+ protected void printChildren(Graphics g) {
1231+ paintChildren(g);
1232+ }
1233+
1234+ /**
1235+ * Prints the component's border. This is implemented to invoke
1236+ * <code>paintBorder</code> on the component. Override this if you
1237+ * wish to print the border differently that it is painted.
1238+ *
1239+ * @param g the <code>Graphics</code> context in which to paint
1240+ * @see #print
1241+ * @since 1.3
1242+ */
1243+ protected void printBorder(Graphics g) {
1244+ paintBorder(g);
1245+ }
1246+
1247+ /**
1248+ * Returns true if the component is currently painting a tile.
1249+ * If this method returns true, paint will be called again for another
1250+ * tile. This method returns false if you are not painting a tile or
1251+ * if the last tile is painted.
1252+ * Use this method to keep some state you might need between tiles.
1253+ *
1254+ * @return true if the component is currently painting a tile,
1255+ * false otherwise
1256+ */
1257+ public boolean isPaintingTile() {
1258+ return getFlag(IS_PAINTING_TILE);
1259+ }
1260+
1261+ /**
1262+ * Returns <code>true</code> if the current painting operation on this
1263+ * component is part of a <code>print</code> operation. This method is
1264+ * useful when you want to customize what you print versus what you show
1265+ * on the screen.
1266+ * <p>
1267+ * You can detect changes in the value of this property by listening for
1268+ * property change events on this component with name
1269+ * <code>"paintingForPrint"</code>.
1270+ * <p>
1271+ * Note: This method provides complimentary functionality to that provided
1272+ * by other high level Swing printing APIs. However, it deals strictly with
1273+ * painting and should not be confused as providing information on higher
1274+ * level print processes. For example, a {@link javax.swing.JTable#print()}
1275+ * operation doesn't necessarily result in a continuous rendering of the
1276+ * full component, and the return value of this method can change multiple
1277+ * times during that operation. It is even possible for the component to be
1278+ * painted to the screen while the printing process is ongoing. In such a
1279+ * case, the return value of this method is <code>true</code> when, and only
1280+ * when, the table is being painted as part of the printing process.
1281+ *
1282+ * @return true if the current painting operation on this component
1283+ * is part of a print operation
1284+ * @see #print
1285+ * @since 1.6
1286+ */
1287+ public final boolean isPaintingForPrint() {
1288+ return getFlag(IS_PRINTING);
1289+ }
1290+
1291+ /**
1292+ * In release 1.4, the focus subsystem was rearchitected.
1293+ * For more information, see
1294+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1295+ * How to Use the Focus Subsystem</a>,
1296+ * a section in <em>The Java Tutorial</em>.
1297+ * <p>
1298+ * Changes this <code>JComponent</code>'s focus traversal keys to
1299+ * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
1300+ * <code>SortingFocusTraversalPolicy</code> from considering descendants
1301+ * of this JComponent when computing a focus traversal cycle.
1302+ *
1303+ * @see java.awt.Component#setFocusTraversalKeys
1304+ * @see SortingFocusTraversalPolicy
1305+ * @deprecated As of 1.4, replaced by
1306+ * <code>Component.setFocusTraversalKeys(int, Set)</code> and
1307+ * <code>Container.setFocusCycleRoot(boolean)</code>.
1308+ */
1309+ @Deprecated
1310+ public boolean isManagingFocus() {
1311+ return false;
1312+ }
1313+
1314+ private void registerNextFocusableComponent() {
1315+ registerNextFocusableComponent(getNextFocusableComponent());
1316+ }
1317+
1318+ private void registerNextFocusableComponent(Component
1319+ nextFocusableComponent) {
1320+ if (nextFocusableComponent == null) {
1321+ return;
1322+ }
1323+
1324+ Container nearestRoot =
1325+ (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1326+ FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1327+ if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) {
1328+ policy = new LegacyGlueFocusTraversalPolicy(policy);
1329+ nearestRoot.setFocusTraversalPolicy(policy);
1330+ }
1331+ ((LegacyGlueFocusTraversalPolicy)policy).
1332+ setNextFocusableComponent(this, nextFocusableComponent);
1333+ }
1334+
1335+ private void deregisterNextFocusableComponent() {
1336+ Component nextFocusableComponent = getNextFocusableComponent();
1337+ if (nextFocusableComponent == null) {
1338+ return;
1339+ }
1340+
1341+ Container nearestRoot =
1342+ (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
1343+ if (nearestRoot == null) {
1344+ return;
1345+ }
1346+ FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
1347+ if (policy instanceof LegacyGlueFocusTraversalPolicy) {
1348+ ((LegacyGlueFocusTraversalPolicy)policy).
1349+ unsetNextFocusableComponent(this, nextFocusableComponent);
1350+ }
1351+ }
1352+
1353+ /**
1354+ * In release 1.4, the focus subsystem was rearchitected.
1355+ * For more information, see
1356+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1357+ * How to Use the Focus Subsystem</a>,
1358+ * a section in <em>The Java Tutorial</em>.
1359+ * <p>
1360+ * Overrides the default <code>FocusTraversalPolicy</code> for this
1361+ * <code>JComponent</code>'s focus traversal cycle by unconditionally
1362+ * setting the specified <code>Component</code> as the next
1363+ * <code>Component</code> in the cycle, and this <code>JComponent</code>
1364+ * as the specified <code>Component</code>'s previous
1365+ * <code>Component</code> in the cycle.
1366+ *
1367+ * @param aComponent the <code>Component</code> that should follow this
1368+ * <code>JComponent</code> in the focus traversal cycle
1369+ *
1370+ * @see #getNextFocusableComponent
1371+ * @see java.awt.FocusTraversalPolicy
1372+ * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
1373+ */
1374+ @Deprecated
1375+ public void setNextFocusableComponent(Component aComponent) {
1376+ boolean displayable = isDisplayable();
1377+ if (displayable) {
1378+ deregisterNextFocusableComponent();
1379+ }
1380+ putClientProperty(NEXT_FOCUS, aComponent);
1381+ if (displayable) {
1382+ registerNextFocusableComponent(aComponent);
1383+ }
1384+ }
1385+
1386+ /**
1387+ * In release 1.4, the focus subsystem was rearchitected.
1388+ * For more information, see
1389+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1390+ * How to Use the Focus Subsystem</a>,
1391+ * a section in <em>The Java Tutorial</em>.
1392+ * <p>
1393+ * Returns the <code>Component</code> set by a prior call to
1394+ * <code>setNextFocusableComponent(Component)</code> on this
1395+ * <code>JComponent</code>.
1396+ *
1397+ * @return the <code>Component</code> that will follow this
1398+ * <code>JComponent</code> in the focus traversal cycle, or
1399+ * <code>null</code> if none has been explicitly specified
1400+ *
1401+ * @see #setNextFocusableComponent
1402+ * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
1403+ */
1404+ @Deprecated
1405+ public Component getNextFocusableComponent() {
1406+ return (Component)getClientProperty(NEXT_FOCUS);
1407+ }
1408+
1409+ /**
1410+ * Provides a hint as to whether or not this <code>JComponent</code>
1411+ * should get focus. This is only a hint, and it is up to consumers that
1412+ * are requesting focus to honor this property. This is typically honored
1413+ * for mouse operations, but not keyboard operations. For example, look
1414+ * and feels could verify this property is true before requesting focus
1415+ * during a mouse operation. This would often times be used if you did
1416+ * not want a mouse press on a <code>JComponent</code> to steal focus,
1417+ * but did want the <code>JComponent</code> to be traversable via the
1418+ * keyboard. If you do not want this <code>JComponent</code> focusable at
1419+ * all, use the <code>setFocusable</code> method instead.
1420+ * <p>
1421+ * Please see
1422+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1423+ * How to Use the Focus Subsystem</a>,
1424+ * a section in <em>The Java Tutorial</em>,
1425+ * for more information.
1426+ *
1427+ * @param requestFocusEnabled indicates whether you want this
1428+ * <code>JComponent</code> to be focusable or not
1429+ * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
1430+ * @see java.awt.Component#setFocusable
1431+ */
1432+ public void setRequestFocusEnabled(boolean requestFocusEnabled) {
1433+ setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
1434+ }
1435+
1436+ /**
1437+ * Returns <code>true</code> if this <code>JComponent</code> should
1438+ * get focus; otherwise returns <code>false</code>.
1439+ * <p>
1440+ * Please see
1441+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1442+ * How to Use the Focus Subsystem</a>,
1443+ * a section in <em>The Java Tutorial</em>,
1444+ * for more information.
1445+ *
1446+ * @return <code>true</code> if this component should get focus,
1447+ * otherwise returns <code>false</code>
1448+ * @see #setRequestFocusEnabled
1449+ * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
1450+ * Specification</a>
1451+ * @see java.awt.Component#isFocusable
1452+ */
1453+ public boolean isRequestFocusEnabled() {
1454+ return !getFlag(REQUEST_FOCUS_DISABLED);
1455+ }
1456+
1457+ /**
1458+ * Requests that this <code>Component</code> gets the input focus.
1459+ * Refer to {@link java.awt.Component#requestFocus()
1460+ * Component.requestFocus()} for a complete description of
1461+ * this method.
1462+ * <p>
1463+ * Note that the use of this method is discouraged because
1464+ * its behavior is platform dependent. Instead we recommend the
1465+ * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
1466+ * If you would like more information on focus, see
1467+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1468+ * How to Use the Focus Subsystem</a>,
1469+ * a section in <em>The Java Tutorial</em>.
1470+ *
1471+ * @see java.awt.Component#requestFocusInWindow()
1472+ * @see java.awt.Component#requestFocusInWindow(boolean)
1473+ * @since 1.4
1474+ */
1475+ public void requestFocus() {
1476+ super.requestFocus();
1477+ }
1478+
1479+ /**
1480+ * Requests that this <code>Component</code> gets the input focus.
1481+ * Refer to {@link java.awt.Component#requestFocus(boolean)
1482+ * Component.requestFocus(boolean)} for a complete description of
1483+ * this method.
1484+ * <p>
1485+ * Note that the use of this method is discouraged because
1486+ * its behavior is platform dependent. Instead we recommend the
1487+ * use of {@link #requestFocusInWindow(boolean)
1488+ * requestFocusInWindow(boolean)}.
1489+ * If you would like more information on focus, see
1490+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1491+ * How to Use the Focus Subsystem</a>,
1492+ * a section in <em>The Java Tutorial</em>.
1493+ *
1494+ * @param temporary boolean indicating if the focus change is temporary
1495+ * @return <code>false</code> if the focus change request is guaranteed to
1496+ * fail; <code>true</code> if it is likely to succeed
1497+ * @see java.awt.Component#requestFocusInWindow()
1498+ * @see java.awt.Component#requestFocusInWindow(boolean)
1499+ * @since 1.4
1500+ */
1501+ public boolean requestFocus(boolean temporary) {
1502+ return super.requestFocus(temporary);
1503+ }
1504+
1505+ /**
1506+ * Requests that this <code>Component</code> gets the input focus.
1507+ * Refer to {@link java.awt.Component#requestFocusInWindow()
1508+ * Component.requestFocusInWindow()} for a complete description of
1509+ * this method.
1510+ * <p>
1511+ * If you would like more information on focus, see
1512+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1513+ * How to Use the Focus Subsystem</a>,
1514+ * a section in <em>The Java Tutorial</em>.
1515+ *
1516+ * @return <code>false</code> if the focus change request is guaranteed to
1517+ * fail; <code>true</code> if it is likely to succeed
1518+ * @see java.awt.Component#requestFocusInWindow()
1519+ * @see java.awt.Component#requestFocusInWindow(boolean)
1520+ * @since 1.4
1521+ */
1522+ public boolean requestFocusInWindow() {
1523+ return super.requestFocusInWindow();
1524+ }
1525+
1526+ /**
1527+ * Requests that this <code>Component</code> gets the input focus.
1528+ * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
1529+ * Component.requestFocusInWindow(boolean)} for a complete description of
1530+ * this method.
1531+ * <p>
1532+ * If you would like more information on focus, see
1533+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
1534+ * How to Use the Focus Subsystem</a>,
1535+ * a section in <em>The Java Tutorial</em>.
1536+ *
1537+ * @param temporary boolean indicating if the focus change is temporary
1538+ * @return <code>false</code> if the focus change request is guaranteed to
1539+ * fail; <code>true</code> if it is likely to succeed
1540+ * @see java.awt.Component#requestFocusInWindow()
1541+ * @see java.awt.Component#requestFocusInWindow(boolean)
1542+ * @since 1.4
1543+ */
1544+ protected boolean requestFocusInWindow(boolean temporary) {
1545+ return super.requestFocusInWindow(temporary);
1546+ }
1547+
1548+ /**
1549+ * Requests that this Component get the input focus, and that this
1550+ * Component's top-level ancestor become the focused Window. This component
1551+ * must be displayable, visible, and focusable for the request to be
1552+ * granted.
1553+ * <p>
1554+ * This method is intended for use by focus implementations. Client code
1555+ * should not use this method; instead, it should use
1556+ * <code>requestFocusInWindow()</code>.
1557+ *
1558+ * @see #requestFocusInWindow()
1559+ */
1560+ public void grabFocus() {
1561+ requestFocus();
1562+ }
1563+
1564+ /**
1565+ * Sets the value to indicate whether input verifier for the
1566+ * current focus owner will be called before this component requests
1567+ * focus. The default is true. Set to false on components such as a
1568+ * Cancel button or a scrollbar, which should activate even if the
1569+ * input in the current focus owner is not "passed" by the input
1570+ * verifier for that component.
1571+ *
1572+ * @param verifyInputWhenFocusTarget value for the
1573+ * <code>verifyInputWhenFocusTarget</code> property
1574+ * @see InputVerifier
1575+ * @see #setInputVerifier
1576+ * @see #getInputVerifier
1577+ * @see #getVerifyInputWhenFocusTarget
1578+ *
1579+ * @since 1.3
1580+ * @beaninfo
1581+ * bound: true
1582+ * description: Whether the Component verifies input before accepting
1583+ * focus.
1584+ */
1585+ public void setVerifyInputWhenFocusTarget(boolean
1586+ verifyInputWhenFocusTarget) {
1587+ boolean oldVerifyInputWhenFocusTarget =
1588+ this.verifyInputWhenFocusTarget;
1589+ this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
1590+ firePropertyChange("verifyInputWhenFocusTarget",
1591+ oldVerifyInputWhenFocusTarget,
1592+ verifyInputWhenFocusTarget);
1593+ }
1594+
1595+ /**
1596+ * Returns the value that indicates whether the input verifier for the
1597+ * current focus owner will be called before this component requests
1598+ * focus.
1599+ *
1600+ * @return value of the <code>verifyInputWhenFocusTarget</code> property
1601+ *
1602+ * @see InputVerifier
1603+ * @see #setInputVerifier
1604+ * @see #getInputVerifier
1605+ * @see #setVerifyInputWhenFocusTarget
1606+ *
1607+ * @since 1.3
1608+ */
1609+ public boolean getVerifyInputWhenFocusTarget() {
1610+ return verifyInputWhenFocusTarget;
1611+ }
1612+
1613+
1614+ /**
1615+ * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
1616+ *
1617+ * @param font the font for which font metrics is to be
1618+ * obtained
1619+ * @return the font metrics for <code>font</code>
1620+ * @throws NullPointerException if <code>font</code> is null
1621+ * @since 1.5
1622+ */
1623+ public FontMetrics getFontMetrics(Font font) {
1624+ return SwingUtilities2.getFontMetrics(this, font);
1625+ }
1626+
1627+
1628+ /**
1629+ * Sets the preferred size of this component.
1630+ * If <code>preferredSize</code> is <code>null</code>, the UI will
1631+ * be asked for the preferred size.
1632+ * @beaninfo
1633+ * preferred: true
1634+ * bound: true
1635+ * description: The preferred size of the component.
1636+ */
1637+ public void setPreferredSize(Dimension preferredSize) {
1638+ super.setPreferredSize(preferredSize);
1639+ }
1640+
1641+
1642+ /**
1643+ * If the <code>preferredSize</code> has been set to a
1644+ * non-<code>null</code> value just returns it.
1645+ * If the UI delegate's <code>getPreferredSize</code>
1646+ * method returns a non <code>null</code> value then return that;
1647+ * otherwise defer to the component's layout manager.
1648+ *
1649+ * @return the value of the <code>preferredSize</code> property
1650+ * @see #setPreferredSize
1651+ * @see ComponentUI
1652+ */
1653+ @Transient
1654+ public Dimension getPreferredSize() {
1655+ if (isPreferredSizeSet()) {
1656+ return super.getPreferredSize();
1657+ }
1658+ Dimension size = null;
1659+ if (ui != null) {
1660+ size = ui.getPreferredSize(this);
1661+ }
1662+ return (size != null) ? size : super.getPreferredSize();
1663+ }
1664+
1665+
1666+ /**
1667+ * Sets the maximum size of this component to a constant
1668+ * value. Subsequent calls to <code>getMaximumSize</code> will always
1669+ * return this value; the component's UI will not be asked
1670+ * to compute it. Setting the maximum size to <code>null</code>
1671+ * restores the default behavior.
1672+ *
1673+ * @param maximumSize a <code>Dimension</code> containing the
1674+ * desired maximum allowable size
1675+ * @see #getMaximumSize
1676+ * @beaninfo
1677+ * bound: true
1678+ * description: The maximum size of the component.
1679+ */
1680+ public void setMaximumSize(Dimension maximumSize) {
1681+ super.setMaximumSize(maximumSize);
1682+ }
1683+
1684+
1685+ /**
1686+ * If the maximum size has been set to a non-<code>null</code> value
1687+ * just returns it. If the UI delegate's <code>getMaximumSize</code>
1688+ * method returns a non-<code>null</code> value then return that;
1689+ * otherwise defer to the component's layout manager.
1690+ *
1691+ * @return the value of the <code>maximumSize</code> property
1692+ * @see #setMaximumSize
1693+ * @see ComponentUI
1694+ */
1695+ @Transient
1696+ public Dimension getMaximumSize() {
1697+ if (isMaximumSizeSet()) {
1698+ return super.getMaximumSize();
1699+ }
1700+ Dimension size = null;
1701+ if (ui != null) {
1702+ size = ui.getMaximumSize(this);
1703+ }
1704+ return (size != null) ? size : super.getMaximumSize();
1705+ }
1706+
1707+
1708+ /**
1709+ * Sets the minimum size of this component to a constant
1710+ * value. Subsequent calls to <code>getMinimumSize</code> will always
1711+ * return this value; the component's UI will not be asked
1712+ * to compute it. Setting the minimum size to <code>null</code>
1713+ * restores the default behavior.
1714+ *
1715+ * @param minimumSize the new minimum size of this component
1716+ * @see #getMinimumSize
1717+ * @beaninfo
1718+ * bound: true
1719+ * description: The minimum size of the component.
1720+ */
1721+ public void setMinimumSize(Dimension minimumSize) {
1722+ super.setMinimumSize(minimumSize);
1723+ }
1724+
1725+ /**
1726+ * If the minimum size has been set to a non-<code>null</code> value
1727+ * just returns it. If the UI delegate's <code>getMinimumSize</code>
1728+ * method returns a non-<code>null</code> value then return that; otherwise
1729+ * defer to the component's layout manager.
1730+ *
1731+ * @return the value of the <code>minimumSize</code> property
1732+ * @see #setMinimumSize
1733+ * @see ComponentUI
1734+ */
1735+ @Transient
1736+ public Dimension getMinimumSize() {
1737+ if (isMinimumSizeSet()) {
1738+ return super.getMinimumSize();
1739+ }
1740+ Dimension size = null;
1741+ if (ui != null) {
1742+ size = ui.getMinimumSize(this);
1743+ }
1744+ return (size != null) ? size : super.getMinimumSize();
1745+ }
1746+
1747+ /**
1748+ * Gives the UI delegate an opportunity to define the precise
1749+ * shape of this component for the sake of mouse processing.
1750+ *
1751+ * @return true if this component logically contains x,y
1752+ * @see java.awt.Component#contains(int, int)
1753+ * @see ComponentUI
1754+ */
1755+ public boolean contains(int x, int y) {
1756+ return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
1757+ }
1758+
1759+ /**
1760+ * Sets the border of this component. The <code>Border</code> object is
1761+ * responsible for defining the insets for the component
1762+ * (overriding any insets set directly on the component) and
1763+ * for optionally rendering any border decorations within the
1764+ * bounds of those insets. Borders should be used (rather
1765+ * than insets) for creating both decorative and non-decorative
1766+ * (such as margins and padding) regions for a swing component.
1767+ * Compound borders can be used to nest multiple borders within a
1768+ * single component.
1769+ * <p>
1770+ * Although technically you can set the border on any object
1771+ * that inherits from <code>JComponent</code>, the look and
1772+ * feel implementation of many standard Swing components
1773+ * doesn't work well with user-set borders. In general,
1774+ * when you want to set a border on a standard Swing
1775+ * component other than <code>JPanel</code> or <code>JLabel</code>,
1776+ * we recommend that you put the component in a <code>JPanel</code>
1777+ * and set the border on the <code>JPanel</code>.
1778+ * <p>
1779+ * This is a bound property.
1780+ *
1781+ * @param border the border to be rendered for this component
1782+ * @see Border
1783+ * @see CompoundBorder
1784+ * @beaninfo
1785+ * bound: true
1786+ * preferred: true
1787+ * attribute: visualUpdate true
1788+ * description: The component's border.
1789+ */
1790+ public void setBorder(Border border) {
1791+ Border oldBorder = this.border;
1792+
1793+ this.border = border;
1794+ firePropertyChange("border", oldBorder, border);
1795+ if (border != oldBorder) {
1796+ if (border == null || oldBorder == null ||
1797+ !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
1798+ revalidate();
1799+ }
1800+ repaint();
1801+ }
1802+ }
1803+
1804+ /**
1805+ * Returns the border of this component or <code>null</code> if no
1806+ * border is currently set.
1807+ *
1808+ * @return the border object for this component
1809+ * @see #setBorder
1810+ */
1811+ public Border getBorder() {
1812+ return border;
1813+ }
1814+
1815+ /**
1816+ * If a border has been set on this component, returns the
1817+ * border's insets; otherwise calls <code>super.getInsets</code>.
1818+ *
1819+ * @return the value of the insets property
1820+ * @see #setBorder
1821+ */
1822+ public Insets getInsets() {
1823+ if (border != null) {
1824+ return border.getBorderInsets(this);
1825+ }
1826+ return super.getInsets();
1827+ }
1828+
1829+ /**
1830+ * Returns an <code>Insets</code> object containing this component's inset
1831+ * values. The passed-in <code>Insets</code> object will be reused
1832+ * if possible.
1833+ * Calling methods cannot assume that the same object will be returned,
1834+ * however. All existing values within this object are overwritten.
1835+ * If <code>insets</code> is null, this will allocate a new one.
1836+ *
1837+ * @param insets the <code>Insets</code> object, which can be reused
1838+ * @return the <code>Insets</code> object
1839+ * @see #getInsets
1840+ * @beaninfo
1841+ * expert: true
1842+ */
1843+ public Insets getInsets(Insets insets) {
1844+ if (insets == null) {
1845+ insets = new Insets(0, 0, 0, 0);
1846+ }
1847+ if (border != null) {
1848+ if (border instanceof AbstractBorder) {
1849+ return ((AbstractBorder)border).getBorderInsets(this, insets);
1850+ } else {
1851+ // Can't reuse border insets because the Border interface
1852+ // can't be enhanced.
1853+ return border.getBorderInsets(this);
1854+ }
1855+ } else {
1856+ // super.getInsets() always returns an Insets object with
1857+ // all of its value zeroed. No need for a new object here.
1858+ insets.left = insets.top = insets.right = insets.bottom = 0;
1859+ return insets;
1860+ }
1861+ }
1862+
1863+ /**
1864+ * Overrides <code>Container.getAlignmentY</code> to return
1865+ * the horizontal alignment.
1866+ *
1867+ * @return the value of the <code>alignmentY</code> property
1868+ * @see #setAlignmentY
1869+ * @see java.awt.Component#getAlignmentY
1870+ */
1871+ public float getAlignmentY() {
1872+ if (isAlignmentYSet) {
1873+ return alignmentY;
1874+ }
1875+ return super.getAlignmentY();
1876+ }
1877+
1878+ /**
1879+ * Sets the the horizontal alignment.
1880+ *
1881+ * @param alignmentY the new horizontal alignment
1882+ * @see #getAlignmentY
1883+ * @beaninfo
1884+ * description: The preferred vertical alignment of the component.
1885+ */
1886+ public void setAlignmentY(float alignmentY) {
1887+ this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
1888+ isAlignmentYSet = true;
1889+ }
1890+
1891+
1892+ /**
1893+ * Overrides <code>Container.getAlignmentX</code> to return
1894+ * the vertical alignment.
1895+ *
1896+ * @return the value of the <code>alignmentX</code> property
1897+ * @see #setAlignmentX
1898+ * @see java.awt.Component#getAlignmentX
1899+ */
1900+ public float getAlignmentX() {
1901+ if (isAlignmentXSet) {
1902+ return alignmentX;
1903+ }
1904+ return super.getAlignmentX();
1905+ }
1906+
1907+ /**
1908+ * Sets the the vertical alignment.
1909+ *
1910+ * @param alignmentX the new vertical alignment
1911+ * @see #getAlignmentX
1912+ * @beaninfo
1913+ * description: The preferred horizontal alignment of the component.
1914+ */
1915+ public void setAlignmentX(float alignmentX) {
1916+ this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
1917+ isAlignmentXSet = true;
1918+ }
1919+
1920+ /**
1921+ * Sets the input verifier for this component.
1922+ *
1923+ * @param inputVerifier the new input verifier
1924+ * @since 1.3
1925+ * @see InputVerifier
1926+ * @beaninfo
1927+ * bound: true
1928+ * description: The component's input verifier.
1929+ */
1930+ public void setInputVerifier(InputVerifier inputVerifier) {
1931+ InputVerifier oldInputVerifier = (InputVerifier)getClientProperty(
1932+ JComponent_INPUT_VERIFIER);
1933+ putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
1934+ firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
1935+ }
1936+
1937+ /**
1938+ * Returns the input verifier for this component.
1939+ *
1940+ * @return the <code>inputVerifier</code> property
1941+ * @since 1.3
1942+ * @see InputVerifier
1943+ */
1944+ public InputVerifier getInputVerifier() {
1945+ return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER);
1946+ }
1947+
1948+ /**
1949+ * Returns this component's graphics context, which lets you draw
1950+ * on a component. Use this method to get a <code>Graphics</code> object and
1951+ * then invoke operations on that object to draw on the component.
1952+ * @return this components graphics context
1953+ */
1954+ public Graphics getGraphics() {
1955+ if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
1956+ DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
1957+ this);
1958+ return graphics;
1959+ }
1960+ return super.getGraphics();
1961+ }
1962+
1963+
1964+ /** Enables or disables diagnostic information about every graphics
1965+ * operation performed within the component or one of its children.
1966+ *
1967+ * @param debugOptions determines how the component should display
1968+ * the information; one of the following options:
1969+ * <ul>
1970+ * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1971+ * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1972+ * times.
1973+ * <li>DebugGraphics.BUFFERED_OPTION - creates an
1974+ * <code>ExternalWindow</code> that displays the operations
1975+ * performed on the View's offscreen buffer.
1976+ * <li>DebugGraphics.NONE_OPTION disables debugging.
1977+ * <li>A value of 0 causes no changes to the debugging options.
1978+ * </ul>
1979+ * <code>debugOptions</code> is bitwise OR'd into the current value
1980+ *
1981+ * @beaninfo
1982+ * preferred: true
1983+ * enum: NONE_OPTION DebugGraphics.NONE_OPTION
1984+ * LOG_OPTION DebugGraphics.LOG_OPTION
1985+ * FLASH_OPTION DebugGraphics.FLASH_OPTION
1986+ * BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
1987+ * description: Diagnostic options for graphics operations.
1988+ */
1989+ public void setDebugGraphicsOptions(int debugOptions) {
1990+ DebugGraphics.setDebugOptions(this, debugOptions);
1991+ }
1992+
1993+ /** Returns the state of graphics debugging.
1994+ *
1995+ * @return a bitwise OR'd flag of zero or more of the following options:
1996+ * <ul>
1997+ * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
1998+ * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
1999+ * times.
2000+ * <li>DebugGraphics.BUFFERED_OPTION - creates an
2001+ * <code>ExternalWindow</code> that displays the operations
2002+ * performed on the View's offscreen buffer.
2003+ * <li>DebugGraphics.NONE_OPTION disables debugging.
2004+ * <li>A value of 0 causes no changes to the debugging options.
2005+ * </ul>
2006+ * @see #setDebugGraphicsOptions
2007+ */
2008+ public int getDebugGraphicsOptions() {
2009+ return DebugGraphics.getDebugOptions(this);
2010+ }
2011+
2012+
2013+ /**
2014+ * Returns true if debug information is enabled for this
2015+ * <code>JComponent</code> or one of its parents.
2016+ */
2017+ int shouldDebugGraphics() {
2018+ return DebugGraphics.shouldComponentDebug(this);
2019+ }
2020+
2021+ /**
2022+ * This method is now obsolete, please use a combination of
2023+ * <code>getActionMap()</code> and <code>getInputMap()</code> for
2024+ * similiar behavior. For example, to bind the <code>KeyStroke</code>
2025+ * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
2026+ * now use:
2027+ * <pre>
2028+ * component.getInputMap().put(aKeyStroke, aCommand);
2029+ * component.getActionMap().put(aCommmand, anAction);
2030+ * </pre>
2031+ * The above assumes you want the binding to be applicable for
2032+ * <code>WHEN_FOCUSED</code>. To register bindings for other focus
2033+ * states use the <code>getInputMap</code> method that takes an integer.
2034+ * <p>
2035+ * Register a new keyboard action.
2036+ * <code>anAction</code> will be invoked if a key event matching
2037+ * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
2038+ * The <code>KeyStroke</code> object defines a
2039+ * particular combination of a keyboard key and one or more modifiers
2040+ * (alt, shift, ctrl, meta).
2041+ * <p>
2042+ * The <code>aCommand</code> will be set in the delivered event if
2043+ * specified.
2044+ * <p>
2045+ * The <code>aCondition</code> can be one of:
2046+ * <blockquote>
2047+ * <DL>
2048+ * <DT>WHEN_FOCUSED
2049+ * <DD>The action will be invoked only when the keystroke occurs
2050+ * while the component has the focus.
2051+ * <DT>WHEN_IN_FOCUSED_WINDOW
2052+ * <DD>The action will be invoked when the keystroke occurs while
2053+ * the component has the focus or if the component is in the
2054+ * window that has the focus. Note that the component need not
2055+ * be an immediate descendent of the window -- it can be
2056+ * anywhere in the window's containment hierarchy. In other
2057+ * words, whenever <em>any</em> component in the window has the focus,
2058+ * the action registered with this component is invoked.
2059+ * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2060+ * <DD>The action will be invoked when the keystroke occurs while the
2061+ * component has the focus or if the component is an ancestor of
2062+ * the component that has the focus.
2063+ * </DL>
2064+ * </blockquote>
2065+ * <p>
2066+ * The combination of keystrokes and conditions lets you define high
2067+ * level (semantic) action events for a specified keystroke+modifier
2068+ * combination (using the KeyStroke class) and direct to a parent or
2069+ * child of a component that has the focus, or to the component itself.
2070+ * In other words, in any hierarchical structure of components, an
2071+ * arbitrary key-combination can be immediately directed to the
2072+ * appropriate component in the hierarchy, and cause a specific method
2073+ * to be invoked (usually by way of adapter objects).
2074+ * <p>
2075+ * If an action has already been registered for the receiving
2076+ * container, with the same charCode and the same modifiers,
2077+ * <code>anAction</code> will replace the action.
2078+ *
2079+ * @param anAction the <code>Action</code> to be registered
2080+ * @param aCommand the command to be set in the delivered event
2081+ * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
2082+ * @param aCondition the condition that needs to be met, see above
2083+ * @see KeyStroke
2084+ */
2085+ public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
2086+
2087+ InputMap inputMap = getInputMap(aCondition, true);
2088+
2089+ if (inputMap != null) {
2090+ ActionMap actionMap = getActionMap(true);
2091+ ActionStandin action = new ActionStandin(anAction, aCommand);
2092+ inputMap.put(aKeyStroke, action);
2093+ if (actionMap != null) {
2094+ actionMap.put(action, action);
2095+ }
2096+ }
2097+ }
2098+
2099+ /**
2100+ * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
2101+ * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
2102+ * is true only actions that haven't been registered are pushed
2103+ * to the <code>KeyboardManager</code>;
2104+ * otherwise all actions are pushed to the <code>KeyboardManager</code>.
2105+ *
2106+ * @param onlyIfNew if true, only actions that haven't been registered
2107+ * are pushed to the <code>KeyboardManager</code>
2108+ */
2109+ private void registerWithKeyboardManager(boolean onlyIfNew) {
2110+ InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2111+ KeyStroke[] strokes;
2112+ Hashtable<KeyStroke, KeyStroke> registered = (Hashtable)getClientProperty
2113+ (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2114+
2115+ if (inputMap != null) {
2116+ // Push any new KeyStrokes to the KeyboardManager.
2117+ strokes = inputMap.allKeys();
2118+ if (strokes != null) {
2119+ for (int counter = strokes.length - 1; counter >= 0;
2120+ counter--) {
2121+ if (!onlyIfNew || registered == null ||
2122+ registered.get(strokes[counter]) == null) {
2123+ registerWithKeyboardManager(strokes[counter]);
2124+ }
2125+ if (registered != null) {
2126+ registered.remove(strokes[counter]);
2127+ }
2128+ }
2129+ }
2130+ }
2131+ else {
2132+ strokes = null;
2133+ }
2134+ // Remove any old ones.
2135+ if (registered != null && registered.size() > 0) {
2136+ Enumeration<KeyStroke> keys = registered.keys();
2137+
2138+ while (keys.hasMoreElements()) {
2139+ KeyStroke ks = keys.nextElement();
2140+ unregisterWithKeyboardManager(ks);
2141+ }
2142+ registered.clear();
2143+ }
2144+ // Updated the registered Hashtable.
2145+ if (strokes != null && strokes.length > 0) {
2146+ if (registered == null) {
2147+ registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length);
2148+ putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
2149+ }
2150+ for (int counter = strokes.length - 1; counter >= 0; counter--) {
2151+ registered.put(strokes[counter], strokes[counter]);
2152+ }
2153+ }
2154+ else {
2155+ putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2156+ }
2157+ }
2158+
2159+ /**
2160+ * Unregisters all the previously registered
2161+ * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
2162+ */
2163+ private void unregisterWithKeyboardManager() {
2164+ Hashtable registered = (Hashtable)getClientProperty
2165+ (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
2166+
2167+ if (registered != null && registered.size() > 0) {
2168+ Enumeration keys = registered.keys();
2169+
2170+ while (keys.hasMoreElements()) {
2171+ KeyStroke ks = (KeyStroke)keys.nextElement();
2172+ unregisterWithKeyboardManager(ks);
2173+ }
2174+ }
2175+ putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
2176+ }
2177+
2178+ /**
2179+ * Invoked from <code>ComponentInputMap</code> when its bindings change.
2180+ * If <code>inputMap</code> is the current <code>windowInputMap</code>
2181+ * (or a parent of the window <code>InputMap</code>)
2182+ * the <code>KeyboardManager</code> is notified of the new bindings.
2183+ *
2184+ * @param inputMap the map containing the new bindings
2185+ */
2186+ void componentInputMapChanged(ComponentInputMap inputMap) {
2187+ InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
2188+
2189+ while (km != inputMap && km != null) {
2190+ km = km.getParent();
2191+ }
2192+ if (km != null) {
2193+ registerWithKeyboardManager(false);
2194+ }
2195+ }
2196+
2197+ private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
2198+ KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
2199+ }
2200+
2201+ private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
2202+ KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
2203+ this);
2204+ }
2205+
2206+ /**
2207+ * This method is now obsolete, please use a combination of
2208+ * <code>getActionMap()</code> and <code>getInputMap()</code> for
2209+ * similiar behavior.
2210+ */
2211+ public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
2212+ registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
2213+ }
2214+
2215+ /**
2216+ * This method is now obsolete. To unregister an existing binding
2217+ * you can either remove the binding from the
2218+ * <code>ActionMap/InputMap</code>, or place a dummy binding the
2219+ * <code>InputMap</code>. Removing the binding from the
2220+ * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
2221+ * to be active, whereas putting a dummy binding in the
2222+ * <code>InputMap</code> effectively disables
2223+ * the binding from ever happening.
2224+ * <p>
2225+ * Unregisters a keyboard action.
2226+ * This will remove the binding from the <code>ActionMap</code>
2227+ * (if it exists) as well as the <code>InputMap</code>s.
2228+ */
2229+ public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
2230+ ActionMap am = getActionMap(false);
2231+ for (int counter = 0; counter < 3; counter++) {
2232+ InputMap km = getInputMap(counter, false);
2233+ if (km != null) {
2234+ Object actionID = km.get(aKeyStroke);
2235+
2236+ if (am != null && actionID != null) {
2237+ am.remove(actionID);
2238+ }
2239+ km.remove(aKeyStroke);
2240+ }
2241+ }
2242+ }
2243+
2244+ /**
2245+ * Returns the <code>KeyStrokes</code> that will initiate
2246+ * registered actions.
2247+ *
2248+ * @return an array of <code>KeyStroke</code> objects
2249+ * @see #registerKeyboardAction
2250+ */
2251+ public KeyStroke[] getRegisteredKeyStrokes() {
2252+ int[] counts = new int[3];
2253+ KeyStroke[][] strokes = new KeyStroke[3][];
2254+
2255+ for (int counter = 0; counter < 3; counter++) {
2256+ InputMap km = getInputMap(counter, false);
2257+ strokes[counter] = (km != null) ? km.allKeys() : null;
2258+ counts[counter] = (strokes[counter] != null) ?
2259+ strokes[counter].length : 0;
2260+ }
2261+ KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] +
2262+ counts[2]];
2263+ for (int counter = 0, last = 0; counter < 3; counter++) {
2264+ if (counts[counter] > 0) {
2265+ System.arraycopy(strokes[counter], 0, retValue, last,
2266+ counts[counter]);
2267+ last += counts[counter];
2268+ }
2269+ }
2270+ return retValue;
2271+ }
2272+
2273+ /**
2274+ * Returns the condition that determines whether a registered action
2275+ * occurs in response to the specified keystroke.
2276+ * <p>
2277+ * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
2278+ * with more than one condition.
2279+ * For example, 'a' could be bound for the two
2280+ * conditions <code>WHEN_FOCUSED</code> and
2281+ * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
2282+ *
2283+ * @return the action-keystroke condition
2284+ */
2285+ public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
2286+ for (int counter = 0; counter < 3; counter++) {
2287+ InputMap inputMap = getInputMap(counter, false);
2288+ if (inputMap != null && inputMap.get(aKeyStroke) != null) {
2289+ return counter;
2290+ }
2291+ }
2292+ return UNDEFINED_CONDITION;
2293+ }
2294+
2295+ /**
2296+ * Returns the object that will perform the action registered for a
2297+ * given keystroke.
2298+ *
2299+ * @return the <code>ActionListener</code>
2300+ * object invoked when the keystroke occurs
2301+ */
2302+ public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
2303+ ActionMap am = getActionMap(false);
2304+
2305+ if (am == null) {
2306+ return null;
2307+ }
2308+ for (int counter = 0; counter < 3; counter++) {
2309+ InputMap inputMap = getInputMap(counter, false);
2310+ if (inputMap != null) {
2311+ Object actionBinding = inputMap.get(aKeyStroke);
2312+
2313+ if (actionBinding != null) {
2314+ Action action = am.get(actionBinding);
2315+ if (action instanceof ActionStandin) {
2316+ return ((ActionStandin)action).actionListener;
2317+ }
2318+ return action;
2319+ }
2320+ }
2321+ }
2322+ return null;
2323+ }
2324+
2325+ /**
2326+ * Unregisters all the bindings in the first tier <code>InputMaps</code>
2327+ * and <code>ActionMap</code>. This has the effect of removing any
2328+ * local bindings, and allowing the bindings defined in parent
2329+ * <code>InputMap/ActionMaps</code>
2330+ * (the UI is usually defined in the second tier) to persist.
2331+ */
2332+ public void resetKeyboardActions() {
2333+ // Keys
2334+ for (int counter = 0; counter < 3; counter++) {
2335+ InputMap inputMap = getInputMap(counter, false);
2336+
2337+ if (inputMap != null) {
2338+ inputMap.clear();
2339+ }
2340+ }
2341+
2342+ // Actions
2343+ ActionMap am = getActionMap(false);
2344+
2345+ if (am != null) {
2346+ am.clear();
2347+ }
2348+ }
2349+
2350+ /**
2351+ * Sets the <code>InputMap</code> to use under the condition
2352+ * <code>condition</code> to
2353+ * <code>map</code>. A <code>null</code> value implies you
2354+ * do not want any bindings to be used, even from the UI. This will
2355+ * not reinstall the UI <code>InputMap</code> (if there was one).
2356+ * <code>condition</code> has one of the following values:
2357+ * <ul>
2358+ * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
2359+ * <li><code>WHEN_FOCUSED</code>
2360+ * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
2361+ * </ul>
2362+ * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code>
2363+ * and <code>map</code> is not a <code>ComponentInputMap</code>, an
2364+ * <code>IllegalArgumentException</code> will be thrown.
2365+ * Similarly, if <code>condition</code> is not one of the values
2366+ * listed, an <code>IllegalArgumentException</code> will be thrown.
2367+ *
2368+ * @param condition one of the values listed above
2369+ * @param map the <code>InputMap</code> to use for the given condition
2370+ * @exception IllegalArgumentException if <code>condition</code> is
2371+ * <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
2372+ * is not an instance of <code>ComponentInputMap</code>; or
2373+ * if <code>condition</code> is not one of the legal values
2374+ * specified above
2375+ * @since 1.3
2376+ */
2377+ public final void setInputMap(int condition, InputMap map) {
2378+ switch (condition) {
2379+ case WHEN_IN_FOCUSED_WINDOW:
2380+ if (map != null && !(map instanceof ComponentInputMap)) {
2381+ throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
2382+ }
2383+ windowInputMap = (ComponentInputMap)map;
2384+ setFlag(WIF_INPUTMAP_CREATED, true);
2385+ registerWithKeyboardManager(false);
2386+ break;
2387+ case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2388+ ancestorInputMap = map;
2389+ setFlag(ANCESTOR_INPUTMAP_CREATED, true);
2390+ break;
2391+ case WHEN_FOCUSED:
2392+ focusInputMap = map;
2393+ setFlag(FOCUS_INPUTMAP_CREATED, true);
2394+ break;
2395+ default:
2396+ throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2397+ }
2398+ }
2399+
2400+ /**
2401+ * Returns the <code>InputMap</code> that is used during
2402+ * <code>condition</code>.
2403+ *
2404+ * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
2405+ * WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2406+ * @return the <code>InputMap</code> for the specified
2407+ * <code>condition</code>
2408+ * @since 1.3
2409+ */
2410+ public final InputMap getInputMap(int condition) {
2411+ return getInputMap(condition, true);
2412+ }
2413+
2414+ /**
2415+ * Returns the <code>InputMap</code> that is used when the
2416+ * component has focus.
2417+ * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
2418+ *
2419+ * @return the <code>InputMap</code> used when the component has focus
2420+ * @since 1.3
2421+ */
2422+ public final InputMap getInputMap() {
2423+ return getInputMap(WHEN_FOCUSED, true);
2424+ }
2425+
2426+ /**
2427+ * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
2428+ * the parent of the <code>am</code> to be the <code>ActionMap</code>
2429+ * from the UI (if there was one), it is up to the caller to have done this.
2430+ *
2431+ * @param am the new <code>ActionMap</code>
2432+ * @since 1.3
2433+ */
2434+ public final void setActionMap(ActionMap am) {
2435+ actionMap = am;
2436+ setFlag(ACTIONMAP_CREATED, true);
2437+ }
2438+
2439+ /**
2440+ * Returns the <code>ActionMap</code> used to determine what
2441+ * <code>Action</code> to fire for particular <code>KeyStroke</code>
2442+ * binding. The returned <code>ActionMap</code>, unless otherwise
2443+ * set, will have the <code>ActionMap</code> from the UI set as the parent.
2444+ *
2445+ * @return the <code>ActionMap</code> containing the key/action bindings
2446+ * @since 1.3
2447+ */
2448+ public final ActionMap getActionMap() {
2449+ return getActionMap(true);
2450+ }
2451+
2452+ /**
2453+ * Returns the <code>InputMap</code> to use for condition
2454+ * <code>condition</code>. If the <code>InputMap</code> hasn't
2455+ * been created, and <code>create</code> is
2456+ * true, it will be created.
2457+ *
2458+ * @param condition one of the following values:
2459+ * <ul>
2460+ * <li>JComponent.FOCUS_INPUTMAP_CREATED
2461+ * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2462+ * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2463+ * </ul>
2464+ * @param create if true, create the <code>InputMap</code> if it
2465+ * is not already created
2466+ * @return the <code>InputMap</code> for the given <code>condition</code>;
2467+ * if <code>create</code> is false and the <code>InputMap</code>
2468+ * hasn't been created, returns <code>null</code>
2469+ * @exception IllegalArgumentException if <code>condition</code>
2470+ * is not one of the legal values listed above
2471+ */
2472+ final InputMap getInputMap(int condition, boolean create) {
2473+ switch (condition) {
2474+ case WHEN_FOCUSED:
2475+ if (getFlag(FOCUS_INPUTMAP_CREATED)) {
2476+ return focusInputMap;
2477+ }
2478+ // Hasn't been created yet.
2479+ if (create) {
2480+ InputMap km = new InputMap();
2481+ setInputMap(condition, km);
2482+ return km;
2483+ }
2484+ break;
2485+ case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
2486+ if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
2487+ return ancestorInputMap;
2488+ }
2489+ // Hasn't been created yet.
2490+ if (create) {
2491+ InputMap km = new InputMap();
2492+ setInputMap(condition, km);
2493+ return km;
2494+ }
2495+ break;
2496+ case WHEN_IN_FOCUSED_WINDOW:
2497+ if (getFlag(WIF_INPUTMAP_CREATED)) {
2498+ return windowInputMap;
2499+ }
2500+ // Hasn't been created yet.
2501+ if (create) {
2502+ ComponentInputMap km = new ComponentInputMap(this);
2503+ setInputMap(condition, km);
2504+ return km;
2505+ }
2506+ break;
2507+ default:
2508+ throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
2509+ }
2510+ return null;
2511+ }
2512+
2513+ /**
2514+ * Finds and returns the appropriate <code>ActionMap</code>.
2515+ *
2516+ * @param create if true, create the <code>ActionMap</code> if it
2517+ * is not already created
2518+ * @return the <code>ActionMap</code> for this component; if the
2519+ * <code>create</code> flag is false and there is no
2520+ * current <code>ActionMap</code>, returns <code>null</code>
2521+ */
2522+ final ActionMap getActionMap(boolean create) {
2523+ if (getFlag(ACTIONMAP_CREATED)) {
2524+ return actionMap;
2525+ }
2526+ // Hasn't been created.
2527+ if (create) {
2528+ ActionMap am = new ActionMap();
2529+ setActionMap(am);
2530+ return am;
2531+ }
2532+ return null;
2533+ }
2534+
2535+ /**
2536+ * Returns the baseline. The baseline is measured from the top of
2537+ * the component. This method is primarily meant for
2538+ * <code>LayoutManager</code>s to align components along their
2539+ * baseline. A return value less than 0 indicates this component
2540+ * does not have a reasonable baseline and that
2541+ * <code>LayoutManager</code>s should not align this component on
2542+ * its baseline.
2543+ * <p>
2544+ * This method calls into the <code>ComponentUI</code> method of the
2545+ * same name. If this component does not have a <code>ComponentUI</code>
2546+ * -1 will be returned. If a value &gt;= 0 is
2547+ * returned, then the component has a valid baseline for any
2548+ * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
2549+ * can be used to determine how the baseline changes with size.
2550+ *
2551+ * @throws IllegalArgumentException {@inheritDoc}
2552+ * @see #getBaselineResizeBehavior
2553+ * @see java.awt.FontMetrics
2554+ * @since 1.6
2555+ */
2556+ public int getBaseline(int width, int height) {
2557+ // check size.
2558+ super.getBaseline(width, height);
2559+ if (ui != null) {
2560+ return ui.getBaseline(this, width, height);
2561+ }
2562+ return -1;
2563+ }
2564+
2565+ /**
2566+ * Returns an enum indicating how the baseline of the component
2567+ * changes as the size changes. This method is primarily meant for
2568+ * layout managers and GUI builders.
2569+ * <p>
2570+ * This method calls into the <code>ComponentUI</code> method of
2571+ * the same name. If this component does not have a
2572+ * <code>ComponentUI</code>
2573+ * <code>BaselineResizeBehavior.OTHER</code> will be
2574+ * returned. Subclasses should
2575+ * never return <code>null</code>; if the baseline can not be
2576+ * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers
2577+ * should first ask for the baseline using
2578+ * <code>getBaseline</code> and if a value &gt;= 0 is returned use
2579+ * this method. It is acceptable for this method to return a
2580+ * value other than <code>BaselineResizeBehavior.OTHER</code> even if
2581+ * <code>getBaseline</code> returns a value less than 0.
2582+ *
2583+ * @see #getBaseline(int, int)
2584+ * @since 1.6
2585+ */
2586+ public BaselineResizeBehavior getBaselineResizeBehavior() {
2587+ if (ui != null) {
2588+ return ui.getBaselineResizeBehavior(this);
2589+ }
2590+ return BaselineResizeBehavior.OTHER;
2591+ }
2592+
2593+ /**
2594+ * In release 1.4, the focus subsystem was rearchitected.
2595+ * For more information, see
2596+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
2597+ * How to Use the Focus Subsystem</a>,
2598+ * a section in <em>The Java Tutorial</em>.
2599+ * <p>
2600+ * Requests focus on this <code>JComponent</code>'s
2601+ * <code>FocusTraversalPolicy</code>'s default <code>Component</code>.
2602+ * If this <code>JComponent</code> is a focus cycle root, then its
2603+ * <code>FocusTraversalPolicy</code> is used. Otherwise, the
2604+ * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
2605+ * focus-cycle-root ancestor is used.
2606+ *
2607+ * @see java.awt.FocusTraversalPolicy#getDefaultComponent
2608+ * @deprecated As of 1.4, replaced by
2609+ * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
2610+ */
2611+ @Deprecated
2612+ public boolean requestDefaultFocus() {
2613+ Container nearestRoot =
2614+ (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
2615+ if (nearestRoot == null) {
2616+ return false;
2617+ }
2618+ Component comp = nearestRoot.getFocusTraversalPolicy().
2619+ getDefaultComponent(nearestRoot);
2620+ if (comp != null) {
2621+ comp.requestFocus();
2622+ return true;
2623+ } else {
2624+ return false;
2625+ }
2626+ }
2627+
2628+ /**
2629+ * Makes the component visible or invisible.
2630+ * Overrides <code>Component.setVisible</code>.
2631+ *
2632+ * @param aFlag true to make the component visible; false to
2633+ * make it invisible
2634+ *
2635+ * @beaninfo
2636+ * attribute: visualUpdate true
2637+ */
2638+ public void setVisible(boolean aFlag) {
2639+ if(aFlag != isVisible()) {
2640+ super.setVisible(aFlag);
2641+ Container parent = getParent();
2642+ if(parent != null) {
2643+ Rectangle r = getBounds();
2644+ parent.repaint(r.x,r.y,r.width,r.height);
2645+ }
2646+ // Some (all should) LayoutManagers do not consider components
2647+ // that are not visible. As such we need to revalidate when the
2648+ // visible bit changes.
2649+ revalidate();
2650+ }
2651+ }
2652+
2653+ /**
2654+ * Sets whether or not this component is enabled.
2655+ * A component that is enabled may respond to user input,
2656+ * while a component that is not enabled cannot respond to
2657+ * user input. Some components may alter their visual
2658+ * representation when they are disabled in order to
2659+ * provide feedback to the user that they cannot take input.
2660+ * <p>Note: Disabling a component does not disable its children.
2661+ *
2662+ * <p>Note: Disabling a lightweight component does not prevent it from
2663+ * receiving MouseEvents.
2664+ *
2665+ * @param enabled true if this component should be enabled, false otherwise
2666+ * @see java.awt.Component#isEnabled
2667+ * @see java.awt.Component#isLightweight
2668+ *
2669+ * @beaninfo
2670+ * preferred: true
2671+ * bound: true
2672+ * attribute: visualUpdate true
2673+ * description: The enabled state of the component.
2674+ */
2675+ public void setEnabled(boolean enabled) {
2676+ boolean oldEnabled = isEnabled();
2677+ super.setEnabled(enabled);
2678+ firePropertyChange("enabled", oldEnabled, enabled);
2679+ if (enabled != oldEnabled) {
2680+ repaint();
2681+ }
2682+ }
2683+
2684+ /**
2685+ * Sets the foreground color of this component. It is up to the
2686+ * look and feel to honor this property, some may choose to ignore
2687+ * it.
2688+ *
2689+ * @param fg the desired foreground <code>Color</code>
2690+ * @see java.awt.Component#getForeground
2691+ *
2692+ * @beaninfo
2693+ * preferred: true
2694+ * bound: true
2695+ * attribute: visualUpdate true
2696+ * description: The foreground color of the component.
2697+ */
2698+ public void setForeground(Color fg) {
2699+ Color oldFg = getForeground();
2700+ super.setForeground(fg);
2701+ if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
2702+ // foreground already bound in AWT1.2
2703+ repaint();
2704+ }
2705+ }
2706+
2707+ /**
2708+ * Sets the background color of this component. The background
2709+ * color is used only if the component is opaque, and only
2710+ * by subclasses of <code>JComponent</code> or
2711+ * <code>ComponentUI</code> implementations. Direct subclasses of
2712+ * <code>JComponent</code> must override
2713+ * <code>paintComponent</code> to honor this property.
2714+ * <p>
2715+ * It is up to the look and feel to honor this property, some may
2716+ * choose to ignore it.
2717+ *
2718+ * @param bg the desired background <code>Color</code>
2719+ * @see java.awt.Component#getBackground
2720+ * @see #setOpaque
2721+ *
2722+ * @beaninfo
2723+ * preferred: true
2724+ * bound: true
2725+ * attribute: visualUpdate true
2726+ * description: The background color of the component.
2727+ */
2728+ public void setBackground(Color bg) {
2729+ Color oldBg = getBackground();
2730+ super.setBackground(bg);
2731+ if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) {
2732+ // background already bound in AWT1.2
2733+ repaint();
2734+ }
2735+ }
2736+
2737+ /**
2738+ * Sets the font for this component.
2739+ *
2740+ * @param font the desired <code>Font</code> for this component
2741+ * @see java.awt.Component#getFont
2742+ *
2743+ * @beaninfo
2744+ * preferred: true
2745+ * bound: true
2746+ * attribute: visualUpdate true
2747+ * description: The font for the component.
2748+ */
2749+ public void setFont(Font font) {
2750+ Font oldFont = getFont();
2751+ super.setFont(font);
2752+ // font already bound in AWT1.2
2753+ if (font != oldFont) {
2754+ revalidate();
2755+ repaint();
2756+ }
2757+ }
2758+
2759+ /**
2760+ * Returns the default locale used to initialize each JComponent's
2761+ * locale property upon creation.
2762+ *
2763+ * The default locale has "AppContext" scope so that applets (and
2764+ * potentially multiple lightweight applications running in a single VM)
2765+ * can have their own setting. An applet can safely alter its default
2766+ * locale because it will have no affect on other applets (or the browser).
2767+ *
2768+ * @return the default <code>Locale</code>.
2769+ * @see #setDefaultLocale
2770+ * @see java.awt.Component#getLocale
2771+ * @see #setLocale
2772+ * @since 1.4
2773+ */
2774+ static public Locale getDefaultLocale() {
2775+ Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale);
2776+ if( l == null ) {
2777+ //REMIND(bcb) choosing the default value is more complicated
2778+ //than this.
2779+ l = Locale.getDefault();
2780+ JComponent.setDefaultLocale( l );
2781+ }
2782+ return l;
2783+ }
2784+
2785+
2786+ /**
2787+ * Sets the default locale used to initialize each JComponent's locale
2788+ * property upon creation. The initial value is the VM's default locale.
2789+ *
2790+ * The default locale has "AppContext" scope so that applets (and
2791+ * potentially multiple lightweight applications running in a single VM)
2792+ * can have their own setting. An applet can safely alter its default
2793+ * locale because it will have no affect on other applets (or the browser).
2794+ *
2795+ * @param l the desired default <code>Locale</code> for new components.
2796+ * @see #getDefaultLocale
2797+ * @see java.awt.Component#getLocale
2798+ * @see #setLocale
2799+ * @since 1.4
2800+ */
2801+ static public void setDefaultLocale( Locale l ) {
2802+ SwingUtilities.appContextPut(defaultLocale, l);
2803+ }
2804+
2805+
2806+ /**
2807+ * Processes any key events that the component itself
2808+ * recognizes. This is called after the focus
2809+ * manager and any interested listeners have been
2810+ * given a chance to steal away the event. This
2811+ * method is called only if the event has not
2812+ * yet been consumed. This method is called prior
2813+ * to the keyboard UI logic.
2814+ * <p>
2815+ * This method is implemented to do nothing. Subclasses would
2816+ * normally override this method if they process some
2817+ * key events themselves. If the event is processed,
2818+ * it should be consumed.
2819+ */
2820+ protected void processComponentKeyEvent(KeyEvent e) {
2821+ }
2822+
2823+ /** Overrides <code>processKeyEvent</code> to process events. **/
2824+ protected void processKeyEvent(KeyEvent e) {
2825+ boolean result;
2826+ boolean shouldProcessKey;
2827+
2828+ // This gives the key event listeners a crack at the event
2829+ super.processKeyEvent(e);
2830+
2831+ // give the component itself a crack at the event
2832+ if (! e.isConsumed()) {
2833+ processComponentKeyEvent(e);
2834+ }
2835+
2836+ shouldProcessKey = KeyboardState.shouldProcess(e);
2837+
2838+ if(e.isConsumed()) {
2839+ return;
2840+ }
2841+
2842+ if (shouldProcessKey && processKeyBindings(e, e.getID() ==
2843+ KeyEvent.KEY_PRESSED)) {
2844+ e.consume();
2845+ }
2846+ }
2847+
2848+ /**
2849+ * Invoked to process the key bindings for <code>ks</code> as the result
2850+ * of the <code>KeyEvent</code> <code>e</code>. This obtains
2851+ * the appropriate <code>InputMap</code>,
2852+ * gets the binding, gets the action from the <code>ActionMap</code>,
2853+ * and then (if the action is found and the component
2854+ * is enabled) invokes <code>notifyAction</code> to notify the action.
2855+ *
2856+ * @param ks the <code>KeyStroke</code> queried
2857+ * @param e the <code>KeyEvent</code>
2858+ * @param condition one of the following values:
2859+ * <ul>
2860+ * <li>JComponent.WHEN_FOCUSED
2861+ * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
2862+ * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
2863+ * </ul>
2864+ * @param pressed true if the key is pressed
2865+ * @return true if there was a binding to an action, and the action
2866+ * was enabled
2867+ *
2868+ * @since 1.3
2869+ */
2870+ protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
2871+ int condition, boolean pressed) {
2872+ InputMap map = getInputMap(condition, false);
2873+ ActionMap am = getActionMap(false);
2874+
2875+ if(map != null && am != null && isEnabled()) {
2876+ Object binding = map.get(ks);
2877+ Action action = (binding == null) ? null : am.get(binding);
2878+ if (action != null) {
2879+ return SwingUtilities.notifyAction(action, ks, e, this,
2880+ e.getModifiers());
2881+ }
2882+ }
2883+ return false;
2884+ }
2885+
2886+ /**
2887+ * This is invoked as the result of a <code>KeyEvent</code>
2888+ * that was not consumed by the <code>FocusManager</code>,
2889+ * <code>KeyListeners</code>, or the component. It will first try
2890+ * <code>WHEN_FOCUSED</code> bindings,
2891+ * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
2892+ * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
2893+ *
2894+ * @param e the unconsumed <code>KeyEvent</code>
2895+ * @param pressed true if the key is pressed
2896+ * @return true if there is a key binding for <code>e</code>
2897+ */
2898+ boolean processKeyBindings(KeyEvent e, boolean pressed) {
2899+ if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
2900+ return false;
2901+ }
2902+ // Get the KeyStroke
2903+ // There may be two keystrokes associated with a low-level key event;
2904+ // in this case a keystroke made of an extended key code has a priority.
2905+ KeyStroke ks;
2906+ KeyStroke ksE = null;
2907+
2908+ if (e.getID() == KeyEvent.KEY_TYPED) {
2909+ ks = KeyStroke.getKeyStroke(e.getKeyChar());
2910+ }
2911+ else {
2912+ ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
2913+ (pressed ? false:true));
2914+ if (e.getKeyCode() != e.getExtendedKeyCode()) {
2915+ ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
2916+ (pressed ? false:true));
2917+ }
2918+ }
2919+
2920+ // Do we have a key binding for e?
2921+ // If we have a binding by an extended code, use it.
2922+ // If not, check for regular code binding.
2923+ if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
2924+ return true;
2925+ }
2926+ if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
2927+ return true;
2928+
2929+ /* We have no key binding. Let's try the path from our parent to the
2930+ * window excluded. We store the path components so we can avoid
2931+ * asking the same component twice.
2932+ */
2933+ Container parent = this;
2934+ while (parent != null && !(parent instanceof Window) &&
2935+ !(parent instanceof Applet)) {
2936+ if(parent instanceof JComponent) {
2937+ if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
2938+ WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2939+ return true;
2940+ if(((JComponent)parent).processKeyBinding(ks, e,
2941+ WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
2942+ return true;
2943+ }
2944+ // This is done so that the children of a JInternalFrame are
2945+ // given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
2946+ // other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
2947+ // more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
2948+ // JInternalFrame's children vs the
2949+ // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
2950+ // maybe generalize from JInternalFrame (like isFocusCycleRoot).
2951+ if ((parent instanceof JInternalFrame) &&
2952+ JComponent.processKeyBindingsForAllComponents(e,parent,pressed)){
2953+ return true;
2954+ }
2955+ parent = parent.getParent();
2956+ }
2957+
2958+ /* No components between the focused component and the window is
2959+ * actually interested by the key event. Let's try the other
2960+ * JComponent in this window.
2961+ */
2962+ if(parent != null) {
2963+ return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
2964+ }
2965+ return false;
2966+ }
2967+
2968+ static boolean processKeyBindingsForAllComponents(KeyEvent e,
2969+ Container container, boolean pressed) {
2970+ while (true) {
2971+ if (KeyboardManager.getCurrentManager().fireKeyboardAction(
2972+ e, pressed, container)) {
2973+ return true;
2974+ }
2975+ if (container instanceof Popup.HeavyWeightWindow) {
2976+ container = ((Window)container).getOwner();
2977+ }
2978+ else {
2979+ return false;
2980+ }
2981+ }
2982+ }
2983+
2984+ /**
2985+ * Registers the text to display in a tool tip.
2986+ * The text displays when the cursor lingers over the component.
2987+ * <p>
2988+ * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
2989+ * in <em>The Java Tutorial</em>
2990+ * for further documentation.
2991+ *
2992+ * @param text the string to display; if the text is <code>null</code>,
2993+ * the tool tip is turned off for this component
2994+ * @see #TOOL_TIP_TEXT_KEY
2995+ * @beaninfo
2996+ * preferred: true
2997+ * description: The text to display in a tool tip.
2998+ */
2999+ public void setToolTipText(String text) {
3000+ String oldText = getToolTipText();
3001+ putClientProperty(TOOL_TIP_TEXT_KEY, text);
3002+ ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
3003+ if (text != null) {
3004+ if (oldText == null) {
3005+ toolTipManager.registerComponent(this);
3006+ }
3007+ } else {
3008+ toolTipManager.unregisterComponent(this);
3009+ }
3010+ }
3011+
3012+ /**
3013+ * Returns the tooltip string that has been set with
3014+ * <code>setToolTipText</code>.
3015+ *
3016+ * @return the text of the tool tip
3017+ * @see #TOOL_TIP_TEXT_KEY
3018+ */
3019+ public String getToolTipText() {
3020+ return (String)getClientProperty(TOOL_TIP_TEXT_KEY);
3021+ }
3022+
3023+
3024+ /**
3025+ * Returns the string to be used as the tooltip for <i>event</i>.
3026+ * By default this returns any string set using
3027+ * <code>setToolTipText</code>. If a component provides
3028+ * more extensive API to support differing tooltips at different locations,
3029+ * this method should be overridden.
3030+ */
3031+ public String getToolTipText(MouseEvent event) {
3032+ return getToolTipText();
3033+ }
3034+
3035+ /**
3036+ * Returns the tooltip location in this component's coordinate system.
3037+ * If <code>null</code> is returned, Swing will choose a location.
3038+ * The default implementation returns <code>null</code>.
3039+ *
3040+ * @param event the <code>MouseEvent</code> that caused the
3041+ * <code>ToolTipManager</code> to show the tooltip
3042+ * @return always returns <code>null</code>
3043+ */
3044+ public Point getToolTipLocation(MouseEvent event) {
3045+ return null;
3046+ }
3047+
3048+ /**
3049+ * Returns the preferred location to display the popup menu in this
3050+ * component's coordinate system. It is up to the look and feel to
3051+ * honor this property, some may choose to ignore it.
3052+ * If {@code null}, the look and feel will choose a suitable location.
3053+ *
3054+ * @param event the {@code MouseEvent} that triggered the popup to be
3055+ * shown, or {@code null} if the popup is not being shown as the
3056+ * result of a mouse event
3057+ * @return location to display the {@code JPopupMenu}, or {@code null}
3058+ * @since 1.5
3059+ */
3060+ public Point getPopupLocation(MouseEvent event) {
3061+ return null;
3062+ }
3063+
3064+
3065+ /**
3066+ * Returns the instance of <code>JToolTip</code> that should be used
3067+ * to display the tooltip.
3068+ * Components typically would not override this method,
3069+ * but it can be used to
3070+ * cause different tooltips to be displayed differently.
3071+ *
3072+ * @return the <code>JToolTip</code> used to display this toolTip
3073+ */
3074+ public JToolTip createToolTip() {
3075+ JToolTip tip = new JToolTip();
3076+ tip.setComponent(this);
3077+ return tip;
3078+ }
3079+
3080+ /**
3081+ * Forwards the <code>scrollRectToVisible()</code> message to the
3082+ * <code>JComponent</code>'s parent. Components that can service
3083+ * the request, such as <code>JViewport</code>,
3084+ * override this method and perform the scrolling.
3085+ *
3086+ * @param aRect the visible <code>Rectangle</code>
3087+ * @see JViewport
3088+ */
3089+ public void scrollRectToVisible(Rectangle aRect) {
3090+ Container parent;
3091+ int dx = getX(), dy = getY();
3092+
3093+ for (parent = getParent();
3094+ !(parent == null) &&
3095+ !(parent instanceof JComponent) &&
3096+ !(parent instanceof CellRendererPane);
3097+ parent = parent.getParent()) {
3098+ Rectangle bounds = parent.getBounds();
3099+
3100+ dx += bounds.x;
3101+ dy += bounds.y;
3102+ }
3103+
3104+ if (!(parent == null) && !(parent instanceof CellRendererPane)) {
3105+ aRect.x += dx;
3106+ aRect.y += dy;
3107+
3108+ ((JComponent)parent).scrollRectToVisible(aRect);
3109+ aRect.x -= dx;
3110+ aRect.y -= dy;
3111+ }
3112+ }
3113+
3114+ /**
3115+ * Sets the <code>autoscrolls</code> property.
3116+ * If <code>true</code> mouse dragged events will be
3117+ * synthetically generated when the mouse is dragged
3118+ * outside of the component's bounds and mouse motion
3119+ * has paused (while the button continues to be held
3120+ * down). The synthetic events make it appear that the
3121+ * drag gesture has resumed in the direction established when
3122+ * the component's boundary was crossed. Components that
3123+ * support autoscrolling must handle <code>mouseDragged</code>
3124+ * events by calling <code>scrollRectToVisible</code> with a
3125+ * rectangle that contains the mouse event's location. All of
3126+ * the Swing components that support item selection and are
3127+ * typically displayed in a <code>JScrollPane</code>
3128+ * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
3129+ * <code>JTextArea</code>, and <code>JEditorPane</code>)
3130+ * already handle mouse dragged events in this way. To enable
3131+ * autoscrolling in any other component, add a mouse motion
3132+ * listener that calls <code>scrollRectToVisible</code>.
3133+ * For example, given a <code>JPanel</code>, <code>myPanel</code>:
3134+ * <pre>
3135+ * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
3136+ * public void mouseDragged(MouseEvent e) {
3137+ * Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
3138+ * ((JPanel)e.getSource()).scrollRectToVisible(r);
3139+ * }
3140+ * };
3141+ * myPanel.addMouseMotionListener(doScrollRectToVisible);
3142+ * </pre>
3143+ * The default value of the <code>autoScrolls</code>
3144+ * property is <code>false</code>.
3145+ *
3146+ * @param autoscrolls if true, synthetic mouse dragged events
3147+ * are generated when the mouse is dragged outside of a component's
3148+ * bounds and the mouse button continues to be held down; otherwise
3149+ * false
3150+ * @see #getAutoscrolls
3151+ * @see JViewport
3152+ * @see JScrollPane
3153+ *
3154+ * @beaninfo
3155+ * expert: true
3156+ * description: Determines if this component automatically scrolls its contents when dragged.
3157+ */
3158+ public void setAutoscrolls(boolean autoscrolls) {
3159+ setFlag(AUTOSCROLLS_SET, true);
3160+ if (this.autoscrolls != autoscrolls) {
3161+ this.autoscrolls = autoscrolls;
3162+ if (autoscrolls) {
3163+ enableEvents(AWTEvent.MOUSE_EVENT_MASK);
3164+ enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
3165+ }
3166+ else {
3167+ Autoscroller.stop(this);
3168+ }
3169+ }
3170+ }
3171+
3172+ /**
3173+ * Gets the <code>autoscrolls</code> property.
3174+ *
3175+ * @return the value of the <code>autoscrolls</code> property
3176+ * @see JViewport
3177+ * @see #setAutoscrolls
3178+ */
3179+ public boolean getAutoscrolls() {
3180+ return autoscrolls;
3181+ }
3182+
3183+ /**
3184+ * Sets the {@code TransferHandler}, which provides support for transfer
3185+ * of data into and out of this component via cut/copy/paste and drag
3186+ * and drop. This may be {@code null} if the component does not support
3187+ * data transfer operations.
3188+ * <p>
3189+ * If the new {@code TransferHandler} is not {@code null}, this method
3190+ * also installs a <b>new</b> {@code DropTarget} on the component to
3191+ * activate drop handling through the {@code TransferHandler} and activate
3192+ * any built-in support (such as calculating and displaying potential drop
3193+ * locations). If you do not wish for this component to respond in any way
3194+ * to drops, you can disable drop support entirely either by removing the
3195+ * drop target ({@code setDropTarget(null)}) or by de-activating it
3196+ * ({@code getDropTaget().setActive(false)}).
3197+ * <p>
3198+ * If the new {@code TransferHandler} is {@code null}, this method removes
3199+ * the drop target.
3200+ * <p>
3201+ * Under two circumstances, this method does not modify the drop target:
3202+ * First, if the existing drop target on this component was explicitly
3203+ * set by the developer to a {@code non-null} value. Second, if the
3204+ * system property {@code suppressSwingDropSupport} is {@code true}. The
3205+ * default value for the system property is {@code false}.
3206+ * <p>
3207+ * Please see
3208+ * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
3209+ * How to Use Drag and Drop and Data Transfer</a>,
3210+ * a section in <em>The Java Tutorial</em>, for more information.
3211+ *
3212+ * @param newHandler the new {@code TransferHandler}
3213+ *
3214+ * @see TransferHandler
3215+ * @see #getTransferHandler
3216+ * @since 1.4
3217+ * @beaninfo
3218+ * bound: true
3219+ * hidden: true
3220+ * description: Mechanism for transfer of data to and from the component
3221+ */
3222+ public void setTransferHandler(TransferHandler newHandler) {
3223+ TransferHandler oldHandler = (TransferHandler)getClientProperty(
3224+ JComponent_TRANSFER_HANDLER);
3225+ putClientProperty(JComponent_TRANSFER_HANDLER, newHandler);
3226+
3227+ SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler);
3228+ firePropertyChange("transferHandler", oldHandler, newHandler);
3229+ }
3230+
3231+ /**
3232+ * Gets the <code>transferHandler</code> property.
3233+ *
3234+ * @return the value of the <code>transferHandler</code> property
3235+ *
3236+ * @see TransferHandler
3237+ * @see #setTransferHandler
3238+ * @since 1.4
3239+ */
3240+ public TransferHandler getTransferHandler() {
3241+ return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER);
3242+ }
3243+
3244+ /**
3245+ * Calculates a custom drop location for this type of component,
3246+ * representing where a drop at the given point should insert data.
3247+ * <code>null</code> is returned if this component doesn't calculate
3248+ * custom drop locations. In this case, <code>TransferHandler</code>
3249+ * will provide a default <code>DropLocation</code> containing just
3250+ * the point.
3251+ *
3252+ * @param p the point to calculate a drop location for
3253+ * @return the drop location, or <code>null</code>
3254+ */
3255+ TransferHandler.DropLocation dropLocationForPoint(Point p) {
3256+ return null;
3257+ }
3258+
3259+ /**
3260+ * Called to set or clear the drop location during a DnD operation.
3261+ * In some cases, the component may need to use its internal selection
3262+ * temporarily to indicate the drop location. To help facilitate this,
3263+ * this method returns and accepts as a parameter a state object.
3264+ * This state object can be used to store, and later restore, the selection
3265+ * state. Whatever this method returns will be passed back to it in
3266+ * future calls, as the state parameter. If it wants the DnD system to
3267+ * continue storing the same state, it must pass it back every time.
3268+ * Here's how this is used:
3269+ * <p>
3270+ * Let's say that on the first call to this method the component decides
3271+ * to save some state (because it is about to use the selection to show
3272+ * a drop index). It can return a state object to the caller encapsulating
3273+ * any saved selection state. On a second call, let's say the drop location
3274+ * is being changed to something else. The component doesn't need to
3275+ * restore anything yet, so it simply passes back the same state object
3276+ * to have the DnD system continue storing it. Finally, let's say this
3277+ * method is messaged with <code>null</code>. This means DnD
3278+ * is finished with this component for now, meaning it should restore
3279+ * state. At this point, it can use the state parameter to restore
3280+ * said state, and of course return <code>null</code> since there's
3281+ * no longer anything to store.
3282+ *
3283+ * @param location the drop location (as calculated by
3284+ * <code>dropLocationForPoint</code>) or <code>null</code>
3285+ * if there's no longer a valid drop location
3286+ * @param state the state object saved earlier for this component,
3287+ * or <code>null</code>
3288+ * @param forDrop whether or not the method is being called because an
3289+ * actual drop occurred
3290+ * @return any saved state for this component, or <code>null</code> if none
3291+ */
3292+ Object setDropLocation(TransferHandler.DropLocation location,
3293+ Object state,
3294+ boolean forDrop) {
3295+
3296+ return null;
3297+ }
3298+
3299+ /**
3300+ * Called to indicate to this component that DnD is done.
3301+ * Needed by <code>JTree</code>.
3302+ */
3303+ void dndDone() {
3304+ }
3305+
3306+ /**
3307+ * Processes mouse events occurring on this component by
3308+ * dispatching them to any registered
3309+ * <code>MouseListener</code> objects, refer to
3310+ * {@link java.awt.Component#processMouseEvent(MouseEvent)}
3311+ * for a complete description of this method.
3312+ *
3313+ * @param e the mouse event
3314+ * @see java.awt.Component#processMouseEvent
3315+ * @since 1.5
3316+ */
3317+ protected void processMouseEvent(MouseEvent e) {
3318+ if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
3319+ Autoscroller.stop(this);
3320+ }
3321+ super.processMouseEvent(e);
3322+ }
3323+
3324+ /**
3325+ * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
3326+ *
3327+ * @param e the <code>MouseEvent</code>
3328+ * @see MouseEvent
3329+ */
3330+ protected void processMouseMotionEvent(MouseEvent e) {
3331+ boolean dispatch = true;
3332+ if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
3333+ // We don't want to do the drags when the mouse moves if we're
3334+ // autoscrolling. It makes it feel spastic.
3335+ dispatch = !Autoscroller.isRunning(this);
3336+ Autoscroller.processMouseDragged(e);
3337+ }
3338+ if (dispatch) {
3339+ super.processMouseMotionEvent(e);
3340+ }
3341+ }
3342+
3343+ // Inner classes can't get at this method from a super class
3344+ void superProcessMouseMotionEvent(MouseEvent e) {
3345+ super.processMouseMotionEvent(e);
3346+ }
3347+
3348+ /**
3349+ * This is invoked by the <code>RepaintManager</code> if
3350+ * <code>createImage</code> is called on the component.
3351+ *
3352+ * @param newValue true if the double buffer image was created from this component
3353+ */
3354+ void setCreatedDoubleBuffer(boolean newValue) {
3355+ setFlag(CREATED_DOUBLE_BUFFER, newValue);
3356+ }
3357+
3358+ /**
3359+ * Returns true if the <code>RepaintManager</code>
3360+ * created the double buffer image from the component.
3361+ *
3362+ * @return true if this component had a double buffer image, false otherwise
3363+ */
3364+ boolean getCreatedDoubleBuffer() {
3365+ return getFlag(CREATED_DOUBLE_BUFFER);
3366+ }
3367+
3368+ /**
3369+ * <code>ActionStandin</code> is used as a standin for
3370+ * <code>ActionListeners</code> that are
3371+ * added via <code>registerKeyboardAction</code>.
3372+ */
3373+ final class ActionStandin implements Action {
3374+ private final ActionListener actionListener;
3375+ private final String command;
3376+ // This will be non-null if actionListener is an Action.
3377+ private final Action action;
3378+
3379+ ActionStandin(ActionListener actionListener, String command) {
3380+ this.actionListener = actionListener;
3381+ if (actionListener instanceof Action) {
3382+ this.action = (Action)actionListener;
3383+ }
3384+ else {
3385+ this.action = null;
3386+ }
3387+ this.command = command;
3388+ }
3389+
3390+ public Object getValue(String key) {
3391+ if (key != null) {
3392+ if (key.equals(Action.ACTION_COMMAND_KEY)) {
3393+ return command;
3394+ }
3395+ if (action != null) {
3396+ return action.getValue(key);
3397+ }
3398+ if (key.equals(NAME)) {
3399+ return "ActionStandin";
3400+ }
3401+ }
3402+ return null;
3403+ }
3404+
3405+ public boolean isEnabled() {
3406+ if (actionListener == null) {
3407+ // This keeps the old semantics where
3408+ // registerKeyboardAction(null) would essentialy remove
3409+ // the binding. We don't remove the binding from the
3410+ // InputMap as that would still allow parent InputMaps
3411+ // bindings to be accessed.
3412+ return false;
3413+ }
3414+ if (action == null) {
3415+ return true;
3416+ }
3417+ return action.isEnabled();
3418+ }
3419+
3420+ public void actionPerformed(ActionEvent ae) {
3421+ if (actionListener != null) {
3422+ actionListener.actionPerformed(ae);
3423+ }
3424+ }
3425+
3426+ // We don't allow any values to be added.
3427+ public void putValue(String key, Object value) {}
3428+
3429+ // Does nothing, our enabledness is determiend from our asociated
3430+ // action.
3431+ public void setEnabled(boolean b) { }
3432+
3433+ public void addPropertyChangeListener
3434+ (PropertyChangeListener listener) {}
3435+ public void removePropertyChangeListener
3436+ (PropertyChangeListener listener) {}
3437+ }
3438+
3439+
3440+ // This class is used by the KeyboardState class to provide a single
3441+ // instance that can be stored in the AppContext.
3442+ static final class IntVector {
3443+ int array[] = null;
3444+ int count = 0;
3445+ int capacity = 0;
3446+
3447+ int size() {
3448+ return count;
3449+ }
3450+
3451+ int elementAt(int index) {
3452+ return array[index];
3453+ }
3454+
3455+ void addElement(int value) {
3456+ if (count == capacity) {
3457+ capacity = (capacity + 2) * 2;
3458+ int[] newarray = new int[capacity];
3459+ if (count > 0) {
3460+ System.arraycopy(array, 0, newarray, 0, count);
3461+ }
3462+ array = newarray;
3463+ }
3464+ array[count++] = value;
3465+ }
3466+
3467+ void setElementAt(int value, int index) {
3468+ array[index] = value;
3469+ }
3470+ }
3471+
3472+ static class KeyboardState implements Serializable {
3473+ private static final Object keyCodesKey =
3474+ JComponent.KeyboardState.class;
3475+
3476+ // Get the array of key codes from the AppContext.
3477+ static IntVector getKeyCodeArray() {
3478+ IntVector iv =
3479+ (IntVector)SwingUtilities.appContextGet(keyCodesKey);
3480+ if (iv == null) {
3481+ iv = new IntVector();
3482+ SwingUtilities.appContextPut(keyCodesKey, iv);
3483+ }
3484+ return iv;
3485+ }
3486+
3487+ static void registerKeyPressed(int keyCode) {
3488+ IntVector kca = getKeyCodeArray();
3489+ int count = kca.size();
3490+ int i;
3491+ for(i=0;i<count;i++) {
3492+ if(kca.elementAt(i) == -1){
3493+ kca.setElementAt(keyCode, i);
3494+ return;
3495+ }
3496+ }
3497+ kca.addElement(keyCode);
3498+ }
3499+
3500+ static void registerKeyReleased(int keyCode) {
3501+ IntVector kca = getKeyCodeArray();
3502+ int count = kca.size();
3503+ int i;
3504+ for(i=0;i<count;i++) {
3505+ if(kca.elementAt(i) == keyCode) {
3506+ kca.setElementAt(-1, i);
3507+ return;
3508+ }
3509+ }
3510+ }
3511+
3512+ static boolean keyIsPressed(int keyCode) {
3513+ IntVector kca = getKeyCodeArray();
3514+ int count = kca.size();
3515+ int i;
3516+ for(i=0;i<count;i++) {
3517+ if(kca.elementAt(i) == keyCode) {
3518+ return true;
3519+ }
3520+ }
3521+ return false;
3522+ }
3523+
3524+ /**
3525+ * Updates internal state of the KeyboardState and returns true
3526+ * if the event should be processed further.
3527+ */
3528+ static boolean shouldProcess(KeyEvent e) {
3529+ switch (e.getID()) {
3530+ case KeyEvent.KEY_PRESSED:
3531+ if (!keyIsPressed(e.getKeyCode())) {
3532+ registerKeyPressed(e.getKeyCode());
3533+ }
3534+ return true;
3535+ case KeyEvent.KEY_RELEASED:
3536+ // We are forced to process VK_PRINTSCREEN separately because
3537+ // the Windows doesn't generate the key pressed event for
3538+ // printscreen and it block the processing of key release
3539+ // event for printscreen.
3540+ if (keyIsPressed(e.getKeyCode()) || e.getKeyCode()==KeyEvent.VK_PRINTSCREEN) {
3541+ registerKeyReleased(e.getKeyCode());
3542+ return true;
3543+ }
3544+ return false;
3545+ case KeyEvent.KEY_TYPED:
3546+ return true;
3547+ default:
3548+ // Not a known KeyEvent type, bail.
3549+ return false;
3550+ }
3551+ }
3552+ }
3553+
3554+ static final sun.awt.RequestFocusController focusController =
3555+ new sun.awt.RequestFocusController() {
3556+ public boolean acceptRequestFocus(Component from, Component to,
3557+ boolean temporary, boolean focusedWindowChangeAllowed,
3558+ sun.awt.CausedFocusEvent.Cause cause)
3559+ {
3560+ if ((to == null) || !(to instanceof JComponent)) {
3561+ return true;
3562+ }
3563+
3564+ if ((from == null) || !(from instanceof JComponent)) {
3565+ return true;
3566+ }
3567+
3568+ JComponent target = (JComponent) to;
3569+ if (!target.getVerifyInputWhenFocusTarget()) {
3570+ return true;
3571+ }
3572+
3573+ JComponent jFocusOwner = (JComponent)from;
3574+ InputVerifier iv = jFocusOwner.getInputVerifier();
3575+
3576+ if (iv == null) {
3577+ return true;
3578+ } else {
3579+ Object currentSource = SwingUtilities.appContextGet(
3580+ INPUT_VERIFIER_SOURCE_KEY);
3581+ if (currentSource == jFocusOwner) {
3582+ // We're currently calling into the InputVerifier
3583+ // for this component, so allow the focus change.
3584+ return true;
3585+ }
3586+ SwingUtilities.appContextPut(INPUT_VERIFIER_SOURCE_KEY,
3587+ jFocusOwner);
3588+ try {
3589+ return iv.shouldYieldFocus(jFocusOwner);
3590+ } finally {
3591+ if (currentSource != null) {
3592+ // We're already in the InputVerifier for
3593+ // currentSource. By resetting the currentSource
3594+ // we ensure that if the InputVerifier for
3595+ // currentSource does a requestFocus, we don't
3596+ // try and run the InputVerifier again.
3597+ SwingUtilities.appContextPut(
3598+ INPUT_VERIFIER_SOURCE_KEY, currentSource);
3599+ } else {
3600+ SwingUtilities.appContextRemove(
3601+ INPUT_VERIFIER_SOURCE_KEY);
3602+ }
3603+ }
3604+ }
3605+ }
3606+ };
3607+
3608+ /*
3609+ * --- Accessibility Support ---
3610+ */
3611+
3612+ /**
3613+ * @deprecated As of JDK version 1.1,
3614+ * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3615+ */
3616+ @Deprecated
3617+ public void enable() {
3618+ if (isEnabled() != true) {
3619+ super.enable();
3620+ if (accessibleContext != null) {
3621+ accessibleContext.firePropertyChange(
3622+ AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3623+ null, AccessibleState.ENABLED);
3624+ }
3625+ }
3626+ }
3627+
3628+ /**
3629+ * @deprecated As of JDK version 1.1,
3630+ * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
3631+ */
3632+ @Deprecated
3633+ public void disable() {
3634+ if (isEnabled() != false) {
3635+ super.disable();
3636+ if (accessibleContext != null) {
3637+ accessibleContext.firePropertyChange(
3638+ AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3639+ AccessibleState.ENABLED, null);
3640+ }
3641+ }
3642+ }
3643+
3644+ /**
3645+ * The <code>AccessibleContext</code> associated with this
3646+ * <code>JComponent</code>.
3647+ */
3648+ protected AccessibleContext accessibleContext = null;
3649+
3650+ /**
3651+ * Returns the <code>AccessibleContext</code> associated with this
3652+ * <code>JComponent</code>. The method implemented by this base
3653+ * class returns null. Classes that extend <code>JComponent</code>
3654+ * should implement this method to return the
3655+ * <code>AccessibleContext</code> associated with the subclass.
3656+ *
3657+ * @return the <code>AccessibleContext</code> of this
3658+ * <code>JComponent</code>
3659+ */
3660+ public AccessibleContext getAccessibleContext() {
3661+ return accessibleContext;
3662+ }
3663+
3664+ /**
3665+ * Inner class of JComponent used to provide default support for
3666+ * accessibility. This class is not meant to be used directly by
3667+ * application developers, but is instead meant only to be
3668+ * subclassed by component developers.
3669+ * <p>
3670+ * <strong>Warning:</strong>
3671+ * Serialized objects of this class will not be compatible with
3672+ * future Swing releases. The current serialization support is
3673+ * appropriate for short term storage or RMI between applications running
3674+ * the same version of Swing. As of 1.4, support for long term storage
3675+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
3676+ * has been added to the <code>java.beans</code> package.
3677+ * Please see {@link java.beans.XMLEncoder}.
3678+ */
3679+ public abstract class AccessibleJComponent extends AccessibleAWTContainer
3680+ implements AccessibleExtendedComponent
3681+ {
3682+ /**
3683+ * Though the class is abstract, this should be called by
3684+ * all sub-classes.
3685+ */
3686+ protected AccessibleJComponent() {
3687+ super();
3688+ }
3689+
3690+ protected ContainerListener accessibleContainerHandler = null;
3691+ protected FocusListener accessibleFocusHandler = null;
3692+
3693+ /**
3694+ * Fire PropertyChange listener, if one is registered,
3695+ * when children added/removed.
3696+ */
3697+ protected class AccessibleContainerHandler
3698+ implements ContainerListener {
3699+ public void componentAdded(ContainerEvent e) {
3700+ Component c = e.getChild();
3701+ if (c != null && c instanceof Accessible) {
3702+ AccessibleJComponent.this.firePropertyChange(
3703+ AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3704+ null, c.getAccessibleContext());
3705+ }
3706+ }
3707+ public void componentRemoved(ContainerEvent e) {
3708+ Component c = e.getChild();
3709+ if (c != null && c instanceof Accessible) {
3710+ AccessibleJComponent.this.firePropertyChange(
3711+ AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
3712+ c.getAccessibleContext(), null);
3713+ }
3714+ }
3715+ }
3716+
3717+ /**
3718+ * Fire PropertyChange listener, if one is registered,
3719+ * when focus events happen
3720+ * @since 1.3
3721+ */
3722+ protected class AccessibleFocusHandler implements FocusListener {
3723+ public void focusGained(FocusEvent event) {
3724+ if (accessibleContext != null) {
3725+ accessibleContext.firePropertyChange(
3726+ AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3727+ null, AccessibleState.FOCUSED);
3728+ }
3729+ }
3730+ public void focusLost(FocusEvent event) {
3731+ if (accessibleContext != null) {
3732+ accessibleContext.firePropertyChange(
3733+ AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
3734+ AccessibleState.FOCUSED, null);
3735+ }
3736+ }
3737+ } // inner class AccessibleFocusHandler
3738+
3739+
3740+ /**
3741+ * Adds a PropertyChangeListener to the listener list.
3742+ *
3743+ * @param listener the PropertyChangeListener to be added
3744+ */
3745+ public void addPropertyChangeListener(PropertyChangeListener listener) {
3746+ if (accessibleFocusHandler == null) {
3747+ accessibleFocusHandler = new AccessibleFocusHandler();
3748+ JComponent.this.addFocusListener(accessibleFocusHandler);
3749+ }
3750+ if (accessibleContainerHandler == null) {
3751+ accessibleContainerHandler = new AccessibleContainerHandler();
3752+ JComponent.this.addContainerListener(accessibleContainerHandler);
3753+ }
3754+ super.addPropertyChangeListener(listener);
3755+ }
3756+
3757+ /**
3758+ * Removes a PropertyChangeListener from the listener list.
3759+ * This removes a PropertyChangeListener that was registered
3760+ * for all properties.
3761+ *
3762+ * @param listener the PropertyChangeListener to be removed
3763+ */
3764+ public void removePropertyChangeListener(PropertyChangeListener listener) {
3765+ if (accessibleFocusHandler != null) {
3766+ JComponent.this.removeFocusListener(accessibleFocusHandler);
3767+ accessibleFocusHandler = null;
3768+ }
3769+ super.removePropertyChangeListener(listener);
3770+ }
3771+
3772+
3773+
3774+ /**
3775+ * Recursively search through the border hierarchy (if it exists)
3776+ * for a TitledBorder with a non-null title. This does a depth
3777+ * first search on first the inside borders then the outside borders.
3778+ * The assumption is that titles make really pretty inside borders
3779+ * but not very pretty outside borders in compound border situations.
3780+ * It's rather arbitrary, but hopefully decent UI programmers will
3781+ * not create multiple titled borders for the same component.
3782+ */
3783+ protected String getBorderTitle(Border b) {
3784+ String s;
3785+ if (b instanceof TitledBorder) {
3786+ return ((TitledBorder) b).getTitle();
3787+ } else if (b instanceof CompoundBorder) {
3788+ s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
3789+ if (s == null) {
3790+ s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
3791+ }
3792+ return s;
3793+ } else {
3794+ return null;
3795+ }
3796+ }
3797+
3798+ // AccessibleContext methods
3799+ //
3800+ /**
3801+ * Gets the accessible name of this object. This should almost never
3802+ * return java.awt.Component.getName(), as that generally isn't
3803+ * a localized name, and doesn't have meaning for the user. If the
3804+ * object is fundamentally a text object (such as a menu item), the
3805+ * accessible name should be the text of the object (for example,
3806+ * "save").
3807+ * If the object has a tooltip, the tooltip text may also be an
3808+ * appropriate String to return.
3809+ *
3810+ * @return the localized name of the object -- can be null if this
3811+ * object does not have a name
3812+ * @see AccessibleContext#setAccessibleName
3813+ */
3814+ public String getAccessibleName() {
3815+ String name = accessibleName;
3816+
3817+ // fallback to the client name property
3818+ //
3819+ if (name == null) {
3820+ name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
3821+ }
3822+
3823+ // fallback to the titled border if it exists
3824+ //
3825+ if (name == null) {
3826+ name = getBorderTitle(getBorder());
3827+ }
3828+
3829+ // fallback to the label labeling us if it exists
3830+ //
3831+ if (name == null) {
3832+ Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3833+ if (o instanceof Accessible) {
3834+ AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3835+ if (ac != null) {
3836+ name = ac.getAccessibleName();
3837+ }
3838+ }
3839+ }
3840+ return name;
3841+ }
3842+
3843+ /**
3844+ * Gets the accessible description of this object. This should be
3845+ * a concise, localized description of what this object is - what
3846+ * is its meaning to the user. If the object has a tooltip, the
3847+ * tooltip text may be an appropriate string to return, assuming
3848+ * it contains a concise description of the object (instead of just
3849+ * the name of the object - for example a "Save" icon on a toolbar that
3850+ * had "save" as the tooltip text shouldn't return the tooltip
3851+ * text as the description, but something like "Saves the current
3852+ * text document" instead).
3853+ *
3854+ * @return the localized description of the object -- can be null if
3855+ * this object does not have a description
3856+ * @see AccessibleContext#setAccessibleDescription
3857+ */
3858+ public String getAccessibleDescription() {
3859+ String description = accessibleDescription;
3860+
3861+ // fallback to the client description property
3862+ //
3863+ if (description == null) {
3864+ description = (String)getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
3865+ }
3866+
3867+ // fallback to the tool tip text if it exists
3868+ //
3869+ if (description == null) {
3870+ try {
3871+ description = getToolTipText();
3872+ } catch (Exception e) {
3873+ // Just in case the subclass overrode the
3874+ // getToolTipText method and actually
3875+ // requires a MouseEvent.
3876+ // [[[FIXME: WDW - we probably should require this
3877+ // method to take a MouseEvent and just pass it on
3878+ // to getToolTipText. The swing-feedback traffic
3879+ // leads me to believe getToolTipText might change,
3880+ // though, so I was hesitant to make this change at
3881+ // this time.]]]
3882+ }
3883+ }
3884+
3885+ // fallback to the label labeling us if it exists
3886+ //
3887+ if (description == null) {
3888+ Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
3889+ if (o instanceof Accessible) {
3890+ AccessibleContext ac = ((Accessible) o).getAccessibleContext();
3891+ if (ac != null) {
3892+ description = ac.getAccessibleDescription();
3893+ }
3894+ }
3895+ }
3896+
3897+ return description;
3898+ }
3899+
3900+ /**
3901+ * Gets the role of this object.
3902+ *
3903+ * @return an instance of AccessibleRole describing the role of the
3904+ * object
3905+ * @see AccessibleRole
3906+ */
3907+ public AccessibleRole getAccessibleRole() {
3908+ return AccessibleRole.SWING_COMPONENT;
3909+ }
3910+
3911+ /**
3912+ * Gets the state of this object.
3913+ *
3914+ * @return an instance of AccessibleStateSet containing the current
3915+ * state set of the object
3916+ * @see AccessibleState
3917+ */
3918+ public AccessibleStateSet getAccessibleStateSet() {
3919+ AccessibleStateSet states = super.getAccessibleStateSet();
3920+ if (JComponent.this.isOpaque()) {
3921+ states.add(AccessibleState.OPAQUE);
3922+ }
3923+ return states;
3924+ }
3925+
3926+ /**
3927+ * Returns the number of accessible children in the object. If all
3928+ * of the children of this object implement Accessible, than this
3929+ * method should return the number of children of this object.
3930+ *
3931+ * @return the number of accessible children in the object.
3932+ */
3933+ public int getAccessibleChildrenCount() {
3934+ return super.getAccessibleChildrenCount();
3935+ }
3936+
3937+ /**
3938+ * Returns the nth Accessible child of the object.
3939+ *
3940+ * @param i zero-based index of child
3941+ * @return the nth Accessible child of the object
3942+ */
3943+ public Accessible getAccessibleChild(int i) {
3944+ return super.getAccessibleChild(i);
3945+ }
3946+
3947+ // ----- AccessibleExtendedComponent
3948+
3949+ /**
3950+ * Returns the AccessibleExtendedComponent
3951+ *
3952+ * @return the AccessibleExtendedComponent
3953+ */
3954+ AccessibleExtendedComponent getAccessibleExtendedComponent() {
3955+ return this;
3956+ }
3957+
3958+ /**
3959+ * Returns the tool tip text
3960+ *
3961+ * @return the tool tip text, if supported, of the object;
3962+ * otherwise, null
3963+ * @since 1.4
3964+ */
3965+ public String getToolTipText() {
3966+ return JComponent.this.getToolTipText();
3967+ }
3968+
3969+ /**
3970+ * Returns the titled border text
3971+ *
3972+ * @return the titled border text, if supported, of the object;
3973+ * otherwise, null
3974+ * @since 1.4
3975+ */
3976+ public String getTitledBorderText() {
3977+ Border border = JComponent.this.getBorder();
3978+ if (border instanceof TitledBorder) {
3979+ return ((TitledBorder)border).getTitle();
3980+ } else {
3981+ return null;
3982+ }
3983+ }
3984+
3985+ /**
3986+ * Returns key bindings associated with this object
3987+ *
3988+ * @return the key bindings, if supported, of the object;
3989+ * otherwise, null
3990+ * @see AccessibleKeyBinding
3991+ * @since 1.4
3992+ */
3993+ public AccessibleKeyBinding getAccessibleKeyBinding() {
3994+ return null;
3995+ }
3996+ } // inner class AccessibleJComponent
3997+
3998+
3999+ /**
4000+ * Returns an <code>ArrayTable</code> used for
4001+ * key/value "client properties" for this component. If the
4002+ * <code>clientProperties</code> table doesn't exist, an empty one
4003+ * will be created.
4004+ *
4005+ * @return an ArrayTable
4006+ * @see #putClientProperty
4007+ * @see #getClientProperty
4008+ */
4009+ private ArrayTable getClientProperties() {
4010+ if (clientProperties == null) {
4011+ clientProperties = new ArrayTable();
4012+ }
4013+ return clientProperties;
4014+ }
4015+
4016+
4017+ /**
4018+ * Returns the value of the property with the specified key. Only
4019+ * properties added with <code>putClientProperty</code> will return
4020+ * a non-<code>null</code> value.
4021+ *
4022+ * @param key the being queried
4023+ * @return the value of this property or <code>null</code>
4024+ * @see #putClientProperty
4025+ */
4026+ public final Object getClientProperty(Object key) {
4027+ if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4028+ return aaTextInfo;
4029+ } else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
4030+ return ui;
4031+ }
4032+ if(clientProperties == null) {
4033+ return null;
4034+ } else {
4035+ synchronized(clientProperties) {
4036+ return clientProperties.get(key);
4037+ }
4038+ }
4039+ }
4040+
4041+ /**
4042+ * Adds an arbitrary key/value "client property" to this component.
4043+ * <p>
4044+ * The <code>get/putClientProperty</code> methods provide access to
4045+ * a small per-instance hashtable. Callers can use get/putClientProperty
4046+ * to annotate components that were created by another module.
4047+ * For example, a
4048+ * layout manager might store per child constraints this way. For example:
4049+ * <pre>
4050+ * componentA.putClientProperty("to the left of", componentB);
4051+ * </pre>
4052+ * If value is <code>null</code> this method will remove the property.
4053+ * Changes to client properties are reported with
4054+ * <code>PropertyChange</code> events.
4055+ * The name of the property (for the sake of PropertyChange
4056+ * events) is <code>key.toString()</code>.
4057+ * <p>
4058+ * The <code>clientProperty</code> dictionary is not intended to
4059+ * support large
4060+ * scale extensions to JComponent nor should be it considered an
4061+ * alternative to subclassing when designing a new component.
4062+ *
4063+ * @param key the new client property key
4064+ * @param value the new client property value; if <code>null</code>
4065+ * this method will remove the property
4066+ * @see #getClientProperty
4067+ * @see #addPropertyChangeListener
4068+ */
4069+ public final void putClientProperty(Object key, Object value) {
4070+ if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
4071+ aaTextInfo = value;
4072+ return;
4073+ }
4074+ if (value == null && clientProperties == null) {
4075+ // Both the value and ArrayTable are null, implying we don't
4076+ // have to do anything.
4077+ return;
4078+ }
4079+ ArrayTable clientProperties = getClientProperties();
4080+ Object oldValue;
4081+ synchronized(clientProperties) {
4082+ oldValue = clientProperties.get(key);
4083+ if (value != null) {
4084+ clientProperties.put(key, value);
4085+ } else if (oldValue != null) {
4086+ clientProperties.remove(key);
4087+ } else {
4088+ // old == new == null
4089+ return;
4090+ }
4091+ }
4092+ clientPropertyChanged(key, oldValue, value);
4093+ firePropertyChange(key.toString(), oldValue, value);
4094+ }
4095+
4096+ // Invoked from putClientProperty. This is provided for subclasses
4097+ // in Swing.
4098+ void clientPropertyChanged(Object key, Object oldValue,
4099+ Object newValue) {
4100+ }
4101+
4102+
4103+ /*
4104+ * Sets the property with the specified name to the specified value if
4105+ * the property has not already been set by the client program.
4106+ * This method is used primarily to set UI defaults for properties
4107+ * with primitive types, where the values cannot be marked with
4108+ * UIResource.
4109+ * @see LookAndFeel#installProperty
4110+ * @param propertyName String containing the name of the property
4111+ * @param value Object containing the property value
4112+ */
4113+ void setUIProperty(String propertyName, Object value) {
4114+ if (propertyName == "opaque") {
4115+ if (!getFlag(OPAQUE_SET)) {
4116+ setOpaque(((Boolean)value).booleanValue());
4117+ setFlag(OPAQUE_SET, false);
4118+ }
4119+ } else if (propertyName == "autoscrolls") {
4120+ if (!getFlag(AUTOSCROLLS_SET)) {
4121+ setAutoscrolls(((Boolean)value).booleanValue());
4122+ setFlag(AUTOSCROLLS_SET, false);
4123+ }
4124+ } else if (propertyName == "focusTraversalKeysForward") {
4125+ if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
4126+ super.setFocusTraversalKeys(KeyboardFocusManager.
4127+ FORWARD_TRAVERSAL_KEYS,
4128+ (Set)value);
4129+ }
4130+ } else if (propertyName == "focusTraversalKeysBackward") {
4131+ if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
4132+ super.setFocusTraversalKeys(KeyboardFocusManager.
4133+ BACKWARD_TRAVERSAL_KEYS,
4134+ (Set)value);
4135+ }
4136+ } else {
4137+ throw new IllegalArgumentException("property \""+
4138+ propertyName+ "\" cannot be set using this method");
4139+ }
4140+ }
4141+
4142+
4143+ /**
4144+ * Sets the focus traversal keys for a given traversal operation for this
4145+ * Component.
4146+ * Refer to
4147+ * {@link java.awt.Component#setFocusTraversalKeys}
4148+ * for a complete description of this method.
4149+ *
4150+ * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4151+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4152+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
4153+ * @param keystrokes the Set of AWTKeyStroke for the specified operation
4154+ * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4155+ * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4156+ * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4157+ * @throws IllegalArgumentException if id is not one of
4158+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
4159+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
4160+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
4161+ * contains null, or if any Object in keystrokes is not an
4162+ * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
4163+ * or if any keystroke already maps to another focus traversal
4164+ * operation for this Component
4165+ * @since 1.5
4166+ * @beaninfo
4167+ * bound: true
4168+ */
4169+ public void
4170+ setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes)
4171+ {
4172+ if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
4173+ setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET,true);
4174+ } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
4175+ setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET,true);
4176+ }
4177+ super.setFocusTraversalKeys(id,keystrokes);
4178+ }
4179+
4180+ /* --- Transitional java.awt.Component Support ---
4181+ * The methods and fields in this section will migrate to
4182+ * java.awt.Component in the next JDK release.
4183+ */
4184+
4185+ /**
4186+ * Returns true if this component is lightweight, that is, if it doesn't
4187+ * have a native window system peer.
4188+ *
4189+ * @return true if this component is lightweight
4190+ */
4191+ public static boolean isLightweightComponent(Component c) {
4192+ return c.getPeer() instanceof LightweightPeer;
4193+ }
4194+
4195+
4196+ /**
4197+ * @deprecated As of JDK 5,
4198+ * replaced by <code>Component.setBounds(int, int, int, int)</code>.
4199+ * <p>
4200+ * Moves and resizes this component.
4201+ *
4202+ * @param x the new horizontal location
4203+ * @param y the new vertical location
4204+ * @param w the new width
4205+ * @param h the new height
4206+ * @see java.awt.Component#setBounds
4207+ */
4208+ @Deprecated
4209+ public void reshape(int x, int y, int w, int h) {
4210+ super.reshape(x, y, w, h);
4211+ }
4212+
4213+
4214+ /**
4215+ * Stores the bounds of this component into "return value"
4216+ * <code>rv</code> and returns <code>rv</code>.
4217+ * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
4218+ * is allocated. This version of <code>getBounds</code> is useful
4219+ * if the caller wants to avoid allocating a new <code>Rectangle</code>
4220+ * object on the heap.
4221+ *
4222+ * @param rv the return value, modified to the component's bounds
4223+ * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
4224+ * return a newly created <code>Rectangle</code> with this
4225+ * component's bounds
4226+ */
4227+ public Rectangle getBounds(Rectangle rv) {
4228+ if (rv == null) {
4229+ return new Rectangle(getX(), getY(), getWidth(), getHeight());
4230+ }
4231+ else {
4232+ rv.setBounds(getX(), getY(), getWidth(), getHeight());
4233+ return rv;
4234+ }
4235+ }
4236+
4237+
4238+ /**
4239+ * Stores the width/height of this component into "return value"
4240+ * <code>rv</code> and returns <code>rv</code>.
4241+ * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
4242+ * object is allocated. This version of <code>getSize</code>
4243+ * is useful if the caller wants to avoid allocating a new
4244+ * <code>Dimension</code> object on the heap.
4245+ *
4246+ * @param rv the return value, modified to the component's size
4247+ * @return <code>rv</code>
4248+ */
4249+ public Dimension getSize(Dimension rv) {
4250+ if (rv == null) {
4251+ return new Dimension(getWidth(), getHeight());
4252+ }
4253+ else {
4254+ rv.setSize(getWidth(), getHeight());
4255+ return rv;
4256+ }
4257+ }
4258+
4259+
4260+ /**
4261+ * Stores the x,y origin of this component into "return value"
4262+ * <code>rv</code> and returns <code>rv</code>.
4263+ * If <code>rv</code> is <code>null</code> a new <code>Point</code>
4264+ * is allocated. This version of <code>getLocation</code> is useful
4265+ * if the caller wants to avoid allocating a new <code>Point</code>
4266+ * object on the heap.
4267+ *
4268+ * @param rv the return value, modified to the component's location
4269+ * @return <code>rv</code>
4270+ */
4271+ public Point getLocation(Point rv) {
4272+ if (rv == null) {
4273+ return new Point(getX(), getY());
4274+ }
4275+ else {
4276+ rv.setLocation(getX(), getY());
4277+ return rv;
4278+ }
4279+ }
4280+
4281+
4282+ /**
4283+ * Returns the current x coordinate of the component's origin.
4284+ * This method is preferable to writing
4285+ * <code>component.getBounds().x</code>, or
4286+ * <code>component.getLocation().x</code> because it doesn't cause any
4287+ * heap allocations.
4288+ *
4289+ * @return the current x coordinate of the component's origin
4290+ */
4291+ public int getX() { return super.getX(); }
4292+
4293+
4294+ /**
4295+ * Returns the current y coordinate of the component's origin.
4296+ * This method is preferable to writing
4297+ * <code>component.getBounds().y</code>, or
4298+ * <code>component.getLocation().y</code> because it doesn't cause any
4299+ * heap allocations.
4300+ *
4301+ * @return the current y coordinate of the component's origin
4302+ */
4303+ public int getY() { return super.getY(); }
4304+
4305+
4306+ /**
4307+ * Returns the current width of this component.
4308+ * This method is preferable to writing
4309+ * <code>component.getBounds().width</code>, or
4310+ * <code>component.getSize().width</code> because it doesn't cause any
4311+ * heap allocations.
4312+ *
4313+ * @return the current width of this component
4314+ */
4315+ public int getWidth() { return super.getWidth(); }
4316+
4317+
4318+ /**
4319+ * Returns the current height of this component.
4320+ * This method is preferable to writing
4321+ * <code>component.getBounds().height</code>, or
4322+ * <code>component.getSize().height</code> because it doesn't cause any
4323+ * heap allocations.
4324+ *
4325+ * @return the current height of this component
4326+ */
4327+ public int getHeight() { return super.getHeight(); }
4328+
4329+ /**
4330+ * Returns true if this component is completely opaque.
4331+ * <p>
4332+ * An opaque component paints every pixel within its
4333+ * rectangular bounds. A non-opaque component paints only a subset of
4334+ * its pixels or none at all, allowing the pixels underneath it to
4335+ * "show through". Therefore, a component that does not fully paint
4336+ * its pixels provides a degree of transparency.
4337+ * <p>
4338+ * Subclasses that guarantee to always completely paint their contents
4339+ * should override this method and return true.
4340+ *
4341+ * @return true if this component is completely opaque
4342+ * @see #setOpaque
4343+ */
4344+ public boolean isOpaque() {
4345+ return getFlag(IS_OPAQUE);
4346+ }
4347+
4348+ /**
4349+ * If true the component paints every pixel within its bounds.
4350+ * Otherwise, the component may not paint some or all of its
4351+ * pixels, allowing the underlying pixels to show through.
4352+ * <p>
4353+ * The default value of this property is false for <code>JComponent</code>.
4354+ * However, the default value for this property on most standard
4355+ * <code>JComponent</code> subclasses (such as <code>JButton</code> and
4356+ * <code>JTree</code>) is look-and-feel dependent.
4357+ *
4358+ * @param isOpaque true if this component should be opaque
4359+ * @see #isOpaque
4360+ * @beaninfo
4361+ * bound: true
4362+ * expert: true
4363+ * description: The component's opacity
4364+ */
4365+ public void setOpaque(boolean isOpaque) {
4366+ boolean oldValue = getFlag(IS_OPAQUE);
4367+ setFlag(IS_OPAQUE, isOpaque);
4368+ setFlag(OPAQUE_SET, true);
4369+ firePropertyChange("opaque", oldValue, isOpaque);
4370+ }
4371+
4372+
4373+ /**
4374+ * If the specified rectangle is completely obscured by any of this
4375+ * component's opaque children then returns true. Only direct children
4376+ * are considered, more distant descendants are ignored. A
4377+ * <code>JComponent</code> is opaque if
4378+ * <code>JComponent.isOpaque()</code> returns true, other lightweight
4379+ * components are always considered transparent, and heavyweight components
4380+ * are always considered opaque.
4381+ *
4382+ * @param x x value of specified rectangle
4383+ * @param y y value of specified rectangle
4384+ * @param width width of specified rectangle
4385+ * @param height height of specified rectangle
4386+ * @return true if the specified rectangle is obscured by an opaque child
4387+ */
4388+ boolean rectangleIsObscured(int x,int y,int width,int height)
4389+ {
4390+ int numChildren = getComponentCount();
4391+
4392+ for(int i = 0; i < numChildren; i++) {
4393+ Component child = getComponent(i);
4394+ int cx, cy, cw, ch;
4395+
4396+ cx = child.getX();
4397+ cy = child.getY();
4398+ cw = child.getWidth();
4399+ ch = child.getHeight();
4400+
4401+ if (x >= cx && (x + width) <= (cx + cw) &&
4402+ y >= cy && (y + height) <= (cy + ch) && child.isVisible()) {
4403+
4404+ if(child instanceof JComponent) {
4405+// System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child);
4406+// System.out.print("B) ");
4407+// Thread.dumpStack();
4408+ return child.isOpaque();
4409+ } else {
4410+ /** Sometimes a heavy weight can have a bound larger than its peer size
4411+ * so we should always draw under heavy weights
4412+ */
4413+ return false;
4414+ }
4415+ }
4416+ }
4417+
4418+ return false;
4419+ }
4420+
4421+
4422+ /**
4423+ * Returns the <code>Component</code>'s "visible rect rectangle" - the
4424+ * intersection of the visible rectangles for the component <code>c</code>
4425+ * and all of its ancestors. The return value is stored in
4426+ * <code>visibleRect</code>.
4427+ *
4428+ * @param c the component
4429+ * @param visibleRect a <code>Rectangle</code> computed as the
4430+ * intersection of all visible rectangles for the component
4431+ * <code>c</code> and all of its ancestors -- this is the
4432+ * return value for this method
4433+ * @see #getVisibleRect
4434+ */
4435+ static final void computeVisibleRect(Component c, Rectangle visibleRect) {
4436+ Container p = c.getParent();
4437+ Rectangle bounds = c.getBounds();
4438+
4439+ if (p == null || p instanceof Window || p instanceof Applet) {
4440+ visibleRect.setBounds(0, 0, bounds.width, bounds.height);
4441+ } else {
4442+ computeVisibleRect(p, visibleRect);
4443+ visibleRect.x -= bounds.x;
4444+ visibleRect.y -= bounds.y;
4445+ SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
4446+ }
4447+ }
4448+
4449+
4450+ /**
4451+ * Returns the <code>Component</code>'s "visible rect rectangle" - the
4452+ * intersection of the visible rectangles for this component
4453+ * and all of its ancestors. The return value is stored in
4454+ * <code>visibleRect</code>.
4455+ *
4456+ * @param visibleRect a <code>Rectangle</code> computed as the
4457+ * intersection of all visible rectangles for this
4458+ * component and all of its ancestors -- this is the return
4459+ * value for this method
4460+ * @see #getVisibleRect
4461+ */
4462+ public void computeVisibleRect(Rectangle visibleRect) {
4463+ computeVisibleRect(this, visibleRect);
4464+ }
4465+
4466+
4467+ /**
4468+ * Returns the <code>Component</code>'s "visible rectangle" - the
4469+ * intersection of this component's visible rectangle,
4470+ * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
4471+ * and all of its ancestors' visible rectangles.
4472+ *
4473+ * @return the visible rectangle
4474+ */
4475+ public Rectangle getVisibleRect() {
4476+ Rectangle visibleRect = new Rectangle();
4477+
4478+ computeVisibleRect(visibleRect);
4479+ return visibleRect;
4480+ }
4481+
4482+ /**
4483+ * Support for reporting bound property changes for boolean properties.
4484+ * This method can be called when a bound property has changed and it will
4485+ * send the appropriate PropertyChangeEvent to any registered
4486+ * PropertyChangeListeners.
4487+ *
4488+ * @param propertyName the property whose value has changed
4489+ * @param oldValue the property's previous value
4490+ * @param newValue the property's new value
4491+ */
4492+ public void firePropertyChange(String propertyName,
4493+ boolean oldValue, boolean newValue) {
4494+ super.firePropertyChange(propertyName, oldValue, newValue);
4495+ }
4496+
4497+
4498+ /**
4499+ * Support for reporting bound property changes for integer properties.
4500+ * This method can be called when a bound property has changed and it will
4501+ * send the appropriate PropertyChangeEvent to any registered
4502+ * PropertyChangeListeners.
4503+ *
4504+ * @param propertyName the property whose value has changed
4505+ * @param oldValue the property's previous value
4506+ * @param newValue the property's new value
4507+ */
4508+ public void firePropertyChange(String propertyName,
4509+ int oldValue, int newValue) {
4510+ super.firePropertyChange(propertyName, oldValue, newValue);
4511+ }
4512+
4513+ // XXX This method is implemented as a workaround to a JLS issue with ambiguous
4514+ // methods. This should be removed once 4758654 is resolved.
4515+ public void firePropertyChange(String propertyName, char oldValue, char newValue) {
4516+ super.firePropertyChange(propertyName, oldValue, newValue);
4517+ }
4518+
4519+ /**
4520+ * Supports reporting constrained property changes.
4521+ * This method can be called when a constrained property has changed
4522+ * and it will send the appropriate <code>PropertyChangeEvent</code>
4523+ * to any registered <code>VetoableChangeListeners</code>.
4524+ *
4525+ * @param propertyName the name of the property that was listened on
4526+ * @param oldValue the old value of the property
4527+ * @param newValue the new value of the property
4528+ * @exception PropertyVetoException when the attempt to set the
4529+ * property is vetoed by the component
4530+ */
4531+ protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
4532+ throws java.beans.PropertyVetoException
4533+ {
4534+ if (vetoableChangeSupport == null) {
4535+ return;
4536+ }
4537+ vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
4538+ }
4539+
4540+
4541+ /**
4542+ * Adds a <code>VetoableChangeListener</code> to the listener list.
4543+ * The listener is registered for all properties.
4544+ *
4545+ * @param listener the <code>VetoableChangeListener</code> to be added
4546+ */
4547+ public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
4548+ if (vetoableChangeSupport == null) {
4549+ vetoableChangeSupport = new java.beans.VetoableChangeSupport(this);
4550+ }
4551+ vetoableChangeSupport.addVetoableChangeListener(listener);
4552+ }
4553+
4554+
4555+ /**
4556+ * Removes a <code>VetoableChangeListener</code> from the listener list.
4557+ * This removes a <code>VetoableChangeListener</code> that was registered
4558+ * for all properties.
4559+ *
4560+ * @param listener the <code>VetoableChangeListener</code> to be removed
4561+ */
4562+ public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
4563+ if (vetoableChangeSupport == null) {
4564+ return;
4565+ }
4566+ vetoableChangeSupport.removeVetoableChangeListener(listener);
4567+ }
4568+
4569+
4570+ /**
4571+ * Returns an array of all the vetoable change listeners
4572+ * registered on this component.
4573+ *
4574+ * @return all of the component's <code>VetoableChangeListener</code>s
4575+ * or an empty
4576+ * array if no vetoable change listeners are currently registered
4577+ *
4578+ * @see #addVetoableChangeListener
4579+ * @see #removeVetoableChangeListener
4580+ *
4581+ * @since 1.4
4582+ */
4583+ public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
4584+ if (vetoableChangeSupport == null) {
4585+ return new VetoableChangeListener[0];
4586+ }
4587+ return vetoableChangeSupport.getVetoableChangeListeners();
4588+ }
4589+
4590+
4591+ /**
4592+ * Returns the top-level ancestor of this component (either the
4593+ * containing <code>Window</code> or <code>Applet</code>),
4594+ * or <code>null</code> if this component has not
4595+ * been added to any container.
4596+ *
4597+ * @return the top-level <code>Container</code> that this component is in,
4598+ * or <code>null</code> if not in any container
4599+ */
4600+ public Container getTopLevelAncestor() {
4601+ for(Container p = this; p != null; p = p.getParent()) {
4602+ if(p instanceof Window || p instanceof Applet) {
4603+ return p;
4604+ }
4605+ }
4606+ return null;
4607+ }
4608+
4609+ private AncestorNotifier getAncestorNotifier() {
4610+ return (AncestorNotifier)
4611+ getClientProperty(JComponent_ANCESTOR_NOTIFIER);
4612+ }
4613+
4614+ /**
4615+ * Registers <code>listener</code> so that it will receive
4616+ * <code>AncestorEvents</code> when it or any of its ancestors
4617+ * move or are made visible or invisible.
4618+ * Events are also sent when the component or its ancestors are added
4619+ * or removed from the containment hierarchy.
4620+ *
4621+ * @param listener the <code>AncestorListener</code> to register
4622+ * @see AncestorEvent
4623+ */
4624+ public void addAncestorListener(AncestorListener listener) {
4625+ AncestorNotifier ancestorNotifier = getAncestorNotifier();
4626+ if (ancestorNotifier == null) {
4627+ ancestorNotifier = new AncestorNotifier(this);
4628+ putClientProperty(JComponent_ANCESTOR_NOTIFIER,
4629+ ancestorNotifier);
4630+ }
4631+ ancestorNotifier.addAncestorListener(listener);
4632+ }
4633+
4634+ /**
4635+ * Unregisters <code>listener</code> so that it will no longer receive
4636+ * <code>AncestorEvents</code>.
4637+ *
4638+ * @param listener the <code>AncestorListener</code> to be removed
4639+ * @see #addAncestorListener
4640+ */
4641+ public void removeAncestorListener(AncestorListener listener) {
4642+ AncestorNotifier ancestorNotifier = getAncestorNotifier();
4643+ if (ancestorNotifier == null) {
4644+ return;
4645+ }
4646+ ancestorNotifier.removeAncestorListener(listener);
4647+ if (ancestorNotifier.listenerList.getListenerList().length == 0) {
4648+ ancestorNotifier.removeAllListeners();
4649+ putClientProperty(JComponent_ANCESTOR_NOTIFIER, null);
4650+ }
4651+ }
4652+
4653+ /**
4654+ * Returns an array of all the ancestor listeners
4655+ * registered on this component.
4656+ *
4657+ * @return all of the component's <code>AncestorListener</code>s
4658+ * or an empty
4659+ * array if no ancestor listeners are currently registered
4660+ *
4661+ * @see #addAncestorListener
4662+ * @see #removeAncestorListener
4663+ *
4664+ * @since 1.4
4665+ */
4666+ public AncestorListener[] getAncestorListeners() {
4667+ AncestorNotifier ancestorNotifier = getAncestorNotifier();
4668+ if (ancestorNotifier == null) {
4669+ return new AncestorListener[0];
4670+ }
4671+ return ancestorNotifier.getAncestorListeners();
4672+ }
4673+
4674+ /**
4675+ * Returns an array of all the objects currently registered
4676+ * as <code><em>Foo</em>Listener</code>s
4677+ * upon this <code>JComponent</code>.
4678+ * <code><em>Foo</em>Listener</code>s are registered using the
4679+ * <code>add<em>Foo</em>Listener</code> method.
4680+ *
4681+ * <p>
4682+ *
4683+ * You can specify the <code>listenerType</code> argument
4684+ * with a class literal,
4685+ * such as
4686+ * <code><em>Foo</em>Listener.class</code>.
4687+ * For example, you can query a
4688+ * <code>JComponent</code> <code>c</code>
4689+ * for its mouse listeners with the following code:
4690+ * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
4691+ * If no such listeners exist, this method returns an empty array.
4692+ *
4693+ * @param listenerType the type of listeners requested; this parameter
4694+ * should specify an interface that descends from
4695+ * <code>java.util.EventListener</code>
4696+ * @return an array of all objects registered as
4697+ * <code><em>Foo</em>Listener</code>s on this component,
4698+ * or an empty array if no such
4699+ * listeners have been added
4700+ * @exception ClassCastException if <code>listenerType</code>
4701+ * doesn't specify a class or interface that implements
4702+ * <code>java.util.EventListener</code>
4703+ *
4704+ * @since 1.3
4705+ *
4706+ * @see #getVetoableChangeListeners
4707+ * @see #getAncestorListeners
4708+ */
4709+ public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
4710+ T[] result;
4711+ if (listenerType == AncestorListener.class) {
4712+ // AncestorListeners are handled by the AncestorNotifier
4713+ result = (T[])getAncestorListeners();
4714+ }
4715+ else if (listenerType == VetoableChangeListener.class) {
4716+ // VetoableChangeListeners are handled by VetoableChangeSupport
4717+ result = (T[])getVetoableChangeListeners();
4718+ }
4719+ else if (listenerType == PropertyChangeListener.class) {
4720+ // PropertyChangeListeners are handled by PropertyChangeSupport
4721+ result = (T[])getPropertyChangeListeners();
4722+ }
4723+ else {
4724+ result = listenerList.getListeners(listenerType);
4725+ }
4726+
4727+ if (result.length == 0) {
4728+ return super.getListeners(listenerType);
4729+ }
4730+ return result;
4731+ }
4732+
4733+ /**
4734+ * Notifies this component that it now has a parent component.
4735+ * When this method is invoked, the chain of parent components is
4736+ * set up with <code>KeyboardAction</code> event listeners.
4737+ * This method is called by the toolkit internally and should
4738+ * not be called directly by programs.
4739+ *
4740+ * @see #registerKeyboardAction
4741+ */
4742+ public void addNotify() {
4743+ super.addNotify();
4744+ firePropertyChange("ancestor", null, getParent());
4745+
4746+ registerWithKeyboardManager(false);
4747+ registerNextFocusableComponent();
4748+ }
4749+
4750+
4751+ /**
4752+ * Notifies this component that it no longer has a parent component.
4753+ * When this method is invoked, any <code>KeyboardAction</code>s
4754+ * set up in the the chain of parent components are removed.
4755+ * This method is called by the toolkit internally and should
4756+ * not be called directly by programs.
4757+ *
4758+ * @see #registerKeyboardAction
4759+ */
4760+ public void removeNotify() {
4761+ super.removeNotify();
4762+ // This isn't strictly correct. The event shouldn't be
4763+ // fired until *after* the parent is set to null. But
4764+ // we only get notified before that happens
4765+ firePropertyChange("ancestor", getParent(), null);
4766+
4767+ unregisterWithKeyboardManager();
4768+ deregisterNextFocusableComponent();
4769+
4770+ if (getCreatedDoubleBuffer()) {
4771+ RepaintManager.currentManager(this).resetDoubleBuffer();
4772+ setCreatedDoubleBuffer(false);
4773+ }
4774+ if (autoscrolls) {
4775+ Autoscroller.stop(this);
4776+ }
4777+ }
4778+
4779+
4780+ /**
4781+ * Adds the specified region to the dirty region list if the component
4782+ * is showing. The component will be repainted after all of the
4783+ * currently pending events have been dispatched.
4784+ *
4785+ * @param tm this parameter is not used
4786+ * @param x the x value of the dirty region
4787+ * @param y the y value of the dirty region
4788+ * @param width the width of the dirty region
4789+ * @param height the height of the dirty region
4790+ * @see #isPaintingOrigin()
4791+ * @see java.awt.Component#isShowing
4792+ * @see RepaintManager#addDirtyRegion
4793+ */
4794+ public void repaint(long tm, int x, int y, int width, int height) {
4795+ RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
4796+ }
4797+
4798+
4799+ /**
4800+ * Adds the specified region to the dirty region list if the component
4801+ * is showing. The component will be repainted after all of the
4802+ * currently pending events have been dispatched.
4803+ *
4804+ * @param r a <code>Rectangle</code> containing the dirty region
4805+ * @see #isPaintingOrigin()
4806+ * @see java.awt.Component#isShowing
4807+ * @see RepaintManager#addDirtyRegion
4808+ */
4809+ public void repaint(Rectangle r) {
4810+ repaint(0,r.x,r.y,r.width,r.height);
4811+ }
4812+
4813+
4814+ /**
4815+ * Supports deferred automatic layout.
4816+ * <p>
4817+ * Calls <code>invalidate</code> and then adds this component's
4818+ * <code>validateRoot</code> to a list of components that need to be
4819+ * validated. Validation will occur after all currently pending
4820+ * events have been dispatched. In other words after this method
4821+ * is called, the first validateRoot (if any) found when walking
4822+ * up the containment hierarchy of this component will be validated.
4823+ * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
4824+ * and <code>JTextField</code> return true
4825+ * from <code>isValidateRoot</code>.
4826+ * <p>
4827+ * This method will automatically be called on this component
4828+ * when a property value changes such that size, location, or
4829+ * internal layout of this component has been affected. This automatic
4830+ * updating differs from the AWT because programs generally no
4831+ * longer need to invoke <code>validate</code> to get the contents of the
4832+ * GUI to update.
4833+ * <p>
4834+ *
4835+ * @see java.awt.Component#invalidate
4836+ * @see java.awt.Container#validate
4837+ * @see #isValidateRoot
4838+ * @see RepaintManager#addInvalidComponent
4839+ */
4840+ public void revalidate() {
4841+ if (getParent() == null) {
4842+ // Note: We don't bother invalidating here as once added
4843+ // to a valid parent invalidate will be invoked (addImpl
4844+ // invokes addNotify which will invoke invalidate on the
4845+ // new Component). Also, if we do add a check to isValid
4846+ // here it can potentially be called before the constructor
4847+ // which was causing some people grief.
4848+ return;
4849+ }
4850+ if (SwingUtilities.isEventDispatchThread()) {
4851+ invalidate();
4852+ RepaintManager.currentManager(this).addInvalidComponent(this);
4853+ }
4854+ else {
4855+ // To avoid a flood of Runnables when constructing GUIs off
4856+ // the EDT, a flag is maintained as to whether or not
4857+ // a Runnable has been scheduled.
4858+ synchronized(this) {
4859+ if (getFlag(REVALIDATE_RUNNABLE_SCHEDULED)) {
4860+ return;
4861+ }
4862+ setFlag(REVALIDATE_RUNNABLE_SCHEDULED, true);
4863+ }
4864+ Runnable callRevalidate = new Runnable() {
4865+ public void run() {
4866+ synchronized(JComponent.this) {
4867+ setFlag(REVALIDATE_RUNNABLE_SCHEDULED, false);
4868+ }
4869+ revalidate();
4870+ }
4871+ };
4872+ SwingUtilities.invokeLater(callRevalidate);
4873+ }
4874+ }
4875+
4876+ /**
4877+ * If this method returns true, <code>revalidate</code> calls by
4878+ * descendants of this component will cause the entire tree
4879+ * beginning with this root to be validated.
4880+ * Returns false by default. <code>JScrollPane</code> overrides
4881+ * this method and returns true.
4882+ *
4883+ * @return always returns false
4884+ * @see #revalidate
4885+ * @see java.awt.Component#invalidate
4886+ * @see java.awt.Container#validate
4887+ * @see java.awt.Container#isValidateRoot
4888+ */
4889+ @Override
4890+ public boolean isValidateRoot() {
4891+ return false;
4892+ }
4893+
4894+
4895+ /**
4896+ * Returns true if this component tiles its children -- that is, if
4897+ * it can guarantee that the children will not overlap. The
4898+ * repainting system is substantially more efficient in this
4899+ * common case. <code>JComponent</code> subclasses that can't make this
4900+ * guarantee, such as <code>JLayeredPane</code>,
4901+ * should override this method to return false.
4902+ *
4903+ * @return always returns true
4904+ */
4905+ public boolean isOptimizedDrawingEnabled() {
4906+ return true;
4907+ }
4908+
4909+ /**
4910+ * Returns {@code true} if a paint triggered on a child component should cause
4911+ * painting to originate from this Component, or one of its ancestors.
4912+ * <p/>
4913+ * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)}
4914+ * on a Swing component will result in calling
4915+ * the {@link JComponent#paintImmediately(int, int, int, int)} method of
4916+ * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any.
4917+ * <p/>
4918+ * {@code JComponent} subclasses that need to be painted when any of their
4919+ * children are repainted should override this method to return {@code true}.
4920+ *
4921+ * @return always returns {@code false}
4922+ *
4923+ * @see #paintImmediately(int, int, int, int)
4924+ */
4925+ protected boolean isPaintingOrigin() {
4926+ return false;
4927+ }
4928+
4929+ /**
4930+ * Paints the specified region in this component and all of its
4931+ * descendants that overlap the region, immediately.
4932+ * <p>
4933+ * It's rarely necessary to call this method. In most cases it's
4934+ * more efficient to call repaint, which defers the actual painting
4935+ * and can collapse redundant requests into a single paint call.
4936+ * This method is useful if one needs to update the display while
4937+ * the current event is being dispatched.
4938+ * <p>
4939+ * This method is to be overridden when the dirty region needs to be changed
4940+ * for components that are painting origins.
4941+ *
4942+ * @param x the x value of the region to be painted
4943+ * @param y the y value of the region to be painted
4944+ * @param w the width of the region to be painted
4945+ * @param h the height of the region to be painted
4946+ * @see #repaint
4947+ * @see #isPaintingOrigin()
4948+ */
4949+ public void paintImmediately(int x,int y,int w, int h) {
4950+ Component c = this;
4951+ Component parent;
4952+
4953+ if(!isShowing()) {
4954+ return;
4955+ }
4956+
4957+ JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
4958+ if (paintingOigin != null) {
4959+ Rectangle rectangle = SwingUtilities.convertRectangle(
4960+ c, new Rectangle(x, y, w, h), paintingOigin);
4961+ paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
4962+ return;
4963+ }
4964+
4965+ while(!c.isOpaque()) {
4966+ parent = c.getParent();
4967+ if(parent != null) {
4968+ x += c.getX();
4969+ y += c.getY();
4970+ c = parent;
4971+ } else {
4972+ break;
4973+ }
4974+
4975+ if(!(c instanceof JComponent)) {
4976+ break;
4977+ }
4978+ }
4979+ if(c instanceof JComponent) {
4980+ ((JComponent)c)._paintImmediately(x,y,w,h);
4981+ } else {
4982+ c.repaint(x,y,w,h);
4983+ }
4984+ }
4985+
4986+ /**
4987+ * Paints the specified region now.
4988+ *
4989+ * @param r a <code>Rectangle</code> containing the region to be painted
4990+ */
4991+ public void paintImmediately(Rectangle r) {
4992+ paintImmediately(r.x,r.y,r.width,r.height);
4993+ }
4994+
4995+ /**
4996+ * Returns whether this component should be guaranteed to be on top.
4997+ * For example, it would make no sense for <code>Menu</code>s to pop up
4998+ * under another component, so they would always return true.
4999+ * Most components will want to return false, hence that is the default.

568 more lines aren’t shown here.