Source for java.awt.Button

   1: /* Button.java -- AWT button widget
   2:    Copyright (C) 1999, 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt;
  40: 
  41: import java.awt.event.ActionEvent;
  42: import java.awt.event.ActionListener;
  43: import java.awt.peer.ButtonPeer;
  44: import java.lang.reflect.Array;
  45: import java.util.EventListener;
  46: 
  47: import javax.accessibility.Accessible;
  48: import javax.accessibility.AccessibleAction;
  49: import javax.accessibility.AccessibleContext;
  50: import javax.accessibility.AccessibleRole;
  51: import javax.accessibility.AccessibleValue;
  52: 
  53: /**
  54:   * This class provides a button widget for the AWT. 
  55:   *
  56:   * @author Aaron M. Renn (arenn@urbanophile.com)
  57:   * @author Tom Tromey (tromey@cygnus.com)
  58:   */
  59: public class Button extends Component
  60:   implements java.io.Serializable, Accessible
  61: {
  62: 
  63: /*
  64:  * Static Variables
  65:  */
  66: 
  67: // FIXME: Need readObject/writeObject for serialization
  68: 
  69: // Serialization version constant
  70: private static final long serialVersionUID = -8774683716313001058L;
  71: 
  72: /*************************************************************************/
  73: 
  74: /*
  75:  * Instance Variables
  76:  */
  77: 
  78: /**
  79:   * @serial The action command name for this button.
  80:   * This is package-private to avoid an accessor method.
  81:   */
  82: String actionCommand;
  83: 
  84: /**
  85:   * @serial The label for this button.
  86:   * This is package-private to avoid an accessor method.
  87:   */
  88: String label;
  89: 
  90: // List of ActionListeners for this class.
  91: private transient ActionListener action_listeners;
  92: 
  93:   /*
  94:    * The number used to generate the name returned by getName.
  95:    */
  96:   private static transient long next_button_number;
  97:   
  98:   protected class AccessibleAWTButton extends AccessibleAWTComponent
  99:     implements AccessibleAction, AccessibleValue
 100:   {
 101:     protected AccessibleAWTButton()
 102:     {
 103:       // Do nothing here.
 104:     }
 105: 
 106:     /* (non-Javadoc)
 107:      * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
 108:      */
 109:     public int getAccessibleActionCount()
 110:     {
 111:       // Only 1 action possible
 112:       return 1;
 113:     }
 114: 
 115:     /* (non-Javadoc)
 116:      * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
 117:      */
 118:     public String getAccessibleActionDescription(int i)
 119:     {
 120:       // JDK 1.4.2 returns the string "click" for action 0.  However, the API
 121:       // docs don't say what the string to be returned is, beyond being a
 122:       // description of the action.  So we return the same thing for
 123:       // compatibility with 1.4.2.
 124:       if (i == 0)
 125:         return "click";
 126:       return null;
 127:     }
 128: 
 129:     /* (non-Javadoc)
 130:      * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
 131:      */
 132:     public boolean doAccessibleAction(int i)
 133:     {
 134:       if (i != 0)
 135:         return false;
 136:       processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
 137:       return true;
 138:     }
 139:     
 140:     public String getAccessibleName()
 141:     {
 142:       return label;
 143:     }
 144:     
 145:     public AccessibleAction getAccessibleAction()
 146:     {
 147:       return this;
 148:     }
 149:     
 150:     public AccessibleValue getAccessibleValue()
 151:     {
 152:       return this;
 153:     }
 154: 
 155:     /* (non-Javadoc)
 156:      * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
 157:      */
 158:     public Number getCurrentAccessibleValue()
 159:     {
 160:       // Docs say return 1 if selected, but buttons can't be selected, right?
 161:       return new Integer(0);
 162:     }
 163: 
 164:     /* (non-Javadoc)
 165:      * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
 166:      */
 167:     public boolean setCurrentAccessibleValue(Number number)
 168:     {
 169:       // Since there's no selection with buttons, we're ignoring this.
 170:       // TODO someone who knows shoulw check this.
 171:       return false;
 172:     }
 173: 
 174:     /* (non-Javadoc)
 175:      * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
 176:      */
 177:     public Number getMinimumAccessibleValue()
 178:     {
 179:       return new Integer(0);
 180:     }
 181: 
 182:     /* (non-Javadoc)
 183:      * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
 184:      */
 185:     public Number getMaximumAccessibleValue()
 186:     {
 187:       return new Integer(0);
 188:     }
 189:     
 190:     public AccessibleRole getAccessibleRole()
 191:     {
 192:       return AccessibleRole.PUSH_BUTTON;
 193:     }
 194:   }
 195: 
 196: /*************************************************************************/
 197: 
 198: /*
 199:  * Constructors
 200:  */
 201: 
 202: /**
 203:   * Initializes a new instance of <code>Button</code> with no label.
 204:   *
 205:   * @exception HeadlessException If GraphicsEnvironment.isHeadless()
 206:   * returns true
 207:   */
 208: public
 209: Button()
 210: {
 211:   this("");
 212: }
 213: 
 214: /*************************************************************************/
 215: 
 216: /**
 217:   * Initializes a new instance of <code>Button</code> with the specified
 218:   * label.  The action command name is also initialized to this value.
 219:   *
 220:   * @param label The label to display on the button.
 221:   *
 222:   * @exception HeadlessException If GraphicsEnvironment.isHeadless()
 223:   * returns true
 224:   */
 225: public
 226: Button(String label)
 227: {
 228:   this.label = label;
 229:   actionCommand = label;
 230: 
 231:   if (GraphicsEnvironment.isHeadless ())
 232:     throw new HeadlessException ();
 233: }
 234: 
 235: /*************************************************************************/
 236: 
 237: /*
 238:  * Instance Variables
 239:  */
 240: 
 241: /**
 242:   * Returns the label for this button.
 243:   *
 244:   * @return The label for this button.
 245:   */
 246: public String
 247: getLabel()
 248: {
 249:   return(label);
 250: }
 251: 
 252: /*************************************************************************/
 253: 
 254: /**
 255:   * Sets the label for this button to the specified value.
 256:   *
 257:   * @param label The new label for this button.
 258:   */
 259: public synchronized void
 260: setLabel(String label)
 261: {
 262:   this.label = label;
 263:   actionCommand = label;
 264:   if (peer != null)
 265:     {
 266:       ButtonPeer bp = (ButtonPeer) peer;
 267:       bp.setLabel (label);
 268:     }
 269: }
 270: 
 271: /*************************************************************************/
 272: 
 273: /**
 274:   * Returns the action command name for this button.
 275:   *
 276:   * @return The action command name for this button.
 277:   */
 278: public String
 279: getActionCommand()
 280: {
 281:   return(actionCommand);
 282: }
 283: 
 284: /*************************************************************************/
 285: 
 286: /**
 287:   * Sets the action command name for this button to the specified value.
 288:   *
 289:   * @param actionCommand The new action command name.
 290:   */
 291: public void
 292: setActionCommand(String actionCommand)
 293: {
 294:   this.actionCommand = actionCommand == null ? label : actionCommand;
 295: }
 296: 
 297: /*************************************************************************/
 298: 
 299: /**
 300:   * Adds a new entry to the list of listeners that will receive
 301:   * action events from this button.
 302:   *
 303:   * @param listener The listener to add.
 304:   */
 305: public synchronized void
 306: addActionListener(ActionListener listener)
 307: {
 308:   action_listeners = AWTEventMulticaster.add(action_listeners, listener);
 309: }
 310: 
 311: /*************************************************************************/
 312: 
 313: /**
 314:   * Removes the specified listener from the list of listeners that will
 315:   * receive action events from this button.
 316:   * 
 317:   * @param listener The listener to remove.
 318:   */
 319: public synchronized void
 320: removeActionListener(ActionListener listener)
 321: {
 322:   action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
 323: }
 324: 
 325:   /**
 326:    * Returns all added <code>ActionListener</code> objects.
 327:    *
 328:    * @return an array of listeners
 329:    *
 330:    * @since 1.4
 331:    */
 332:   public synchronized ActionListener[] getActionListeners()
 333:   {
 334:     return (ActionListener[])
 335:       AWTEventMulticaster.getListeners(action_listeners,
 336:                                        ActionListener.class);
 337:   }
 338: 
 339: /**
 340:  * Returns all registered EventListers of the given listenerType. 
 341:  * listenerType must be a subclass of EventListener, or a 
 342:  * ClassClassException is thrown.
 343:  *
 344:  * @param listenerType the listener type to return
 345:  *
 346:  * @return an array of listeners
 347:  * 
 348:  * @exception ClassCastException If listenerType doesn't specify a class or
 349:  * interface that implements @see java.util.EventListener.
 350:  *
 351:  * @since 1.3 
 352:  */
 353:   public EventListener[] getListeners(Class listenerType)
 354:   {
 355:     if (listenerType == ActionListener.class)
 356:       return getActionListeners();
 357:     return (EventListener[]) Array.newInstance(listenerType, 0);
 358:   }
 359: 
 360: /*************************************************************************/
 361: 
 362: /**
 363:   * Notifies this button that it should create its native peer object.
 364:   */
 365: public void
 366: addNotify()
 367: {
 368:   if (peer == null)
 369:     peer = getToolkit ().createButton (this);
 370:   super.addNotify();
 371: }
 372: 
 373: /*************************************************************************/
 374: 
 375: /**
 376:   * Processes an event for this button.  If the specified event is an
 377:   * instance of <code>ActionEvent</code>, then the
 378:   * <code>processActionEvent()</code> method is called to dispatch it
 379:   * to any registered listeners.  Otherwise, the superclass method
 380:   * will be invoked.  Note that this method will not be called at all
 381:   * unless <code>ActionEvent</code>'s are enabled.  This will be done
 382:   * implicitly if any listeners are added.
 383:   *
 384:   * @param event The event to process.
 385:   */
 386: protected void
 387: processEvent(AWTEvent event)
 388: {
 389:   if (event instanceof ActionEvent)
 390:     processActionEvent((ActionEvent)event);
 391:   else
 392:     super.processEvent(event);
 393: }
 394: 
 395: /*************************************************************************/
 396: 
 397: /**
 398:   * This method dispatches an action event for this button to any
 399:   * registered listeners.
 400:   *
 401:   * @param event The event to process.
 402:   */
 403: protected void
 404: processActionEvent(ActionEvent event)
 405: {
 406:   if (action_listeners != null)
 407:     action_listeners.actionPerformed(event);
 408: }
 409: 
 410: void
 411: dispatchEventImpl(AWTEvent e)
 412: {
 413:   if (e.id <= ActionEvent.ACTION_LAST 
 414:       && e.id >= ActionEvent.ACTION_FIRST
 415:       && (action_listeners != null 
 416:       || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
 417:     processEvent(e);
 418:   else
 419:     super.dispatchEventImpl(e);
 420: }
 421: 
 422: /*************************************************************************/
 423: 
 424: /**
 425:   * Returns a debugging string for this button.
 426:   *
 427:   * @return A debugging string for this button.
 428:   */
 429: protected String
 430: paramString()
 431: {
 432:   return getName () + "," + getX () + "," + getY () + ","
 433:     + getWidth () + "x" + getHeight () + ",label=" + getLabel ();
 434: }
 435: 
 436: /**
 437:  * Gets the AccessibleContext associated with this <code>Button</code>.
 438:  * The context is created, if necessary.
 439:  *
 440:  * @return the associated context
 441:  */
 442: public AccessibleContext getAccessibleContext()
 443: {
 444:   /* Create the context if this is the first request */
 445:   if (accessibleContext == null)
 446:     accessibleContext = new AccessibleAWTButton();
 447:   return accessibleContext;
 448: }
 449: 
 450:   /**
 451:    * Generate a unique name for this button.
 452:    *
 453:    * @return A unique name for this button.
 454:    */
 455:   String generateName ()
 456:   {
 457:     return "button" + getUniqueLong ();
 458:   }
 459: 
 460:   private static synchronized long getUniqueLong ()
 461:   {
 462:     return next_button_number++;
 463:   }
 464: 
 465: } // class Button