/* 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.java.lang.CPStringBuilder;

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.Document;
import javax.swing.text.Element;
import javax.swing.text.Position;
import javax.swing.text.StyledDocument;
import javax.swing.text.View;


/**
 * Provides an abstract implementation of common button behaviour,
 * data model and look &amp; 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)
    {
      getEventHandler().stateChanged(ev);
    }
  }

  /**
   * The combined event handler for ActionEvent, ChangeEvent and
   * ItemEvent. This combines ButtonChangeListener, ActionListener
   */
  private class EventHandler
    implements ActionListener, ChangeListener, ItemListener
  {
    public void actionPerformed(ActionEvent ev)
    {
      fireActionPerformed(ev);
    }

    public void stateChanged(ChangeEvent ev)
    {
      fireStateChanged();
      repaint();
    }

    public void itemStateChanged(ItemEvent ev)
    {
      fireItemStateChanged(ev);
    }
  }

  /** 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 event handler for ActionEvent, ItemEvent and ChangeEvent.
   * This replaces the above three handlers and combines them
   * into one for efficiency.
   */
  private EventHandler eventHandler;

  /**
   * 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;
    }

    /**
     * Returns the character, word or sentence at the specified index. The
     * <code>part</code> parameter determines what is returned, the character,
     * word or sentence after the index.
     *
     * @param part one of {@link AccessibleText#CHARACTER},
     *             {@link AccessibleText#WORD} or
     *             {@link AccessibleText#SENTENCE}, specifying what is returned
     * @param index the index
     *
     * @return the character, word or sentence after <code>index</code>
     */
    public String getAtIndex(int part, int index)
    {
      String result = "";
      int startIndex = -1;
      int endIndex = -1;
      switch(part)
        {
        case AccessibleText.CHARACTER:
          result = String.valueOf(text.charAt(index));
          break;
        case AccessibleText.WORD:
          startIndex = text.lastIndexOf(' ', index);
          endIndex = text.indexOf(' ', startIndex + 1);
          if (endIndex == -1)
            endIndex = startIndex + 1;
          result = text.substring(startIndex + 1, endIndex);
          break;
        case AccessibleText.SENTENCE:
        default:
          startIndex = text.lastIndexOf('.', index);
          endIndex = text.indexOf('.', startIndex + 1);
          if (endIndex == -1)
            endIndex = startIndex + 1;
          result = text.substring(startIndex + 1, endIndex);
          break;
        }
      return result;
    }

    /**
     * Returns the character, word or sentence after the specified index. The
     * <code>part</code> parameter determines what is returned, the character,
     * word or sentence after the index.
     *
     * @param part one of {@link AccessibleText#CHARACTER},
     *             {@link AccessibleText#WORD} or
     *             {@link AccessibleText#SENTENCE}, specifying what is returned
     * @param index the index
     *
     * @return the character, word or sentence after <code>index</code>
     */
    public String getAfterIndex(int part, int index)
    {
      String result = "";
      int startIndex = -1;
      int endIndex = -1;
      switch(part)
        {
        case AccessibleText.CHARACTER:
          result = String.valueOf(text.charAt(index + 1));
          break;
        case AccessibleText.WORD:
          startIndex = text.indexOf(' ', index);
          endIndex = text.indexOf(' ', startIndex + 1);
          if (endIndex == -1)
            endIndex = startIndex + 1;
          result = text.substring(startIndex + 1, endIndex);
          break;
        case AccessibleText.SENTENCE:
        default:
          startIndex = text.indexOf('.', index);
          endIndex = text.indexOf('.', startIndex + 1);
          if (endIndex == -1)
            endIndex = startIndex + 1;
          result = text.substring(startIndex + 1, endIndex);
          break;
        }
      return result;
    }

    /**
     * Returns the character, word or sentence before the specified index. The
     * <code>part</code> parameter determines what is returned, the character,
     * word or sentence before the index.
     *
     * @param part one of {@link AccessibleText#CHARACTER},
     *             {@link AccessibleText#WORD} or
     *             {@link AccessibleText#SENTENCE}, specifying what is returned
     * @param index the index
     *
     * @return the character, word or sentence before <code>index</code>
     */
    public String getBeforeIndex(int part, int index)
    {
      String result = "";
      int startIndex = -1;
      int endIndex = -1;
      switch(part)
        {
        case AccessibleText.CHARACTER:
          result = String.valueOf(text.charAt(index - 1));
          break;
        case AccessibleText.WORD:
          endIndex = text.lastIndexOf(' ', index);
          if (endIndex == -1)
            endIndex = 0;
          startIndex = text.lastIndexOf(' ', endIndex - 1);
          result = text.substring(startIndex + 1, endIndex);
          break;
        case AccessibleText.SENTENCE:
        default:
          endIndex = text.lastIndexOf('.', index);
          if (endIndex == -1)
            endIndex = 0;
          startIndex = text.lastIndexOf('.', endIndex - 1);
          result = text.substring(startIndex + 1, endIndex);
          break;
        }
      return result;
    }

    /**
     * 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)
        {
          Document doc = view.getDocument();
          if (doc instanceof StyledDocument)
            {
              StyledDocument sDoc = (StyledDocument) doc;
              Element charEl = sDoc.getCharacterElement(i);
              if (charEl != null)
                atts = charEl.getAttributes();
            }
        }
      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()
  {
    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 = "";
    // testing on JRE1.5 shows that the iconTextGap default value is
    // hard-coded here and the 'Button.iconTextGap' setting in the
    // UI defaults is ignored, at least by the MetalLookAndFeel
    iconTextGap = 4;
  }

  /**
   * 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);
        actionListener = null;
        model.removeChangeListener(changeListener);
        changeListener = null;
        model.removeItemListener(itemListener);
        itemListener = null;
      }
    ButtonModel old = model;
    model = newModel;
    if (model != null)
      {
        actionListener = createActionListener();
        model.addActionListener(actionListener);
        changeListener = createChangeListener();
        model.addChangeListener(changeListener);
        itemListener = createItemListener();
        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;

    updateUI();
 }

  /**
   * <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 getEventHandler();
  }

  /**
   * <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 getEventHandler();
  }

  /**
   * <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 getEventHandler();
  }

  /**
   * 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()
  {
    CPStringBuilder sb = new CPStringBuilder();
    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);
      }
  }

  /**
   * Returns the combined event handler. The instance is created if
   * necessary.
   *
   * @return the combined event handler
   */
  EventHandler getEventHandler()
  {
    if (eventHandler == null)
      eventHandler = new EventHandler();
    return eventHandler;
  }
}
