1 /*
   2  * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.awt.peer.CheckboxPeer;
  28 import java.awt.event.*;
  29 import java.util.EventListener;
  30 import java.io.ObjectOutputStream;
  31 import java.io.ObjectInputStream;
  32 import java.io.IOException;
  33 import javax.accessibility.*;
  34 
  35 
  36 /**
  37  * A check box is a graphical component that can be in either an
  38  * "on" (<code>true</code>) or "off" (<code>false</code>) state.
  39  * Clicking on a check box changes its state from
  40  * "on" to "off," or from "off" to "on."
  41  * <p>
  42  * The following code example creates a set of check boxes in
  43  * a grid layout:
  44  *
  45  * <hr><blockquote><pre>
  46  * setLayout(new GridLayout(3, 1));
  47  * add(new Checkbox("one", null, true));
  48  * add(new Checkbox("two"));
  49  * add(new Checkbox("three"));
  50  * </pre></blockquote><hr>
  51  * <p>
  52  * This image depicts the check boxes and grid layout
  53  * created by this code example:
  54  * <p>
  55  * <img src="doc-files/Checkbox-1.gif" alt="The following context describes the graphic."
  56  * style="float:center; margin: 7px 10px;">
  57  * <p>
  58  * The button labeled <code>one</code> is in the "on" state, and the
  59  * other two are in the "off" state. In this example, which uses the
  60  * <code>GridLayout</code> class, the states of the three check
  61  * boxes are set independently.
  62  * <p>
  63  * Alternatively, several check boxes can be grouped together under
  64  * the control of a single object, using the
  65  * <code>CheckboxGroup</code> class.
  66  * In a check box group, at most one button can be in the "on"
  67  * state at any given time. Clicking on a check box to turn it on
  68  * forces any other check box in the same group that is on
  69  * into the "off" state.
  70  *
  71  * @author      Sami Shaio
  72  * @see         java.awt.GridLayout
  73  * @see         java.awt.CheckboxGroup
  74  * @since       JDK1.0
  75  */
  76 public class Checkbox extends Component implements ItemSelectable, Accessible {
  77 
  78     static {
  79         /* ensure that the necessary native libraries are loaded */
  80         Toolkit.loadLibraries();
  81         if (!GraphicsEnvironment.isHeadless()) {
  82             initIDs();
  83         }
  84     }
  85 
  86     /**
  87      * The label of the Checkbox.
  88      * This field can be null.
  89      * @serial
  90      * @see #getLabel()
  91      * @see #setLabel(String)
  92      */
  93     String label;
  94 
  95     /**
  96      * The state of the <code>Checkbox</code>.
  97      * @serial
  98      * @see #getState()
  99      * @see #setState(boolean)
 100      */
 101     boolean state;
 102 
 103     /**
 104      * The check box group.
 105          * This field can be null indicating that the checkbox
 106          * is not a group checkbox.
 107          * @serial
 108      * @see #getCheckboxGroup()
 109      * @see #setCheckboxGroup(CheckboxGroup)
 110      */
 111     CheckboxGroup group;
 112 
 113     transient ItemListener itemListener;
 114 
 115     private static final String base = "checkbox";
 116     private static int nameCounter = 0;
 117 
 118     /*
 119      * JDK 1.1 serialVersionUID
 120      */
 121     private static final long serialVersionUID = 7270714317450821763L;
 122 
 123     /**
 124      * Helper function for setState and CheckboxGroup.setSelectedCheckbox
 125      * Should remain package-private.
 126      */
 127     void setStateInternal(boolean state) {
 128         this.state = state;
 129         CheckboxPeer peer = (CheckboxPeer)this.peer;
 130         if (peer != null) {
 131             peer.setState(state);
 132         }
 133     }
 134 
 135     /**
 136      * Creates a check box with an empty string for its label.
 137      * The state of this check box is set to "off," and it is not
 138      * part of any check box group.
 139      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 140      * returns true
 141      * @see java.awt.GraphicsEnvironment#isHeadless
 142      */
 143     public Checkbox() throws HeadlessException {
 144         this("", false, null);
 145     }
 146 
 147     /**
 148      * Creates a check box with the specified label.  The state
 149      * of this check box is set to "off," and it is not part of
 150      * any check box group.
 151      *
 152      * @param     label   a string label for this check box,
 153      *                        or <code>null</code> for no label.
 154      * @exception HeadlessException if
 155      *      <code>GraphicsEnvironment.isHeadless</code>
 156      *      returns <code>true</code>
 157      * @see java.awt.GraphicsEnvironment#isHeadless
 158      */
 159     public Checkbox(String label) throws HeadlessException {
 160         this(label, false, null);
 161     }
 162 
 163     /**
 164      * Creates a check box with the specified label
 165      * and sets the specified state.
 166      * This check box is not part of any check box group.
 167      *
 168      * @param     label   a string label for this check box,
 169      *                        or <code>null</code> for no label
 170      * @param     state    the initial state of this check box
 171      * @exception HeadlessException if
 172      *     <code>GraphicsEnvironment.isHeadless</code>
 173      *     returns <code>true</code>
 174      * @see java.awt.GraphicsEnvironment#isHeadless
 175      */
 176     public Checkbox(String label, boolean state) throws HeadlessException {
 177         this(label, state, null);
 178     }
 179 
 180     /**
 181      * Constructs a Checkbox with the specified label, set to the
 182      * specified state, and in the specified check box group.
 183      *
 184      * @param     label   a string label for this check box,
 185      *                        or <code>null</code> for no label.
 186      * @param     state   the initial state of this check box.
 187      * @param     group   a check box group for this check box,
 188      *                           or <code>null</code> for no group.
 189      * @exception HeadlessException if
 190      *     <code>GraphicsEnvironment.isHeadless</code>
 191      *     returns <code>true</code>
 192      * @see java.awt.GraphicsEnvironment#isHeadless
 193      * @since     JDK1.1
 194      */
 195     public Checkbox(String label, boolean state, CheckboxGroup group)
 196         throws HeadlessException {
 197         GraphicsEnvironment.checkHeadless();
 198         this.label = label;
 199         this.state = state;
 200         this.group = group;
 201         if (state && (group != null)) {
 202             group.setSelectedCheckbox(this);
 203         }
 204     }
 205 
 206     /**
 207      * Creates a check box with the specified label, in the specified
 208      * check box group, and set to the specified state.
 209      *
 210      * @param     label   a string label for this check box,
 211      *                        or <code>null</code> for no label.
 212      * @param     group   a check box group for this check box,
 213      *                           or <code>null</code> for no group.
 214      * @param     state   the initial state of this check box.
 215      * @exception HeadlessException if
 216      *    <code>GraphicsEnvironment.isHeadless</code>
 217      *    returns <code>true</code>
 218      * @see java.awt.GraphicsEnvironment#isHeadless
 219      * @since     JDK1.1
 220      */
 221     public Checkbox(String label, CheckboxGroup group, boolean state)
 222         throws HeadlessException {
 223         this(label, state, group);
 224     }
 225 
 226     /**
 227      * Constructs a name for this component.  Called by
 228      * <code>getName</code> when the name is <code>null</code>.
 229      *
 230      * @return a name for this component
 231      */
 232     String constructComponentName() {
 233         synchronized (Checkbox.class) {
 234             return base + nameCounter++;
 235         }
 236     }
 237 
 238     /**
 239      * Creates the peer of the Checkbox. The peer allows you to change the
 240      * look of the Checkbox without changing its functionality.
 241      *
 242      * @see     java.awt.Toolkit#createCheckbox(java.awt.Checkbox)
 243      * @see     java.awt.Component#getToolkit()
 244      */
 245     public void addNotify() {
 246         synchronized (getTreeLock()) {
 247             if (peer == null)
 248                 peer = getToolkit().createCheckbox(this);
 249             super.addNotify();
 250         }
 251     }
 252 
 253     /**
 254      * Gets the label of this check box.
 255      *
 256      * @return   the label of this check box, or <code>null</code>
 257      *                  if this check box has no label.
 258      * @see      #setLabel(String)
 259      */
 260     public String getLabel() {
 261         return label;
 262     }
 263 
 264     /**
 265      * Sets this check box's label to be the string argument.
 266      *
 267      * @param    label   a string to set as the new label, or
 268      *                        <code>null</code> for no label.
 269      * @see      #getLabel
 270      */
 271     public void setLabel(String label) {
 272         boolean testvalid = false;
 273 
 274         synchronized (this) {
 275             if (label != this.label && (this.label == null ||
 276                                         !this.label.equals(label))) {
 277                 this.label = label;
 278                 CheckboxPeer peer = (CheckboxPeer)this.peer;
 279                 if (peer != null) {
 280                     peer.setLabel(label);
 281                 }
 282                 testvalid = true;
 283             }
 284         }
 285 
 286         // This could change the preferred size of the Component.
 287         if (testvalid) {
 288             invalidateIfValid();
 289         }
 290     }
 291 
 292     /**
 293      * Determines whether this check box is in the "on" or "off" state.
 294      * The boolean value <code>true</code> indicates the "on" state,
 295      * and <code>false</code> indicates the "off" state.
 296      *
 297      * @return    the state of this check box, as a boolean value
 298      * @see       #setState
 299      */
 300     public boolean getState() {
 301         return state;
 302     }
 303 
 304     /**
 305      * Sets the state of this check box to the specified state.
 306      * The boolean value <code>true</code> indicates the "on" state,
 307      * and <code>false</code> indicates the "off" state.
 308      *
 309      * <p>Note that this method should be primarily used to
 310      * initialize the state of the checkbox.  Programmatically
 311      * setting the state of the checkbox will <i>not</i> trigger
 312      * an <code>ItemEvent</code>.  The only way to trigger an
 313      * <code>ItemEvent</code> is by user interaction.
 314      *
 315      * @param     state   the boolean state of the check box
 316      * @see       #getState
 317      */
 318     public void setState(boolean state) {
 319         /* Cannot hold check box lock when calling group.setSelectedCheckbox. */
 320         CheckboxGroup group = this.group;
 321         if (group != null) {
 322             if (state) {
 323                 group.setSelectedCheckbox(this);
 324             } else if (group.getSelectedCheckbox() == this) {
 325                 state = true;
 326             }
 327         }
 328         setStateInternal(state);
 329     }
 330 
 331     /**
 332      * Returns an array (length 1) containing the checkbox
 333      * label or null if the checkbox is not selected.
 334      * @see ItemSelectable
 335      */
 336     public Object[] getSelectedObjects() {
 337         if (state) {
 338             Object[] items = new Object[1];
 339             items[0] = label;
 340             return items;
 341         }
 342         return null;
 343     }
 344 
 345     /**
 346      * Determines this check box's group.
 347      * @return     this check box's group, or <code>null</code>
 348      *               if the check box is not part of a check box group.
 349      * @see        #setCheckboxGroup(CheckboxGroup)
 350      */
 351     public CheckboxGroup getCheckboxGroup() {
 352         return group;
 353     }
 354 
 355     /**
 356      * Sets this check box's group to the specified check box group.
 357      * If this check box is already in a different check box group,
 358      * it is first taken out of that group.
 359      * <p>
 360      * If the state of this check box is <code>true</code> and the new
 361      * group already has a check box selected, this check box's state
 362      * is changed to <code>false</code>.  If the state of this check
 363      * box is <code>true</code> and the new group has no check box
 364      * selected, this check box becomes the selected checkbox for
 365      * the new group and its state is <code>true</code>.
 366      *
 367      * @param     g   the new check box group, or <code>null</code>
 368      *                to remove this check box from any check box group
 369      * @see       #getCheckboxGroup
 370      */
 371     public void setCheckboxGroup(CheckboxGroup g) {
 372         CheckboxGroup oldGroup;
 373         boolean oldState;
 374 
 375         /* Do nothing if this check box has already belonged
 376          * to the check box group g.
 377          */
 378         if (this.group == g) {
 379             return;
 380         }
 381 
 382         synchronized (this) {
 383             oldGroup = this.group;
 384             oldState = getState();
 385 
 386             this.group = g;
 387             CheckboxPeer peer = (CheckboxPeer)this.peer;
 388             if (peer != null) {
 389                 peer.setCheckboxGroup(g);
 390             }
 391             if (this.group != null && getState()) {
 392                 if (this.group.getSelectedCheckbox() != null) {
 393                     setState(false);
 394                 } else {
 395                     this.group.setSelectedCheckbox(this);
 396                 }
 397             }
 398         }
 399 
 400         /* Locking check box below could cause deadlock with
 401          * CheckboxGroup's setSelectedCheckbox method.
 402          *
 403          * Fix for 4726853 by kdm@sparc.spb.su
 404          * Here we should check if this check box was selected
 405          * in the previous group and set selected check box to
 406          * null for that group if so.
 407          */
 408         if (oldGroup != null && oldState) {
 409             oldGroup.setSelectedCheckbox(null);
 410         }
 411     }
 412 
 413     /**
 414      * Adds the specified item listener to receive item events from
 415      * this check box.  Item events are sent to listeners in response
 416      * to user input, but not in response to calls to setState().
 417      * If l is null, no exception is thrown and no action is performed.
 418      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 419      * >AWT Threading Issues</a> for details on AWT's threading model.
 420      *
 421      * @param         l    the item listener
 422      * @see           #removeItemListener
 423      * @see           #getItemListeners
 424      * @see           #setState
 425      * @see           java.awt.event.ItemEvent
 426      * @see           java.awt.event.ItemListener
 427      * @since         JDK1.1
 428      */
 429     public synchronized void addItemListener(ItemListener l) {
 430         if (l == null) {
 431             return;
 432         }
 433         itemListener = AWTEventMulticaster.add(itemListener, l);
 434         newEventsOnly = true;
 435     }
 436 
 437     /**
 438      * Removes the specified item listener so that the item listener
 439      * no longer receives item events from this check box.
 440      * If l is null, no exception is thrown and no action is performed.
 441      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 442      * >AWT Threading Issues</a> for details on AWT's threading model.
 443      *
 444      * @param         l    the item listener
 445      * @see           #addItemListener
 446      * @see           #getItemListeners
 447      * @see           java.awt.event.ItemEvent
 448      * @see           java.awt.event.ItemListener
 449      * @since         JDK1.1
 450      */
 451     public synchronized void removeItemListener(ItemListener l) {
 452         if (l == null) {
 453             return;
 454         }
 455         itemListener = AWTEventMulticaster.remove(itemListener, l);
 456     }
 457 
 458     /**
 459      * Returns an array of all the item listeners
 460      * registered on this checkbox.
 461      *
 462      * @return all of this checkbox's <code>ItemListener</code>s
 463      *         or an empty array if no item
 464      *         listeners are currently registered
 465      *
 466      * @see           #addItemListener
 467      * @see           #removeItemListener
 468      * @see           java.awt.event.ItemEvent
 469      * @see           java.awt.event.ItemListener
 470      * @since 1.4
 471      */
 472     public synchronized ItemListener[] getItemListeners() {
 473         return getListeners(ItemListener.class);
 474     }
 475 
 476     /**
 477      * Returns an array of all the objects currently registered
 478      * as <code><em>Foo</em>Listener</code>s
 479      * upon this <code>Checkbox</code>.
 480      * <code><em>Foo</em>Listener</code>s are registered using the
 481      * <code>add<em>Foo</em>Listener</code> method.
 482      *
 483      * <p>
 484      * You can specify the <code>listenerType</code> argument
 485      * with a class literal, such as
 486      * <code><em>Foo</em>Listener.class</code>.
 487      * For example, you can query a
 488      * <code>Checkbox</code> <code>c</code>
 489      * for its item listeners with the following code:
 490      *
 491      * <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>
 492      *
 493      * If no such listeners exist, this method returns an empty array.
 494      *
 495      * @param listenerType the type of listeners requested; this parameter
 496      *          should specify an interface that descends from
 497      *          <code>java.util.EventListener</code>
 498      * @return an array of all objects registered as
 499      *          <code><em>Foo</em>Listener</code>s on this checkbox,
 500      *          or an empty array if no such
 501      *          listeners have been added
 502      * @exception ClassCastException if <code>listenerType</code>
 503      *          doesn't specify a class or interface that implements
 504      *          <code>java.util.EventListener</code>
 505      *
 506      * @see #getItemListeners
 507      * @since 1.3
 508      */
 509     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
 510         EventListener l = null;
 511         if  (listenerType == ItemListener.class) {
 512             l = itemListener;
 513         } else {
 514             return super.getListeners(listenerType);
 515         }
 516         return AWTEventMulticaster.getListeners(l, listenerType);
 517     }
 518 
 519     // REMIND: remove when filtering is done at lower level
 520     boolean eventEnabled(AWTEvent e) {
 521         if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
 522             if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
 523                 itemListener != null) {
 524                 return true;
 525             }
 526             return false;
 527         }
 528         return super.eventEnabled(e);
 529     }
 530 
 531     /**
 532      * Processes events on this check box.
 533      * If the event is an instance of <code>ItemEvent</code>,
 534      * this method invokes the <code>processItemEvent</code> method.
 535      * Otherwise, it calls its superclass's <code>processEvent</code> method.
 536      * <p>Note that if the event parameter is <code>null</code>
 537      * the behavior is unspecified and may result in an
 538      * exception.
 539      *
 540      * @param         e the event
 541      * @see           java.awt.event.ItemEvent
 542      * @see           #processItemEvent
 543      * @since         JDK1.1
 544      */
 545     protected void processEvent(AWTEvent e) {
 546         if (e instanceof ItemEvent) {
 547             processItemEvent((ItemEvent)e);
 548             return;
 549         }
 550         super.processEvent(e);
 551     }
 552 
 553     /**
 554      * Processes item events occurring on this check box by
 555      * dispatching them to any registered
 556      * <code>ItemListener</code> objects.
 557      * <p>
 558      * This method is not called unless item events are
 559      * enabled for this component. Item events are enabled
 560      * when one of the following occurs:
 561      * <ul>
 562      * <li>An <code>ItemListener</code> object is registered
 563      * via <code>addItemListener</code>.
 564      * <li>Item events are enabled via <code>enableEvents</code>.
 565      * </ul>
 566      * <p>Note that if the event parameter is <code>null</code>
 567      * the behavior is unspecified and may result in an
 568      * exception.
 569      *
 570      * @param       e the item event
 571      * @see         java.awt.event.ItemEvent
 572      * @see         java.awt.event.ItemListener
 573      * @see         #addItemListener
 574      * @see         java.awt.Component#enableEvents
 575      * @since       JDK1.1
 576      */
 577     protected void processItemEvent(ItemEvent e) {
 578         ItemListener listener = itemListener;
 579         if (listener != null) {
 580             listener.itemStateChanged(e);
 581         }
 582     }
 583 
 584     /**
 585      * Returns a string representing the state of this <code>Checkbox</code>.
 586      * This method is intended to be used only for debugging purposes, and the
 587      * content and format of the returned string may vary between
 588      * implementations. The returned string may be empty but may not be
 589      * <code>null</code>.
 590      *
 591      * @return    the parameter string of this check box
 592      */
 593     protected String paramString() {
 594         String str = super.paramString();
 595         String label = this.label;
 596         if (label != null) {
 597             str += ",label=" + label;
 598         }
 599         return str + ",state=" + state;
 600     }
 601 
 602 
 603     /* Serialization support.
 604      */
 605 
 606     /*
 607      * Serialized data version
 608      * @serial
 609      */
 610     private int checkboxSerializedDataVersion = 1;
 611 
 612     /**
 613      * Writes default serializable fields to stream.  Writes
 614      * a list of serializable <code>ItemListeners</code>
 615      * as optional data.  The non-serializable
 616      * <code>ItemListeners</code> are detected and
 617      * no attempt is made to serialize them.
 618      *
 619      * @param s the <code>ObjectOutputStream</code> to write
 620      * @serialData <code>null</code> terminated sequence of 0
 621      *   or more pairs; the pair consists of a <code>String</code>
 622      *   and an <code>Object</code>; the <code>String</code> indicates
 623      *   the type of object and is one of the following:
 624      *   <code>itemListenerK</code> indicating an
 625      *     <code>ItemListener</code> object
 626      *
 627      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
 628      * @see java.awt.Component#itemListenerK
 629      * @see #readObject(ObjectInputStream)
 630      */
 631     private void writeObject(ObjectOutputStream s)
 632       throws java.io.IOException
 633     {
 634       s.defaultWriteObject();
 635 
 636       AWTEventMulticaster.save(s, itemListenerK, itemListener);
 637       s.writeObject(null);
 638     }
 639 
 640     /**
 641      * Reads the <code>ObjectInputStream</code> and if it
 642      * isn't <code>null</code> adds a listener to receive
 643      * item events fired by the <code>Checkbox</code>.
 644      * Unrecognized keys or values will be ignored.
 645      *
 646      * @param s the <code>ObjectInputStream</code> to read
 647      * @exception HeadlessException if
 648      *   <code>GraphicsEnvironment.isHeadless</code> returns
 649      *   <code>true</code>
 650      * @serial
 651      * @see #removeItemListener(ItemListener)
 652      * @see #addItemListener(ItemListener)
 653      * @see java.awt.GraphicsEnvironment#isHeadless
 654      * @see #writeObject(ObjectOutputStream)
 655      */
 656     private void readObject(ObjectInputStream s)
 657       throws ClassNotFoundException, IOException, HeadlessException
 658     {
 659       GraphicsEnvironment.checkHeadless();
 660       s.defaultReadObject();
 661 
 662       Object keyOrNull;
 663       while(null != (keyOrNull = s.readObject())) {
 664         String key = ((String)keyOrNull).intern();
 665 
 666         if (itemListenerK == key)
 667           addItemListener((ItemListener)(s.readObject()));
 668 
 669         else // skip value for unrecognized key
 670           s.readObject();
 671       }
 672     }
 673 
 674     /**
 675      * Initialize JNI field and method ids
 676      */
 677     private static native void initIDs();
 678 
 679 
 680 /////////////////
 681 // Accessibility support
 682 ////////////////
 683 
 684 
 685     /**
 686      * Gets the AccessibleContext associated with this Checkbox.
 687      * For checkboxes, the AccessibleContext takes the form of an
 688      * AccessibleAWTCheckbox.
 689      * A new AccessibleAWTCheckbox is created if necessary.
 690      *
 691      * @return an AccessibleAWTCheckbox that serves as the
 692      *         AccessibleContext of this Checkbox
 693      * @since 1.3
 694      */
 695     public AccessibleContext getAccessibleContext() {
 696         if (accessibleContext == null) {
 697             accessibleContext = new AccessibleAWTCheckbox();
 698         }
 699         return accessibleContext;
 700     }
 701 
 702     /**
 703      * This class implements accessibility support for the
 704      * <code>Checkbox</code> class.  It provides an implementation of the
 705      * Java Accessibility API appropriate to checkbox user-interface elements.
 706      * @since 1.3
 707      */
 708     protected class AccessibleAWTCheckbox extends AccessibleAWTComponent
 709         implements ItemListener, AccessibleAction, AccessibleValue
 710     {
 711         /*
 712          * JDK 1.3 serialVersionUID
 713          */
 714         private static final long serialVersionUID = 7881579233144754107L;
 715 
 716         /**
 717          * Constructor for {@code AccessibleAWTCheckbox}
 718          */
 719         public AccessibleAWTCheckbox() {
 720             super();
 721             Checkbox.this.addItemListener(this);
 722         }
 723 
 724         /**
 725          * Fire accessible property change events when the state of the
 726          * toggle button changes.
 727          */
 728         public void itemStateChanged(ItemEvent e) {
 729             Checkbox cb = (Checkbox) e.getSource();
 730             if (Checkbox.this.accessibleContext != null) {
 731                 if (cb.getState()) {
 732                     Checkbox.this.accessibleContext.firePropertyChange(
 733                             AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 734                             null, AccessibleState.CHECKED);
 735                 } else {
 736                     Checkbox.this.accessibleContext.firePropertyChange(
 737                             AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 738                             AccessibleState.CHECKED, null);
 739                 }
 740             }
 741         }
 742 
 743         /**
 744          * Get the AccessibleAction associated with this object.  In the
 745          * implementation of the Java Accessibility API for this class,
 746          * return this object, which is responsible for implementing the
 747          * AccessibleAction interface on behalf of itself.
 748          *
 749          * @return this object
 750          */
 751         public AccessibleAction getAccessibleAction() {
 752             return this;
 753         }
 754 
 755         /**
 756          * Get the AccessibleValue associated with this object.  In the
 757          * implementation of the Java Accessibility API for this class,
 758          * return this object, which is responsible for implementing the
 759          * AccessibleValue interface on behalf of itself.
 760          *
 761          * @return this object
 762          */
 763         public AccessibleValue getAccessibleValue() {
 764             return this;
 765         }
 766 
 767         /**
 768          * Returns the number of Actions available in this object.
 769          * If there is more than one, the first one is the "default"
 770          * action.
 771          *
 772          * @return the number of Actions in this object
 773          */
 774         public int getAccessibleActionCount() {
 775             return 0;  //  To be fully implemented in a future release
 776         }
 777 
 778         /**
 779          * Return a description of the specified action of the object.
 780          *
 781          * @param i zero-based index of the actions
 782          */
 783         public String getAccessibleActionDescription(int i) {
 784             return null;  //  To be fully implemented in a future release
 785         }
 786 
 787         /**
 788          * Perform the specified Action on the object
 789          *
 790          * @param i zero-based index of actions
 791          * @return true if the the action was performed; else false.
 792          */
 793         public boolean doAccessibleAction(int i) {
 794             return false;    //  To be fully implemented in a future release
 795         }
 796 
 797         /**
 798          * Get the value of this object as a Number.  If the value has not been
 799          * set, the return value will be null.
 800          *
 801          * @return value of the object
 802          * @see #setCurrentAccessibleValue
 803          */
 804         public Number getCurrentAccessibleValue() {
 805             return null;  //  To be fully implemented in a future release
 806         }
 807 
 808         /**
 809          * Set the value of this object as a Number.
 810          *
 811          * @return True if the value was set; else False
 812          * @see #getCurrentAccessibleValue
 813          */
 814         public boolean setCurrentAccessibleValue(Number n) {
 815             return false;  //  To be fully implemented in a future release
 816         }
 817 
 818         /**
 819          * Get the minimum value of this object as a Number.
 820          *
 821          * @return Minimum value of the object; null if this object does not
 822          * have a minimum value
 823          * @see #getMaximumAccessibleValue
 824          */
 825         public Number getMinimumAccessibleValue() {
 826             return null;  //  To be fully implemented in a future release
 827         }
 828 
 829         /**
 830          * Get the maximum value of this object as a Number.
 831          *
 832          * @return Maximum value of the object; null if this object does not
 833          * have a maximum value
 834          * @see #getMinimumAccessibleValue
 835          */
 836         public Number getMaximumAccessibleValue() {
 837             return null;  //  To be fully implemented in a future release
 838         }
 839 
 840         /**
 841          * Get the role of this object.
 842          *
 843          * @return an instance of AccessibleRole describing the role of
 844          * the object
 845          * @see AccessibleRole
 846          */
 847         public AccessibleRole getAccessibleRole() {
 848             return AccessibleRole.CHECK_BOX;
 849         }
 850 
 851         /**
 852          * Get the state set of this object.
 853          *
 854          * @return an instance of AccessibleState containing the current state
 855          * of the object
 856          * @see AccessibleState
 857          */
 858         public AccessibleStateSet getAccessibleStateSet() {
 859             AccessibleStateSet states = super.getAccessibleStateSet();
 860             if (getState()) {
 861                 states.add(AccessibleState.CHECKED);
 862             }
 863             return states;
 864         }
 865 
 866 
 867     } // inner class AccessibleAWTCheckbox
 868 
 869 }