Source for java.awt.Checkbox

   1: /* Checkbox.java -- An AWT checkbox widget
   2:    Copyright (C) 1999, 2000, 2001, 2002, 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.ItemEvent;
  42: import java.awt.event.ItemListener;
  43: import java.awt.peer.CheckboxPeer;
  44: import java.io.Serializable;
  45: 
  46: import javax.accessibility.Accessible;
  47: import javax.accessibility.AccessibleAction;
  48: import javax.accessibility.AccessibleContext;
  49: import javax.accessibility.AccessibleRole;
  50: import javax.accessibility.AccessibleState;
  51: import javax.accessibility.AccessibleStateSet;
  52: import javax.accessibility.AccessibleValue;
  53: 
  54: /**
  55:  * This class implements a component which has an on/off state.  Two
  56:  * or more Checkboxes can be grouped by a CheckboxGroup.
  57:  *
  58:  * @author Aaron M. Renn (arenn@urbanophile.com)
  59:  * @author Tom Tromey (tromey@redhat.com)
  60:  */
  61: public class Checkbox extends Component
  62:   implements ItemSelectable, Accessible, Serializable
  63: {
  64: 
  65: // FIXME: Need readObject/writeObject for this.
  66: 
  67: /*
  68:  * Static Variables
  69:  */
  70: 
  71: // Serialization Constant
  72: private static final long serialVersionUID = 7270714317450821763L;
  73: 
  74: /*************************************************************************/
  75: 
  76: /*
  77:  * Instance Variables
  78:  */
  79: 
  80: /**
  81:   * @serial The checkbox group for this checkbox.
  82:   */
  83: private CheckboxGroup group;
  84: 
  85: /**
  86:   * @serial The label on this checkbox.
  87:   */
  88: private String label;
  89: 
  90: /**
  91:   * @serial The state of this checkbox.
  92:   * This is package-private to avoid an accessor method.
  93:   */
  94: boolean state;
  95: 
  96: // The list of listeners for this object.
  97: private transient ItemListener item_listeners;
  98: 
  99:   /*
 100:    * The number used to generate the name returned by getName.
 101:    */
 102:   private static transient long next_checkbox_number;
 103: 
 104: /**
 105:  * This class provides accessibility support for the
 106:  * checkbox.
 107:  *
 108:  * @author Jerry Quinn  (jlquinn@optonline.net)
 109:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 110:  */
 111: protected class AccessibleAWTCheckbox
 112:   extends AccessibleAWTComponent
 113:   implements ItemListener, AccessibleAction, AccessibleValue
 114: {
 115:   /**
 116:    * Serialization constant to match JDK 1.5
 117:    */
 118:   private static final long serialVersionUID = 7881579233144754107L;
 119: 
 120:   /**
 121:    * Default constructor which simply calls the
 122:    * super class for generic component accessibility
 123:    * handling.
 124:    */
 125:   public AccessibleAWTCheckbox()
 126:   {
 127:     super();
 128:   }
 129: 
 130:   /**
 131:    * Captures changes to the state of the checkbox and
 132:    * fires appropriate accessible property change events.
 133:    *
 134:    * @param event the event fired.
 135:    * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
 136:    */
 137:   public void itemStateChanged(ItemEvent event)
 138:   {
 139:     firePropertyChange(ACCESSIBLE_STATE_PROPERTY,
 140:                state ? null : AccessibleState.CHECKED,
 141:                        state ? AccessibleState.CHECKED : null);
 142:   }
 143:   
 144:   /**
 145:    * Returns an implementation of the <code>AccessibleAction</code>
 146:    * interface for this accessible object.  In this case, the
 147:    * current instance is simply returned (with a more appropriate
 148:    * type), as it also implements the accessible action as well as
 149:    * the context.
 150:    *
 151:    * @return the accessible action associated with this context.
 152:    * @see javax.accessibility.AccessibleAction
 153:    */
 154:   public AccessibleAction getAccessibleAction()
 155:   {
 156:     return this;
 157:   }
 158:   
 159:   /**
 160:    * Returns an implementation of the <code>AccessibleValue</code>
 161:    * interface for this accessible object.  In this case, the
 162:    * current instance is simply returned (with a more appropriate
 163:    * type), as it also implements the accessible value as well as
 164:    * the context.
 165:    *
 166:    * @return the accessible value associated with this context.
 167:    * @see javax.accessibility.AccessibleValue
 168:    */
 169:   public AccessibleValue getAccessibleValue()
 170:   {
 171:     return this;
 172:   }
 173:   
 174:   /* 
 175:    * The following methods are implemented in the JDK (up to
 176:    * 1.5) as stubs.  We do likewise here.
 177:    */
 178: 
 179:   /**
 180:    * Returns the number of actions associated with this accessible
 181:    * object.  This default implementation returns 0.
 182:    *
 183:    * @return the number of accessible actions available.
 184:    * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
 185:    */
 186:   public int getAccessibleActionCount()
 187:   {
 188:     // 1.4.1 and 1.5 do this
 189:     return 0;
 190:   }
 191: 
 192:   /**
 193:    * Returns a description of the action with the supplied id.
 194:    * This default implementation always returns null.
 195:    *
 196:    * @param i the id of the action whose description should be
 197:    *          retrieved.
 198:    * @return a <code>String</code> describing the action.
 199:    * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
 200:    */
 201:   public String getAccessibleActionDescription(int i)
 202:   {
 203:     // 1.5 does this
 204:     return null;
 205:   }
 206: 
 207:   /**
 208:    * Executes the action with the specified id.  This
 209:    * default implementation simply returns false.
 210:    *
 211:    * @param i the id of the action to perform.
 212:    * @return true if the action was performed.
 213:    * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
 214:    */
 215:   public boolean doAccessibleAction(int i)
 216:   {
 217:     // 1.5 does this
 218:     return false;
 219:   }
 220: 
 221:   /**
 222:    * Returns the current value of this accessible object.
 223:    * If no value has been set, null is returned.  This
 224:    * default implementation always returns null, regardless.
 225:    *
 226:    * @return the numeric value of this object, or null if
 227:    *         no value has been set.
 228:    * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
 229:    */
 230:   public Number getCurrentAccessibleValue()
 231:   {
 232:     // 1.5 does this
 233:     return null;
 234:   }
 235: 
 236:   /**
 237:    * Sets the current value of this accessible object
 238:    * to that supplied.  In this default implementation,
 239:    * the value is never set and the method always returns
 240:    * false.
 241:    *
 242:    * @param number the new accessible value.
 243:    * @return true if the value was set.
 244:    * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
 245:    */
 246:   public boolean setCurrentAccessibleValue(Number number)
 247:   {
 248:     // 1.5 does this
 249:     return false;
 250:   }
 251: 
 252:   /**
 253:    * Returns the minimum acceptable accessible value used
 254:    * by this object, or null if no minimum value exists.
 255:    * This default implementation always returns null.
 256:    *
 257:    * @return the minimum acceptable accessible value, or null
 258:    *         if there is no minimum.
 259:    * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
 260:    */
 261:   public Number getMinimumAccessibleValue()
 262:   {
 263:     return null;
 264:   }
 265: 
 266:   /**
 267:    * Returns the maximum acceptable accessible value used
 268:    * by this object, or null if no maximum value exists.
 269:    * This default implementation always returns null.
 270:    *
 271:    * @return the maximum acceptable accessible value, or null
 272:    *         if there is no maximum.
 273:    * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
 274:    */
 275:   public Number getMaximumAccessibleValue()
 276:   {
 277:     return null;
 278:   }
 279:   
 280:   /**
 281:    * Returns the role of this accessible object.
 282:    *
 283:    * @return the instance of <code>AccessibleRole</code>,
 284:    *         which describes this object.
 285:    * @see javax.accessibility.AccessibleRole
 286:    */
 287:   public AccessibleRole getAccessibleRole() 
 288:   {
 289:     return AccessibleRole.CHECK_BOX;
 290:   }
 291:   
 292:   /**
 293:    * Returns the state set of this accessible object.
 294:    *
 295:    * @return a set of <code>AccessibleState</code>s
 296:    *         which represent the current state of the
 297:    *         accessible object.
 298:    * @see javax.accessibility.AccessibleState
 299:    * @see javax.accessibility.AccessibleStateSet
 300:    */
 301:   public AccessibleStateSet getAccessibleStateSet()
 302:   {
 303:     AccessibleStateSet set = super.getAccessibleStateSet();
 304:     if (state)
 305:       set.add(AccessibleState.CHECKED);
 306:     return set;
 307:   }
 308: 
 309: }
 310: 
 311: /*************************************************************************/
 312: 
 313: /*
 314:  * Constructors
 315:  */
 316: 
 317: /**
 318:   * Initializes a new instance of <code>Checkbox</code> with no label,
 319:   * an initial state of off, and that is not part of any checkbox group.
 320:   */
 321: public 
 322: Checkbox()
 323: {
 324:   this("", false, null);
 325: }
 326: 
 327: /*************************************************************************/
 328: 
 329: /**
 330:   * Initializes a new instance of <code>Checkbox</code> with the specified
 331:   * label, an initial state of off, and that is not part of any checkbox
 332:   * group.
 333:   *
 334:   * @param label The label for this checkbox.
 335:   */
 336: public
 337: Checkbox(String label)
 338: {
 339:   this(label, false, null);
 340: }
 341: 
 342: /*************************************************************************/
 343: 
 344: /**
 345:   * Initializes a new instance of <code>Checkbox</code> with the specified
 346:   * label and initial state, and that is not part of any checkbox
 347:   * group.
 348:   *
 349:   * @param label The label for this checkbox.
 350:   * @param state The initial state of the checkbox, <code>true</code> for
 351:   * on, <code>false</code> for off.
 352:   */
 353: public
 354: Checkbox(String label, boolean state)
 355: {
 356:   this(label, state, null);
 357: }
 358: 
 359: /*************************************************************************/
 360: 
 361: /**
 362:   * Initializes a new instance of <code>Checkbox</code> with the specified
 363:   * label, initial state, and checkbox group.
 364:   *
 365:   * @param label The label for this checkbox.
 366:   * @param group The checkbox group for this box, or <code>null</code>
 367:   * if there is no checkbox group.
 368:   * @param state The initial state of the checkbox, <code>true</code> for
 369:   * on, <code>false</code> for off.
 370:   */
 371: public
 372: Checkbox(String label, CheckboxGroup group, boolean state)
 373: {
 374:   this(label, state, group);
 375: }
 376: 
 377: /*************************************************************************/
 378: 
 379: /**
 380:   * Initializes a new instance of <code>Checkbox</code> with the specified
 381:   * label, initial state, and checkbox group.
 382:   *
 383:   * @param label The label for this checkbox.
 384:   * @param state The initial state of the checkbox, <code>true</code> for
 385:   * on, <code>false</code> for off.
 386:   * @param group The checkbox group for this box, or <code>null</code>
 387:   * if there is no checkbox group.
 388:   */
 389: public
 390: Checkbox(String label, boolean state, CheckboxGroup group)
 391: {
 392:   this.label = label;
 393:   this.state = state;
 394:   this.group = group;
 395: 
 396:   if ( state && group != null )
 397:     {
 398:       group.setSelectedCheckbox(this);
 399:     }
 400: }
 401: 
 402: /*************************************************************************/
 403: 
 404: /*
 405:  * Instance Variables
 406:  */
 407: 
 408: /**
 409:   * Returns the label for this checkbox.
 410:   *
 411:   * @return The label for this checkbox.
 412:   */
 413: public String
 414: getLabel()
 415: {
 416:   return(label);
 417: }
 418: 
 419: /*************************************************************************/
 420: 
 421: /**
 422:   * Sets the label for this checkbox to the specified value.
 423:   *
 424:   * @param label The new checkbox label.
 425:   */
 426: public synchronized void
 427: setLabel(String label)
 428: {
 429:   this.label = label;
 430:   if (peer != null)
 431:     {
 432:       CheckboxPeer cp = (CheckboxPeer) peer;
 433:       cp.setLabel(label);
 434:     }
 435: }
 436: 
 437: /*************************************************************************/
 438: 
 439: /**
 440:   * Returns the state of this checkbox.
 441:   *
 442:   * @return The state of this checkbox, which will be <code>true</code> for
 443:   * on and <code>false</code> for off.
 444:   */
 445: public boolean
 446: getState()
 447: {
 448:   return(state);
 449: }
 450: 
 451: /*************************************************************************/
 452: 
 453: /**
 454:   * Sets the state of this checkbox to the specified value.
 455:   *
 456:   * @param state The new state of the checkbox, which will be <code>true</code>
 457:   * for on or <code>false</code> for off.
 458:   */
 459: public synchronized void
 460: setState(boolean state)
 461: {
 462:   this.state = state;
 463:   if (peer != null)
 464:     {
 465:       CheckboxPeer cp = (CheckboxPeer) peer;
 466:       cp.setState (state);
 467:     }
 468: }
 469: 
 470: /*************************************************************************/
 471: 
 472: /**
 473:   * Returns an array of length one containing the checkbox label if this
 474:   * checkbox is selected.  Otherwise <code>null</code> is returned.
 475:   *
 476:   * @return The selection state of this checkbox.
 477:   */
 478: public Object[]
 479: getSelectedObjects()
 480: {
 481:   if (state == false)
 482:     return(null);
 483: 
 484:   Object[] objs = new Object[1];
 485:   objs[0] = label;
 486: 
 487:   return(objs);
 488: }
 489: 
 490: /*************************************************************************/
 491: 
 492: /**
 493:   * Returns the checkbox group this object is a member of, if any.
 494:   *
 495:   * @return This object's checkbox group, of <code>null</code> if it is
 496:   * not a member of any group.
 497:   */
 498: public CheckboxGroup
 499: getCheckboxGroup()
 500: {
 501:   return(group);
 502: }
 503: 
 504: /*************************************************************************/
 505: 
 506: /**
 507:   * Sets this object's checkbox group to the specified group.
 508:   *
 509:   * @param group The new checkbox group, or <code>null</code> to make this
 510:   * object part of no checkbox group.
 511:   */
 512: public synchronized void
 513: setCheckboxGroup(CheckboxGroup group)
 514: {
 515:   this.group = group;
 516:   if (peer != null)
 517:     {
 518:       CheckboxPeer cp = (CheckboxPeer) peer;
 519:       cp.setCheckboxGroup (group);
 520:     }
 521: }
 522: 
 523: /*************************************************************************/
 524: 
 525: /**
 526:   * Creates this object's native peer.
 527:   */
 528: public void
 529: addNotify()
 530: {
 531:   if (peer == null)
 532:     peer = getToolkit ().createCheckbox (this);
 533:   super.addNotify ();
 534: }
 535: 
 536:   public ItemListener[] getItemListeners ()
 537:   {
 538:     return (ItemListener[])
 539:       AWTEventMulticaster.getListeners (item_listeners, ItemListener.class);
 540:   }
 541: 
 542: /**
 543:   * Adds a new listeners to the list of registered listeners for this object.
 544:   *
 545:   * @param listener The new listener to add.
 546:   */
 547: public synchronized void
 548: addItemListener(ItemListener listener)
 549: {
 550:   item_listeners = AWTEventMulticaster.add(item_listeners, listener);
 551: }
 552: 
 553: /*************************************************************************/
 554: 
 555: /**
 556:   * Removes a listener from the list of registered listeners for this object.
 557:   *
 558:   * @param listener The listener to remove.
 559:   */
 560: public synchronized void
 561: removeItemListener(ItemListener listener)
 562: {
 563:   item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
 564: }
 565: 
 566: /*************************************************************************/
 567: 
 568: /**
 569:   * Processes this event by calling <code>processItemEvent()</code> if it
 570:   * is any instance of <code>ItemEvent</code>.  Otherwise it is passed to
 571:   * the superclass for processing.
 572:   *
 573:   * @param event The event to process.
 574:   */
 575: protected void
 576: processEvent(AWTEvent event)
 577: {
 578:   if (event instanceof ItemEvent)
 579:     processItemEvent((ItemEvent)event);
 580:   else
 581:     super.processEvent(event);
 582: }
 583: 
 584: /*************************************************************************/
 585: 
 586: /**
 587:   * Processes this event by dispatching it to any registered listeners.
 588:   *
 589:   * @param event The <code>ItemEvent</code> to process.
 590:   */
 591: protected void
 592: processItemEvent(ItemEvent event)
 593: {
 594:   if (item_listeners != null)
 595:     item_listeners.itemStateChanged(event);
 596: }
 597: 
 598: void
 599: dispatchEventImpl(AWTEvent e)
 600: {
 601:   if (e.id <= ItemEvent.ITEM_LAST
 602:       && e.id >= ItemEvent.ITEM_FIRST
 603:       && (item_listeners != null 
 604:       || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
 605:     processEvent(e);
 606:   else
 607:     super.dispatchEventImpl(e);
 608: }
 609: 
 610: /*************************************************************************/
 611: 
 612: /**
 613:   * Returns a debugging string for this object.
 614:   */
 615: protected String
 616: paramString()
 617: {
 618:   // Note: We cannot add the checkbox group information here because this
 619:   // would trigger infinite recursion when CheckboxGroup.toString() is
 620:   // called and the box is in its selected state.
 621:   return ("label=" + label + ",state=" + state + "," + super.paramString());
 622: }
 623: 
 624: /**
 625:  * Gets the AccessibleContext associated with this <code>Checkbox</code>.
 626:  * The context is created, if necessary.
 627:  *
 628:  * @return the associated context
 629:  */
 630: public AccessibleContext getAccessibleContext()
 631: {
 632:   /* Create the context if this is the first request */
 633:   if (accessibleContext == null)
 634:   {
 635:     AccessibleAWTCheckbox ac = new AccessibleAWTCheckbox();
 636:     accessibleContext = ac;
 637:     addItemListener(ac);
 638:   }
 639:   return accessibleContext;
 640: }
 641: 
 642:   /**
 643:    * Generate a unique name for this checkbox.
 644:    *
 645:    * @return A unique name for this checkbox.
 646:    */
 647:   String generateName()
 648:   {
 649:     return "checkbox" + getUniqueLong();
 650:   }
 651: 
 652:   private static synchronized long getUniqueLong()
 653:   {
 654:     return next_checkbox_number++;
 655:   }
 656: }