Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / javax / swing / AbstractButton.java
blob376b3a056ae222e64b54e32b7d7b7e974ed3387a
1 /* AbstractButton.java -- Provides basic button functionality.
2 Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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. */
38 package javax.swing;
40 import java.awt.Graphics;
41 import java.awt.Image;
42 import java.awt.Insets;
43 import java.awt.ItemSelectable;
44 import java.awt.Point;
45 import java.awt.Rectangle;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.awt.event.ItemEvent;
49 import java.awt.event.ItemListener;
50 import java.awt.image.ImageObserver;
51 import java.beans.PropertyChangeEvent;
52 import java.beans.PropertyChangeListener;
53 import java.io.Serializable;
55 import javax.accessibility.AccessibleAction;
56 import javax.accessibility.AccessibleIcon;
57 import javax.accessibility.AccessibleRelationSet;
58 import javax.accessibility.AccessibleStateSet;
59 import javax.accessibility.AccessibleText;
60 import javax.accessibility.AccessibleValue;
61 import javax.swing.event.ChangeEvent;
62 import javax.swing.event.ChangeListener;
63 import javax.swing.plaf.ButtonUI;
64 import javax.swing.text.AttributeSet;
67 /**
68 * Provides an abstract implementation of common button behaviour,
69 * data model and look & feel.
71 * <p>This class is supposed to serve as a base class for
72 * several kinds of buttons with similar but non-identical semantics:
73 * toggle buttons (radio buttons and checkboxes), simple push buttons,
74 * menu items, etc.</p>
76 * <p>Buttons have many properties, some of which are stored in this class
77 * while others are delegated to the button's model. The following properties
78 * are available:</p>
80 * <table>
81 * <tr><th>Property </th><th>Stored in</th><th>Bound?</th></tr>
83 * <tr><td>action </td><td>button</td> <td>no</td></tr>
84 * <tr><td>actionCommand </td><td>model</td> <td>no</td></tr>
85 * <tr><td>borderPainted </td><td>button</td> <td>yes</td></tr>
86 * <tr><td>contentAreaFilled </td><td>button</td> <td>yes</td></tr>
87 * <tr><td>disabledIcon </td><td>button</td> <td>yes</td></tr>
88 * <tr><td>disabledSelectedIcon </td><td>button</td> <td>yes</td></tr>
89 * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr>
90 * <tr><td>enabled </td><td>model</td> <td>no</td></tr>
91 * <tr><td>focusPainted </td><td>button</td> <td>yes</td></tr>
92 * <tr><td>horizontalAlignment </td><td>button</td> <td>yes</td></tr>
93 * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr>
94 * <tr><td>icon </td><td>button</td> <td>yes</td></tr>
95 * <tr><td>iconTextGap </td><td>button</td> <td>no</td></tr>
96 * <tr><td>label (same as text) </td><td>model</td> <td>yes</td></tr>
97 * <tr><td>margin </td><td>button</td> <td>yes</td></tr>
98 * <tr><td>multiClickThreshold </td><td>button</td> <td>no</td></tr>
99 * <tr><td>pressedIcon </td><td>button</td> <td>yes</td></tr>
100 * <tr><td>rolloverEnabled </td><td>button</td> <td>yes</td></tr>
101 * <tr><td>rolloverIcon </td><td>button</td> <td>yes</td></tr>
102 * <tr><td>rolloverSelectedIcon </td><td>button</td> <td>yes</td></tr>
103 * <tr><td>selected </td><td>model</td> <td>no</td></tr>
104 * <tr><td>selectedIcon </td><td>button</td> <td>yes</td></tr>
105 * <tr><td>selectedObjects </td><td>button</td> <td>no</td></tr>
106 * <tr><td>text </td><td>model</td> <td>yes</td></tr>
107 * <tr><td>UI </td><td>button</td> <td>yes</td></tr>
108 * <tr><td>verticalAlignment </td><td>button</td> <td>yes</td></tr>
109 * <tr><td>verticalTextPosition </td><td>button</td> <td>yes</td></tr>
111 * </table>
113 * <p>The various behavioral aspects of these properties follows:</p>
115 * <ul>
117 * <li>When non-bound properties stored in the button change, the button
118 * fires ChangeEvents to its ChangeListeners.</li>
120 * <li>When bound properties stored in the button change, the button fires
121 * PropertyChangeEvents to its PropertyChangeListeners</li>
123 * <li>If any of the model's properties change, it fires a ChangeEvent to
124 * its ChangeListeners, which include the button.</li>
126 * <li>If the button receives a ChangeEvent from its model, it will
127 * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's
128 * "source" property set to refer to the button, rather than the model. The
129 * the button will request a repaint, to paint its updated state.</li>
131 * <li>If the model's "selected" property changes, the model will fire an
132 * ItemEvent to its ItemListeners, which include the button, in addition to
133 * the ChangeEvent which models the property change. The button propagates
134 * ItemEvents directly to its ItemListeners.</li>
136 * <li>If the model's armed and pressed properties are simultaneously
137 * <code>true</code>, the model will fire an ActionEvent to its
138 * ActionListeners, which include the button. The button will propagate
139 * this ActionEvent to its ActionListeners, with the ActionEvent's "source"
140 * property set to refer to the button, rather than the model.</li>
142 * </ul>
144 * @author Ronald Veldema (rveldema@cs.vu.nl)
145 * @author Graydon Hoare (graydon@redhat.com)
148 public abstract class AbstractButton extends JComponent
149 implements ItemSelectable, SwingConstants
151 private static final long serialVersionUID = -937921345538462020L;
154 * An extension of ChangeListener to be serializable.
156 protected class ButtonChangeListener
157 implements ChangeListener, Serializable
159 private static final long serialVersionUID = 1471056094226600578L;
162 * Notified when the target of the listener changes its state.
164 * @param ev the ChangeEvent describing the change
166 public void stateChanged(ChangeEvent ev)
168 AbstractButton.this.fireStateChanged();
169 repaint();
173 /** The icon displayed by default. */
174 Icon default_icon;
176 /** The icon displayed when the button is pressed. */
177 Icon pressed_icon;
179 /** The icon displayed when the button is disabled. */
180 Icon disabeldIcon;
182 /** The icon displayed when the button is selected. */
183 Icon selectedIcon;
185 /** The icon displayed when the button is selected but disabled. */
186 Icon disabledSelectedIcon;
188 /** The icon displayed when the button is rolled over. */
189 Icon rolloverIcon;
191 /** The icon displayed when the button is selected and rolled over. */
192 Icon rolloverSelectedIcon;
194 /** The icon currently displayed. */
195 Icon current_icon;
197 /** The text displayed in the button. */
198 String text;
201 * The gap between icon and text, if both icon and text are
202 * non-<code>null</code>.
204 int iconTextGap;
206 /** The vertical alignment of the button's text and icon. */
207 int verticalAlignment;
209 /** The horizontal alignment of the button's text and icon. */
210 int horizontalAlignment;
212 /** The horizontal position of the button's text relative to its icon. */
213 int horizontalTextPosition;
215 /** The vertical position of the button's text relative to its icon. */
216 int verticalTextPosition;
218 /** Whether or not the button paints its border. */
219 boolean borderPainted;
221 /** Whether or not the button paints its focus state. */
222 boolean focusPainted;
224 /** Whether or not the button fills its content area. */
225 boolean contentAreaFilled;
227 /** Whether rollover is enabled. */
228 boolean rollOverEnabled;
230 /** The action taken when the button is clicked. */
231 Action action;
233 /** The button's current state. */
234 protected ButtonModel model;
236 /** The margin between the button's border and its label. */
237 Insets margin;
240 * A hint to the look and feel class, suggesting which character in the
241 * button's label should be underlined when drawing the label.
243 int mnemonicIndex;
245 /** Listener the button uses to receive ActionEvents from its model. */
246 protected ActionListener actionListener;
248 /** Listener the button uses to receive ItemEvents from its model. */
249 protected ItemListener itemListener;
251 /** Listener the button uses to receive ChangeEvents from its model. */
252 protected ChangeListener changeListener;
255 * The time in miliseconds in which clicks get coalesced into a single
256 * <code>ActionEvent</code>.
258 long multiClickThreshhold;
261 * Listener the button uses to receive PropertyChangeEvents from its
262 * Action.
264 PropertyChangeListener actionPropertyChangeListener;
266 /** ChangeEvent that is fired to button's ChangeEventListeners */
267 protected ChangeEvent changeEvent = new ChangeEvent(this);
270 * Fired in a PropertyChangeEvent when the "borderPainted" property changes.
272 public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted";
275 * Fired in a PropertyChangeEvent when the "contentAreaFilled" property
276 * changes.
278 public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY =
279 "contentAreaFilled";
282 * Fired in a PropertyChangeEvent when the "disabledIcon" property changes.
284 public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon";
287 * Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property
288 * changes.
290 public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY =
291 "disabledSelectedIcon";
294 * Fired in a PropertyChangeEvent when the "focusPainted" property changes.
296 public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted";
299 * Fired in a PropertyChangeEvent when the "horizontalAlignment" property
300 * changes.
302 public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY =
303 "horizontalAlignment";
306 * Fired in a PropertyChangeEvent when the "horizontalTextPosition" property
307 * changes.
309 public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY =
310 "horizontalTextPosition";
313 * Fired in a PropertyChangeEvent when the "icon" property changes. */
314 public static final String ICON_CHANGED_PROPERTY = "icon";
316 /** Fired in a PropertyChangeEvent when the "margin" property changes. */
317 public static final String MARGIN_CHANGED_PROPERTY = "margin";
319 /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */
320 public static final String MNEMONIC_CHANGED_PROPERTY = "mnemonic";
322 /** Fired in a PropertyChangeEvent when the "model" property changes. */
323 public static final String MODEL_CHANGED_PROPERTY = "model";
325 /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */
326 public static final String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon";
329 * Fired in a PropertyChangeEvent when the "rolloverEnabled" property
330 * changes.
332 public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY =
333 "rolloverEnabled";
336 * Fired in a PropertyChangeEvent when the "rolloverIcon" property changes.
338 public static final String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon";
341 * Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property
342 * changes.
344 public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY =
345 "rolloverSelectedIcon";
348 * Fired in a PropertyChangeEvent when the "selectedIcon" property changes.
350 public static final String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon";
352 /** Fired in a PropertyChangeEvent when the "text" property changes. */
353 public static final String TEXT_CHANGED_PROPERTY = "text";
356 * Fired in a PropertyChangeEvent when the "verticalAlignment" property
357 * changes.
359 public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY =
360 "verticalAlignment";
363 * Fired in a PropertyChangeEvent when the "verticalTextPosition" property
364 * changes.
366 public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY =
367 "verticalTextPosition";
370 * A Java Accessibility extension of the AbstractButton.
372 protected abstract class AccessibleAbstractButton
373 extends AccessibleJComponent implements AccessibleAction, AccessibleValue,
374 AccessibleText
376 private static final long serialVersionUID = -5673062525319836790L;
378 protected AccessibleAbstractButton()
380 // Nothing to do here yet.
383 public AccessibleStateSet getAccessibleStateSet()
385 return null; // TODO
388 public String getAccessibleName()
390 return null; // TODO
393 public AccessibleIcon[] getAccessibleIcon()
395 return null; // TODO
398 public AccessibleRelationSet getAccessibleRelationSet()
400 return null; // TODO
403 public AccessibleAction getAccessibleAction()
405 return null; // TODO
408 public AccessibleValue getAccessibleValue()
410 return null; // TODO
413 public int getAccessibleActionCount()
415 return 0; // TODO
418 public String getAccessibleActionDescription(int value0)
420 return null; // TODO
423 public boolean doAccessibleAction(int value0)
425 return false; // TODO
428 public Number getCurrentAccessibleValue()
430 return null; // TODO
433 public boolean setCurrentAccessibleValue(Number value0)
435 return false; // TODO
438 public Number getMinimumAccessibleValue()
440 return null; // TODO
443 public Number getMaximumAccessibleValue()
445 return null; // TODO
448 public AccessibleText getAccessibleText()
450 return null; // TODO
453 public int getIndexAtPoint(Point value0)
455 return 0; // TODO
458 public Rectangle getCharacterBounds(int value0)
460 return null; // TODO
463 public int getCharCount()
465 return 0; // TODO
468 public int getCaretPosition()
470 return 0; // TODO
473 public String getAtIndex(int value0, int value1)
475 return null; // TODO
478 public String getAfterIndex(int value0, int value1)
480 return null; // TODO
483 public String getBeforeIndex(int value0, int value1)
485 return null; // TODO
488 public AttributeSet getCharacterAttribute(int value0)
490 return null; // TODO
493 public int getSelectionStart()
495 return 0; // TODO
498 public int getSelectionEnd()
500 return 0; // TODO
503 public String getSelectedText()
505 return null; // TODO
508 private Rectangle getTextRectangle()
510 return null; // TODO
515 * Creates a new AbstractButton object. Subclasses should call the following
516 * sequence in their constructor in order to initialize the button correctly:
517 * <pre>
518 * super();
519 * init(text, icon);
520 * </pre>
522 * The {@link #init(String, Icon)} method is not called automatically by this
523 * constructor.
525 * @see #init(String, Icon)
527 public AbstractButton()
529 actionListener = createActionListener();
530 changeListener = createChangeListener();
531 itemListener = createItemListener();
533 horizontalAlignment = CENTER;
534 horizontalTextPosition = TRAILING;
535 verticalAlignment = CENTER;
536 verticalTextPosition = CENTER;
537 borderPainted = true;
538 contentAreaFilled = true;
539 focusPainted = true;
540 setFocusable(true);
541 setAlignmentX(CENTER_ALIGNMENT);
542 setAlignmentY(CENTER_ALIGNMENT);
543 setDisplayedMnemonicIndex(-1);
544 setOpaque(true);
545 text = "";
546 updateUI();
550 * Get the model the button is currently using.
552 * @return The current model
554 public ButtonModel getModel()
556 return model;
560 * Set the model the button is currently using. This un-registers all
561 * listeners associated with the current model, and re-registers them
562 * with the new model.
564 * @param newModel The new model
566 public void setModel(ButtonModel newModel)
568 if (newModel == model)
569 return;
571 if (model != null)
573 model.removeActionListener(actionListener);
574 model.removeChangeListener(changeListener);
575 model.removeItemListener(itemListener);
577 ButtonModel old = model;
578 model = newModel;
579 if (model != null)
581 model.addActionListener(actionListener);
582 model.addChangeListener(changeListener);
583 model.addItemListener(itemListener);
585 firePropertyChange(MODEL_CHANGED_PROPERTY, old, model);
586 revalidate();
587 repaint();
590 protected void init(String text, Icon icon)
592 // If text is null, we fall back to the empty
593 // string (which is set using AbstractButton's
594 // constructor).
595 // This way the behavior of the JDK is matched.
596 if(text != null)
597 this.text = text;
599 if (icon != null)
600 default_icon = icon;
604 * <p>Returns the action command string for this button's model.</p>
606 * <p>If the action command was set to <code>null</code>, the button's
607 * text (label) is returned instead.</p>
609 * @return The current action command string from the button's model
611 public String getActionCommand()
613 String ac = model.getActionCommand();
614 if (ac != null)
615 return ac;
616 else
617 return text;
621 * Sets the action command string for this button's model.
623 * @param actionCommand The new action command string to set in the button's
624 * model.
626 public void setActionCommand(String actionCommand)
628 if (model != null)
629 model.setActionCommand(actionCommand);
633 * Adds an ActionListener to the button's listener list. When the
634 * button's model is clicked it fires an ActionEvent, and these
635 * listeners will be called.
637 * @param l The new listener to add
639 public void addActionListener(ActionListener l)
641 listenerList.add(ActionListener.class, l);
645 * Removes an ActionListener from the button's listener list.
647 * @param l The listener to remove
649 public void removeActionListener(ActionListener l)
651 listenerList.remove(ActionListener.class, l);
655 * Returns all added <code>ActionListener</code> objects.
657 * @return an array of listeners
659 * @since 1.4
661 public ActionListener[] getActionListeners()
663 return (ActionListener[]) listenerList.getListeners(ActionListener.class);
667 * Adds an ItemListener to the button's listener list. When the button's
668 * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER
669 * or SELECTED) it fires an ItemEvent, and these listeners will be
670 * called.
672 * @param l The new listener to add
674 public void addItemListener(ItemListener l)
676 listenerList.add(ItemListener.class, l);
680 * Removes an ItemListener from the button's listener list.
682 * @param l The listener to remove
684 public void removeItemListener(ItemListener l)
686 listenerList.remove(ItemListener.class, l);
690 * Returns all added <code>ItemListener</code> objects.
692 * @return an array of listeners
694 * @since 1.4
696 public ItemListener[] getItemListeners()
698 return (ItemListener[]) listenerList.getListeners(ItemListener.class);
702 * Adds a ChangeListener to the button's listener list. When the button's
703 * model changes any of its (non-bound) properties, these listeners will be
704 * called.
706 * @param l The new listener to add
708 public void addChangeListener(ChangeListener l)
710 listenerList.add(ChangeListener.class, l);
714 * Removes a ChangeListener from the button's listener list.
716 * @param l The listener to remove
718 public void removeChangeListener(ChangeListener l)
720 listenerList.remove(ChangeListener.class, l);
724 * Returns all added <code>ChangeListener</code> objects.
726 * @return an array of listeners
728 * @since 1.4
730 public ChangeListener[] getChangeListeners()
732 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
736 * Calls {@link ItemListener#itemStateChanged} on each ItemListener in
737 * the button's listener list.
739 * @param e The event signifying that the button's model changed state
741 protected void fireItemStateChanged(ItemEvent e)
743 e.setSource(this);
744 ItemListener[] listeners = getItemListeners();
746 for (int i = 0; i < listeners.length; i++)
747 listeners[i].itemStateChanged(e);
751 * Calls {@link ActionListener#actionPerformed} on each {@link
752 * ActionListener} in the button's listener list.
754 * @param e The event signifying that the button's model was clicked
756 protected void fireActionPerformed(ActionEvent e)
758 // Dispatch a copy of the given ActionEvent in order to
759 // set the source and action command correctly.
760 ActionEvent ae = new ActionEvent(
761 this,
762 e.getID(),
763 getActionCommand(),
764 e.getWhen(),
765 e.getModifiers());
767 ActionListener[] listeners = getActionListeners();
769 for (int i = 0; i < listeners.length; i++)
770 listeners[i].actionPerformed(ae);
774 * Calls {@link ChangeListener#stateChanged} on each {@link ChangeListener}
775 * in the button's listener list.
777 protected void fireStateChanged()
779 ChangeListener[] listeners = getChangeListeners();
781 for (int i = 0; i < listeners.length; i++)
782 listeners[i].stateChanged(changeEvent);
786 * Get the current keyboard mnemonic value. This value corresponds to a
787 * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
788 * codes) and is used to activate the button when pressed in conjunction
789 * with the "mouseless modifier" of the button's look and feel class, and
790 * when focus is in one of the button's ancestors.
792 * @return The button's current keyboard mnemonic
794 public int getMnemonic()
796 ButtonModel mod = getModel();
797 if (mod != null)
798 return mod.getMnemonic();
799 return -1;
803 * Set the current keyboard mnemonic value. This value corresponds to a
804 * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
805 * codes) and is used to activate the button when pressed in conjunction
806 * with the "mouseless modifier" of the button's look and feel class, and
807 * when focus is in one of the button's ancestors.
809 * @param mne A new mnemonic to use for the button
811 public void setMnemonic(char mne)
813 setMnemonic((int) mne);
817 * Set the current keyboard mnemonic value. This value corresponds to a
818 * single key code (one of the {@link java.awt.event.KeyEvent} VK_*
819 * codes) and is used to activate the button when pressed in conjunction
820 * with the "mouseless modifier" of the button's look and feel class, and
821 * when focus is in one of the button's ancestors.
823 * @param mne A new mnemonic to use for the button
825 public void setMnemonic(int mne)
827 ButtonModel mod = getModel();
828 int old = -1;
829 if (mod != null)
830 old = mod.getMnemonic();
832 if (old != mne)
834 if (mod != null)
835 mod.setMnemonic(mne);
837 if (text != null && !text.equals(""))
839 // Since lower case char = upper case char for
840 // mnemonic, we will convert both text and mnemonic
841 // to upper case before checking if mnemonic character occurs
842 // in the menu item text.
843 int upperCaseMne = Character.toUpperCase((char) mne);
844 String upperCaseText = text.toUpperCase();
845 setDisplayedMnemonicIndex(upperCaseText.indexOf(upperCaseMne));
848 firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne);
849 revalidate();
850 repaint();
854 /**
855 * Sets the button's mnemonic index. The mnemonic index is a hint to the
856 * look and feel class, suggesting which character in the button's label
857 * should be underlined when drawing the label. If the mnemonic index is
858 * -1, no mnemonic will be displayed.
860 * If no mnemonic index is set, the button will choose a mnemonic index
861 * by default, which will be the first occurrence of the mnemonic
862 * character in the button's text.
864 * @param index An offset into the "text" property of the button
865 * @throws IllegalArgumentException If <code>index</code> is not within the
866 * range of legal offsets for the "text" property of the button.
867 * @since 1.4
870 public void setDisplayedMnemonicIndex(int index)
872 if (index < -1 || (text != null && index >= text.length()))
873 throw new IllegalArgumentException();
875 mnemonicIndex = index;
878 /**
879 * Get the button's mnemonic index, which is an offset into the button's
880 * "text" property. The character specified by this offset should be
881 * underlined when the look and feel class draws this button.
883 * @return An index into the button's "text" property
885 public int getDisplayedMnemonicIndex()
887 return mnemonicIndex;
892 * Set the "rolloverEnabled" property. When rollover is enabled, and the
893 * look and feel supports it, the button will change its icon to
894 * rolloverIcon, when the mouse passes over it.
896 * @param r Whether or not to enable rollover icon changes
898 public void setRolloverEnabled(boolean r)
900 if (rollOverEnabled != r)
902 rollOverEnabled = r;
903 firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, !r, r);
904 revalidate();
905 repaint();
910 * Returns whether or not rollover icon changes are enabled on the
911 * button.
913 * @return The state of the "rolloverEnabled" property
915 public boolean isRolloverEnabled()
917 return rollOverEnabled;
921 * Set the value of the button's "selected" property. Selection is only
922 * meaningful for toggle-type buttons (check boxes, radio buttons).
924 * @param s New value for the property
926 public void setSelected(boolean s)
928 ButtonModel mod = getModel();
929 if (mod != null)
930 mod.setSelected(s);
934 * Get the value of the button's "selected" property. Selection is only
935 * meaningful for toggle-type buttons (check boxes, radio buttons).
937 * @return The value of the property
939 public boolean isSelected()
941 ButtonModel mod = getModel();
942 if (mod != null)
943 return mod.isSelected();
944 return false;
948 * Enables or disables the button. A button will neither be selectable
949 * nor preform any actions unless it is enabled.
951 * @param b Whether or not to enable the button
953 public void setEnabled(boolean b)
955 // Do nothing if state does not change.
956 if (b == isEnabled())
957 return;
958 super.setEnabled(b);
959 setFocusable(b);
960 ButtonModel mod = getModel();
961 if (mod != null)
962 mod.setEnabled(b);
965 /**
966 * Set the horizontal alignment of the button's text and icon. The
967 * alignment is a numeric constant from {@link SwingConstants}. It must
968 * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
969 * <code>LEADING</code> or <code>TRAILING</code>. The default is
970 * <code>RIGHT</code>.
972 * @return The current horizontal alignment
974 public int getHorizontalAlignment()
976 return horizontalAlignment;
980 * Set the horizontal alignment of the button's text and icon. The
981 * alignment is a numeric constant from {@link SwingConstants}. It must
982 * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
983 * <code>LEADING</code> or <code>TRAILING</code>. The default is
984 * <code>RIGHT</code>.
986 * @param a The new horizontal alignment
987 * @throws IllegalArgumentException If alignment is not one of the legal
988 * constants.
990 public void setHorizontalAlignment(int a)
992 if (horizontalAlignment == a)
993 return;
995 int old = horizontalAlignment;
996 horizontalAlignment = a;
997 firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
998 revalidate();
999 repaint();
1003 * Get the horizontal position of the button's text relative to its
1004 * icon. The position is a numeric constant from {@link
1005 * SwingConstants}. It must be one of: <code>RIGHT</code>,
1006 * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
1007 * <code>TRAILING</code>. The default is <code>TRAILING</code>.
1009 * @return The current horizontal text position
1011 public int getHorizontalTextPosition()
1013 return horizontalTextPosition;
1017 * Set the horizontal position of the button's text relative to its
1018 * icon. The position is a numeric constant from {@link
1019 * SwingConstants}. It must be one of: <code>RIGHT</code>,
1020 * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or
1021 * <code>TRAILING</code>. The default is <code>TRAILING</code>.
1023 * @param t The new horizontal text position
1024 * @throws IllegalArgumentException If position is not one of the legal
1025 * constants.
1027 public void setHorizontalTextPosition(int t)
1029 if (horizontalTextPosition == t)
1030 return;
1032 int old = horizontalTextPosition;
1033 horizontalTextPosition = t;
1034 firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
1035 revalidate();
1036 repaint();
1040 * Get the vertical alignment of the button's text and icon. The
1041 * alignment is a numeric constant from {@link SwingConstants}. It must
1042 * be one of: <code>CENTER</code>, <code>TOP</code>, or
1043 * <code>BOTTOM</code>. The default is <code>CENTER</code>.
1045 * @return The current vertical alignment
1047 public int getVerticalAlignment()
1049 return verticalAlignment;
1053 * Set the vertical alignment of the button's text and icon. The
1054 * alignment is a numeric constant from {@link SwingConstants}. It must
1055 * be one of: <code>CENTER</code>, <code>TOP</code>, or
1056 * <code>BOTTOM</code>. The default is <code>CENTER</code>.
1058 * @param a The new vertical alignment
1059 * @throws IllegalArgumentException If alignment is not one of the legal
1060 * constants.
1062 public void setVerticalAlignment(int a)
1064 if (verticalAlignment == a)
1065 return;
1067 int old = verticalAlignment;
1068 verticalAlignment = a;
1069 firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a);
1070 revalidate();
1071 repaint();
1075 * Get the vertical position of the button's text relative to its
1076 * icon. The alignment is a numeric constant from {@link
1077 * SwingConstants}. It must be one of: <code>CENTER</code>,
1078 * <code>TOP</code>, or <code>BOTTOM</code>. The default is
1079 * <code>CENTER</code>.
1081 * @return The current vertical position
1083 public int getVerticalTextPosition()
1085 return verticalTextPosition;
1089 * Set the vertical position of the button's text relative to its
1090 * icon. The alignment is a numeric constant from {@link
1091 * SwingConstants}. It must be one of: <code>CENTER</code>,
1092 * <code>TOP</code>, or <code>BOTTOM</code>. The default is
1093 * <code>CENTER</code>.
1095 * @param t The new vertical position
1096 * @throws IllegalArgumentException If position is not one of the legal
1097 * constants.
1099 public void setVerticalTextPosition(int t)
1101 if (verticalTextPosition == t)
1102 return;
1104 int old = verticalTextPosition;
1105 verticalTextPosition = t;
1106 firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t);
1107 revalidate();
1108 repaint();
1112 * Set the value of the "borderPainted" property. If set to
1113 * <code>false</code>, the button's look and feel class should not paint
1114 * a border for the button. The default is <code>true</code>.
1116 * @return The current value of the property.
1118 public boolean isBorderPainted()
1120 return borderPainted;
1124 * Set the value of the "borderPainted" property. If set to
1125 * <code>false</code>, the button's look and feel class should not paint
1126 * a border for the button. The default is <code>true</code>.
1128 * @param b The new value of the property.
1130 public void setBorderPainted(boolean b)
1132 if (borderPainted == b)
1133 return;
1135 boolean old = borderPainted;
1136 borderPainted = b;
1137 firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b);
1138 revalidate();
1139 repaint();
1143 * Get the value of the "action" property.
1145 * @return The current value of the "action" property
1147 public Action getAction()
1149 return action;
1153 * <p>Set the button's "action" property, subscribing the new action to the
1154 * button, as an ActionListener, if it is not already subscribed. The old
1155 * Action, if it exists, is unsubscribed, and the button is unsubscribed
1156 * from the old Action if it was previously subscribed as a
1157 * PropertyChangeListener.</p>
1159 * <p>This method also configures several of the button's properties from
1160 * the Action, by calling {@link #configurePropertiesFromAction}, and
1161 * subscribes the button to the Action as a PropertyChangeListener.
1162 * Subsequent changes to the Action will thus reconfigure the button
1163 * automatically.</p>
1165 * @param a The new value of the "action" property
1167 public void setAction(Action a)
1169 if (action != null)
1171 action.removePropertyChangeListener(actionPropertyChangeListener);
1172 removeActionListener(action);
1173 if (actionPropertyChangeListener != null)
1175 action.removePropertyChangeListener(actionPropertyChangeListener);
1176 actionPropertyChangeListener = null;
1180 Action old = action;
1181 action = a;
1182 configurePropertiesFromAction(action);
1183 if (action != null)
1185 actionPropertyChangeListener = createActionPropertyChangeListener(a);
1186 action.addPropertyChangeListener(actionPropertyChangeListener);
1187 addActionListener(action);
1192 * Return the button's default "icon" property.
1194 * @return The current default icon
1196 public Icon getIcon()
1198 return default_icon;
1202 * Set the button's default "icon" property. This icon is used as a basis
1203 * for the pressed and disabled icons, if none are explicitly set.
1205 * @param i The new default icon
1207 public void setIcon(Icon i)
1209 if (default_icon == i)
1210 return;
1212 Icon old = default_icon;
1213 default_icon = i;
1214 firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
1215 revalidate();
1216 repaint();
1220 * Return the button's "text" property. This property is synonymous with
1221 * the "label" property.
1223 * @return The current "text" property
1225 public String getText()
1227 return text;
1231 * Set the button's "label" property. This property is synonymous with the
1232 * "text" property.
1234 * @param label The new "label" property
1236 * @deprecated use <code>setText(text)</code>
1238 public void setLabel(String label)
1240 setText(label);
1244 * Return the button's "label" property. This property is synonymous with
1245 * the "text" property.
1247 * @return The current "label" property
1249 * @deprecated use <code>getText()</code>
1251 public String getLabel()
1253 return getText();
1257 * Set the button's "text" property. This property is synonymous with the
1258 * "label" property.
1260 * @param t The new "text" property
1262 public void setText(String t)
1264 if (text == t)
1265 return;
1267 String old = text;
1268 text = t;
1269 firePropertyChange(TEXT_CHANGED_PROPERTY, old, t);
1270 revalidate();
1271 repaint();
1275 * Set the value of the {@link #iconTextGap} property.
1277 * @param i The new value of the property
1279 public void setIconTextGap(int i)
1281 if (iconTextGap == i)
1282 return;
1284 int old = iconTextGap;
1285 iconTextGap = i;
1286 fireStateChanged();
1287 revalidate();
1288 repaint();
1292 * Get the value of the {@link #iconTextGap} property.
1294 * @return The current value of the property
1296 public int getIconTextGap()
1298 return iconTextGap;
1302 * Return the button's "margin" property, which is an {@link Insets} object
1303 * describing the distance between the button's border and its text and
1304 * icon.
1306 * @return The current "margin" property
1308 public Insets getMargin()
1310 return margin;
1314 * Set the button's "margin" property, which is an {@link Insets} object
1315 * describing the distance between the button's border and its text and
1316 * icon.
1318 * @param m The new "margin" property
1320 public void setMargin(Insets m)
1322 if (margin == m)
1323 return;
1325 Insets old = margin;
1326 margin = m;
1327 firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m);
1328 revalidate();
1329 repaint();
1333 * Return the button's "pressedIcon" property. The look and feel class
1334 * should paint this icon when the "pressed" property of the button's
1335 * {@link ButtonModel} is <code>true</code>. This property may be
1336 * <code>null</code>, in which case the default icon is used.
1338 * @return The current "pressedIcon" property
1340 public Icon getPressedIcon()
1342 return pressed_icon;
1346 * Set the button's "pressedIcon" property. The look and feel class
1347 * should paint this icon when the "pressed" property of the button's
1348 * {@link ButtonModel} is <code>true</code>. This property may be
1349 * <code>null</code>, in which case the default icon is used.
1351 * @param pressedIcon The new "pressedIcon" property
1353 public void setPressedIcon(Icon pressedIcon)
1355 if (pressed_icon == pressedIcon)
1356 return;
1358 Icon old = pressed_icon;
1359 pressed_icon = pressedIcon;
1360 firePropertyChange(PRESSED_ICON_CHANGED_PROPERTY, old, pressed_icon);
1361 revalidate();
1362 repaint();
1366 * Return the button's "disabledIcon" property. The look and feel class
1367 * should paint this icon when the "enabled" property of the button's
1368 * {@link ButtonModel} is <code>false</code>. This property may be
1369 * <code>null</code>, in which case an icon is constructed, based on the
1370 * default icon.
1372 * @return The current "disabledIcon" property
1374 public Icon getDisabledIcon()
1376 if (disabeldIcon == null && default_icon instanceof ImageIcon)
1378 Image iconImage = ((ImageIcon) default_icon).getImage();
1379 Image grayImage = GrayFilter.createDisabledImage(iconImage);
1380 disabeldIcon = new ImageIcon(grayImage);
1383 return disabeldIcon;
1387 * Set the button's "disabledIcon" property. The look and feel class should
1388 * paint this icon when the "enabled" property of the button's {@link
1389 * ButtonModel} is <code>false</code>. This property may be
1390 * <code>null</code>, in which case an icon is constructed, based on the
1391 * default icon.
1393 * @param d The new "disabledIcon" property
1395 public void setDisabledIcon(Icon d)
1397 disabeldIcon = d;
1398 revalidate();
1399 repaint();
1403 * Return the button's "paintFocus" property. This property controls
1404 * whether or not the look and feel class will paint a special indicator
1405 * of focus state for the button. If it is false, the button still paints
1406 * when focused, but no special decoration is painted to indicate the
1407 * presence of focus.
1409 * @return The current "paintFocus" property
1411 public boolean isFocusPainted()
1413 return focusPainted;
1417 * Set the button's "paintFocus" property. This property controls whether
1418 * or not the look and feel class will paint a special indicator of focus
1419 * state for the button. If it is false, the button still paints when
1420 * focused, but no special decoration is painted to indicate the presence
1421 * of focus.
1423 * @param p The new "paintFocus" property
1425 public void setFocusPainted(boolean p)
1427 if (focusPainted == p)
1428 return;
1430 boolean old = focusPainted;
1431 focusPainted = p;
1432 firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, p);
1433 revalidate();
1434 repaint();
1438 * Verifies that a particular key is one of the valid constants used for
1439 * describing horizontal alignment and positioning. The valid constants
1440 * are the following members of {@link SwingConstants}:
1441 * <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>,
1442 * <code>LEADING</code> or <code>TRAILING</code>.
1444 * @param key The key to check
1445 * @param exception A message to include in an IllegalArgumentException
1447 * @return the value of key
1449 * @throws IllegalArgumentException If key is not one of the valid constants
1451 * @see #setHorizontalTextPosition(int)
1452 * @see #setHorizontalAlignment(int)
1454 protected int checkHorizontalKey(int key, String exception)
1456 switch (key)
1458 case SwingConstants.RIGHT:
1459 case SwingConstants.LEFT:
1460 case SwingConstants.CENTER:
1461 case SwingConstants.LEADING:
1462 case SwingConstants.TRAILING:
1463 break;
1464 default:
1465 throw new IllegalArgumentException(exception);
1467 return key;
1471 * Verifies that a particular key is one of the valid constants used for
1472 * describing vertical alignment and positioning. The valid constants are
1473 * the following members of {@link SwingConstants}: <code>TOP</code>,
1474 * <code>BOTTOM</code> or <code>CENTER</code>.
1476 * @param key The key to check
1477 * @param exception A message to include in an IllegalArgumentException
1479 * @return the value of key
1481 * @throws IllegalArgumentException If key is not one of the valid constants
1483 * @see #setVerticalTextPosition(int)
1484 * @see #setVerticalAlignment(int)
1486 protected int checkVerticalKey(int key, String exception)
1488 switch (key)
1490 case SwingConstants.TOP:
1491 case SwingConstants.BOTTOM:
1492 case SwingConstants.CENTER:
1493 break;
1494 default:
1495 throw new IllegalArgumentException(exception);
1497 return key;
1501 * Configure various properties of the button by reading properties
1502 * of an {@link Action}. The mapping of properties is as follows:
1504 * <table>
1506 * <tr><th>Action keyed property</th> <th>AbstractButton property</th></tr>
1508 * <tr><td>NAME </td> <td>text </td></tr>
1509 * <tr><td>SMALL_ICON </td> <td>icon </td></tr>
1510 * <tr><td>SHORT_DESCRIPTION </td> <td>toolTipText </td></tr>
1511 * <tr><td>MNEMONIC_KEY </td> <td>mnemonic </td></tr>
1512 * <tr><td>ACTION_COMMAND_KEY </td> <td>actionCommand </td></tr>
1514 * </table>
1516 * <p>In addition, this method always sets the button's "enabled" property to
1517 * the value of the Action's "enabled" property.</p>
1519 * <p>If the provided Action is <code>null</code>, the text, icon, and
1520 * toolTipText properties of the button are set to <code>null</code>, and
1521 * the "enabled" property is set to <code>true</code>; the mnemonic and
1522 * actionCommand properties are unchanged.</p>
1524 * @param a An Action to configure the button from
1526 protected void configurePropertiesFromAction(Action a)
1528 if (a == null)
1530 setText(null);
1531 setIcon(null);
1532 setEnabled(true);
1533 setToolTipText(null);
1535 else
1537 setText((String) (a.getValue(Action.NAME)));
1538 setIcon((Icon) (a.getValue(Action.SMALL_ICON)));
1539 setEnabled(a.isEnabled());
1540 setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
1541 if (a.getValue(Action.MNEMONIC_KEY) != null)
1542 setMnemonic(((Integer) (a.getValue(Action.MNEMONIC_KEY))).intValue());
1543 String actionCommand = (String) (a.getValue(Action.ACTION_COMMAND_KEY));
1545 // Set actionCommand to button's text by default if it is not specified
1546 if (actionCommand != null)
1547 setActionCommand((String) (a.getValue(Action.ACTION_COMMAND_KEY)));
1548 else
1549 setActionCommand(getText());
1554 * <p>A factory method which should return an {@link ActionListener} that
1555 * propagates events from the button's {@link ButtonModel} to any of the
1556 * button's ActionListeners. By default, this is an inner class which
1557 * calls {@link AbstractButton#fireActionPerformed} with a modified copy
1558 * of the incoming model {@link ActionEvent}.</p>
1560 * <p>The button calls this method during construction, stores the
1561 * resulting ActionListener in its <code>actionListener</code> member
1562 * field, and subscribes it to the button's model. If the button's model
1563 * is changed, this listener is unsubscribed from the old model and
1564 * subscribed to the new one.</p>
1566 * @return A new ActionListener
1568 protected ActionListener createActionListener()
1570 return new ActionListener()
1572 public void actionPerformed(ActionEvent e)
1574 AbstractButton.this.fireActionPerformed(e);
1580 * <p>A factory method which should return a {@link PropertyChangeListener}
1581 * that accepts changes to the specified {@link Action} and reconfigure
1582 * the {@link AbstractButton}, by default using the {@link
1583 * #configurePropertiesFromAction} method.</p>
1585 * <p>The button calls this method whenever a new Action is assigned to
1586 * the button's "action" property, via {@link #setAction}, and stores the
1587 * resulting PropertyChangeListener in its
1588 * <code>actionPropertyChangeListener</code> member field. The button
1589 * then subscribes the listener to the button's new action. If the
1590 * button's action is changed subsequently, the listener is unsubscribed
1591 * from the old action and subscribed to the new one.</p>
1593 * @param a The Action which will be listened to, and which should be
1594 * the same as the source of any PropertyChangeEvents received by the
1595 * new listener returned from this method.
1597 * @return A new PropertyChangeListener
1599 protected PropertyChangeListener createActionPropertyChangeListener(Action a)
1601 return new PropertyChangeListener()
1603 public void propertyChange(PropertyChangeEvent e)
1605 Action act = (Action) (e.getSource());
1606 if (e.getPropertyName().equals("enabled"))
1607 setEnabled(act.isEnabled());
1608 else if (e.getPropertyName().equals(Action.NAME))
1609 setText((String) (act.getValue(Action.NAME)));
1610 else if (e.getPropertyName().equals(Action.SMALL_ICON))
1611 setIcon((Icon) (act.getValue(Action.SMALL_ICON)));
1612 else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION))
1613 setToolTipText((String) (act.getValue(Action.SHORT_DESCRIPTION)));
1614 else if (e.getPropertyName().equals(Action.MNEMONIC_KEY))
1615 if (act.getValue(Action.MNEMONIC_KEY) != null)
1616 setMnemonic(((Integer) (act.getValue(Action.MNEMONIC_KEY)))
1617 .intValue());
1618 else if (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY))
1619 setActionCommand((String) (act.getValue(Action.ACTION_COMMAND_KEY)));
1625 * <p>Factory method which creates a {@link ChangeListener}, used to
1626 * subscribe to ChangeEvents from the button's model. Subclasses of
1627 * AbstractButton may wish to override the listener used to subscribe to
1628 * such ChangeEvents. By default, the listener just propagates the
1629 * {@link ChangeEvent} to the button's ChangeListeners, via the {@link
1630 * AbstractButton#fireStateChanged} method.</p>
1632 * <p>The button calls this method during construction, stores the
1633 * resulting ChangeListener in its <code>changeListener</code> member
1634 * field, and subscribes it to the button's model. If the button's model
1635 * is changed, this listener is unsubscribed from the old model and
1636 * subscribed to the new one.</p>
1638 * @return The new ChangeListener
1640 protected ChangeListener createChangeListener()
1642 return new ButtonChangeListener();
1646 * <p>Factory method which creates a {@link ItemListener}, used to
1647 * subscribe to ItemEvents from the button's model. Subclasses of
1648 * AbstractButton may wish to override the listener used to subscribe to
1649 * such ItemEvents. By default, the listener just propagates the
1650 * {@link ItemEvent} to the button's ItemListeners, via the {@link
1651 * AbstractButton#fireItemStateChanged} method.</p>
1653 * <p>The button calls this method during construction, stores the
1654 * resulting ItemListener in its <code>changeListener</code> member
1655 * field, and subscribes it to the button's model. If the button's model
1656 * is changed, this listener is unsubscribed from the old model and
1657 * subscribed to the new one.</p>
1659 * <p>Note that ItemEvents are only generated from the button's model
1660 * when the model's <em>selected</em> property changes. If you want to
1661 * subscribe to other properties of the model, you must subscribe to
1662 * ChangeEvents.
1664 * @return The new ItemListener
1666 protected ItemListener createItemListener()
1668 return new ItemListener()
1670 public void itemStateChanged(ItemEvent e)
1672 AbstractButton.this.fireItemStateChanged(e);
1678 * Programmatically perform a "click" on the button: arming, pressing,
1679 * waiting, un-pressing, and disarming the model.
1681 public void doClick()
1683 doClick(100);
1687 * Programmatically perform a "click" on the button: arming, pressing,
1688 * waiting, un-pressing, and disarming the model.
1690 * @param pressTime The number of milliseconds to wait in the pressed state
1692 public void doClick(int pressTime)
1694 ButtonModel mod = getModel();
1695 if (mod != null)
1697 mod.setArmed(true);
1698 mod.setPressed(true);
1701 java.lang.Thread.sleep(pressTime);
1703 catch (java.lang.InterruptedException e)
1705 // probably harmless
1707 mod.setPressed(false);
1708 mod.setArmed(false);
1713 * Return the button's disabled selected icon. The look and feel class
1714 * should paint this icon when the "enabled" property of the button's model
1715 * is <code>false</code> and its "selected" property is
1716 * <code>true</code>. This icon can be <code>null</code>, in which case
1717 * it is synthesized from the button's selected icon.
1719 * @return The current disabled selected icon
1721 public Icon getDisabledSelectedIcon()
1723 return disabledSelectedIcon;
1727 * Set the button's disabled selected icon. The look and feel class
1728 * should paint this icon when the "enabled" property of the button's model
1729 * is <code>false</code> and its "selected" property is
1730 * <code>true</code>. This icon can be <code>null</code>, in which case
1731 * it is synthesized from the button's selected icon.
1733 * @param icon The new disabled selected icon
1735 public void setDisabledSelectedIcon(Icon icon)
1737 if (disabledSelectedIcon == icon)
1738 return;
1740 Icon old = disabledSelectedIcon;
1741 disabledSelectedIcon = icon;
1742 firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old, icon);
1743 revalidate();
1744 repaint();
1748 * Return the button's rollover icon. The look and feel class should
1749 * paint this icon when the "rolloverEnabled" property of the button is
1750 * <code>true</code> and the mouse rolls over the button.
1752 * @return The current rollover icon
1754 public Icon getRolloverIcon()
1756 return rolloverIcon;
1760 * Set the button's rollover icon. The look and feel class should
1761 * paint this icon when the "rolloverEnabled" property of the button is
1762 * <code>true</code> and the mouse rolls over the button.
1764 * @param r The new rollover icon
1766 public void setRolloverIcon(Icon r)
1768 if (rolloverIcon == r)
1769 return;
1771 Icon old = rolloverIcon;
1772 rolloverIcon = r;
1773 firePropertyChange(ROLLOVER_ICON_CHANGED_PROPERTY, old, rolloverIcon);
1774 revalidate();
1775 repaint();
1779 * Return the button's rollover selected icon. The look and feel class
1780 * should paint this icon when the "rolloverEnabled" property of the button
1781 * is <code>true</code>, the "selected" property of the button's model is
1782 * <code>true</code>, and the mouse rolls over the button.
1784 * @return The current rollover selected icon
1786 public Icon getRolloverSelectedIcon()
1788 return rolloverSelectedIcon;
1792 * Set the button's rollover selected icon. The look and feel class
1793 * should paint this icon when the "rolloverEnabled" property of the button
1794 * is <code>true</code>, the "selected" property of the button's model is
1795 * <code>true</code>, and the mouse rolls over the button.
1797 * @param r The new rollover selected icon
1799 public void setRolloverSelectedIcon(Icon r)
1801 if (rolloverSelectedIcon == r)
1802 return;
1804 Icon old = rolloverSelectedIcon;
1805 rolloverSelectedIcon = r;
1806 firePropertyChange(ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY, old, r);
1807 revalidate();
1808 repaint();
1812 * Return the button's selected icon. The look and feel class should
1813 * paint this icon when the "selected" property of the button's model is
1814 * <code>true</code>, and either the "rolloverEnabled" property of the
1815 * button is <code>false</code> or the mouse is not currently rolled
1816 * over the button.
1818 * @return The current selected icon
1820 public Icon getSelectedIcon()
1822 return selectedIcon;
1826 * Set the button's selected icon. The look and feel class should
1827 * paint this icon when the "selected" property of the button's model is
1828 * <code>true</code>, and either the "rolloverEnabled" property of the
1829 * button is <code>false</code> or the mouse is not currently rolled
1830 * over the button.
1832 * @param s The new selected icon
1834 public void setSelectedIcon(Icon s)
1836 if (selectedIcon == s)
1837 return;
1839 Icon old = selectedIcon;
1840 selectedIcon = s;
1841 firePropertyChange(SELECTED_ICON_CHANGED_PROPERTY, old, s);
1842 revalidate();
1843 repaint();
1847 * Returns an single-element array containing the "text" property of the
1848 * button if the "selected" property of the button's model is
1849 * <code>true</code>, otherwise returns <code>null</code>.
1851 * @return The button's "selected object" array
1853 public Object[] getSelectedObjects()
1855 if (isSelected())
1857 Object[] objs = new Object[1];
1858 objs[0] = getText();
1859 return objs;
1861 else
1863 return null;
1868 * Called when image data becomes available for one of the button's icons.
1870 * @param img The image being updated
1871 * @param infoflags One of the constant codes in {@link ImageObserver} used
1872 * to describe updated portions of an image.
1873 * @param x X coordinate of the region being updated
1874 * @param y Y coordinate of the region being updated
1875 * @param w Width of the region beign updated
1876 * @param h Height of the region being updated
1878 * @return <code>true</code> if img is equal to the button's current icon,
1879 * otherwise <code>false</code>
1881 public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
1882 int h)
1884 return current_icon == img;
1888 * Returns the value of the button's "contentAreaFilled" property. This
1889 * property indicates whether the area surrounding the text and icon of
1890 * the button should be filled by the look and feel class. If this
1891 * property is <code>false</code>, the look and feel class should leave
1892 * the content area transparent.
1894 * @return The current value of the "contentAreaFilled" property
1896 public boolean isContentAreaFilled()
1898 return contentAreaFilled;
1902 * Sets the value of the button's "contentAreaFilled" property. This
1903 * property indicates whether the area surrounding the text and icon of
1904 * the button should be filled by the look and feel class. If this
1905 * property is <code>false</code>, the look and feel class should leave
1906 * the content area transparent.
1908 * @param b The new value of the "contentAreaFilled" property
1910 public void setContentAreaFilled(boolean b)
1912 if (contentAreaFilled == b)
1913 return;
1915 boolean old = contentAreaFilled;
1916 contentAreaFilled = b;
1917 firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b);
1918 // The JDK sets the opaque property to the value of the contentAreaFilled
1919 // property, so should we do.
1920 setOpaque(b);
1924 * Paints the button's border, if the button's "borderPainted" property is
1925 * <code>true</code>, by out calling to the button's look and feel class.
1927 * @param g The graphics context used to paint the border
1929 protected void paintBorder(Graphics g)
1931 if (isBorderPainted())
1932 super.paintBorder(g);
1936 * Returns a string, used only for debugging, which identifies or somehow
1937 * represents this button. The exact value is implementation-defined.
1939 * @return A string representation of the button
1941 protected String paramString()
1943 StringBuffer sb = new StringBuffer();
1944 sb.append(super.paramString());
1945 sb.append(",defaultIcon=");
1946 if (getIcon() != null)
1947 sb.append(getIcon());
1948 sb.append(",disabledIcon=");
1949 if (getDisabledIcon() != null)
1950 sb.append(getDisabledIcon());
1951 sb.append(",disabledSelectedIcon=");
1952 if (getDisabledSelectedIcon() != null)
1953 sb.append(getDisabledSelectedIcon());
1954 sb.append(",margin=");
1955 if (getMargin() != null)
1956 sb.append(getMargin());
1957 sb.append(",paintBorder=").append(isBorderPainted());
1958 sb.append(",paintFocus=").append(isFocusPainted());
1959 sb.append(",pressedIcon=");
1960 if (getPressedIcon() != null)
1961 sb.append(getPressedIcon());
1962 sb.append(",rolloverEnabled=").append(isRolloverEnabled());
1963 sb.append(",rolloverIcon=");
1964 if (getRolloverIcon() != null)
1965 sb.append(getRolloverIcon());
1966 sb.append(",rolloverSelected=");
1967 if (getRolloverSelectedIcon() != null)
1968 sb.append(getRolloverSelectedIcon());
1969 sb.append(",selectedIcon=");
1970 if (getSelectedIcon() != null)
1971 sb.append(getSelectedIcon());
1972 sb.append(",text=");
1973 if (getText() != null)
1974 sb.append(getText());
1975 return sb.toString();
1979 * Set the "UI" property of the button, which is a look and feel class
1980 * responsible for handling the button's input events and painting it.
1982 * @param ui The new "UI" property
1984 public void setUI(ButtonUI ui)
1986 super.setUI(ui);
1990 * Set the "UI" property of the button, which is a look and feel class
1991 * responsible for handling the button's input events and painting it.
1993 * @return The current "UI" property
1995 public ButtonUI getUI()
1997 return (ButtonUI) ui;
2001 * Set the "UI" property to a class constructed, via the {@link
2002 * UIManager}, from the current look and feel. This should be overridden
2003 * for each subclass of AbstractButton, to retrieve a suitable {@link
2004 * ButtonUI} look and feel class.
2006 public void updateUI()
2008 // TODO: What to do here?
2012 * Returns the current time in milliseconds in which clicks gets coalesced
2013 * into a single <code>ActionEvent</code>.
2015 * @return the time in milliseconds
2017 * @since 1.4
2019 public long getMultiClickThreshhold()
2021 return multiClickThreshhold;
2025 * Sets the time in milliseconds in which clicks gets coalesced into a single
2026 * <code>ActionEvent</code>.
2028 * @param threshhold the time in milliseconds
2030 * @since 1.4
2032 public void setMultiClickThreshhold(long threshhold)
2034 if (threshhold < 0)
2035 throw new IllegalArgumentException();
2037 multiClickThreshhold = threshhold;