Frames | No Frames |
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: private static final long serialVersionUID = -5932203980244017102L; 102: 103: protected AccessibleAWTButton() 104: { 105: // Do nothing here. 106: } 107: 108: /* (non-Javadoc) 109: * @see javax.accessibility.AccessibleAction#getAccessibleActionCount() 110: */ 111: public int getAccessibleActionCount() 112: { 113: // Only 1 action possible 114: return 1; 115: } 116: 117: /* (non-Javadoc) 118: * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int) 119: */ 120: public String getAccessibleActionDescription(int i) 121: { 122: // JDK 1.4.2 returns the string "click" for action 0. However, the API 123: // docs don't say what the string to be returned is, beyond being a 124: // description of the action. So we return the same thing for 125: // compatibility with 1.4.2. 126: if (i == 0) 127: return "click"; 128: return null; 129: } 130: 131: /* (non-Javadoc) 132: * @see javax.accessibility.AccessibleAction#doAccessibleAction(int) 133: */ 134: public boolean doAccessibleAction(int i) 135: { 136: if (i != 0) 137: return false; 138: processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand)); 139: return true; 140: } 141: 142: public String getAccessibleName() 143: { 144: return label; 145: } 146: 147: public AccessibleAction getAccessibleAction() 148: { 149: return this; 150: } 151: 152: public AccessibleValue getAccessibleValue() 153: { 154: return this; 155: } 156: 157: /* (non-Javadoc) 158: * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue() 159: */ 160: public Number getCurrentAccessibleValue() 161: { 162: // Docs say return 1 if selected, but buttons can't be selected, right? 163: return new Integer(0); 164: } 165: 166: /* (non-Javadoc) 167: * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number) 168: */ 169: public boolean setCurrentAccessibleValue(Number number) 170: { 171: // Since there's no selection with buttons, we're ignoring this. 172: // TODO someone who knows shoulw check this. 173: return false; 174: } 175: 176: /* (non-Javadoc) 177: * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue() 178: */ 179: public Number getMinimumAccessibleValue() 180: { 181: return new Integer(0); 182: } 183: 184: /* (non-Javadoc) 185: * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue() 186: */ 187: public Number getMaximumAccessibleValue() 188: { 189: return new Integer(0); 190: } 191: 192: public AccessibleRole getAccessibleRole() 193: { 194: return AccessibleRole.PUSH_BUTTON; 195: } 196: } 197: 198: /*************************************************************************/ 199: 200: /* 201: * Constructors 202: */ 203: 204: /** 205: * Initializes a new instance of <code>Button</code> with no label. 206: * 207: * @exception HeadlessException If GraphicsEnvironment.isHeadless() 208: * returns true 209: */ 210: public 211: Button() 212: { 213: this(""); 214: } 215: 216: /*************************************************************************/ 217: 218: /** 219: * Initializes a new instance of <code>Button</code> with the specified 220: * label. The action command name is also initialized to this value. 221: * 222: * @param label The label to display on the button. 223: * 224: * @exception HeadlessException If GraphicsEnvironment.isHeadless() 225: * returns true 226: */ 227: public 228: Button(String label) 229: { 230: this.label = label; 231: actionCommand = label; 232: 233: if (GraphicsEnvironment.isHeadless ()) 234: throw new HeadlessException (); 235: } 236: 237: /*************************************************************************/ 238: 239: /* 240: * Instance Variables 241: */ 242: 243: /** 244: * Returns the label for this button. 245: * 246: * @return The label for this button. 247: */ 248: public String 249: getLabel() 250: { 251: return(label); 252: } 253: 254: /*************************************************************************/ 255: 256: /** 257: * Sets the label for this button to the specified value. 258: * 259: * @param label The new label for this button. 260: */ 261: public synchronized void 262: setLabel(String label) 263: { 264: this.label = label; 265: actionCommand = label; 266: if (peer != null) 267: { 268: ButtonPeer bp = (ButtonPeer) peer; 269: bp.setLabel (label); 270: } 271: } 272: 273: /*************************************************************************/ 274: 275: /** 276: * Returns the action command name for this button. 277: * 278: * @return The action command name for this button. 279: */ 280: public String 281: getActionCommand() 282: { 283: return(actionCommand); 284: } 285: 286: /*************************************************************************/ 287: 288: /** 289: * Sets the action command name for this button to the specified value. 290: * 291: * @param actionCommand The new action command name. 292: */ 293: public void 294: setActionCommand(String actionCommand) 295: { 296: this.actionCommand = actionCommand == null ? label : actionCommand; 297: } 298: 299: /*************************************************************************/ 300: 301: /** 302: * Adds a new entry to the list of listeners that will receive 303: * action events from this button. 304: * 305: * @param listener The listener to add. 306: */ 307: public synchronized void 308: addActionListener(ActionListener listener) 309: { 310: action_listeners = AWTEventMulticaster.add(action_listeners, listener); 311: } 312: 313: /*************************************************************************/ 314: 315: /** 316: * Removes the specified listener from the list of listeners that will 317: * receive action events from this button. 318: * 319: * @param listener The listener to remove. 320: */ 321: public synchronized void 322: removeActionListener(ActionListener listener) 323: { 324: action_listeners = AWTEventMulticaster.remove(action_listeners, listener); 325: } 326: 327: /** 328: * Returns all added <code>ActionListener</code> objects. 329: * 330: * @return an array of listeners 331: * 332: * @since 1.4 333: */ 334: public synchronized ActionListener[] getActionListeners() 335: { 336: return (ActionListener[]) 337: AWTEventMulticaster.getListeners(action_listeners, 338: ActionListener.class); 339: } 340: 341: /** 342: * Returns all registered EventListers of the given listenerType. 343: * listenerType must be a subclass of EventListener, or a 344: * ClassClassException is thrown. 345: * 346: * @param listenerType the listener type to return 347: * 348: * @return an array of listeners 349: * 350: * @exception ClassCastException If listenerType doesn't specify a class or 351: * interface that implements @see java.util.EventListener. 352: * 353: * @since 1.3 354: */ 355: public <T extends EventListener> T[] getListeners(Class<T> listenerType) 356: { 357: if (listenerType == ActionListener.class) 358: return (T[]) getActionListeners(); 359: return (T[]) Array.newInstance(listenerType, 0); 360: } 361: 362: /*************************************************************************/ 363: 364: /** 365: * Notifies this button that it should create its native peer object. 366: */ 367: public void 368: addNotify() 369: { 370: if (peer == null) 371: peer = getToolkit ().createButton (this); 372: super.addNotify(); 373: } 374: 375: /*************************************************************************/ 376: 377: /** 378: * Processes an event for this button. If the specified event is an 379: * instance of <code>ActionEvent</code>, then the 380: * <code>processActionEvent()</code> method is called to dispatch it 381: * to any registered listeners. Otherwise, the superclass method 382: * will be invoked. Note that this method will not be called at all 383: * unless <code>ActionEvent</code>'s are enabled. This will be done 384: * implicitly if any listeners are added. 385: * 386: * @param event The event to process. 387: */ 388: protected void 389: processEvent(AWTEvent event) 390: { 391: if (event instanceof ActionEvent) 392: processActionEvent((ActionEvent)event); 393: else 394: super.processEvent(event); 395: } 396: 397: /*************************************************************************/ 398: 399: /** 400: * This method dispatches an action event for this button to any 401: * registered listeners. 402: * 403: * @param event The event to process. 404: */ 405: protected void 406: processActionEvent(ActionEvent event) 407: { 408: if (action_listeners != null) 409: action_listeners.actionPerformed(event); 410: } 411: 412: void 413: dispatchEventImpl(AWTEvent e) 414: { 415: if (e.id <= ActionEvent.ACTION_LAST 416: && e.id >= ActionEvent.ACTION_FIRST 417: && (action_listeners != null 418: || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0)) 419: processEvent(e); 420: else 421: super.dispatchEventImpl(e); 422: } 423: 424: /*************************************************************************/ 425: 426: /** 427: * Returns a debugging string for this button. 428: * 429: * @return A debugging string for this button. 430: */ 431: protected String 432: paramString() 433: { 434: return getName () + "," + getX () + "," + getY () + "," 435: + getWidth () + "x" + getHeight () + ",label=" + getLabel (); 436: } 437: 438: /** 439: * Gets the AccessibleContext associated with this <code>Button</code>. 440: * The context is created, if necessary. 441: * 442: * @return the associated context 443: */ 444: public AccessibleContext getAccessibleContext() 445: { 446: /* Create the context if this is the first request */ 447: if (accessibleContext == null) 448: accessibleContext = new AccessibleAWTButton(); 449: return accessibleContext; 450: } 451: 452: /** 453: * Generate a unique name for this button. 454: * 455: * @return A unique name for this button. 456: */ 457: String generateName () 458: { 459: return "button" + getUniqueLong (); 460: } 461: 462: private static synchronized long getUniqueLong () 463: { 464: return next_button_number++; 465: } 466: 467: } // class Button