Merge from the pain train
[official-gcc.git] / libjava / javax / swing / JComponent.java
blobad7603cf76ae606492b92869322432f61840d91d
1 /* JComponent.java -- Every component in swing inherits from this class.
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import java.awt.AWTEvent;
42 import java.awt.Color;
43 import java.awt.Component;
44 import java.awt.Container;
45 import java.awt.Dimension;
46 import java.awt.FlowLayout;
47 import java.awt.Font;
48 import java.awt.Graphics;
49 import java.awt.Image;
50 import java.awt.Insets;
51 import java.awt.Point;
52 import java.awt.Rectangle;
53 import java.awt.dnd.DropTarget;
54 import java.awt.event.ActionEvent;
55 import java.awt.event.ActionListener;
56 import java.awt.event.ContainerEvent;
57 import java.awt.event.ContainerListener;
58 import java.awt.event.FocusEvent;
59 import java.awt.event.FocusListener;
60 import java.awt.event.KeyEvent;
61 import java.awt.event.MouseEvent;
62 import java.awt.geom.Rectangle2D;
63 import java.awt.image.ImageObserver;
64 import java.awt.peer.LightweightPeer;
65 import java.beans.PropertyChangeEvent;
66 import java.beans.PropertyChangeListener;
67 import java.beans.PropertyVetoException;
68 import java.beans.VetoableChangeListener;
69 import java.io.Serializable;
70 import java.util.EventListener;
71 import java.util.Hashtable;
72 import java.util.Locale;
74 import javax.accessibility.Accessible;
75 import javax.accessibility.AccessibleContext;
76 import javax.accessibility.AccessibleKeyBinding;
77 import javax.accessibility.AccessibleRole;
78 import javax.accessibility.AccessibleStateSet;
79 import javax.swing.border.Border;
80 import javax.swing.event.AncestorListener;
81 import javax.swing.event.EventListenerList;
82 import javax.swing.event.SwingPropertyChangeSupport;
83 import javax.swing.plaf.ComponentUI;
85 /**
86 * Every component in swing inherits from this class (JLabel, JButton, etc).
87 * It contains generic methods to manage events, properties and sizes. Actual
88 * drawing of the component is channeled to a look-and-feel class that is
89 * implemented elsewhere.
91 * @author Ronald Veldema (rveldema&064;cs.vu.nl)
92 * @author Graydon Hoare (graydon&064;redhat.com)
94 public abstract class JComponent extends Container implements Serializable
96 private static final long serialVersionUID = -7908749299918704233L;
98 /**
99 * Accessibility support is currently missing.
102 protected AccessibleContext accessibleContext;
104 public abstract class AccessibleJComponent
105 extends AccessibleAWTContainer
107 protected class AccessibleFocusHandler
108 implements FocusListener
110 protected AccessibleFocusHandler(){}
111 public void focusGained(FocusEvent event){}
112 public void focusLost(FocusEvent valevent){}
115 protected class AccessibleContainerHandler
116 implements ContainerListener
118 protected AccessibleContainerHandler() {}
119 public void componentAdded(ContainerEvent event) {}
120 public void componentRemoved(ContainerEvent valevent) {}
123 private static final long serialVersionUID = -7047089700479897799L;
125 protected ContainerListener accessibleContainerHandler;
126 protected FocusListener accessibleFocusHandler;
128 protected AccessibleJComponent() {}
129 public void addPropertyChangeListener(PropertyChangeListener listener) {}
130 public void removePropertyChangeListener(PropertyChangeListener listener) {}
131 public int getAccessibleChildrenCount() { return 0; }
132 public Accessible getAccessibleChild(int value0) { return null; }
133 public AccessibleStateSet getAccessibleStateSet() { return null; }
134 public String getAccessibleName() { return null; }
135 public String getAccessibleDescription() { return null; }
136 public AccessibleRole getAccessibleRole() { return null; }
137 protected String getBorderTitle(Border value0) { return null; }
138 public String getToolTipText() { return null; }
139 public String getTitledBorderText() { return null; }
140 public AccessibleKeyBinding getAccessibleKeyBinding() { return null; }
143 /**
144 * An explicit value for the component's preferred size; if not set by a
145 * user, this is calculated on the fly by delegating to the {@link
146 * ComponentUI.getPreferredSize} method on the {@link #ui} property.
148 Dimension preferredSize;
150 /**
151 * An explicit value for the component's minimum size; if not set by a
152 * user, this is calculated on the fly by delegating to the {@link
153 * ComponentUI.getMinimumSize} method on the {@link #ui} property.
155 Dimension minimumSize;
157 /**
158 * An explicit value for the component's maximum size; if not set by a
159 * user, this is calculated on the fly by delegating to the {@link
160 * ComponentUI.getMaximumSize} method on the {@link #ui} property.
162 Dimension maximumSize;
166 * A value between 0.0 and 1.0 indicating the preferred horizontal
167 * alignment of the component, relative to its siblings. The values
168 * {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
169 * #RIGHT_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
170 * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
171 * managers use this property.
173 * @see #getAlignmentX
174 * @see #setAlignmentX
175 * @see javax.swing.OverlayLayout
176 * @see javax.swing.BoxLayout
178 float alignmentX = 0.0f;
181 * A value between 0.0 and 1.0 indicating the preferred vertical
182 * alignment of the component, relative to its siblings. The values
183 * {@link #TOP_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
184 * #BOTTOM_ALIGNMENT} can also be used, as synonyms for <code>0.0</code>,
185 * <code>0.5</code>, and <code>1.0</code>, respectively. Not all layout
186 * managers use this property.
188 * @see #getAlignmentY
189 * @see #setAlignmentY
190 * @see javax.swing.OverlayLayout
191 * @see javax.swing.BoxLayout
193 float alignmentY = 0.0f;
195 /**
196 * The border painted around this component.
198 * @see #paintBorder
200 Border border;
202 /**
203 * The text to show in the tooltip associated with this component.
205 * @see #setToolTipText
206 * @see #getToolTipText
208 String toolTipText;
210 /**
211 * <p>Whether to double buffer this component when painting. This flag
212 * should generally be <code>false</code>, except for top level
213 * components such as {@link JFrame} or {@link JApplet}.</p>
215 * <p>All children of a double buffered component are painted into the
216 * double buffer automatically, so only the top widget in a window needs
217 * to be double buffered.</p>
219 * @see #setDoubleBuffered
220 * @see #isDoubleBuffered
221 * @see #paintLock
222 * @see #paint
224 boolean doubleBuffered = false;
227 * A set of flags indicating which debugging graphics facilities should
228 * be enabled on this component. The values should be a combination of
229 * {@link DebugGraphics.NONE_OPTION}, {@link DebugGraphics.LOG_OPTION},
230 * {@link DebugGraphics.FLASH_OPTION}, or {@link
231 * DebugGraphics.BUFFERED_OPTION}.
233 * @see setDebugGraphicsOptions
234 * @see getDebugGraphicsOptions
235 * @see DebugGraphics
236 * @see getComponentGraphics
238 int debugGraphicsOptions;
240 /**
241 * <p>This property controls two independent behaviors simultaneously.</p>
243 * <p>First, it controls whether to fill the background of this widget
244 * when painting its body. This affects calls to {@link
245 * JComponent#paintComponent}, which in turn calls {@link
246 * ComponentUI#update} on the component's {@link #ui} property. If the
247 * component is opaque during this call, the background will be filled
248 * before calling {@link ComponentUI#paint}. This happens merely as a
249 * convenience; you may fill the component's background yourself too,
250 * but there is no need to do so if you will be filling with the same
251 * color.</p>
253 * <p>Second, it the opaque property informs swing's repaint system
254 * whether it will be necessary to paint the components "underneath" this
255 * component, in Z-order. If the component is opaque, it is considered to
256 * completely occlude components "underneath" it, so they will not be
257 * repainted along with the opaque component.</p>
259 * <p>The default value for this property is <code>false</code>, but most
260 * components will want to set it to <code>true</code> when installing UI
261 * defaults in {@link ComponentUI#installUI}.</p>
263 * @see #setOpaque
264 * @see #isOpaque
265 * @see #paintComponent
267 boolean opaque = false;
269 /**
270 * The user interface delegate for this component. Event delivery and
271 * repainting of the component are usually delegated to this object.
273 * @see #setUI
274 * @see #getUI
275 * @see #updateUI
277 protected ComponentUI ui;
280 * A hint to the focus system that this component should or should not
281 * get focus. If this is <code>false</code>, swing will not try to
282 * request focus on this component; if <code>true</code>, swing might
283 * try to request focus, but the request might fail. Thus it is only
284 * a hint guiding swing's behavior.
286 * @see #requestFocus
287 * @see #isRequestFocusEnabled
288 * @see #setRequestFocusEnabled
290 boolean requestFocusEnabled;
293 * Flag indicating behavior of this component when the mouse is dragged
294 * outside the component and the mouse <em>stops moving</em>. If
295 * <code>true</code>, synthetic mouse events will be delivered on regular
296 * timed intervals, continuing off in the direction the mouse exited the
297 * component, until the mouse is released or re-enters the component.
299 * @see setAutoscrolls
300 * @see getAutoscrolls
302 boolean autoscrolls = false;
305 * Listeners for events other than {@link PropertyChangeEvent} are
306 * handled by this listener list. PropertyChangeEvents are handled in
307 * {@link #changeSupport}.
309 protected EventListenerList listenerList = new EventListenerList();
311 /**
312 * Support for {@link PropertyChangeEvent} events. This is constructed
313 * lazily when the component gets its first {@link
314 * PropertyChangeListener} subscription; until then it's an empty slot.
316 private SwingPropertyChangeSupport changeSupport;
319 /**
320 * Storage for "client properties", which are key/value pairs associated
321 * with this component by a "client", such as a user application or a
322 * layout manager. This is lazily constructed when the component gets its
323 * first client property.
325 private Hashtable clientProperties;
327 private InputMap inputMap_whenFocused;
328 private InputMap inputMap_whenAncestorOfFocused;
329 private InputMap inputMap_whenInFocusedWindow;
330 private ActionMap actionMap;
331 /** @since 1.3 */
332 private boolean verifyInputWhenFocusTarget;
333 private InputVerifier inputVerifier;
335 private TransferHandler transferHandler;
337 /**
338 * A lock held during recursive painting; this is used to serialize
339 * access to the double buffer, and also to select the "top level"
340 * object which should acquire the double buffer in a given widget
341 * tree (which may have multiple double buffered children).
343 * @see #doubleBuffered
344 * @see #paint
346 private static final Object paintLock = new Object();
350 * The default locale of the component.
352 * @see #getDefaultLocale
353 * @see #setDefaultLocale
355 private static Locale defaultLocale;
357 public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
360 * Constant used to indicate that no condition has been assigned to a
361 * particular action.
363 * @see #registerKeyboardAction
365 public static final int UNDEFINED_CONDITION = -1;
368 * Constant used to indicate that an action should be performed only when
369 * the component has focus.
371 * @see #registerKeyboardAction
373 public static final int WHEN_FOCUSED = 0;
376 * Constant used to indicate that an action should be performed only when
377 * the component is an ancestor of the component which has focus.
379 * @see #registerKeyboardAction
381 public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
384 * Constant used to indicate that an action should be performed only when
385 * the component is in the window which has focus.
387 * @see #registerKeyboardAction
389 public static final int WHEN_IN_FOCUSED_WINDOW = 2;
393 * Creates a new <code>JComponent</code> instance.
395 public JComponent()
397 super();
398 super.setLayout(new FlowLayout());
399 setDropTarget(new DropTarget());
400 defaultLocale = Locale.getDefault();
401 debugGraphicsOptions = DebugGraphics.NONE_OPTION;
405 * Helper to lazily construct and return the client properties table.
407 * @return The current client properties table
409 * @see #clientProperties
410 * @see #getClientProperty
411 * @see #putClientProperty
413 private Hashtable getClientProperties()
415 if (clientProperties == null)
416 clientProperties = new Hashtable();
417 return clientProperties;
421 * Get a client property associated with this component and a particular
422 * key.
424 * @param key The key with which to look up the client property
426 * @return A client property associated with this object and key
428 * @see #clientProperties
429 * @see #getClientProperties
430 * @see #putClientProperty
432 public final Object getClientProperty(Object key)
434 return getClientProperties().get(key);
438 * Add a client property <code>value</code> to this component, associated
439 * with <code>key</code>. If there is an existing client property
440 * associated with <code>key</code>, it will be replaced.
442 * @param key The key of the client property association to add
443 * @param value The value of the client property association to add
445 * @see #clientProperties
446 * @see #getClientProperties
447 * @see #getClientProperty
449 public final void putClientProperty(Object key, Object value)
451 getClientProperties().put(key, value);
455 * Unregister an <code>AncestorListener</code>.
457 * @param listener The listener to unregister
459 * @see addAncestorListener
461 public void removeAncestorListener(AncestorListener listener)
463 listenerList.remove(AncestorListener.class, listener);
467 * Unregister a <code>PropertyChangeListener</code>.
469 * @param listener The listener to register
471 * @see #addPropertyChangeListener
472 * @see #changeSupport
474 public void removePropertyChangeListener(PropertyChangeListener listener)
476 if (changeSupport != null)
477 changeSupport.removePropertyChangeListener(listener);
481 * Unregister a <code>PropertyChangeListener</code>.
483 * @param propertyName The property name to unregister the listener from
484 * @param listener The listener to unregister
486 * @see #addPropertyChangeListener
487 * @see #changeSupport
489 public void removePropertyChangeListener(String propertyName,
490 PropertyChangeListener listener)
492 if (changeSupport != null)
493 changeSupport.removePropertyChangeListener(propertyName, listener);
497 * Unregister a <code>VetoableChangeChangeListener</code>.
499 * @param listener The listener to unregister
501 * @see #addVetoableChangeListener
503 public void removeVetoableChangeListener(VetoableChangeListener listener)
505 listenerList.remove(VetoableChangeListener.class, listener);
509 * Register an <code>AncestorListener</code>.
511 * @param listener The listener to register
513 * @see #removeVetoableChangeListener
515 public void addAncestorListener(AncestorListener listener)
517 listenerList.add(AncestorListener.class, listener);
521 * Register a <code>PropertyChangeListener</code>. This listener will
522 * receive any PropertyChangeEvent, regardless of property name. To
523 * listen to a specific property name, use {@link
524 * #addPropertyChangeListener(String,PropertyChangeListener)} instead.
526 * @param listener The listener to register
528 * @see #removePropertyChangeListener
529 * @see #changeSupport
531 public void addPropertyChangeListener(PropertyChangeListener listener)
533 if (changeSupport == null)
534 changeSupport = new SwingPropertyChangeSupport(this);
535 changeSupport.addPropertyChangeListener(listener);
539 * Register a <code>PropertyChangeListener</code> for a specific, named
540 * property. To listen to all property changes, regardless of name, use
541 * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
543 * @param propertyName The property name to listen to
544 * @param listener The listener to register
546 * @see #removePropertyChangeListener
547 * @see #changeSupport
549 public void addPropertyChangeListener(String propertyName,
550 PropertyChangeListener listener)
552 listenerList.add(PropertyChangeListener.class, listener);
556 * Register a <code>VetoableChangeListener</code>.
558 * @param listener The listener to register
560 * @see #removeVetoableChangeListener
561 * @see #listenerList
563 public void addVetoableChangeListener(VetoableChangeListener listener)
565 listenerList.add(VetoableChangeListener.class, listener);
569 * Return all registered listeners of a particular type.
571 * @param listenerType The type of listener to return
573 * @return All listeners in the {@link #listenerList} which
574 * are of the specified type
576 * @see #listenerList
578 public EventListener[] getListeners(Class listenerType)
580 return listenerList.getListeners(listenerType);
584 * Return all registered <code>AncestorListener</code> objects.
586 * @return The set of <code>AncestorListener</code> objects in {@link
587 * #listenerList}
589 public AncestorListener[] getAncestorListeners()
591 return (AncestorListener[]) getListeners(AncestorListener.class);
595 * Return all registered <code>VetoableChangeListener</code> objects.
597 * @return The set of <code>VetoableChangeListener</code> objects in {@link
598 * #listenerList}
600 public VetoableChangeListener[] getVetoableChangeListeners()
602 return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
606 * Return all <code>PropertyChangeListener</code> objects registered to listen
607 * for a particular property.
609 * @param property The property to return the listeners of
611 * @return The set of <code>PropertyChangeListener</code> objects in
612 * {@link #changeSupport} registered to listen on the specified propert
614 public PropertyChangeListener[] getPropertyChangeListeners(String property)
616 return changeSupport == null ? new PropertyChangeListener[0]
617 : changeSupport.getPropertyChangeListeners(property);
621 * A variant of {@link #firePropertyChange(String,Object,Object)}
622 * for properties with <code>boolean</code> values.
624 public void firePropertyChange(String propertyName, boolean oldValue,
625 boolean newValue)
627 if (changeSupport != null)
628 changeSupport.firePropertyChange(propertyName, Boolean.valueOf(oldValue),
629 Boolean.valueOf(newValue));
633 * A variant of {@link #firePropertyChange(String,Object,Object)}
634 * for properties with <code>byte</code> values.
636 public void firePropertyChange(String propertyName, byte oldValue,
637 byte newValue)
639 if (changeSupport != null)
640 changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
641 new Byte(newValue));
645 * A variant of {@link #firePropertyChange(String,Object,Object)}
646 * for properties with <code>char</code> values.
648 public void firePropertyChange(String propertyName, char oldValue,
649 char newValue)
651 if (changeSupport != null)
652 changeSupport.firePropertyChange(propertyName, new Character(oldValue),
653 new Character(newValue));
657 * A variant of {@link #firePropertyChange(String,Object,Object)}
658 * for properties with <code>double</code> values.
660 public void firePropertyChange(String propertyName, double oldValue,
661 double newValue)
663 if (changeSupport != null)
664 changeSupport.firePropertyChange(propertyName, new Double(oldValue),
665 new Double(newValue));
669 * A variant of {@link #firePropertyChange(String,Object,Object)}
670 * for properties with <code>float</code> values.
672 public void firePropertyChange(String propertyName, float oldValue,
673 float newValue)
675 if (changeSupport != null)
676 changeSupport.firePropertyChange(propertyName, new Float(oldValue),
677 new Float(newValue));
681 * A variant of {@link #firePropertyChange(String,Object,Object)}
682 * for properties with <code>int</code> values.
684 public void firePropertyChange(String propertyName, int oldValue,
685 int newValue)
687 if (changeSupport != null)
688 changeSupport.firePropertyChange(propertyName, new Integer(oldValue),
689 new Integer(newValue));
693 * A variant of {@link #firePropertyChange(String,Object,Object)}
694 * for properties with <code>long</code> values.
696 public void firePropertyChange(String propertyName, long oldValue,
697 long newValue)
699 if (changeSupport != null)
700 changeSupport.firePropertyChange(propertyName, new Long(oldValue),
701 new Long(newValue));
705 * Call {@link PropertyChangeListener#propertyChange} on all listeners
706 * registered to listen to a given property. Any method which changes
707 * the specified property of this component should call this method.
709 * @param propertyName The property which changed
710 * @param oldValue The old value of the property
711 * @param newValue The new value of the property
713 * @see #changeSupport
714 * @see #addPropertyChangeListener
715 * @see #removePropertyChangeListener
717 protected void firePropertyChange(String propertyName, Object oldValue,
718 Object newValue)
720 if (changeSupport != null)
721 changeSupport.firePropertyChange(propertyName, oldValue, newValue);
725 * A variant of {@link #firePropertyChange(String,Object,Object)}
726 * for properties with <code>short</code> values.
728 public void firePropertyChange(String propertyName, short oldValue,
729 short newValue)
731 if (changeSupport != null)
732 changeSupport.firePropertyChange(propertyName, new Short(oldValue),
733 new Short(newValue));
737 * Call {@link VetoableChangeListener#vetoableChange} on all listeners
738 * registered to listen to a given property. Any method which changes
739 * the specified property of this component should call this method.
741 * @param propertyName The property which changed
742 * @param oldValue The old value of the property
743 * @param newValue The new value of the property
745 * @throws PropertyVetoException if the change was vetoed by a listener
747 * @see addVetoableChangeListener
748 * @see removeVetoableChangeListener
750 protected void fireVetoableChange(String propertyName, Object oldValue,
751 Object newValue)
752 throws PropertyVetoException
754 VetoableChangeListener[] listeners = getVetoableChangeListeners();
756 PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
758 for (int i = 0; i < listeners.length; i++)
759 listeners[i].vetoableChange(evt);
763 * Get the value of the accessibleContext property for this component.
765 * @return the current value of the property
767 public AccessibleContext getAccessibleContext()
769 return null;
774 * Get the value of the {@link #alignmentX} property.
776 * @return The current value of the property.
778 * @see #setAlignmentX
779 * @see #alignmentY
781 public float getAlignmentX()
783 return alignmentX;
787 * Get the value of the {@link #alignmentY} property.
789 * @return The current value of the property.
791 * @see #setAlignmentY
792 * @see #alignmentX
794 public float getAlignmentY()
796 return alignmentY;
800 * Get the current value of the {@link #autoscrolls} property.
802 * @return The current value of the property
804 public boolean getAutoscrolls()
806 return autoscrolls;
810 * Set the value of the {@link #border} property, revalidate
811 * and repaint this component.
813 * @param newBorder The new value of the property
815 * @see #getBorder
817 public void setBorder(Border newBorder)
819 Border oldBorder = border;
820 border = newBorder;
821 firePropertyChange("border", oldBorder, newBorder);
822 revalidate();
823 repaint();
827 * Get the value of the {@link #border} property.
829 * @return The property's current value
831 * @see #setBorder
833 public Border getBorder()
835 return border;
839 * Get the component's current bounding box. If a rectangle is provided,
840 * use this as the return value (adjusting its fields in place);
841 * otherwise (of <code>null</code> is provided) return a new {@link
842 * Rectangle}.
844 * @param rv Optional return value to use
846 * @return A rectangle bounding the component
848 public Rectangle getBounds(Rectangle rv)
850 if (rv == null)
851 return new Rectangle(getX(), getY(), getWidth(), getHeight());
852 else
854 rv.setBounds(getX(), getY(), getWidth(), getHeight());
855 return rv;
860 * Prepares a graphics context for painting this object. If {@link
861 * #debugGraphicsOptions} is not equal to {@link
862 * DebugGraphics#NONE_OPTION}, produce a new {@link DebugGraphics} object
863 * wrapping the parameter. Otherwise configure the parameter with this
864 * component's foreground color and font.
866 * @param g The graphics context to wrap or configure
868 * @return A graphics context to paint this object with
870 * @see #debugGraphicsOptions
871 * @see #paint
873 protected Graphics getComponentGraphics(Graphics g)
875 Graphics g2 = g.create();
876 g2.setFont(this.getFont());
877 g2.setColor(this.getForeground());
878 return g2;
883 * Get the value of the {@link #debugGraphicsOptions} property.
885 * @return The current value of the property.
887 * @see #setDebugGraphicsOptions
888 * @see #debugGraphicsOptions
890 public int getDebugGraphicsOptions()
892 return 0;
896 * Get the component's insets, which are calculated from
897 * the {@link #border} property. If the border is <code>null</code>,
898 * calls {@link Container#getInsets}.
900 * @return The component's current insets
902 public Insets getInsets()
904 if (border == null)
905 return super.getInsets();
906 return getBorder().getBorderInsets(this);
910 * Get the component's insets, which are calculated from the {@link
911 * #border} property. If the border is <code>null</code>, calls {@link
912 * Container#getInsets}. The passed-in {@link Insets} value will be
913 * used as the return value, if possible.
915 * @param insets Return value object to reuse, if possible
917 * @return The component's current insets
919 public Insets getInsets(Insets insets)
921 Insets t = getInsets();
923 if (insets == null)
924 return t;
926 insets.left = t.left;
927 insets.right = t.right;
928 insets.top = t.top;
929 insets.bottom = t.bottom;
930 return insets;
934 * Get the component's location. The passed-in {@link Point} value
935 * will be used as the return value, if possible.
937 * @param rv Return value object to reuse, if possible
939 * @return The component's current location
941 public Point getLocation(Point rv)
943 if (rv == null)
944 return new Point(getX(), getY());
946 rv.setLocation(getX(), getY());
947 return rv;
951 * Get the component's maximum size. If the {@link #maximumSize} property
952 * has been explicitly set, it is returned. If the {@link #maximumSize}
953 * property has not been set but the {@link ui} property has been, the
954 * result of {@link ComponentUI#getMaximumSize} is returned. If neither
955 * property has been set, the result of {@link Container#getMaximumSize}
956 * is returned.
958 * @return The maximum size of the component
960 * @see #maximumSize
961 * @see #setMaximumSize
963 public Dimension getMaximumSize()
965 if (maximumSize != null)
966 return maximumSize;
968 if (ui != null)
970 Dimension s = ui.getMaximumSize(this);
971 if (s != null)
972 return s;
975 Dimension p = super.getMaximumSize();
976 return p;
980 * Get the component's minimum size. If the {@link #minimumSize} property
981 * has been explicitly set, it is returned. If the {@link #minimumSize}
982 * property has not been set but the {@link ui} property has been, the
983 * result of {@link ComponentUI#getMinimumSize} is returned. If neither
984 * property has been set, the result of {@link Container#getMinimumSize}
985 * is returned.
987 * @return The minimum size of the component
989 * @see #minimumSize
990 * @see #setMinimumSize
992 public Dimension getMinimumSize()
994 if (minimumSize != null)
995 return minimumSize;
997 if (ui != null)
999 Dimension s = ui.getMinimumSize(this);
1000 if (s != null)
1001 return s;
1004 Dimension p = super.getMinimumSize();
1005 return p;
1009 * Get the component's preferred size. If the {@link #preferredSize}
1010 * property has been explicitly set, it is returned. If the {@link
1011 * #preferredSize} property has not been set but the {@link ui} property
1012 * has been, the result of {@link ComponentUI#getPreferredSize} is
1013 * returned. If neither property has been set, the result of {@link
1014 * Container#getPreferredSize} is returned.
1016 * @return The preferred size of the component
1018 * @see #preferredSize
1019 * @see #setPreferredSize
1021 public Dimension getPreferredSize()
1023 if (preferredSize != null)
1024 return preferredSize;
1026 if (ui != null)
1028 Dimension s = ui.getPreferredSize(this);
1029 if (s != null)
1030 return s;
1032 Dimension p = super.getPreferredSize();
1033 return p;
1037 * Checks if a maximum size was explicitely set on the component.
1039 * @return <code>true</code> if a maximum size was set,
1040 * <code>false</code> otherwise
1042 * @since 1.3
1044 public boolean isMaximumSizeSet()
1046 return maximumSize != null;
1050 * Checks if a minimum size was explicitely set on the component.
1052 * @return <code>true</code> if a minimum size was set,
1053 * <code>false</code> otherwise
1055 * @since 1.3
1057 public boolean isMinimumSizeSet()
1059 return minimumSize != null;
1063 * Checks if a preferred size was explicitely set on the component.
1065 * @return <code>true</code> if a preferred size was set,
1066 * <code>false</code> otherwise
1068 * @since 1.3
1070 public boolean isPreferredSizeSet()
1072 return preferredSize != null;
1076 * Return the value of the {@link #nextFocusableComponent} property.
1078 * @return The current value of the property, or <code>null</code>
1079 * if none has been set.
1081 * @deprecated See {@link java.awt.FocusTraversalPolicy}
1083 public Component getNextFocusableComponent()
1085 return null;
1089 * Return the set of {@link KeyStroke} objects which are registered
1090 * to initiate actions on this component.
1092 * @return An array of the registered keystrokes
1094 public KeyStroke[] getRegisteredKeyStrokes()
1096 return null;
1100 * Returns the first ancestor of this component which is a {@link JRootPane}.
1101 * Equivalent to calling <code>SwingUtilities.getRootPane(this);</code>.
1103 * @return An ancestral JRootPane, or <code>null</code> if none exists.
1105 public JRootPane getRootPane()
1107 JRootPane p = SwingUtilities.getRootPane(this);
1108 return p;
1112 * Get the component's size. The passed-in {@link Dimension} value
1113 * will be used as the return value, if possible.
1115 * @param rv Return value object to reuse, if possible
1117 * @return The component's current size
1119 public Dimension getSize(Dimension rv)
1121 if (rv == null)
1122 return new Dimension(getWidth(), getHeight());
1123 else
1125 rv.setSize(getWidth(), getHeight());
1126 return rv;
1131 * Return the {@link #toolTip} property of this component, creating it and
1132 * setting it if it is currently <code>null</code>. This method can be
1133 * overridden in subclasses which wish to control the exact form of
1134 * tooltip created.
1136 * @return The current toolTip
1138 public JToolTip createToolTip()
1140 JToolTip toolTip = new JToolTip();
1141 toolTip.setComponent(this);
1142 toolTip.setTipText(toolTipText);
1144 return toolTip;
1148 * Return the location at which the {@link #toolTip} property should be
1149 * displayed, when triggered by a particular mouse event.
1151 * @param event The event the tooltip is being presented in response to
1153 * @return The point at which to display a tooltip, or <code>null</code>
1154 * if swing is to choose a default location.
1156 public Point getToolTipLocation(MouseEvent event)
1158 return null;
1162 * Set the value of the {@link #toolTipText} property.
1164 * @param text The new property value
1166 * @see #getToolTipText
1168 public void setToolTipText(String text)
1170 if (text == null)
1172 ToolTipManager.sharedInstance().unregisterComponent(this);
1173 toolTipText = null;
1174 return;
1177 // XXX: The tip text doesn't get updated unless you set it to null
1178 // and then to something not-null. This is consistent with the behaviour
1179 // of Sun's ToolTipManager.
1181 String oldText = toolTipText;
1182 toolTipText = text;
1184 if (oldText == null)
1185 ToolTipManager.sharedInstance().registerComponent(this);
1189 * Get the value of the {@link #toolTipText} property.
1191 * @return The current property value
1193 * @see #setToolTipText
1195 public String getToolTipText()
1197 return toolTipText;
1201 * Get the value of the {@link #toolTipText} property, in response to a
1202 * particular mouse event.
1204 * @param event The mouse event which triggered the tooltip
1206 * @return The current property value
1208 * @see #setToolTipText
1210 public String getToolTipText(MouseEvent event)
1212 return getToolTipText();
1216 * Return the top level ancestral container (usually a {@link
1217 * java.awt.Window} or {@link java.awt.Applet}) which this component is
1218 * contained within, or <code>null</code> if no ancestors exist.
1220 * @return The top level container, if it exists
1222 public Container getTopLevelAncestor()
1224 Container c = getParent();
1225 for (Container peek = c; peek != null; peek = peek.getParent())
1226 c = peek;
1227 return c;
1231 * Compute the component's visible rectangle, which is defined
1232 * recursively as either the component's bounds, if it has no parent, or
1233 * the intersection of the component's bounds with the visible rectangle
1234 * of its parent.
1236 * @param rect The return value slot to place the visible rectangle in
1238 public void computeVisibleRect(Rectangle rect)
1240 Component c = getParent();
1241 if (c != null && c instanceof JComponent)
1243 ((JComponent) c).computeVisibleRect(rect);
1244 rect.translate(-getX(), -getY());
1245 Rectangle2D.intersect(rect,
1246 new Rectangle(0, 0, getWidth(), getHeight()),
1247 rect);
1249 else
1250 rect.setRect(0, 0, getWidth(), getHeight());
1254 * Return the component's visible rectangle in a new {@link Rectangle},
1255 * rather than via a return slot.
1257 * @return The component's visible rectangle
1259 * @see #computeVisibleRect(Rectangle)
1261 public Rectangle getVisibleRect()
1263 Rectangle r = new Rectangle();
1264 computeVisibleRect(r);
1265 return r;
1269 * <p>Requests that this component receive input focus, giving window
1270 * focus to the top level ancestor of this component. Only works on
1271 * displayable, focusable, visible components.</p>
1273 * <p>This method should not be called by clients; it is intended for
1274 * focus implementations. Use {@link Component#requestFocus} instead.</p>
1276 * @see {@link Component#requestFocus}
1278 public void grabFocus()
1283 * Get the value of the {@link #doubleBuffered} property.
1285 * @return The property's current value
1287 public boolean isDoubleBuffered()
1289 return doubleBuffered;
1293 * Return <code>true</code> if the provided component has no native peer;
1294 * in other words, if it is a "lightweight component".
1296 * @param c The component to test for lightweight-ness
1298 * @return Whether or not the component is lightweight
1300 public static boolean isLightweightComponent(Component c)
1302 return c.getPeer() instanceof LightweightPeer;
1306 * Return <code>true</code> if you wish this component to manage its own
1307 * focus. In particular: if you want this component to be sent
1308 * <code>TAB</code> and <code>SHIFT+TAB</code> key events, and to not
1309 * have its children considered as focus transfer targets. If
1310 * <code>true</code>, focus traversal around this component changes to
1311 * <code>CTRL+TAB</code> and <code>CTRL+SHIFT+TAB</code>.
1313 * @return <code>true</code> if you want this component to manage its own
1314 * focus, otherwise (by default) <code>false</code>
1316 * @deprecated 1.4 Use {@link Component.setFocusTraversalKeys(int,Set)} and
1317 * {@link Container.setFocusCycleRoot(boolean)} instead
1319 public boolean isManagingFocus()
1321 return false;
1325 * Return the current value of the {@link opaque} property.
1327 * @return The current property value
1329 public boolean isOpaque()
1331 return opaque;
1335 * Return <code>true</code> if the component can guarantee that none of its
1336 * children will overlap in Z-order. This is a hint to the painting system.
1337 * The default is to return <code>true</code>, but some components such as
1338 * {@link JLayeredPane} should override this to return <code>false</code>.
1340 * @return Whether the component tiles its children
1342 public boolean isOptimizedDrawingEnabled()
1344 return true;
1348 * Return <code>true</code> if this component is currently painting a tile.
1350 * @return Whether the component is painting a tile
1352 public boolean isPaintingTile()
1354 return false;
1358 * Get the value of the {@link #requestFocusEnabled} property.
1360 * @return The current value of the property
1362 public boolean isRequestFocusEnabled()
1364 return requestFocusEnabled;
1368 * Return <code>true</code> if this component is a validation root; this
1369 * will cause calls to {@link #invalidate} in this component's children
1370 * to be "captured" at this component, and not propagate to its parents.
1371 * For most components this should return <code>false</code>, but some
1372 * components such as {@link JViewPort} will want to return
1373 * <code>true</code>.
1375 * @return Whether this component is a validation root
1377 public boolean isValidateRoot()
1379 return false;
1383 * <p>Paint the component. This is a delicate process, and should only be
1384 * called from the repaint thread, under control of the {@link
1385 * RepaintManager}. Client code should usually call {@link #repaint} to
1386 * trigger painting.</p>
1388 * <p>This method will acquire a double buffer from the {@link
1389 * RepaintManager} if the component's {@link #doubleBuffered} property is
1390 * <code>true</code> and the <code>paint</code> call is the
1391 * <em>first</em> recursive <code>paint</code> call inside swing.</p>
1393 * <p>The method will also modify the provided {@link Graphics} context
1394 * via the {@link #getComponentGraphics} method. If you want to customize
1395 * the graphics object used for painting, you should override that method
1396 * rather than <code>paint</code>.</p>
1398 * <p>The body of the <code>paint</code> call involves calling {@link
1399 * #paintComponent}, {@link #paintBorder}, and {@link #paintChildren} in
1400 * order. If you want to customize painting behavior, you should override
1401 * one of these methods rather than <code>paint</code>.</p>
1403 * <p>For more details on the painting sequence, see <a
1404 * href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
1405 * article</a>.</p>
1407 * @param g The graphics context to paint with
1409 * @see #paintImmediately
1411 public void paint(Graphics g)
1413 Graphics g2 = g;
1414 Image doubleBuffer = null;
1415 RepaintManager rm = RepaintManager.currentManager(this);
1417 if (isDoubleBuffered()
1418 && (rm.isDoubleBufferingEnabled())
1419 && (! Thread.holdsLock(paintLock)))
1421 doubleBuffer = rm.getOffscreenBuffer(this, getWidth(), getHeight());
1424 synchronized (paintLock)
1426 if (doubleBuffer != null)
1428 g2 = doubleBuffer.getGraphics();
1429 g2.setClip(g.getClipBounds());
1432 g2 = getComponentGraphics(g2);
1433 paintComponent(g2);
1434 paintBorder(g2);
1435 paintChildren(g2);
1437 if (doubleBuffer != null)
1438 g.drawImage(doubleBuffer, 0, 0, (ImageObserver) null);
1443 * Paint the component's border. This usually means calling {@link
1444 * Border#paintBorder} on the {@link #border} property, if it is
1445 * non-<code>null</code>. You may override this if you wish to customize
1446 * border painting behavior. The border is painted after the component's
1447 * body, but before the component's children.
1449 * @param g The graphics context with which to paint the border
1451 * @see #paint
1452 * @see #paintChildren
1453 * @see #paintComponent
1455 protected void paintBorder(Graphics g)
1457 if (getBorder() != null)
1458 getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
1462 * Paint the component's children. This usually means calling {@link
1463 * Container#paint}, which recursively calls {@link #paint} on any of the
1464 * component's children, with appropriate changes to coordinate space and
1465 * clipping region. You may override this if you wish to customize
1466 * children painting behavior. The children are painted after the
1467 * component's body and border.
1469 * @param g The graphics context with which to paint the children
1471 * @see #paint
1472 * @see #paintBorder
1473 * @see #paintComponent
1475 protected void paintChildren(Graphics g)
1477 super.paint(g);
1481 * Paint the component's body. This usually means calling {@link
1482 * ComponentUI#update} on the {@link #ui} property of the component, if
1483 * it is non-<code>null</code>. You may override this if you wish to
1484 * customize the component's body-painting behavior. The component's body
1485 * is painted first, before the border and children.
1487 * @param g The graphics context with which to paint the body
1489 * @see #paint
1490 * @see #paintBorder
1491 * @see #paintChildren
1493 protected void paintComponent(Graphics g)
1495 if (ui != null)
1496 ui.update(g, this);
1500 * A variant of {@link #paintImmediately(Rectangle)} which takes
1501 * integer parameters.
1503 * @param x The left x coordinate of the dirty region
1504 * @param y The top y coordinate of the dirty region
1505 * @param w The width of the dirty region
1506 * @param h The height of the dirty region
1508 public void paintImmediately(int x, int y, int w, int h)
1510 paintImmediately(new Rectangle(x, y, w, h));
1514 * Transform the provided dirty rectangle for this component into the
1515 * appropriate ancestral {@link JRootPane} and call {@link #paint} on
1516 * that root pane. This method is called from the {@link RepaintManager}
1517 * and should always be called within the painting thread.
1519 * @param r The dirty rectangle to paint
1521 public void paintImmediately(Rectangle r)
1523 Component root = SwingUtilities.getRoot(this);
1524 if (root == null || ! root.isShowing())
1525 return;
1526 Graphics g = root.getGraphics();
1527 if (g == null)
1528 return;
1530 Rectangle clip = SwingUtilities.convertRectangle(this, r, root);
1531 g.setClip(clip);
1532 root.paint(g);
1533 g.dispose();
1537 * Return a string representation for this component, for use in
1538 * debugging.
1540 * @return A string describing this component.
1542 protected String paramString()
1544 StringBuffer sb = new StringBuffer();
1545 sb.append(super.paramString());
1546 sb.append(",alignmentX=").append(getAlignmentX());
1547 sb.append(",alignmentY=").append(getAlignmentY());
1548 sb.append(",border=");
1549 if (getBorder() != null)
1550 sb.append(getBorder());
1551 sb.append(",maximumSize=");
1552 if (getMaximumSize() != null)
1553 sb.append(getMaximumSize());
1554 sb.append(",minimumSize=");
1555 if (getMinimumSize() != null)
1556 sb.append(getMinimumSize());
1557 sb.append(",preferredSize=");
1558 if (getPreferredSize() != null)
1559 sb.append(getPreferredSize());
1560 return sb.toString();
1564 * A variant of {@link
1565 * #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
1566 * provides <code>null</code> for the command name.
1568 public void registerKeyboardAction(ActionListener act,
1569 KeyStroke stroke,
1570 int cond)
1572 registerKeyboardAction(act, null, stroke, cond);
1576 * There is some charmingly undocumented behavior sun seems to be using
1577 * to simulate the old register/unregister keyboard binding API. It's not
1578 * clear to me why this matters, but we shall endeavour to follow suit.
1580 * Two main thing seem to be happening when you do registerKeyboardAction():
1582 * - no actionMap() entry gets created, just an entry in inputMap()
1584 * - the inputMap() entry is a proxy class which invokes the the
1585 * binding's actionListener as a target, and which clobbers the command
1586 * name sent in the ActionEvent, providing the binding command name
1587 * instead.
1589 * This much you can work out just by asking the input and action maps
1590 * what they contain after making bindings, and watching the event which
1591 * gets delivered to the recipient. Beyond that, it seems to be a
1592 * sun-private solution so I will only immitate it as much as it matters
1593 * to external observers.
1596 private static class ActionListenerProxy
1597 extends AbstractAction
1599 ActionListener target;
1600 String bindingCommandName;
1602 public ActionListenerProxy(ActionListener li,
1603 String cmd)
1605 target = li;
1606 bindingCommandName = cmd;
1609 public void actionPerformed(ActionEvent e)
1611 ActionEvent derivedEvent = new ActionEvent(e.getSource(),
1612 e.getID(),
1613 bindingCommandName,
1614 e.getModifiers());
1615 target.actionPerformed(derivedEvent);
1621 * An obsolete method to register a keyboard action on this component.
1622 * You should use <code>getInputMap</code> and <code>getActionMap</code>
1623 * to fetch mapping tables from keystrokes to commands, and commands to
1624 * actions, respectively, and modify those mappings directly.
1626 * @param anAction The action to be registered
1627 * @param aCommand The command to deliver in the delivered {@link
1628 * java.awt.ActionEvent}
1629 * @param aKeyStroke The keystroke to register on
1630 * @param aCondition One of the values {@link #UNDEFINED_CONDITION},
1631 * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or
1632 * {@link #WHEN_IN_FOCUSED_WINDOW}, indicating the condition which must
1633 * be met for the action to be fired
1635 * @see #unregisterKeyboardAction
1636 * @see #getConditionForKeystroke
1637 * @see #resetKeyboardActiond
1639 public void registerKeyboardAction(ActionListener act,
1640 String cmd,
1641 KeyStroke stroke,
1642 int cond)
1644 getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
1649 public final void setInputMap(int condition, InputMap map)
1651 enableEvents(AWTEvent.KEY_EVENT_MASK);
1652 switch (condition)
1654 case WHEN_FOCUSED:
1655 inputMap_whenFocused = map;
1656 break;
1658 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
1659 inputMap_whenAncestorOfFocused = map;
1660 break;
1662 case WHEN_IN_FOCUSED_WINDOW:
1663 inputMap_whenInFocusedWindow = map;
1664 break;
1666 case UNDEFINED_CONDITION:
1667 default:
1668 throw new IllegalArgumentException();
1672 public final InputMap getInputMap(int condition)
1674 enableEvents(AWTEvent.KEY_EVENT_MASK);
1675 switch (condition)
1677 case WHEN_FOCUSED:
1678 if (inputMap_whenFocused == null)
1679 inputMap_whenFocused = new InputMap();
1680 return inputMap_whenFocused;
1682 case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
1683 if (inputMap_whenAncestorOfFocused == null)
1684 inputMap_whenAncestorOfFocused = new InputMap();
1685 return inputMap_whenAncestorOfFocused;
1687 case WHEN_IN_FOCUSED_WINDOW:
1688 if (inputMap_whenInFocusedWindow == null)
1689 inputMap_whenInFocusedWindow = new InputMap();
1690 return inputMap_whenInFocusedWindow;
1692 case UNDEFINED_CONDITION:
1693 default:
1694 return null;
1698 public final InputMap getInputMap()
1700 return getInputMap(WHEN_FOCUSED);
1703 public final ActionMap getActionMap()
1705 if (actionMap == null)
1706 actionMap = new ActionMap();
1707 return actionMap;
1710 public final void setActionMap(ActionMap map)
1712 actionMap = map;
1716 * Return the condition that determines whether a registered action
1717 * occurs in response to the specified keystroke.
1719 * @param aKeyStroke The keystroke to return the condition of
1721 * @return One of the values {@link #UNDEFINED_CONDITION}, {@link
1722 * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, {@link #WHEN_FOCUSED}, or {@link
1723 * #WHEN_IN_FOCUSED_WINDOW}
1725 * @deprecated As of 1.3 KeyStrokes can be registered with multiple
1726 * simultaneous conditions.
1728 * @see #registerKeyboardAction
1729 * @see #unregisterKeyboardAction
1730 * @see #resetKeyboardActiond
1732 public int getConditionForKeyStroke(KeyStroke ks)
1734 if (inputMap_whenFocused != null
1735 && inputMap_whenFocused.get(ks) != null)
1736 return WHEN_FOCUSED;
1737 else if (inputMap_whenAncestorOfFocused != null
1738 && inputMap_whenAncestorOfFocused.get(ks) != null)
1739 return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
1740 else if (inputMap_whenInFocusedWindow != null
1741 && inputMap_whenInFocusedWindow.get(ks) != null)
1742 return WHEN_IN_FOCUSED_WINDOW;
1743 else
1744 return UNDEFINED_CONDITION;
1748 * Get the ActionListener (typically an {@link Action} object) which is
1749 * associated with a particular keystroke.
1751 * @param aKeyStroke The keystroke to retrieve the action of
1753 * @return The action associated with the specified keystroke
1755 * @deprecated Use {@link #getActionMap()}
1757 public ActionListener getActionForKeyStroke(KeyStroke ks)
1759 Object cmd = getInputMap().get(ks);
1760 if (cmd != null)
1762 if (cmd instanceof ActionListenerProxy)
1763 return (ActionListenerProxy) cmd;
1764 else if (cmd instanceof String)
1765 return getActionMap().get(cmd);
1767 return null;
1771 * A hook for subclasses which want to customize event processing.
1773 protected void processComponentKeyEvent(KeyEvent e)
1778 * Override the default key dispatch system from Component to hook into
1779 * the swing {@link InputMap} / {@link ActionMap} system.
1781 * See <a
1782 * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">this
1783 * report</a> for more details, it's somewhat complex.
1785 protected void processKeyEvent(KeyEvent e)
1787 processComponentKeyEvent(e);
1789 // FIXME: this needs to be elaborated significantly, to do all the
1790 // focus / ancestor / window searching for the various binding modes.
1791 if (! e.isConsumed() &&
1792 processKeyBinding(KeyStroke.getKeyStrokeForEvent(e),
1793 e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
1794 e.consume();
1797 protected boolean processKeyBinding(KeyStroke ks,
1798 KeyEvent e,
1799 int condition,
1800 boolean pressed)
1802 if (isEnabled())
1804 Action act = null;
1805 InputMap map = getInputMap(condition);
1806 if (map != null)
1808 Object cmd = map.get(ks);
1809 if (cmd != null)
1811 if (cmd instanceof ActionListenerProxy)
1812 act = (Action) cmd;
1813 else
1814 act = (Action) getActionMap().get(cmd);
1817 if (act != null && act.isEnabled())
1818 return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
1820 return false;
1824 * Remove a keyboard action registry.
1826 * @param stroke The keystroke to unregister
1828 * @see #registerKeyboardAction
1829 * @see #getConditionForKeystroke
1830 * @see #resetKeyboardActiond
1832 public void unregisterKeyboardAction(KeyStroke aKeyStroke)
1838 * Reset all keyboard action registries.
1840 * @see #registerKeyboardAction
1841 * @see #unregisterKeyboardAction
1842 * @see #getConditionForKeystroke
1844 public void resetKeyboardActions()
1846 if (inputMap_whenFocused != null)
1847 inputMap_whenFocused.clear();
1848 if (inputMap_whenAncestorOfFocused != null)
1849 inputMap_whenAncestorOfFocused.clear();
1850 if (inputMap_whenInFocusedWindow != null)
1851 inputMap_whenInFocusedWindow.clear();
1852 if (actionMap != null)
1853 actionMap.clear();
1858 * Mark the described region of this component as dirty in the current
1859 * {@link RepaintManager}. This will queue an asynchronous repaint using
1860 * the system painting thread in the near future.
1862 * @param tm ignored
1863 * @param x coordinate of the region to mark as dirty
1864 * @param y coordinate of the region to mark as dirty
1865 * @param width dimension of the region to mark as dirty
1866 * @param height dimension of the region to mark as dirty
1868 public void repaint(long tm, int x, int y, int width, int height)
1870 Rectangle dirty = new Rectangle(x, y, width, height);
1871 Rectangle vis = getVisibleRect();
1872 dirty = dirty.intersection(vis);
1873 RepaintManager.currentManager(this).addDirtyRegion(this, dirty.x, dirty.y,
1874 dirty.width,
1875 dirty.height);
1879 * Mark the described region of this component as dirty in the current
1880 * {@link RepaintManager}. This will queue an asynchronous repaint using
1881 * the system painting thread in the near future.
1883 * @param r The rectangle to mark as dirty
1885 public void repaint(Rectangle r)
1887 repaint((long) 0, (int) r.getX(), (int) r.getY(), (int) r.getWidth(),
1888 (int) r.getHeight());
1892 * Request focus on the default component of this component's {@link
1893 * FocusTraversalPolicy}.
1895 * @return The result of {@link #requestFocus}
1897 * @deprecated Use {@link #requestFocus()} on the default component provided from
1898 * the {@link FocusTraversalPolicy} instead.
1900 public boolean requestDefaultFocus()
1902 return false;
1906 * Queue a an invalidation and revalidation of this component, using
1907 * {@link RepaintManager#addInvalidComponent}.
1909 public void revalidate()
1911 invalidate();
1912 RepaintManager.currentManager(this).addInvalidComponent(this);
1916 * Calls <code>scrollRectToVisible</code> on the component's parent.
1917 * Components which can service this call should override.
1919 * @param r The rectangle to make visible
1921 public void scrollRectToVisible(Rectangle r)
1923 Component p = getParent();
1924 if (p instanceof JComponent)
1925 ((JComponent) p).scrollRectToVisible(r);
1929 * Set the value of the {@link #alignmentX} property.
1931 * @param a The new value of the property
1933 public void setAlignmentX(float a)
1935 alignmentX = a;
1939 * Set the value of the {@link #alignmentY} property.
1941 * @param a The new value of the property
1943 public void setAlignmentY(float a)
1945 alignmentY = a;
1949 * Set the value of the {@link #autoscrolls} property.
1951 * @param a The new value of the property
1953 public void setAutoscrolls(boolean a)
1955 autoscrolls = a;
1959 * Set the value of the {@link #debugGraphicsOptions} property.
1961 * @param debugOptions The new value of the property
1963 public void setDebugGraphicsOptions(int debugOptions)
1965 debugGraphicsOptions = debugOptions;
1969 * Set the value of the {@link #doubleBuffered} property.
1971 * @param db The new value of the property
1973 public void setDoubleBuffered(boolean db)
1975 doubleBuffered = db;
1979 * Set the value of the {@link #enabled} property, revalidate
1980 * and repaint this component.
1982 * @param enable The new value of the property
1984 public void setEnabled(boolean enable)
1986 boolean oldEnabled = isEnabled();
1987 super.setEnabled(enable);
1988 firePropertyChange("enabeld", oldEnabled, enable);
1989 revalidate();
1990 repaint();
1994 * Set the value of the {@link #font} property, revalidate
1995 * and repaint this component.
1997 * @param f The new value of the property
1999 public void setFont(Font f)
2001 super.setFont(f);
2002 revalidate();
2003 repaint();
2007 * Set the value of the {@link #background} property, revalidate
2008 * and repaint this component.
2010 * @param bg The new value of the property
2012 public void setBackground(Color bg)
2014 super.setBackground(bg);
2015 revalidate();
2016 repaint();
2020 * Set the value of the {@link #foreground} property, revalidate
2021 * and repaint this component.
2023 * @param fg The new value of the property
2025 public void setForeground(Color fg)
2027 super.setForeground(fg);
2028 revalidate();
2029 repaint();
2033 * Set the value of the {@link #maximumSize} property, revalidate
2034 * and repaint this component.
2036 * @param max The new value of the property
2038 public void setMaximumSize(Dimension max)
2040 Dimension oldMaximumSize = maximumSize;
2041 maximumSize = max;
2042 firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
2043 revalidate();
2044 repaint();
2048 * Set the value of the {@link #minimumSize} property, revalidate
2049 * and repaint this component.
2051 * @param min The new value of the property
2053 public void setMinimumSize(Dimension min)
2055 Dimension oldMinimumSize = minimumSize;
2056 minimumSize = min;
2057 firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
2058 revalidate();
2059 repaint();
2063 * Set the value of the {@link #preferredSize} property, revalidate
2064 * and repaint this component.
2066 * @param pref The new value of the property
2068 public void setPreferredSize(Dimension pref)
2070 Dimension oldPreferredSize = preferredSize;
2071 preferredSize = pref;
2072 firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
2076 * Set the specified component to be the next component in the
2077 * focus cycle, overriding the {@link FocusTraversalPolicy} for
2078 * this component.
2080 * @param aComponent The component to set as the next focusable
2082 * @deprecated Use FocusTraversalPolicy instead
2084 public void setNextFocusableComponent(Component aComponent)
2089 * Set the value of the {@link #requestFocusEnabled} property.
2091 * @param e The new value of the property
2093 public void setRequestFocusEnabled(boolean e)
2095 requestFocusEnabled = e;
2099 * Get the value of the {@link #transferHandler} property.
2101 * @return The current value of the property
2103 * @see ComponentUI#setTransferHandler
2106 public TransferHandler getTransferHandler()
2108 return transferHandler;
2112 * Set the value of the {@link #transferHandler} property.
2114 * @param newHandler The new value of the property
2116 * @see ComponentUI#getTransferHandler
2119 public void setTransferHandler(TransferHandler newHandler)
2121 if (transferHandler == newHandler)
2122 return;
2124 TransferHandler oldHandler = transferHandler;
2125 transferHandler = newHandler;
2126 firePropertyChange("transferHandler", oldHandler, newHandler);
2130 * Set the value of the {@link #opaque} property, revalidate and repaint
2131 * this component.
2133 * @param isOpaque The new value of the property
2135 * @see ComponentUI#update
2137 public void setOpaque(boolean isOpaque)
2139 boolean oldOpaque = opaque;
2140 opaque = isOpaque;
2141 firePropertyChange("opaque", oldOpaque, opaque);
2142 revalidate();
2143 repaint();
2147 * Set the value of the visible property, and revalidate / repaint the
2148 * component.
2150 * @param v The new value of the property
2152 public void setVisible(boolean v)
2154 super.setVisible(v);
2155 revalidate();
2156 repaint();
2160 * Call {@link paint}.
2162 * @param g The graphics context to paint into
2164 public void update(Graphics g)
2166 paint(g);
2170 * Get the value of the UIClassID property. This property should be a key
2171 * in the {@link UIDefaults} table managed by {@link UIManager}, the
2172 * value of which is the name of a class to load for the component's
2173 * {@link ui} property.
2175 * @return A "symbolic" name which will map to a class to use for the
2176 * component's UI, such as <code>"ComponentUI"</code>
2178 * @see #setUI
2179 * @see #updateUI
2181 public String getUIClassID()
2183 return "ComponentUI";
2187 * Install a new UI delegate as the component's {@link ui} property. In
2188 * the process, this will call {@link ComponentUI.uninstallUI} on any
2189 * existing value for the {@link ui} property, and {@link
2190 * ComponentUI.installUI} on the new UI delegate.
2192 * @param newUI The new UI delegate to install
2194 * @see #updateUI
2195 * @see #getUIClassID
2197 protected void setUI(ComponentUI newUI)
2199 if (ui != null)
2200 ui.uninstallUI(this);
2202 ComponentUI oldUI = ui;
2203 ui = newUI;
2205 if (ui != null)
2206 ui.installUI(this);
2208 firePropertyChange("UI", oldUI, newUI);
2210 revalidate();
2211 repaint();
2215 * This method should be overridden in subclasses. In JComponent, the
2216 * method does nothing. In subclasses, it should a UI delegate
2217 * (corresponding to the symbolic name returned from {@link
2218 * getUIClassID}) from the {@link UIManager}, and calls {@link setUI}
2219 * with the new delegate.
2221 public void updateUI()
2223 System.out.println("update UI not overwritten in class: " + this);
2226 public static Locale getDefaultLocale()
2228 return defaultLocale;
2231 public static void setDefaultLocale(Locale l)
2233 defaultLocale = l;
2237 * Returns the currently set input verifier for this component.
2239 * @return the input verifier, or <code>null</code> if none
2241 public InputVerifier getInputVerifier()
2243 return inputVerifier;
2247 * Sets the input verifier to use by this component.
2249 * @param verifier the input verifier, or <code>null</code>
2251 public void setInputVerifier(InputVerifier verifier)
2253 InputVerifier oldVerifier = inputVerifier;
2254 inputVerifier = verifier;
2255 firePropertyChange("inputVerifier", oldVerifier, verifier);
2259 * @since 1.3
2261 public boolean getVerifyInputWhenFocusTarget()
2263 return verifyInputWhenFocusTarget;
2267 * @since 1.3
2269 public void setVerifyInputWhenFocusTarget(boolean verifyInputWhenFocusTarget)
2271 if (this.verifyInputWhenFocusTarget == verifyInputWhenFocusTarget)
2272 return;
2274 this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
2275 firePropertyChange("verifyInputWhenFocusTarget",
2276 ! verifyInputWhenFocusTarget,
2277 verifyInputWhenFocusTarget);