| /* AbstractButton.java -- Provides basic button functionality. |
| Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| package javax.swing; |
| |
| import gnu.classpath.NotImplementedException; |
| |
| import java.awt.Component; |
| import java.awt.Graphics; |
| import java.awt.Image; |
| import java.awt.Insets; |
| import java.awt.ItemSelectable; |
| import java.awt.LayoutManager; |
| import java.awt.Point; |
| import java.awt.Rectangle; |
| import java.awt.Shape; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.ItemEvent; |
| import java.awt.event.ItemListener; |
| import java.awt.image.ImageObserver; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.io.Serializable; |
| import java.util.Enumeration; |
| |
| import javax.accessibility.Accessible; |
| import javax.accessibility.AccessibleAction; |
| import javax.accessibility.AccessibleContext; |
| import javax.accessibility.AccessibleIcon; |
| import javax.accessibility.AccessibleRelation; |
| import javax.accessibility.AccessibleRelationSet; |
| import javax.accessibility.AccessibleState; |
| import javax.accessibility.AccessibleStateSet; |
| import javax.accessibility.AccessibleText; |
| import javax.accessibility.AccessibleValue; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.plaf.ButtonUI; |
| import javax.swing.plaf.basic.BasicHTML; |
| import javax.swing.text.AttributeSet; |
| import javax.swing.text.BadLocationException; |
| import javax.swing.text.Position; |
| import javax.swing.text.View; |
| |
| |
| /** |
| * Provides an abstract implementation of common button behaviour, |
| * data model and look & feel. |
| * |
| * <p>This class is supposed to serve as a base class for |
| * several kinds of buttons with similar but non-identical semantics: |
| * toggle buttons (radio buttons and checkboxes), simple push buttons, |
| * menu items, etc.</p> |
| * |
| * <p>Buttons have many properties, some of which are stored in this class |
| * while others are delegated to the button's model. The following properties |
| * are available:</p> |
| * |
| * <table> |
| * <tr><th>Property </th><th>Stored in</th><th>Bound?</th></tr> |
| * |
| * <tr><td>action </td><td>button</td> <td>no</td></tr> |
| * <tr><td>actionCommand </td><td>model</td> <td>no</td></tr> |
| * <tr><td>borderPainted </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>contentAreaFilled </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>disabledIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>disabledSelectedIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>displayedMnemonicIndex </td><td>button</td> <td>no</td></tr> |
| * <tr><td>enabled </td><td>model</td> <td>no</td></tr> |
| * <tr><td>focusPainted </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>horizontalAlignment </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>horizontalTextPosition </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>icon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>iconTextGap </td><td>button</td> <td>no</td></tr> |
| * <tr><td>label (same as text) </td><td>model</td> <td>yes</td></tr> |
| * <tr><td>margin </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>multiClickThreshold </td><td>button</td> <td>no</td></tr> |
| * <tr><td>pressedIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>rolloverEnabled </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>rolloverIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>rolloverSelectedIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>selected </td><td>model</td> <td>no</td></tr> |
| * <tr><td>selectedIcon </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>selectedObjects </td><td>button</td> <td>no</td></tr> |
| * <tr><td>text </td><td>model</td> <td>yes</td></tr> |
| * <tr><td>UI </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>verticalAlignment </td><td>button</td> <td>yes</td></tr> |
| * <tr><td>verticalTextPosition </td><td>button</td> <td>yes</td></tr> |
| * |
| * </table> |
| * |
| * <p>The various behavioral aspects of these properties follows:</p> |
| * |
| * <ul> |
| * |
| * <li>When non-bound properties stored in the button change, the button |
| * fires ChangeEvents to its ChangeListeners.</li> |
| * |
| * <li>When bound properties stored in the button change, the button fires |
| * PropertyChangeEvents to its PropertyChangeListeners</li> |
| * |
| * <li>If any of the model's properties change, it fires a ChangeEvent to |
| * its ChangeListeners, which include the button.</li> |
| * |
| * <li>If the button receives a ChangeEvent from its model, it will |
| * propagate the ChangeEvent to its ChangeListeners, with the ChangeEvent's |
| * "source" property set to refer to the button, rather than the model. The |
| * the button will request a repaint, to paint its updated state.</li> |
| * |
| * <li>If the model's "selected" property changes, the model will fire an |
| * ItemEvent to its ItemListeners, which include the button, in addition to |
| * the ChangeEvent which models the property change. The button propagates |
| * ItemEvents directly to its ItemListeners.</li> |
| * |
| * <li>If the model's armed and pressed properties are simultaneously |
| * <code>true</code>, the model will fire an ActionEvent to its |
| * ActionListeners, which include the button. The button will propagate |
| * this ActionEvent to its ActionListeners, with the ActionEvent's "source" |
| * property set to refer to the button, rather than the model.</li> |
| * |
| * </ul> |
| * |
| * @author Ronald Veldema (rveldema@cs.vu.nl) |
| * @author Graydon Hoare (graydon@redhat.com) |
| */ |
| |
| public abstract class AbstractButton extends JComponent |
| implements ItemSelectable, SwingConstants |
| { |
| private static final long serialVersionUID = -937921345538462020L; |
| |
| /** |
| * An extension of ChangeListener to be serializable. |
| */ |
| protected class ButtonChangeListener |
| implements ChangeListener, Serializable |
| { |
| private static final long serialVersionUID = 1471056094226600578L; |
| |
| /** |
| * The spec has no public/protected constructor for this class, so do we. |
| */ |
| ButtonChangeListener() |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * Notified when the target of the listener changes its state. |
| * |
| * @param ev the ChangeEvent describing the change |
| */ |
| public void stateChanged(ChangeEvent ev) |
| { |
| AbstractButton.this.fireStateChanged(); |
| repaint(); |
| } |
| } |
| |
| /** The icon displayed by default. */ |
| Icon default_icon; |
| |
| /** The icon displayed when the button is pressed. */ |
| Icon pressed_icon; |
| |
| /** The icon displayed when the button is disabled. */ |
| Icon disabledIcon; |
| |
| /** The icon displayed when the button is selected. */ |
| Icon selectedIcon; |
| |
| /** The icon displayed when the button is selected but disabled. */ |
| Icon disabledSelectedIcon; |
| |
| /** The icon displayed when the button is rolled over. */ |
| Icon rolloverIcon; |
| |
| /** The icon displayed when the button is selected and rolled over. */ |
| Icon rolloverSelectedIcon; |
| |
| /** The icon currently displayed. */ |
| Icon current_icon; |
| |
| /** The text displayed in the button. */ |
| String text; |
| |
| /** |
| * The gap between icon and text, if both icon and text are |
| * non-<code>null</code>. |
| */ |
| int iconTextGap; |
| |
| /** The vertical alignment of the button's text and icon. */ |
| int verticalAlignment; |
| |
| /** The horizontal alignment of the button's text and icon. */ |
| int horizontalAlignment; |
| |
| /** The horizontal position of the button's text relative to its icon. */ |
| int horizontalTextPosition; |
| |
| /** The vertical position of the button's text relative to its icon. */ |
| int verticalTextPosition; |
| |
| /** Whether or not the button paints its border. */ |
| boolean borderPainted; |
| |
| /** Whether or not the button paints its focus state. */ |
| boolean focusPainted; |
| |
| /** Whether or not the button fills its content area. */ |
| boolean contentAreaFilled; |
| |
| /** Whether rollover is enabled. */ |
| boolean rollOverEnabled; |
| |
| /** The action taken when the button is clicked. */ |
| Action action; |
| |
| /** The button's current state. */ |
| protected ButtonModel model; |
| |
| /** The margin between the button's border and its label. */ |
| Insets margin; |
| |
| /** |
| * A hint to the look and feel class, suggesting which character in the |
| * button's label should be underlined when drawing the label. |
| */ |
| int mnemonicIndex; |
| |
| /** Listener the button uses to receive ActionEvents from its model. */ |
| protected ActionListener actionListener; |
| |
| /** Listener the button uses to receive ItemEvents from its model. */ |
| protected ItemListener itemListener; |
| |
| /** Listener the button uses to receive ChangeEvents from its model. */ |
| protected ChangeListener changeListener; |
| |
| /** |
| * The time in milliseconds in which clicks get coalesced into a single |
| * <code>ActionEvent</code>. |
| */ |
| long multiClickThreshhold; |
| |
| /** |
| * Listener the button uses to receive PropertyChangeEvents from its |
| * Action. |
| */ |
| PropertyChangeListener actionPropertyChangeListener; |
| |
| /** ChangeEvent that is fired to button's ChangeEventListeners */ |
| protected ChangeEvent changeEvent = new ChangeEvent(this); |
| |
| /** |
| * Indicates if the borderPainted property has been set by a client |
| * program or by the UI. |
| * |
| * @see #setUIProperty(String, Object) |
| * @see LookAndFeel#installProperty(JComponent, String, Object) |
| */ |
| private boolean clientBorderPaintedSet = false; |
| |
| /** |
| * Indicates if the rolloverEnabled property has been set by a client |
| * program or by the UI. |
| * |
| * @see #setUIProperty(String, Object) |
| * @see LookAndFeel#installProperty(JComponent, String, Object) |
| */ |
| private boolean clientRolloverEnabledSet = false; |
| |
| /** |
| * Indicates if the iconTextGap property has been set by a client |
| * program or by the UI. |
| * |
| * @see #setUIProperty(String, Object) |
| * @see LookAndFeel#installProperty(JComponent, String, Object) |
| */ |
| private boolean clientIconTextGapSet = false; |
| |
| /** |
| * Indicates if the contentAreaFilled property has been set by a client |
| * program or by the UI. |
| * |
| * @see #setUIProperty(String, Object) |
| * @see LookAndFeel#installProperty(JComponent, String, Object) |
| */ |
| private boolean clientContentAreaFilledSet = false; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "borderPainted" property changes. |
| */ |
| public static final String BORDER_PAINTED_CHANGED_PROPERTY = "borderPainted"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "contentAreaFilled" property |
| * changes. |
| */ |
| public static final String CONTENT_AREA_FILLED_CHANGED_PROPERTY = |
| "contentAreaFilled"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "disabledIcon" property changes. |
| */ |
| public static final String DISABLED_ICON_CHANGED_PROPERTY = "disabledIcon"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "disabledSelectedIcon" property |
| * changes. |
| */ |
| public static final String DISABLED_SELECTED_ICON_CHANGED_PROPERTY = |
| "disabledSelectedIcon"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "focusPainted" property changes. |
| */ |
| public static final String FOCUS_PAINTED_CHANGED_PROPERTY = "focusPainted"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "horizontalAlignment" property |
| * changes. |
| */ |
| public static final String HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY = |
| "horizontalAlignment"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "horizontalTextPosition" property |
| * changes. |
| */ |
| public static final String HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY = |
| "horizontalTextPosition"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "icon" property changes. */ |
| public static final String ICON_CHANGED_PROPERTY = "icon"; |
| |
| /** Fired in a PropertyChangeEvent when the "margin" property changes. */ |
| public static final String MARGIN_CHANGED_PROPERTY = "margin"; |
| |
| /** Fired in a PropertyChangeEvent when the "mnemonic" property changes. */ |
| public static final String MNEMONIC_CHANGED_PROPERTY = "mnemonic"; |
| |
| /** Fired in a PropertyChangeEvent when the "model" property changes. */ |
| public static final String MODEL_CHANGED_PROPERTY = "model"; |
| |
| /** Fired in a PropertyChangeEvent when the "pressedIcon" property changes. */ |
| public static final String PRESSED_ICON_CHANGED_PROPERTY = "pressedIcon"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "rolloverEnabled" property |
| * changes. |
| */ |
| public static final String ROLLOVER_ENABLED_CHANGED_PROPERTY = |
| "rolloverEnabled"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "rolloverIcon" property changes. |
| */ |
| public static final String ROLLOVER_ICON_CHANGED_PROPERTY = "rolloverIcon"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "rolloverSelectedIcon" property |
| * changes. |
| */ |
| public static final String ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY = |
| "rolloverSelectedIcon"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "selectedIcon" property changes. |
| */ |
| public static final String SELECTED_ICON_CHANGED_PROPERTY = "selectedIcon"; |
| |
| /** Fired in a PropertyChangeEvent when the "text" property changes. */ |
| public static final String TEXT_CHANGED_PROPERTY = "text"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "verticalAlignment" property |
| * changes. |
| */ |
| public static final String VERTICAL_ALIGNMENT_CHANGED_PROPERTY = |
| "verticalAlignment"; |
| |
| /** |
| * Fired in a PropertyChangeEvent when the "verticalTextPosition" property |
| * changes. |
| */ |
| public static final String VERTICAL_TEXT_POSITION_CHANGED_PROPERTY = |
| "verticalTextPosition"; |
| |
| /** |
| * A Java Accessibility extension of the AbstractButton. |
| */ |
| protected abstract class AccessibleAbstractButton |
| extends AccessibleJComponent implements AccessibleAction, AccessibleValue, |
| AccessibleText |
| { |
| private static final long serialVersionUID = -5673062525319836790L; |
| |
| protected AccessibleAbstractButton() |
| { |
| // Nothing to do here yet. |
| } |
| |
| /** |
| * Returns the accessible state set of this object. In addition to the |
| * superclass's states, the <code>AccessibleAbstractButton</code> |
| * supports the following states: {@link AccessibleState#ARMED}, |
| * {@link AccessibleState#FOCUSED}, {@link AccessibleState#PRESSED} and |
| * {@link AccessibleState#CHECKED}. |
| * |
| * @return the current state of this accessible object |
| */ |
| public AccessibleStateSet getAccessibleStateSet() |
| { |
| AccessibleStateSet state = super.getAccessibleStateSet(); |
| |
| if (getModel().isArmed()) |
| state.add(AccessibleState.ARMED); |
| if (getModel().isPressed()) |
| state.add(AccessibleState.PRESSED); |
| if (isSelected()) |
| state.add(AccessibleState.CHECKED); |
| |
| return state; |
| } |
| |
| /** |
| * Returns the accessible name for the button. |
| */ |
| public String getAccessibleName() |
| { |
| String result = super.getAccessibleName(); |
| if (result == null) |
| result = text; |
| return result; |
| } |
| |
| /** |
| * Returns the accessible icons of this object. If the AbstractButton's |
| * icon is an Accessible, and it's AccessibleContext is an AccessibleIcon, |
| * then this AccessibleIcon is returned, otherwise <code>null</code>. |
| * |
| * @return the accessible icons of this object, or <code>null</code> if |
| * there is no accessible icon |
| */ |
| public AccessibleIcon[] getAccessibleIcon() |
| { |
| AccessibleIcon[] ret = null; |
| Icon icon = getIcon(); |
| if (icon instanceof Accessible) |
| { |
| AccessibleContext ctx = ((Accessible) icon).getAccessibleContext(); |
| if (ctx instanceof AccessibleIcon) |
| { |
| ret = new AccessibleIcon[]{ (AccessibleIcon) ctx }; |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * Returns the accessible relations of this AccessibleAbstractButton. |
| * If the AbstractButton is part of a ButtonGroup, then all the buttons |
| * in this button group are added as targets in a MEMBER_OF relation, |
| * otherwise an empty relation set is returned (from super). |
| * |
| * @return the accessible relations of this AccessibleAbstractButton |
| */ |
| public AccessibleRelationSet getAccessibleRelationSet() |
| { |
| AccessibleRelationSet relations = super.getAccessibleRelationSet(); |
| ButtonModel model = getModel(); |
| if (model instanceof DefaultButtonModel) |
| { |
| ButtonGroup group = ((DefaultButtonModel) model).getGroup(); |
| if (group != null) |
| { |
| Object[] target = new Object[group.getButtonCount()]; |
| Enumeration els = group.getElements(); |
| |
| for (int index = 0; els.hasMoreElements(); ++index) |
| { |
| target[index] = els.nextElement(); |
| } |
| |
| AccessibleRelation rel = |
| new AccessibleRelation(AccessibleRelation.MEMBER_OF); |
| rel.setTarget(target); |
| relations.add(rel); |
| } |
| } |
| return relations; |
| } |
| |
| /** |
| * Returns the accessible action associated with this object. For buttons, |
| * this will be <code>this</code>. |
| * |
| * @return <code>this</code> |
| */ |
| public AccessibleAction getAccessibleAction() |
| { |
| return this; |
| } |
| |
| /** |
| * Returns the accessible value of this AccessibleAbstractButton, which |
| * is always <code>this</code>. |
| * |
| * @return the accessible value of this AccessibleAbstractButton, which |
| * is always <code>this</code> |
| */ |
| public AccessibleValue getAccessibleValue() |
| { |
| return this; |
| } |
| |
| /** |
| * Returns the number of accessible actions that are supported by this |
| * object. Buttons support one action by default ('press button'), so this |
| * method always returns <code>1</code>. |
| * |
| * @return <code>1</code>, the number of supported accessible actions |
| */ |
| public int getAccessibleActionCount() |
| { |
| return 1; |
| } |
| |
| /** |
| * Returns a description for the action with the specified index or |
| * <code>null</code> if such action does not exist. |
| * |
| * @param actionIndex the zero based index to the actions |
| * |
| * @return a description for the action with the specified index or |
| * <code>null</code> if such action does not exist |
| */ |
| public String getAccessibleActionDescription(int actionIndex) |
| { |
| String descr = null; |
| if (actionIndex == 0) |
| { |
| // FIXME: Supply localized descriptions in the UIDefaults. |
| descr = UIManager.getString("AbstractButton.clickText"); |
| } |
| return descr; |
| } |
| |
| /** |
| * Performs the acccessible action with the specified index on this object. |
| * Since buttons have only one action by default (which is to press the |
| * button), this method performs a 'press button' when the specified index |
| * is <code>0</code> and nothing otherwise. |
| * |
| * @param actionIndex a zero based index into the actions of this button |
| * |
| * @return <code>true</code> if the specified action has been performed |
| * successfully, <code>false</code> otherwise |
| */ |
| public boolean doAccessibleAction(int actionIndex) |
| { |
| boolean retVal = false; |
| if (actionIndex == 0) |
| { |
| doClick(); |
| retVal = true; |
| } |
| return retVal; |
| } |
| |
| /** |
| * Returns the current value of this object as a number. This |
| * implementation returns an <code>Integer(1)</code> if the button is |
| * selected, <code>Integer(0)</code> if the button is not selected. |
| * |
| * @return the current value of this object as a number |
| */ |
| public Number getCurrentAccessibleValue() |
| { |
| Integer retVal; |
| if (isSelected()) |
| retVal = new Integer(1); |
| else |
| retVal = new Integer(0); |
| return retVal; |
| } |
| |
| /** |
| * Sets the current accessible value as object. If the specified number |
| * is 0 the button will be deselected, otherwise the button will |
| * be selected. |
| * |
| * @param value 0 for deselected button, other for selected button |
| * |
| * @return <code>true</code> if the value has been set, <code>false</code> |
| * otherwise |
| */ |
| public boolean setCurrentAccessibleValue(Number value) |
| { |
| boolean retVal = false; |
| if (value != null) |
| { |
| if (value.intValue() == 0) |
| setSelected(false); |
| else |
| setSelected(true); |
| retVal = true; |
| } |
| return retVal; |
| } |
| |
| /** |
| * Returns the minimum accessible value for the AccessibleAbstractButton, |
| * which is <code>0</code>. |
| * |
| * @return the minimimum accessible value for the AccessibleAbstractButton, |
| * which is <code>0</code> |
| */ |
| public Number getMinimumAccessibleValue() |
| { |
| return new Integer(0); |
| } |
| |
| /** |
| * Returns the maximum accessible value for the AccessibleAbstractButton, |
| * which is <code>1</code>. |
| * |
| * @return the maximum accessible value for the AccessibleAbstractButton, |
| * which is <code>1</code> |
| */ |
| public Number getMaximumAccessibleValue() |
| { |
| return new Integer(1); |
| } |
| |
| /** |
| * Returns the accessible text for this AccessibleAbstractButton. This |
| * will be <code>null</code> if the button has a non-HTML label, otherwise |
| * <code>this</code>. |
| * |
| * @return the accessible text for this AccessibleAbstractButton |
| */ |
| public AccessibleText getAccessibleText() |
| { |
| AccessibleText accessibleText = null; |
| if (getClientProperty(BasicHTML.propertyKey) != null) |
| accessibleText = this; |
| |
| return accessibleText; |
| } |
| |
| /** |
| * Returns the index of the label's character at the specified point, |
| * relative to the local bounds of the button. This only works for |
| * HTML labels. |
| * |
| * @param p the point, relative to the buttons local bounds |
| * |
| * @return the index of the label's character at the specified point |
| */ |
| public int getIndexAtPoint(Point p) |
| { |
| int index = -1; |
| View view = (View) getClientProperty(BasicHTML.propertyKey); |
| if (view != null) |
| { |
| Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight()); |
| index = view.viewToModel(p.x, p.y, shape, new Position.Bias[1]); |
| } |
| return index; |
| } |
| |
| /** |
| * Returns the bounds of the character at the specified index of the |
| * button's label. This will only work for HTML labels. |
| * |
| * @param i the index of the character of the label |
| * |
| * @return the bounds of the character at the specified index of the |
| * button's label |
| */ |
| public Rectangle getCharacterBounds(int i) |
| { |
| Rectangle rect = null; |
| View view = (View) getClientProperty(BasicHTML.propertyKey); |
| if (view != null) |
| { |
| Rectangle shape = new Rectangle(0, 0, getWidth(), getHeight()); |
| try |
| { |
| Shape s = view.modelToView(i, shape, Position.Bias.Forward); |
| rect = s.getBounds(); |
| } |
| catch (BadLocationException ex) |
| { |
| rect = null; |
| } |
| } |
| return rect; |
| } |
| |
| /** |
| * Returns the number of characters in the button's label. |
| * |
| * @return the bounds of the character at the specified index of the |
| * button's label |
| */ |
| public int getCharCount() |
| { |
| int charCount; |
| View view = (View) getClientProperty(BasicHTML.propertyKey); |
| if (view != null) |
| { |
| charCount = view.getDocument().getLength(); |
| } |
| else |
| { |
| charCount = getAccessibleName().length(); |
| } |
| return charCount; |
| } |
| |
| /** |
| * This always returns <code>-1</code> since there is no caret in a button. |
| * |
| * @return <code>-1</code> since there is no caret in a button |
| */ |
| public int getCaretPosition() |
| { |
| return -1; |
| } |
| |
| public String getAtIndex(int value0, int value1) |
| throws NotImplementedException |
| { |
| return null; // TODO |
| } |
| |
| public String getAfterIndex(int value0, int value1) |
| throws NotImplementedException |
| { |
| return null; // TODO |
| } |
| |
| public String getBeforeIndex(int value0, int value1) |
| throws NotImplementedException |
| { |
| return null; // TODO |
| } |
| |
| /** |
| * Returns the text attribute for the character at the specified character |
| * index. |
| * |
| * @param i the character index |
| * |
| * @return the character attributes for the specified character or |
| * <code>null</code> if the character has no attributes |
| */ |
| public AttributeSet getCharacterAttribute(int i) |
| { |
| AttributeSet atts = null; |
| View view = (View) getClientProperty(BasicHTML.propertyKey); |
| if (view != null) |
| { |
| |
| } |
| return atts; |
| } |
| |
| /** |
| * This always returns <code>-1</code> since |
| * button labels can't be selected. |
| * |
| * @return <code>-1</code>, button labels can't be selected |
| */ |
| public int getSelectionStart() |
| { |
| return -1; |
| } |
| |
| /** |
| * This always returns <code>-1</code> since |
| * button labels can't be selected. |
| * |
| * @return <code>-1</code>, button labels can't be selected |
| */ |
| public int getSelectionEnd() |
| { |
| return -1; |
| } |
| |
| /** |
| * Returns the selected text. This always returns <code>null</code> since |
| * button labels can't be selected. |
| * |
| * @return <code>null</code>, button labels can't be selected |
| */ |
| public String getSelectedText() |
| { |
| return null; |
| } |
| } |
| |
| /** |
| * Creates a new AbstractButton object. Subclasses should call the following |
| * sequence in their constructor in order to initialize the button correctly: |
| * <pre> |
| * super(); |
| * init(text, icon); |
| * </pre> |
| * |
| * The {@link #init(String, Icon)} method is not called automatically by this |
| * constructor. |
| * |
| * @see #init(String, Icon) |
| */ |
| public AbstractButton() |
| { |
| actionListener = createActionListener(); |
| changeListener = createChangeListener(); |
| itemListener = createItemListener(); |
| |
| horizontalAlignment = CENTER; |
| horizontalTextPosition = TRAILING; |
| verticalAlignment = CENTER; |
| verticalTextPosition = CENTER; |
| borderPainted = true; |
| contentAreaFilled = true; |
| focusPainted = true; |
| setFocusable(true); |
| setAlignmentX(CENTER_ALIGNMENT); |
| setAlignmentY(CENTER_ALIGNMENT); |
| setDisplayedMnemonicIndex(-1); |
| setOpaque(true); |
| text = ""; |
| updateUI(); |
| } |
| |
| /** |
| * Get the model the button is currently using. |
| * |
| * @return The current model |
| */ |
| public ButtonModel getModel() |
| { |
| return model; |
| } |
| |
| /** |
| * Set the model the button is currently using. This un-registers all |
| * listeners associated with the current model, and re-registers them |
| * with the new model. |
| * |
| * @param newModel The new model |
| */ |
| public void setModel(ButtonModel newModel) |
| { |
| if (newModel == model) |
| return; |
| |
| if (model != null) |
| { |
| model.removeActionListener(actionListener); |
| model.removeChangeListener(changeListener); |
| model.removeItemListener(itemListener); |
| } |
| ButtonModel old = model; |
| model = newModel; |
| if (model != null) |
| { |
| model.addActionListener(actionListener); |
| model.addChangeListener(changeListener); |
| model.addItemListener(itemListener); |
| } |
| firePropertyChange(MODEL_CHANGED_PROPERTY, old, model); |
| revalidate(); |
| repaint(); |
| } |
| |
| protected void init(String text, Icon icon) |
| { |
| // If text is null, we fall back to the empty |
| // string (which is set using AbstractButton's |
| // constructor). |
| // This way the behavior of the JDK is matched. |
| if(text != null) |
| setText(text); |
| |
| if (icon != null) |
| default_icon = icon; |
| } |
| |
| /** |
| * <p>Returns the action command string for this button's model.</p> |
| * |
| * <p>If the action command was set to <code>null</code>, the button's |
| * text (label) is returned instead.</p> |
| * |
| * @return The current action command string from the button's model |
| */ |
| public String getActionCommand() |
| { |
| String ac = model.getActionCommand(); |
| if (ac != null) |
| return ac; |
| else |
| return text; |
| } |
| |
| /** |
| * Sets the action command string for this button's model. |
| * |
| * @param actionCommand The new action command string to set in the button's |
| * model. |
| */ |
| public void setActionCommand(String actionCommand) |
| { |
| if (model != null) |
| model.setActionCommand(actionCommand); |
| } |
| |
| /** |
| * Adds an ActionListener to the button's listener list. When the |
| * button's model is clicked it fires an ActionEvent, and these |
| * listeners will be called. |
| * |
| * @param l The new listener to add |
| */ |
| public void addActionListener(ActionListener l) |
| { |
| listenerList.add(ActionListener.class, l); |
| } |
| |
| /** |
| * Removes an ActionListener from the button's listener list. |
| * |
| * @param l The listener to remove |
| */ |
| public void removeActionListener(ActionListener l) |
| { |
| listenerList.remove(ActionListener.class, l); |
| } |
| |
| /** |
| * Returns all added <code>ActionListener</code> objects. |
| * |
| * @return an array of listeners |
| * |
| * @since 1.4 |
| */ |
| public ActionListener[] getActionListeners() |
| { |
| return (ActionListener[]) listenerList.getListeners(ActionListener.class); |
| } |
| |
| /** |
| * Adds an ItemListener to the button's listener list. When the button's |
| * model changes state (between any of ARMED, ENABLED, PRESSED, ROLLOVER |
| * or SELECTED) it fires an ItemEvent, and these listeners will be |
| * called. |
| * |
| * @param l The new listener to add |
| */ |
| public void addItemListener(ItemListener l) |
| { |
| listenerList.add(ItemListener.class, l); |
| } |
| |
| /** |
| * Removes an ItemListener from the button's listener list. |
| * |
| * @param l The listener to remove |
| */ |
| public void removeItemListener(ItemListener l) |
| { |
| listenerList.remove(ItemListener.class, l); |
| } |
| |
| /** |
| * Returns all added <code>ItemListener</code> objects. |
| * |
| * @return an array of listeners |
| * |
| * @since 1.4 |
| */ |
| public ItemListener[] getItemListeners() |
| { |
| return (ItemListener[]) listenerList.getListeners(ItemListener.class); |
| } |
| |
| /** |
| * Adds a ChangeListener to the button's listener list. When the button's |
| * model changes any of its (non-bound) properties, these listeners will be |
| * called. |
| * |
| * @param l The new listener to add |
| */ |
| public void addChangeListener(ChangeListener l) |
| { |
| listenerList.add(ChangeListener.class, l); |
| } |
| |
| /** |
| * Removes a ChangeListener from the button's listener list. |
| * |
| * @param l The listener to remove |
| */ |
| public void removeChangeListener(ChangeListener l) |
| { |
| listenerList.remove(ChangeListener.class, l); |
| } |
| |
| /** |
| * Returns all added <code>ChangeListener</code> objects. |
| * |
| * @return an array of listeners |
| * |
| * @since 1.4 |
| */ |
| public ChangeListener[] getChangeListeners() |
| { |
| return (ChangeListener[]) listenerList.getListeners(ChangeListener.class); |
| } |
| |
| /** |
| * Calls {@link ItemListener#itemStateChanged} on each ItemListener in |
| * the button's listener list. |
| * |
| * @param e The event signifying that the button's model changed state |
| */ |
| protected void fireItemStateChanged(ItemEvent e) |
| { |
| e.setSource(this); |
| ItemListener[] listeners = getItemListeners(); |
| |
| for (int i = 0; i < listeners.length; i++) |
| listeners[i].itemStateChanged(e); |
| } |
| |
| /** |
| * Calls {@link ActionListener#actionPerformed} on each {@link |
| * ActionListener} in the button's listener list. |
| * |
| * @param e The event signifying that the button's model was clicked |
| */ |
| protected void fireActionPerformed(ActionEvent e) |
| { |
| // Dispatch a copy of the given ActionEvent in order to |
| // set the source and action command correctly. |
| ActionEvent ae = new ActionEvent( |
| this, |
| e.getID(), |
| getActionCommand(), |
| e.getWhen(), |
| e.getModifiers()); |
| |
| ActionListener[] listeners = getActionListeners(); |
| |
| for (int i = 0; i < listeners.length; i++) |
| listeners[i].actionPerformed(ae); |
| } |
| |
| /** |
| * Calls {@link ChangeListener#stateChanged} on each {@link ChangeListener} |
| * in the button's listener list. |
| */ |
| protected void fireStateChanged() |
| { |
| ChangeListener[] listeners = getChangeListeners(); |
| |
| for (int i = 0; i < listeners.length; i++) |
| listeners[i].stateChanged(changeEvent); |
| } |
| |
| /** |
| * Get the current keyboard mnemonic value. This value corresponds to a |
| * single key code (one of the {@link java.awt.event.KeyEvent} VK_* |
| * codes) and is used to activate the button when pressed in conjunction |
| * with the "mouseless modifier" of the button's look and feel class, and |
| * when focus is in one of the button's ancestors. |
| * |
| * @return The button's current keyboard mnemonic |
| */ |
| public int getMnemonic() |
| { |
| ButtonModel mod = getModel(); |
| if (mod != null) |
| return mod.getMnemonic(); |
| return -1; |
| } |
| |
| /** |
| * Set the current keyboard mnemonic value. This value corresponds to a |
| * single key code (one of the {@link java.awt.event.KeyEvent} VK_* |
| * codes) and is used to activate the button when pressed in conjunction |
| * with the "mouseless modifier" of the button's look and feel class, and |
| * when focus is in one of the button's ancestors. |
| * |
| * @param mne A new mnemonic to use for the button |
| */ |
| public void setMnemonic(char mne) |
| { |
| setMnemonic((int) mne); |
| } |
| |
| /** |
| * Set the current keyboard mnemonic value. This value corresponds to a |
| * single key code (one of the {@link java.awt.event.KeyEvent} VK_* |
| * codes) and is used to activate the button when pressed in conjunction |
| * with the "mouseless modifier" of the button's look and feel class, and |
| * when focus is in one of the button's ancestors. |
| * |
| * @param mne A new mnemonic to use for the button |
| */ |
| public void setMnemonic(int mne) |
| { |
| ButtonModel mod = getModel(); |
| int old = -1; |
| if (mod != null) |
| old = mod.getMnemonic(); |
| |
| if (old != mne) |
| { |
| if (mod != null) |
| mod.setMnemonic(mne); |
| |
| if (text != null && !text.equals("")) |
| { |
| // Since lower case char = upper case char for |
| // mnemonic, we will convert both text and mnemonic |
| // to upper case before checking if mnemonic character occurs |
| // in the menu item text. |
| int upperCaseMne = Character.toUpperCase((char) mne); |
| String upperCaseText = text.toUpperCase(); |
| setDisplayedMnemonicIndex(upperCaseText.indexOf(upperCaseMne)); |
| } |
| |
| firePropertyChange(MNEMONIC_CHANGED_PROPERTY, old, mne); |
| revalidate(); |
| repaint(); |
| } |
| } |
| |
| /** |
| * Sets the button's mnemonic index. The mnemonic index is a hint to the |
| * look and feel class, suggesting which character in the button's label |
| * should be underlined when drawing the label. If the mnemonic index is |
| * -1, no mnemonic will be displayed. |
| * |
| * If no mnemonic index is set, the button will choose a mnemonic index |
| * by default, which will be the first occurrence of the mnemonic |
| * character in the button's text. |
| * |
| * @param index An offset into the "text" property of the button |
| * @throws IllegalArgumentException If <code>index</code> is not within the |
| * range of legal offsets for the "text" property of the button. |
| * @since 1.4 |
| */ |
| |
| public void setDisplayedMnemonicIndex(int index) |
| { |
| if (index < -1 || (text != null && index >= text.length())) |
| throw new IllegalArgumentException(); |
| |
| mnemonicIndex = index; |
| } |
| |
| /** |
| * Get the button's mnemonic index, which is an offset into the button's |
| * "text" property. The character specified by this offset should be |
| * underlined when the look and feel class draws this button. |
| * |
| * @return An index into the button's "text" property |
| */ |
| public int getDisplayedMnemonicIndex() |
| { |
| return mnemonicIndex; |
| } |
| |
| |
| /** |
| * Set the "rolloverEnabled" property. When rollover is enabled, and the |
| * look and feel supports it, the button will change its icon to |
| * rolloverIcon, when the mouse passes over it. |
| * |
| * @param r Whether or not to enable rollover icon changes |
| */ |
| public void setRolloverEnabled(boolean r) |
| { |
| clientRolloverEnabledSet = true; |
| if (rollOverEnabled != r) |
| { |
| rollOverEnabled = r; |
| firePropertyChange(ROLLOVER_ENABLED_CHANGED_PROPERTY, !r, r); |
| revalidate(); |
| repaint(); |
| } |
| } |
| |
| /** |
| * Returns whether or not rollover icon changes are enabled on the |
| * button. |
| * |
| * @return The state of the "rolloverEnabled" property |
| */ |
| public boolean isRolloverEnabled() |
| { |
| return rollOverEnabled; |
| } |
| |
| /** |
| * Set the value of the button's "selected" property. Selection is only |
| * meaningful for toggle-type buttons (check boxes, radio buttons). |
| * |
| * @param s New value for the property |
| */ |
| public void setSelected(boolean s) |
| { |
| ButtonModel mod = getModel(); |
| if (mod != null) |
| mod.setSelected(s); |
| } |
| |
| /** |
| * Get the value of the button's "selected" property. Selection is only |
| * meaningful for toggle-type buttons (check boxes, radio buttons). |
| * |
| * @return The value of the property |
| */ |
| public boolean isSelected() |
| { |
| ButtonModel mod = getModel(); |
| if (mod != null) |
| return mod.isSelected(); |
| return false; |
| } |
| |
| /** |
| * Enables or disables the button. A button will neither be selectable |
| * nor preform any actions unless it is enabled. |
| * |
| * @param b Whether or not to enable the button |
| */ |
| public void setEnabled(boolean b) |
| { |
| // Do nothing if state does not change. |
| if (b == isEnabled()) |
| return; |
| super.setEnabled(b); |
| setFocusable(b); |
| ButtonModel mod = getModel(); |
| if (mod != null) |
| mod.setEnabled(b); |
| } |
| |
| /** |
| * Set the horizontal alignment of the button's text and icon. The |
| * alignment is a numeric constant from {@link SwingConstants}. It must |
| * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>, |
| * <code>LEADING</code> or <code>TRAILING</code>. The default is |
| * <code>CENTER</code>. |
| * |
| * @return The current horizontal alignment |
| * |
| * @see #setHorizontalAlignment(int) |
| */ |
| public int getHorizontalAlignment() |
| { |
| return horizontalAlignment; |
| } |
| |
| /** |
| * Set the horizontal alignment of the button's text and icon. The |
| * alignment is a numeric constant from {@link SwingConstants}. It must |
| * be one of: <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>, |
| * <code>LEADING</code> or <code>TRAILING</code>. The default is |
| * <code>CENTER</code>. |
| * |
| * @param a The new horizontal alignment |
| * @throws IllegalArgumentException If alignment is not one of the legal |
| * constants. |
| * |
| * @see #getHorizontalAlignment() |
| */ |
| public void setHorizontalAlignment(int a) |
| { |
| if (horizontalAlignment == a) |
| return; |
| if (a != LEFT && a != CENTER && a != RIGHT && a != LEADING |
| && a != TRAILING) |
| throw new IllegalArgumentException("Invalid alignment."); |
| int old = horizontalAlignment; |
| horizontalAlignment = a; |
| firePropertyChange(HORIZONTAL_ALIGNMENT_CHANGED_PROPERTY, old, a); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Get the horizontal position of the button's text relative to its |
| * icon. The position is a numeric constant from {@link |
| * SwingConstants}. It must be one of: <code>RIGHT</code>, |
| * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or |
| * <code>TRAILING</code>. The default is <code>TRAILING</code>. |
| * |
| * @return The current horizontal text position |
| */ |
| public int getHorizontalTextPosition() |
| { |
| return horizontalTextPosition; |
| } |
| |
| /** |
| * Set the horizontal position of the button's text relative to its |
| * icon. The position is a numeric constant from {@link |
| * SwingConstants}. It must be one of: <code>RIGHT</code>, |
| * <code>LEFT</code>, <code>CENTER</code>, <code>LEADING</code> or |
| * <code>TRAILING</code>. The default is <code>TRAILING</code>. |
| * |
| * @param t The new horizontal text position |
| * @throws IllegalArgumentException If position is not one of the legal |
| * constants. |
| */ |
| public void setHorizontalTextPosition(int t) |
| { |
| if (horizontalTextPosition == t) |
| return; |
| if (t != LEFT && t != CENTER && t != RIGHT && t != LEADING |
| && t != TRAILING) |
| throw new IllegalArgumentException("Invalid alignment."); |
| |
| int old = horizontalTextPosition; |
| horizontalTextPosition = t; |
| firePropertyChange(HORIZONTAL_TEXT_POSITION_CHANGED_PROPERTY, old, t); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Get the vertical alignment of the button's text and icon. The |
| * alignment is a numeric constant from {@link SwingConstants}. It must |
| * be one of: <code>CENTER</code>, <code>TOP</code>, or |
| * <code>BOTTOM</code>. The default is <code>CENTER</code>. |
| * |
| * @return The current vertical alignment |
| * |
| * @see #setVerticalAlignment(int) |
| */ |
| public int getVerticalAlignment() |
| { |
| return verticalAlignment; |
| } |
| |
| /** |
| * Set the vertical alignment of the button's text and icon. The |
| * alignment is a numeric constant from {@link SwingConstants}. It must |
| * be one of: <code>CENTER</code>, <code>TOP</code>, or |
| * <code>BOTTOM</code>. The default is <code>CENTER</code>. |
| * |
| * @param a The new vertical alignment |
| * @throws IllegalArgumentException If alignment is not one of the legal |
| * constants. |
| * |
| * @see #getVerticalAlignment() |
| */ |
| public void setVerticalAlignment(int a) |
| { |
| if (verticalAlignment == a) |
| return; |
| if (a != TOP && a != CENTER && a != BOTTOM) |
| throw new IllegalArgumentException("Invalid alignment."); |
| |
| int old = verticalAlignment; |
| verticalAlignment = a; |
| firePropertyChange(VERTICAL_ALIGNMENT_CHANGED_PROPERTY, old, a); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Get the vertical position of the button's text relative to its |
| * icon. The alignment is a numeric constant from {@link |
| * SwingConstants}. It must be one of: <code>CENTER</code>, |
| * <code>TOP</code>, or <code>BOTTOM</code>. The default is |
| * <code>CENTER</code>. |
| * |
| * @return The current vertical position |
| */ |
| public int getVerticalTextPosition() |
| { |
| return verticalTextPosition; |
| } |
| |
| /** |
| * Set the vertical position of the button's text relative to its |
| * icon. The alignment is a numeric constant from {@link |
| * SwingConstants}. It must be one of: <code>CENTER</code>, |
| * <code>TOP</code>, or <code>BOTTOM</code>. The default is |
| * <code>CENTER</code>. |
| * |
| * @param t The new vertical position |
| * @throws IllegalArgumentException If position is not one of the legal |
| * constants. |
| */ |
| public void setVerticalTextPosition(int t) |
| { |
| if (verticalTextPosition == t) |
| return; |
| if (t != TOP && t != CENTER && t != BOTTOM) |
| throw new IllegalArgumentException("Invalid alignment."); |
| |
| int old = verticalTextPosition; |
| verticalTextPosition = t; |
| firePropertyChange(VERTICAL_TEXT_POSITION_CHANGED_PROPERTY, old, t); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Set the value of the "borderPainted" property. If set to |
| * <code>false</code>, the button's look and feel class should not paint |
| * a border for the button. The default is <code>true</code>. |
| * |
| * @return The current value of the property. |
| */ |
| public boolean isBorderPainted() |
| { |
| return borderPainted; |
| } |
| |
| /** |
| * Set the value of the "borderPainted" property. If set to |
| * <code>false</code>, the button's look and feel class should not paint |
| * a border for the button. The default is <code>true</code>. |
| * |
| * @param b The new value of the property. |
| */ |
| public void setBorderPainted(boolean b) |
| { |
| clientBorderPaintedSet = true; |
| if (borderPainted == b) |
| return; |
| boolean old = borderPainted; |
| borderPainted = b; |
| firePropertyChange(BORDER_PAINTED_CHANGED_PROPERTY, old, b); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Get the value of the "action" property. |
| * |
| * @return The current value of the "action" property |
| */ |
| public Action getAction() |
| { |
| return action; |
| } |
| |
| /** |
| * <p>Set the button's "action" property, subscribing the new action to the |
| * button, as an ActionListener, if it is not already subscribed. The old |
| * Action, if it exists, is unsubscribed, and the button is unsubscribed |
| * from the old Action if it was previously subscribed as a |
| * PropertyChangeListener.</p> |
| * |
| * <p>This method also configures several of the button's properties from |
| * the Action, by calling {@link #configurePropertiesFromAction}, and |
| * subscribes the button to the Action as a PropertyChangeListener. |
| * Subsequent changes to the Action will thus reconfigure the button |
| * automatically.</p> |
| * |
| * @param a The new value of the "action" property |
| */ |
| public void setAction(Action a) |
| { |
| if (action != null) |
| { |
| action.removePropertyChangeListener(actionPropertyChangeListener); |
| removeActionListener(action); |
| if (actionPropertyChangeListener != null) |
| { |
| action.removePropertyChangeListener(actionPropertyChangeListener); |
| actionPropertyChangeListener = null; |
| } |
| } |
| |
| Action old = action; |
| action = a; |
| configurePropertiesFromAction(action); |
| if (action != null) |
| { |
| actionPropertyChangeListener = createActionPropertyChangeListener(a); |
| action.addPropertyChangeListener(actionPropertyChangeListener); |
| addActionListener(action); |
| } |
| } |
| |
| /** |
| * Return the button's default "icon" property. |
| * |
| * @return The current default icon |
| */ |
| public Icon getIcon() |
| { |
| return default_icon; |
| } |
| |
| /** |
| * Set the button's default "icon" property. This icon is used as a basis |
| * for the pressed and disabled icons, if none are explicitly set. |
| * |
| * @param i The new default icon |
| */ |
| public void setIcon(Icon i) |
| { |
| if (default_icon == i) |
| return; |
| |
| Icon old = default_icon; |
| default_icon = i; |
| firePropertyChange(ICON_CHANGED_PROPERTY, old, i); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's "text" property. This property is synonymous with |
| * the "label" property. |
| * |
| * @return The current "text" property |
| */ |
| public String getText() |
| { |
| return text; |
| } |
| |
| /** |
| * Set the button's "label" property. This property is synonymous with the |
| * "text" property. |
| * |
| * @param label The new "label" property |
| * |
| * @deprecated use <code>setText(text)</code> |
| */ |
| public void setLabel(String label) |
| { |
| setText(label); |
| } |
| |
| /** |
| * Return the button's "label" property. This property is synonymous with |
| * the "text" property. |
| * |
| * @return The current "label" property |
| * |
| * @deprecated use <code>getText()</code> |
| */ |
| public String getLabel() |
| { |
| return getText(); |
| } |
| |
| /** |
| * Set the button's "text" property. This property is synonymous with the |
| * "label" property. |
| * |
| * @param t The new "text" property |
| */ |
| public void setText(String t) |
| { |
| if (text == t) |
| return; |
| |
| String old = text; |
| text = t; |
| firePropertyChange(TEXT_CHANGED_PROPERTY, old, t); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Set the value of the {@link #iconTextGap} property. |
| * |
| * @param i The new value of the property |
| * |
| * @since 1.4 |
| */ |
| public void setIconTextGap(int i) |
| { |
| clientIconTextGapSet = true; |
| if (iconTextGap == i) |
| return; |
| |
| int old = iconTextGap; |
| iconTextGap = i; |
| firePropertyChange("iconTextGap", new Integer(old), new Integer(i)); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Get the value of the {@link #iconTextGap} property. |
| * |
| * @return The current value of the property |
| * |
| * @since 1.4 |
| */ |
| public int getIconTextGap() |
| { |
| return iconTextGap; |
| } |
| |
| /** |
| * Return the button's "margin" property, which is an {@link Insets} object |
| * describing the distance between the button's border and its text and |
| * icon. |
| * |
| * @return The current "margin" property |
| */ |
| public Insets getMargin() |
| { |
| return margin; |
| } |
| |
| /** |
| * Set the button's "margin" property, which is an {@link Insets} object |
| * describing the distance between the button's border and its text and |
| * icon. |
| * |
| * @param m The new "margin" property |
| */ |
| public void setMargin(Insets m) |
| { |
| if (margin == m) |
| return; |
| |
| Insets old = margin; |
| margin = m; |
| firePropertyChange(MARGIN_CHANGED_PROPERTY, old, m); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's "pressedIcon" property. The look and feel class |
| * should paint this icon when the "pressed" property of the button's |
| * {@link ButtonModel} is <code>true</code>. This property may be |
| * <code>null</code>, in which case the default icon is used. |
| * |
| * @return The current "pressedIcon" property |
| */ |
| public Icon getPressedIcon() |
| { |
| return pressed_icon; |
| } |
| |
| /** |
| * Set the button's "pressedIcon" property. The look and feel class |
| * should paint this icon when the "pressed" property of the button's |
| * {@link ButtonModel} is <code>true</code>. This property may be |
| * <code>null</code>, in which case the default icon is used. |
| * |
| * @param pressedIcon The new "pressedIcon" property |
| */ |
| public void setPressedIcon(Icon pressedIcon) |
| { |
| if (pressed_icon == pressedIcon) |
| return; |
| |
| Icon old = pressed_icon; |
| pressed_icon = pressedIcon; |
| firePropertyChange(PRESSED_ICON_CHANGED_PROPERTY, old, pressed_icon); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's "disabledIcon" property. The look and feel class |
| * should paint this icon when the "enabled" property of the button's |
| * {@link ButtonModel} is <code>false</code>. This property may be |
| * <code>null</code>, in which case an icon is constructed, based on the |
| * default icon. |
| * |
| * @return The current "disabledIcon" property |
| */ |
| public Icon getDisabledIcon() |
| { |
| if (disabledIcon == null && default_icon instanceof ImageIcon) |
| { |
| Image iconImage = ((ImageIcon) default_icon).getImage(); |
| Image grayImage = GrayFilter.createDisabledImage(iconImage); |
| disabledIcon = new ImageIcon(grayImage); |
| } |
| |
| return disabledIcon; |
| } |
| |
| /** |
| * Set the button's "disabledIcon" property. The look and feel class should |
| * paint this icon when the "enabled" property of the button's {@link |
| * ButtonModel} is <code>false</code>. This property may be |
| * <code>null</code>, in which case an icon is constructed, based on the |
| * default icon. |
| * |
| * @param d The new "disabledIcon" property |
| */ |
| public void setDisabledIcon(Icon d) |
| { |
| if (disabledIcon == d) |
| return; |
| Icon old = disabledIcon; |
| disabledIcon = d; |
| firePropertyChange(DISABLED_ICON_CHANGED_PROPERTY, old, d); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's "paintFocus" property. This property controls |
| * whether or not the look and feel class will paint a special indicator |
| * of focus state for the button. If it is false, the button still paints |
| * when focused, but no special decoration is painted to indicate the |
| * presence of focus. |
| * |
| * @return The current "paintFocus" property |
| */ |
| public boolean isFocusPainted() |
| { |
| return focusPainted; |
| } |
| |
| /** |
| * Set the button's "paintFocus" property. This property controls whether |
| * or not the look and feel class will paint a special indicator of focus |
| * state for the button. If it is false, the button still paints when |
| * focused, but no special decoration is painted to indicate the presence |
| * of focus. |
| * |
| * @param p The new "paintFocus" property |
| */ |
| public void setFocusPainted(boolean p) |
| { |
| if (focusPainted == p) |
| return; |
| |
| boolean old = focusPainted; |
| focusPainted = p; |
| firePropertyChange(FOCUS_PAINTED_CHANGED_PROPERTY, old, p); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Verifies that a particular key is one of the valid constants used for |
| * describing horizontal alignment and positioning. The valid constants |
| * are the following members of {@link SwingConstants}: |
| * <code>RIGHT</code>, <code>LEFT</code>, <code>CENTER</code>, |
| * <code>LEADING</code> or <code>TRAILING</code>. |
| * |
| * @param key The key to check |
| * @param exception A message to include in an IllegalArgumentException |
| * |
| * @return the value of key |
| * |
| * @throws IllegalArgumentException If key is not one of the valid constants |
| * |
| * @see #setHorizontalTextPosition(int) |
| * @see #setHorizontalAlignment(int) |
| */ |
| protected int checkHorizontalKey(int key, String exception) |
| { |
| switch (key) |
| { |
| case SwingConstants.RIGHT: |
| case SwingConstants.LEFT: |
| case SwingConstants.CENTER: |
| case SwingConstants.LEADING: |
| case SwingConstants.TRAILING: |
| break; |
| default: |
| throw new IllegalArgumentException(exception); |
| } |
| return key; |
| } |
| |
| /** |
| * Verifies that a particular key is one of the valid constants used for |
| * describing vertical alignment and positioning. The valid constants are |
| * the following members of {@link SwingConstants}: <code>TOP</code>, |
| * <code>BOTTOM</code> or <code>CENTER</code>. |
| * |
| * @param key The key to check |
| * @param exception A message to include in an IllegalArgumentException |
| * |
| * @return the value of key |
| * |
| * @throws IllegalArgumentException If key is not one of the valid constants |
| * |
| * @see #setVerticalTextPosition(int) |
| * @see #setVerticalAlignment(int) |
| */ |
| protected int checkVerticalKey(int key, String exception) |
| { |
| switch (key) |
| { |
| case SwingConstants.TOP: |
| case SwingConstants.BOTTOM: |
| case SwingConstants.CENTER: |
| break; |
| default: |
| throw new IllegalArgumentException(exception); |
| } |
| return key; |
| } |
| |
| /** |
| * Configure various properties of the button by reading properties |
| * of an {@link Action}. The mapping of properties is as follows: |
| * |
| * <table> |
| * |
| * <tr><th>Action keyed property</th> <th>AbstractButton property</th></tr> |
| * |
| * <tr><td>NAME </td> <td>text </td></tr> |
| * <tr><td>SMALL_ICON </td> <td>icon </td></tr> |
| * <tr><td>SHORT_DESCRIPTION </td> <td>toolTipText </td></tr> |
| * <tr><td>MNEMONIC_KEY </td> <td>mnemonic </td></tr> |
| * <tr><td>ACTION_COMMAND_KEY </td> <td>actionCommand </td></tr> |
| * |
| * </table> |
| * |
| * <p>In addition, this method always sets the button's "enabled" property to |
| * the value of the Action's "enabled" property.</p> |
| * |
| * <p>If the provided Action is <code>null</code>, the text, icon, and |
| * toolTipText properties of the button are set to <code>null</code>, and |
| * the "enabled" property is set to <code>true</code>; the mnemonic and |
| * actionCommand properties are unchanged.</p> |
| * |
| * @param a An Action to configure the button from |
| */ |
| protected void configurePropertiesFromAction(Action a) |
| { |
| if (a == null) |
| { |
| setText(null); |
| setIcon(null); |
| setEnabled(true); |
| setToolTipText(null); |
| } |
| else |
| { |
| setText((String) (a.getValue(Action.NAME))); |
| setIcon((Icon) (a.getValue(Action.SMALL_ICON))); |
| setEnabled(a.isEnabled()); |
| setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION))); |
| if (a.getValue(Action.MNEMONIC_KEY) != null) |
| setMnemonic(((Integer) (a.getValue(Action.MNEMONIC_KEY))).intValue()); |
| String actionCommand = (String) (a.getValue(Action.ACTION_COMMAND_KEY)); |
| |
| // Set actionCommand to button's text by default if it is not specified |
| if (actionCommand != null) |
| setActionCommand((String) (a.getValue(Action.ACTION_COMMAND_KEY))); |
| else |
| setActionCommand(getText()); |
| } |
| } |
| |
| /** |
| * <p>A factory method which should return an {@link ActionListener} that |
| * propagates events from the button's {@link ButtonModel} to any of the |
| * button's ActionListeners. By default, this is an inner class which |
| * calls {@link AbstractButton#fireActionPerformed} with a modified copy |
| * of the incoming model {@link ActionEvent}.</p> |
| * |
| * <p>The button calls this method during construction, stores the |
| * resulting ActionListener in its <code>actionListener</code> member |
| * field, and subscribes it to the button's model. If the button's model |
| * is changed, this listener is unsubscribed from the old model and |
| * subscribed to the new one.</p> |
| * |
| * @return A new ActionListener |
| */ |
| protected ActionListener createActionListener() |
| { |
| return new ActionListener() |
| { |
| public void actionPerformed(ActionEvent e) |
| { |
| AbstractButton.this.fireActionPerformed(e); |
| } |
| }; |
| } |
| |
| /** |
| * <p>A factory method which should return a {@link PropertyChangeListener} |
| * that accepts changes to the specified {@link Action} and reconfigure |
| * the {@link AbstractButton}, by default using the {@link |
| * #configurePropertiesFromAction} method.</p> |
| * |
| * <p>The button calls this method whenever a new Action is assigned to |
| * the button's "action" property, via {@link #setAction}, and stores the |
| * resulting PropertyChangeListener in its |
| * <code>actionPropertyChangeListener</code> member field. The button |
| * then subscribes the listener to the button's new action. If the |
| * button's action is changed subsequently, the listener is unsubscribed |
| * from the old action and subscribed to the new one.</p> |
| * |
| * @param a The Action which will be listened to, and which should be |
| * the same as the source of any PropertyChangeEvents received by the |
| * new listener returned from this method. |
| * |
| * @return A new PropertyChangeListener |
| */ |
| protected PropertyChangeListener createActionPropertyChangeListener(Action a) |
| { |
| return new PropertyChangeListener() |
| { |
| public void propertyChange(PropertyChangeEvent e) |
| { |
| Action act = (Action) (e.getSource()); |
| if (e.getPropertyName().equals("enabled")) |
| setEnabled(act.isEnabled()); |
| else if (e.getPropertyName().equals(Action.NAME)) |
| setText((String) (act.getValue(Action.NAME))); |
| else if (e.getPropertyName().equals(Action.SMALL_ICON)) |
| setIcon((Icon) (act.getValue(Action.SMALL_ICON))); |
| else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION)) |
| setToolTipText((String) (act.getValue(Action.SHORT_DESCRIPTION))); |
| else if (e.getPropertyName().equals(Action.MNEMONIC_KEY)) |
| if (act.getValue(Action.MNEMONIC_KEY) != null) |
| setMnemonic(((Integer) (act.getValue(Action.MNEMONIC_KEY))) |
| .intValue()); |
| else if (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY)) |
| setActionCommand((String) (act.getValue(Action.ACTION_COMMAND_KEY))); |
| } |
| }; |
| } |
| |
| /** |
| * <p>Factory method which creates a {@link ChangeListener}, used to |
| * subscribe to ChangeEvents from the button's model. Subclasses of |
| * AbstractButton may wish to override the listener used to subscribe to |
| * such ChangeEvents. By default, the listener just propagates the |
| * {@link ChangeEvent} to the button's ChangeListeners, via the {@link |
| * AbstractButton#fireStateChanged} method.</p> |
| * |
| * <p>The button calls this method during construction, stores the |
| * resulting ChangeListener in its <code>changeListener</code> member |
| * field, and subscribes it to the button's model. If the button's model |
| * is changed, this listener is unsubscribed from the old model and |
| * subscribed to the new one.</p> |
| * |
| * @return The new ChangeListener |
| */ |
| protected ChangeListener createChangeListener() |
| { |
| return new ButtonChangeListener(); |
| } |
| |
| /** |
| * <p>Factory method which creates a {@link ItemListener}, used to |
| * subscribe to ItemEvents from the button's model. Subclasses of |
| * AbstractButton may wish to override the listener used to subscribe to |
| * such ItemEvents. By default, the listener just propagates the |
| * {@link ItemEvent} to the button's ItemListeners, via the {@link |
| * AbstractButton#fireItemStateChanged} method.</p> |
| * |
| * <p>The button calls this method during construction, stores the |
| * resulting ItemListener in its <code>changeListener</code> member |
| * field, and subscribes it to the button's model. If the button's model |
| * is changed, this listener is unsubscribed from the old model and |
| * subscribed to the new one.</p> |
| * |
| * <p>Note that ItemEvents are only generated from the button's model |
| * when the model's <em>selected</em> property changes. If you want to |
| * subscribe to other properties of the model, you must subscribe to |
| * ChangeEvents. |
| * |
| * @return The new ItemListener |
| */ |
| protected ItemListener createItemListener() |
| { |
| return new ItemListener() |
| { |
| public void itemStateChanged(ItemEvent e) |
| { |
| AbstractButton.this.fireItemStateChanged(e); |
| } |
| }; |
| } |
| |
| /** |
| * Programmatically perform a "click" on the button: arming, pressing, |
| * waiting, un-pressing, and disarming the model. |
| */ |
| public void doClick() |
| { |
| doClick(100); |
| } |
| |
| /** |
| * Programmatically perform a "click" on the button: arming, pressing, |
| * waiting, un-pressing, and disarming the model. |
| * |
| * @param pressTime The number of milliseconds to wait in the pressed state |
| */ |
| public void doClick(int pressTime) |
| { |
| ButtonModel mod = getModel(); |
| if (mod != null) |
| { |
| mod.setArmed(true); |
| mod.setPressed(true); |
| try |
| { |
| java.lang.Thread.sleep(pressTime); |
| } |
| catch (java.lang.InterruptedException e) |
| { |
| // probably harmless |
| } |
| mod.setPressed(false); |
| mod.setArmed(false); |
| } |
| } |
| |
| /** |
| * Return the button's disabled selected icon. The look and feel class |
| * should paint this icon when the "enabled" property of the button's model |
| * is <code>false</code> and its "selected" property is |
| * <code>true</code>. This icon can be <code>null</code>, in which case |
| * it is synthesized from the button's selected icon. |
| * |
| * @return The current disabled selected icon |
| */ |
| public Icon getDisabledSelectedIcon() |
| { |
| return disabledSelectedIcon; |
| } |
| |
| /** |
| * Set the button's disabled selected icon. The look and feel class |
| * should paint this icon when the "enabled" property of the button's model |
| * is <code>false</code> and its "selected" property is |
| * <code>true</code>. This icon can be <code>null</code>, in which case |
| * it is synthesized from the button's selected icon. |
| * |
| * @param icon The new disabled selected icon |
| */ |
| public void setDisabledSelectedIcon(Icon icon) |
| { |
| if (disabledSelectedIcon == icon) |
| return; |
| |
| Icon old = disabledSelectedIcon; |
| disabledSelectedIcon = icon; |
| firePropertyChange(DISABLED_SELECTED_ICON_CHANGED_PROPERTY, old, icon); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's rollover icon. The look and feel class should |
| * paint this icon when the "rolloverEnabled" property of the button is |
| * <code>true</code> and the mouse rolls over the button. |
| * |
| * @return The current rollover icon |
| */ |
| public Icon getRolloverIcon() |
| { |
| return rolloverIcon; |
| } |
| |
| /** |
| * Set the button's rollover icon and sets the <code>rolloverEnabled</code> |
| * property to <code>true</code>. The look and feel class should |
| * paint this icon when the "rolloverEnabled" property of the button is |
| * <code>true</code> and the mouse rolls over the button. |
| * |
| * @param r The new rollover icon |
| */ |
| public void setRolloverIcon(Icon r) |
| { |
| if (rolloverIcon == r) |
| return; |
| |
| Icon old = rolloverIcon; |
| rolloverIcon = r; |
| firePropertyChange(ROLLOVER_ICON_CHANGED_PROPERTY, old, rolloverIcon); |
| setRolloverEnabled(true); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's rollover selected icon. The look and feel class |
| * should paint this icon when the "rolloverEnabled" property of the button |
| * is <code>true</code>, the "selected" property of the button's model is |
| * <code>true</code>, and the mouse rolls over the button. |
| * |
| * @return The current rollover selected icon |
| */ |
| public Icon getRolloverSelectedIcon() |
| { |
| return rolloverSelectedIcon; |
| } |
| |
| /** |
| * Set the button's rollover selected icon and sets the |
| * <code>rolloverEnabled</code> property to <code>true</code>. The look and |
| * feel class should paint this icon when the "rolloverEnabled" property of |
| * the button is <code>true</code>, the "selected" property of the button's |
| * model is <code>true</code>, and the mouse rolls over the button. |
| * |
| * @param r The new rollover selected icon. |
| */ |
| public void setRolloverSelectedIcon(Icon r) |
| { |
| if (rolloverSelectedIcon == r) |
| return; |
| |
| Icon old = rolloverSelectedIcon; |
| rolloverSelectedIcon = r; |
| firePropertyChange(ROLLOVER_SELECTED_ICON_CHANGED_PROPERTY, old, r); |
| setRolloverEnabled(true); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Return the button's selected icon. The look and feel class should |
| * paint this icon when the "selected" property of the button's model is |
| * <code>true</code>, and either the "rolloverEnabled" property of the |
| * button is <code>false</code> or the mouse is not currently rolled |
| * over the button. |
| * |
| * @return The current selected icon |
| */ |
| public Icon getSelectedIcon() |
| { |
| return selectedIcon; |
| } |
| |
| /** |
| * Set the button's selected icon. The look and feel class should |
| * paint this icon when the "selected" property of the button's model is |
| * <code>true</code>, and either the "rolloverEnabled" property of the |
| * button is <code>false</code> or the mouse is not currently rolled |
| * over the button. |
| * |
| * @param s The new selected icon |
| */ |
| public void setSelectedIcon(Icon s) |
| { |
| if (selectedIcon == s) |
| return; |
| |
| Icon old = selectedIcon; |
| selectedIcon = s; |
| firePropertyChange(SELECTED_ICON_CHANGED_PROPERTY, old, s); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Returns an single-element array containing the "text" property of the |
| * button if the "selected" property of the button's model is |
| * <code>true</code>, otherwise returns <code>null</code>. |
| * |
| * @return The button's "selected object" array |
| */ |
| public Object[] getSelectedObjects() |
| { |
| if (isSelected()) |
| { |
| Object[] objs = new Object[1]; |
| objs[0] = getText(); |
| return objs; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| /** |
| * Called when image data becomes available for one of the button's icons. |
| * |
| * @param img The image being updated |
| * @param infoflags One of the constant codes in {@link ImageObserver} used |
| * to describe updated portions of an image. |
| * @param x X coordinate of the region being updated |
| * @param y Y coordinate of the region being updated |
| * @param w Width of the region beign updated |
| * @param h Height of the region being updated |
| * |
| * @return <code>true</code> if img is equal to the button's current icon, |
| * otherwise <code>false</code> |
| */ |
| public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, |
| int h) |
| { |
| return current_icon == img; |
| } |
| |
| /** |
| * Returns the value of the button's "contentAreaFilled" property. This |
| * property indicates whether the area surrounding the text and icon of |
| * the button should be filled by the look and feel class. If this |
| * property is <code>false</code>, the look and feel class should leave |
| * the content area transparent. |
| * |
| * @return The current value of the "contentAreaFilled" property |
| */ |
| public boolean isContentAreaFilled() |
| { |
| return contentAreaFilled; |
| } |
| |
| /** |
| * Sets the value of the button's "contentAreaFilled" property. This |
| * property indicates whether the area surrounding the text and icon of |
| * the button should be filled by the look and feel class. If this |
| * property is <code>false</code>, the look and feel class should leave |
| * the content area transparent. |
| * |
| * @param b The new value of the "contentAreaFilled" property |
| */ |
| public void setContentAreaFilled(boolean b) |
| { |
| clientContentAreaFilledSet = true; |
| if (contentAreaFilled == b) |
| return; |
| |
| // The JDK sets the opaque property to the value of the contentAreaFilled |
| // property, so should we do. |
| setOpaque(b); |
| boolean old = contentAreaFilled; |
| contentAreaFilled = b; |
| firePropertyChange(CONTENT_AREA_FILLED_CHANGED_PROPERTY, old, b); |
| } |
| |
| /** |
| * Paints the button's border, if the button's "borderPainted" property is |
| * <code>true</code>, by out calling to the button's look and feel class. |
| * |
| * @param g The graphics context used to paint the border |
| */ |
| protected void paintBorder(Graphics g) |
| { |
| if (isBorderPainted()) |
| super.paintBorder(g); |
| } |
| |
| /** |
| * Returns a string, used only for debugging, which identifies or somehow |
| * represents this button. The exact value is implementation-defined. |
| * |
| * @return A string representation of the button |
| */ |
| protected String paramString() |
| { |
| StringBuffer sb = new StringBuffer(); |
| sb.append(super.paramString()); |
| sb.append(",defaultIcon="); |
| if (getIcon() != null) |
| sb.append(getIcon()); |
| sb.append(",disabledIcon="); |
| if (getDisabledIcon() != null) |
| sb.append(getDisabledIcon()); |
| sb.append(",disabledSelectedIcon="); |
| if (getDisabledSelectedIcon() != null) |
| sb.append(getDisabledSelectedIcon()); |
| sb.append(",margin="); |
| if (getMargin() != null) |
| sb.append(getMargin()); |
| sb.append(",paintBorder=").append(isBorderPainted()); |
| sb.append(",paintFocus=").append(isFocusPainted()); |
| sb.append(",pressedIcon="); |
| if (getPressedIcon() != null) |
| sb.append(getPressedIcon()); |
| sb.append(",rolloverEnabled=").append(isRolloverEnabled()); |
| sb.append(",rolloverIcon="); |
| if (getRolloverIcon() != null) |
| sb.append(getRolloverIcon()); |
| sb.append(",rolloverSelected="); |
| if (getRolloverSelectedIcon() != null) |
| sb.append(getRolloverSelectedIcon()); |
| sb.append(",selectedIcon="); |
| if (getSelectedIcon() != null) |
| sb.append(getSelectedIcon()); |
| sb.append(",text="); |
| if (getText() != null) |
| sb.append(getText()); |
| return sb.toString(); |
| } |
| |
| /** |
| * Set the "UI" property of the button, which is a look and feel class |
| * responsible for handling the button's input events and painting it. |
| * |
| * @param ui The new "UI" property |
| */ |
| public void setUI(ButtonUI ui) |
| { |
| super.setUI(ui); |
| } |
| |
| /** |
| * Set the "UI" property of the button, which is a look and feel class |
| * responsible for handling the button's input events and painting it. |
| * |
| * @return The current "UI" property |
| */ |
| public ButtonUI getUI() |
| { |
| return (ButtonUI) ui; |
| } |
| |
| /** |
| * Set the "UI" property to a class constructed, via the {@link |
| * UIManager}, from the current look and feel. This should be overridden |
| * for each subclass of AbstractButton, to retrieve a suitable {@link |
| * ButtonUI} look and feel class. |
| */ |
| public void updateUI() |
| { |
| // TODO: What to do here? |
| } |
| |
| /** |
| * Returns the current time in milliseconds in which clicks gets coalesced |
| * into a single <code>ActionEvent</code>. |
| * |
| * @return the time in milliseconds |
| * |
| * @since 1.4 |
| */ |
| public long getMultiClickThreshhold() |
| { |
| return multiClickThreshhold; |
| } |
| |
| /** |
| * Sets the time in milliseconds in which clicks gets coalesced into a single |
| * <code>ActionEvent</code>. |
| * |
| * @param threshhold the time in milliseconds |
| * |
| * @since 1.4 |
| */ |
| public void setMultiClickThreshhold(long threshhold) |
| { |
| if (threshhold < 0) |
| throw new IllegalArgumentException(); |
| |
| multiClickThreshhold = threshhold; |
| } |
| |
| /** |
| * Adds the specified component to this AbstractButton. This overrides the |
| * default in order to install an {@link OverlayLayout} layout manager |
| * before adding the component. The layout manager is only installed if |
| * no other layout manager has been installed before. |
| * |
| * @param comp the component to be added |
| * @param constraints constraints for the layout manager |
| * @param index the index at which the component is added |
| * |
| * @since 1.5 |
| */ |
| protected void addImpl(Component comp, Object constraints, int index) |
| { |
| // We use a client property here, so that no extra memory is used in |
| // the common case with no layout manager. |
| if (getClientProperty("AbstractButton.customLayoutSet") == null) |
| setLayout(new OverlayLayout(this)); |
| super.addImpl(comp, constraints, index); |
| } |
| |
| /** |
| * Sets a layout manager on this AbstractButton. This is overridden in order |
| * to detect if the application sets a custom layout manager. If no custom |
| * layout manager is set, {@link #addImpl(Component, Object, int)} installs |
| * an OverlayLayout before adding a component. |
| * |
| * @param layout the layout manager to install |
| * |
| * @since 1.5 |
| */ |
| public void setLayout(LayoutManager layout) |
| { |
| // We use a client property here, so that no extra memory is used in |
| // the common case with no layout manager. |
| putClientProperty("AbstractButton.customLayoutSet", Boolean.TRUE); |
| super.setLayout(layout); |
| } |
| |
| /** |
| * Helper method for |
| * {@link LookAndFeel#installProperty(JComponent, String, Object)}. |
| * |
| * @param propertyName the name of the property |
| * @param value the value of the property |
| * |
| * @throws IllegalArgumentException if the specified property cannot be set |
| * by this method |
| * @throws ClassCastException if the property value does not match the |
| * property type |
| * @throws NullPointerException if <code>c</code> or |
| * <code>propertyValue</code> is <code>null</code> |
| */ |
| void setUIProperty(String propertyName, Object value) |
| { |
| if (propertyName.equals("borderPainted")) |
| { |
| if (! clientBorderPaintedSet) |
| { |
| setBorderPainted(((Boolean) value).booleanValue()); |
| clientBorderPaintedSet = false; |
| } |
| } |
| else if (propertyName.equals("rolloverEnabled")) |
| { |
| if (! clientRolloverEnabledSet) |
| { |
| setRolloverEnabled(((Boolean) value).booleanValue()); |
| clientRolloverEnabledSet = false; |
| } |
| } |
| else if (propertyName.equals("iconTextGap")) |
| { |
| if (! clientIconTextGapSet) |
| { |
| setIconTextGap(((Integer) value).intValue()); |
| clientIconTextGapSet = false; |
| } |
| } |
| else if (propertyName.equals("contentAreaFilled")) |
| { |
| if (! clientContentAreaFilledSet) |
| { |
| setContentAreaFilled(((Boolean) value).booleanValue()); |
| clientContentAreaFilledSet = false; |
| } |
| } |
| else |
| { |
| super.setUIProperty(propertyName, value); |
| } |
| } |
| } |