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: 
 397: /*************************************************************************/
 398: 
 399: /*
 400:  * Instance Variables
 401:  */
 402: 
 403: /**
 404:   * Returns the label for this checkbox.
 405:   *
 406:   * @return The label for this checkbox.
 407:   */
 408: public String
 409: getLabel()
 410: {
 411:   return(label);
 412: }
 413: 
 414: /*************************************************************************/
 415: 
 416: /**
 417:   * Sets the label for this checkbox to the specified value.
 418:   *
 419:   * @param label The new checkbox label.
 420:   */
 421: public synchronized void
 422: setLabel(String label)
 423: {
 424:   this.label = label;
 425:   if (peer != null)
 426:     {
 427:       CheckboxPeer cp = (CheckboxPeer) peer;
 428:       cp.setLabel(label);
 429:     }
 430: }
 431: 
 432: /*************************************************************************/
 433: 
 434: /**
 435:   * Returns the state of this checkbox.
 436:   *
 437:   * @return The state of this checkbox, which will be <code>true</code> for
 438:   * on and <code>false</code> for off.
 439:   */
 440: public boolean
 441: getState()
 442: {
 443:   return(state);
 444: }
 445: 
 446: /*************************************************************************/
 447: 
 448: /**
 449:   * Sets the state of this checkbox to the specified value.
 450:   *
 451:   * @param state The new state of the checkbox, which will be <code>true</code>
 452:   * for on or <code>false</code> for off.
 453:   */
 454: public synchronized void
 455: setState(boolean state)
 456: {
 457:   this.state = state;
 458:   if (peer != null)
 459:     {
 460:       CheckboxPeer cp = (CheckboxPeer) peer;
 461:       cp.setState (state);
 462:     }
 463: }
 464: 
 465: /*************************************************************************/
 466: 
 467: /**
 468:   * Returns an array of length one containing the checkbox label if this
 469:   * checkbox is selected.  Otherwise <code>null</code> is returned.
 470:   *
 471:   * @return The selection state of this checkbox.
 472:   */
 473: public Object[]
 474: getSelectedObjects()
 475: {
 476:   if (state == false)
 477:     return(null);
 478: 
 479:   Object[] objs = new Object[1];
 480:   objs[0] = label;
 481: 
 482:   return(objs);
 483: }
 484: 
 485: /*************************************************************************/
 486: 
 487: /**
 488:   * Returns the checkbox group this object is a member of, if any.
 489:   *
 490:   * @return This object's checkbox group, of <code>null</code> if it is
 491:   * not a member of any group.
 492:   */
 493: public CheckboxGroup
 494: getCheckboxGroup()
 495: {
 496:   return(group);
 497: }
 498: 
 499: /*************************************************************************/
 500: 
 501: /**
 502:   * Sets this object's checkbox group to the specified group.
 503:   *
 504:   * @param group The new checkbox group, or <code>null</code> to make this
 505:   * object part of no checkbox group.
 506:   */
 507: public synchronized void
 508: setCheckboxGroup(CheckboxGroup group)
 509: {
 510:   this.group = group;
 511:   if (peer != null)
 512:     {
 513:       CheckboxPeer cp = (CheckboxPeer) peer;
 514:       cp.setCheckboxGroup (group);
 515:     }
 516: }
 517: 
 518: /*************************************************************************/
 519: 
 520: /**
 521:   * Creates this object's native peer.
 522:   */
 523: public void
 524: addNotify()
 525: {
 526:   if (peer == null)
 527:     peer = getToolkit ().createCheckbox (this);
 528:   super.addNotify ();
 529: }
 530: 
 531:   public ItemListener[] getItemListeners ()
 532:   {
 533:     return (ItemListener[])
 534:       AWTEventMulticaster.getListeners (item_listeners, ItemListener.class);
 535:   }
 536: 
 537: /**
 538:   * Adds a new listeners to the list of registered listeners for this object.
 539:   *
 540:   * @param listener The new listener to add.
 541:   */
 542: public synchronized void
 543: addItemListener(ItemListener listener)
 544: {
 545:   item_listeners = AWTEventMulticaster.add(item_listeners, listener);
 546: }
 547: 
 548: /*************************************************************************/
 549: 
 550: /**
 551:   * Removes a listener from the list of registered listeners for this object.
 552:   *
 553:   * @param listener The listener to remove.
 554:   */
 555: public synchronized void
 556: removeItemListener(ItemListener listener)
 557: {
 558:   item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
 559: }
 560: 
 561: /*************************************************************************/
 562: 
 563: /**
 564:   * Processes this event by calling <code>processItemEvent()</code> if it
 565:   * is any instance of <code>ItemEvent</code>.  Otherwise it is passed to
 566:   * the superclass for processing.
 567:   *
 568:   * @param event The event to process.
 569:   */
 570: protected void
 571: processEvent(AWTEvent event)
 572: {
 573:   if (event instanceof ItemEvent)
 574:     processItemEvent((ItemEvent)event);
 575:   else
 576:     super.processEvent(event);
 577: }
 578: 
 579: /*************************************************************************/
 580: 
 581: /**
 582:   * Processes this event by dispatching it to any registered listeners.
 583:   *
 584:   * @param event The <code>ItemEvent</code> to process.
 585:   */
 586: protected void
 587: processItemEvent(ItemEvent event)
 588: {
 589:   if (item_listeners != null)
 590:     item_listeners.itemStateChanged(event);
 591: }
 592: 
 593: void
 594: dispatchEventImpl(AWTEvent e)
 595: {
 596:   if (e.id <= ItemEvent.ITEM_LAST
 597:       && e.id >= ItemEvent.ITEM_FIRST
 598:       && (item_listeners != null 
 599:       || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
 600:     processEvent(e);
 601:   else
 602:     super.dispatchEventImpl(e);
 603: }
 604: 
 605: /*************************************************************************/
 606: 
 607: /**
 608:   * Returns a debugging string for this object.
 609:   */
 610: protected String
 611: paramString()
 612: {
 613:   return ("label=" + label + ",state=" + state + ",group=" + group
 614:       + "," + super.paramString());
 615: }
 616: 
 617: /**
 618:  * Gets the AccessibleContext associated with this <code>Checkbox</code>.
 619:  * The context is created, if necessary.
 620:  *
 621:  * @return the associated context
 622:  */
 623: public AccessibleContext getAccessibleContext()
 624: {
 625:   /* Create the context if this is the first request */
 626:   if (accessibleContext == null)
 627:   {
 628:     AccessibleAWTCheckbox ac = new AccessibleAWTCheckbox();
 629:     accessibleContext = ac;
 630:     addItemListener(ac);
 631:   }
 632:   return accessibleContext;
 633: }
 634: 
 635:   /**
 636:    * Generate a unique name for this checkbox.
 637:    *
 638:    * @return A unique name for this checkbox.
 639:    */
 640:   String generateName()
 641:   {
 642:     return "checkbox" + getUniqueLong();
 643:   }
 644: 
 645:   private static synchronized long getUniqueLong()
 646:   {
 647:     return next_checkbox_number++;
 648:   }
 649: }