Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/Checkbox.java
38829 views
/*1* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package java.awt;2526import java.awt.peer.CheckboxPeer;27import java.awt.event.*;28import java.util.EventListener;29import java.io.ObjectOutputStream;30import java.io.ObjectInputStream;31import java.io.IOException;32import javax.accessibility.*;333435/**36* A check box is a graphical component that can be in either an37* "on" (<code>true</code>) or "off" (<code>false</code>) state.38* Clicking on a check box changes its state from39* "on" to "off," or from "off" to "on."40* <p>41* The following code example creates a set of check boxes in42* a grid layout:43*44* <hr><blockquote><pre>45* setLayout(new GridLayout(3, 1));46* add(new Checkbox("one", null, true));47* add(new Checkbox("two"));48* add(new Checkbox("three"));49* </pre></blockquote><hr>50* <p>51* This image depicts the check boxes and grid layout52* created by this code example:53* <p>54* <img src="doc-files/Checkbox-1.gif" alt="The following context describes the graphic."55* style="float:center; margin: 7px 10px;">56* <p>57* The button labeled <code>one</code> is in the "on" state, and the58* other two are in the "off" state. In this example, which uses the59* <code>GridLayout</code> class, the states of the three check60* boxes are set independently.61* <p>62* Alternatively, several check boxes can be grouped together under63* the control of a single object, using the64* <code>CheckboxGroup</code> class.65* In a check box group, at most one button can be in the "on"66* state at any given time. Clicking on a check box to turn it on67* forces any other check box in the same group that is on68* into the "off" state.69*70* @author Sami Shaio71* @see java.awt.GridLayout72* @see java.awt.CheckboxGroup73* @since JDK1.074*/75public class Checkbox extends Component implements ItemSelectable, Accessible {7677static {78/* ensure that the necessary native libraries are loaded */79Toolkit.loadLibraries();80if (!GraphicsEnvironment.isHeadless()) {81initIDs();82}83}8485/**86* The label of the Checkbox.87* This field can be null.88* @serial89* @see #getLabel()90* @see #setLabel(String)91*/92String label;9394/**95* The state of the <code>Checkbox</code>.96* @serial97* @see #getState()98* @see #setState(boolean)99*/100boolean state;101102/**103* The check box group.104* This field can be null indicating that the checkbox105* is not a group checkbox.106* @serial107* @see #getCheckboxGroup()108* @see #setCheckboxGroup(CheckboxGroup)109*/110CheckboxGroup group;111112transient ItemListener itemListener;113114private static final String base = "checkbox";115private static int nameCounter = 0;116117/*118* JDK 1.1 serialVersionUID119*/120private static final long serialVersionUID = 7270714317450821763L;121122/**123* Helper function for setState and CheckboxGroup.setSelectedCheckbox124* Should remain package-private.125*/126void setStateInternal(boolean state) {127this.state = state;128CheckboxPeer peer = (CheckboxPeer)this.peer;129if (peer != null) {130peer.setState(state);131}132}133134/**135* Creates a check box with an empty string for its label.136* The state of this check box is set to "off," and it is not137* part of any check box group.138* @exception HeadlessException if GraphicsEnvironment.isHeadless()139* returns true140* @see java.awt.GraphicsEnvironment#isHeadless141*/142public Checkbox() throws HeadlessException {143this("", false, null);144}145146/**147* Creates a check box with the specified label. The state148* of this check box is set to "off," and it is not part of149* any check box group.150*151* @param label a string label for this check box,152* or <code>null</code> for no label.153* @exception HeadlessException if154* <code>GraphicsEnvironment.isHeadless</code>155* returns <code>true</code>156* @see java.awt.GraphicsEnvironment#isHeadless157*/158public Checkbox(String label) throws HeadlessException {159this(label, false, null);160}161162/**163* Creates a check box with the specified label164* and sets the specified state.165* This check box is not part of any check box group.166*167* @param label a string label for this check box,168* or <code>null</code> for no label169* @param state the initial state of this check box170* @exception HeadlessException if171* <code>GraphicsEnvironment.isHeadless</code>172* returns <code>true</code>173* @see java.awt.GraphicsEnvironment#isHeadless174*/175public Checkbox(String label, boolean state) throws HeadlessException {176this(label, state, null);177}178179/**180* Constructs a Checkbox with the specified label, set to the181* specified state, and in the specified check box group.182*183* @param label a string label for this check box,184* or <code>null</code> for no label.185* @param state the initial state of this check box.186* @param group a check box group for this check box,187* or <code>null</code> for no group.188* @exception HeadlessException if189* <code>GraphicsEnvironment.isHeadless</code>190* returns <code>true</code>191* @see java.awt.GraphicsEnvironment#isHeadless192* @since JDK1.1193*/194public Checkbox(String label, boolean state, CheckboxGroup group)195throws HeadlessException {196GraphicsEnvironment.checkHeadless();197this.label = label;198this.state = state;199this.group = group;200if (state && (group != null)) {201group.setSelectedCheckbox(this);202}203}204205/**206* Creates a check box with the specified label, in the specified207* check box group, and set to the specified state.208*209* @param label a string label for this check box,210* or <code>null</code> for no label.211* @param group a check box group for this check box,212* or <code>null</code> for no group.213* @param state the initial state of this check box.214* @exception HeadlessException if215* <code>GraphicsEnvironment.isHeadless</code>216* returns <code>true</code>217* @see java.awt.GraphicsEnvironment#isHeadless218* @since JDK1.1219*/220public Checkbox(String label, CheckboxGroup group, boolean state)221throws HeadlessException {222this(label, state, group);223}224225/**226* Constructs a name for this component. Called by227* <code>getName</code> when the name is <code>null</code>.228*229* @return a name for this component230*/231String constructComponentName() {232synchronized (Checkbox.class) {233return base + nameCounter++;234}235}236237/**238* Creates the peer of the Checkbox. The peer allows you to change the239* look of the Checkbox without changing its functionality.240*241* @see java.awt.Toolkit#createCheckbox(java.awt.Checkbox)242* @see java.awt.Component#getToolkit()243*/244public void addNotify() {245synchronized (getTreeLock()) {246if (peer == null)247peer = getToolkit().createCheckbox(this);248super.addNotify();249}250}251252/**253* Gets the label of this check box.254*255* @return the label of this check box, or <code>null</code>256* if this check box has no label.257* @see #setLabel(String)258*/259public String getLabel() {260return label;261}262263/**264* Sets this check box's label to be the string argument.265*266* @param label a string to set as the new label, or267* <code>null</code> for no label.268* @see #getLabel269*/270public void setLabel(String label) {271boolean testvalid = false;272273synchronized (this) {274if (label != this.label && (this.label == null ||275!this.label.equals(label))) {276this.label = label;277CheckboxPeer peer = (CheckboxPeer)this.peer;278if (peer != null) {279peer.setLabel(label);280}281testvalid = true;282}283}284285// This could change the preferred size of the Component.286if (testvalid) {287invalidateIfValid();288}289}290291/**292* Determines whether this check box is in the "on" or "off" state.293* The boolean value <code>true</code> indicates the "on" state,294* and <code>false</code> indicates the "off" state.295*296* @return the state of this check box, as a boolean value297* @see #setState298*/299public boolean getState() {300return state;301}302303/**304* Sets the state of this check box to the specified state.305* The boolean value <code>true</code> indicates the "on" state,306* and <code>false</code> indicates the "off" state.307*308* <p>Note that this method should be primarily used to309* initialize the state of the checkbox. Programmatically310* setting the state of the checkbox will <i>not</i> trigger311* an <code>ItemEvent</code>. The only way to trigger an312* <code>ItemEvent</code> is by user interaction.313*314* @param state the boolean state of the check box315* @see #getState316*/317public void setState(boolean state) {318/* Cannot hold check box lock when calling group.setSelectedCheckbox. */319CheckboxGroup group = this.group;320if (group != null) {321if (state) {322group.setSelectedCheckbox(this);323} else if (group.getSelectedCheckbox() == this) {324state = true;325}326}327setStateInternal(state);328}329330/**331* Returns an array (length 1) containing the checkbox332* label or null if the checkbox is not selected.333* @see ItemSelectable334*/335public Object[] getSelectedObjects() {336if (state) {337Object[] items = new Object[1];338items[0] = label;339return items;340}341return null;342}343344/**345* Determines this check box's group.346* @return this check box's group, or <code>null</code>347* if the check box is not part of a check box group.348* @see #setCheckboxGroup(CheckboxGroup)349*/350public CheckboxGroup getCheckboxGroup() {351return group;352}353354/**355* Sets this check box's group to the specified check box group.356* If this check box is already in a different check box group,357* it is first taken out of that group.358* <p>359* If the state of this check box is <code>true</code> and the new360* group already has a check box selected, this check box's state361* is changed to <code>false</code>. If the state of this check362* box is <code>true</code> and the new group has no check box363* selected, this check box becomes the selected checkbox for364* the new group and its state is <code>true</code>.365*366* @param g the new check box group, or <code>null</code>367* to remove this check box from any check box group368* @see #getCheckboxGroup369*/370public void setCheckboxGroup(CheckboxGroup g) {371CheckboxGroup oldGroup;372boolean oldState;373374/* Do nothing if this check box has already belonged375* to the check box group g.376*/377if (this.group == g) {378return;379}380381synchronized (this) {382oldGroup = this.group;383oldState = getState();384385this.group = g;386CheckboxPeer peer = (CheckboxPeer)this.peer;387if (peer != null) {388peer.setCheckboxGroup(g);389}390if (this.group != null && getState()) {391if (this.group.getSelectedCheckbox() != null) {392setState(false);393} else {394this.group.setSelectedCheckbox(this);395}396}397}398399/* Locking check box below could cause deadlock with400* CheckboxGroup's setSelectedCheckbox method.401*402* Fix for 4726853 by [email protected]403* Here we should check if this check box was selected404* in the previous group and set selected check box to405* null for that group if so.406*/407if (oldGroup != null && oldState) {408oldGroup.setSelectedCheckbox(null);409}410}411412/**413* Adds the specified item listener to receive item events from414* this check box. Item events are sent to listeners in response415* to user input, but not in response to calls to setState().416* If l is null, no exception is thrown and no action is performed.417* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"418* >AWT Threading Issues</a> for details on AWT's threading model.419*420* @param l the item listener421* @see #removeItemListener422* @see #getItemListeners423* @see #setState424* @see java.awt.event.ItemEvent425* @see java.awt.event.ItemListener426* @since JDK1.1427*/428public synchronized void addItemListener(ItemListener l) {429if (l == null) {430return;431}432itemListener = AWTEventMulticaster.add(itemListener, l);433newEventsOnly = true;434}435436/**437* Removes the specified item listener so that the item listener438* no longer receives item events from this check box.439* If l is null, no exception is thrown and no action is performed.440* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"441* >AWT Threading Issues</a> for details on AWT's threading model.442*443* @param l the item listener444* @see #addItemListener445* @see #getItemListeners446* @see java.awt.event.ItemEvent447* @see java.awt.event.ItemListener448* @since JDK1.1449*/450public synchronized void removeItemListener(ItemListener l) {451if (l == null) {452return;453}454itemListener = AWTEventMulticaster.remove(itemListener, l);455}456457/**458* Returns an array of all the item listeners459* registered on this checkbox.460*461* @return all of this checkbox's <code>ItemListener</code>s462* or an empty array if no item463* listeners are currently registered464*465* @see #addItemListener466* @see #removeItemListener467* @see java.awt.event.ItemEvent468* @see java.awt.event.ItemListener469* @since 1.4470*/471public synchronized ItemListener[] getItemListeners() {472return getListeners(ItemListener.class);473}474475/**476* Returns an array of all the objects currently registered477* as <code><em>Foo</em>Listener</code>s478* upon this <code>Checkbox</code>.479* <code><em>Foo</em>Listener</code>s are registered using the480* <code>add<em>Foo</em>Listener</code> method.481*482* <p>483* You can specify the <code>listenerType</code> argument484* with a class literal, such as485* <code><em>Foo</em>Listener.class</code>.486* For example, you can query a487* <code>Checkbox</code> <code>c</code>488* for its item listeners with the following code:489*490* <pre>ItemListener[] ils = (ItemListener[])(c.getListeners(ItemListener.class));</pre>491*492* If no such listeners exist, this method returns an empty array.493*494* @param listenerType the type of listeners requested; this parameter495* should specify an interface that descends from496* <code>java.util.EventListener</code>497* @return an array of all objects registered as498* <code><em>Foo</em>Listener</code>s on this checkbox,499* or an empty array if no such500* listeners have been added501* @exception ClassCastException if <code>listenerType</code>502* doesn't specify a class or interface that implements503* <code>java.util.EventListener</code>504*505* @see #getItemListeners506* @since 1.3507*/508public <T extends EventListener> T[] getListeners(Class<T> listenerType) {509EventListener l = null;510if (listenerType == ItemListener.class) {511l = itemListener;512} else {513return super.getListeners(listenerType);514}515return AWTEventMulticaster.getListeners(l, listenerType);516}517518// REMIND: remove when filtering is done at lower level519boolean eventEnabled(AWTEvent e) {520if (e.id == ItemEvent.ITEM_STATE_CHANGED) {521if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||522itemListener != null) {523return true;524}525return false;526}527return super.eventEnabled(e);528}529530/**531* Processes events on this check box.532* If the event is an instance of <code>ItemEvent</code>,533* this method invokes the <code>processItemEvent</code> method.534* Otherwise, it calls its superclass's <code>processEvent</code> method.535* <p>Note that if the event parameter is <code>null</code>536* the behavior is unspecified and may result in an537* exception.538*539* @param e the event540* @see java.awt.event.ItemEvent541* @see #processItemEvent542* @since JDK1.1543*/544protected void processEvent(AWTEvent e) {545if (e instanceof ItemEvent) {546processItemEvent((ItemEvent)e);547return;548}549super.processEvent(e);550}551552/**553* Processes item events occurring on this check box by554* dispatching them to any registered555* <code>ItemListener</code> objects.556* <p>557* This method is not called unless item events are558* enabled for this component. Item events are enabled559* when one of the following occurs:560* <ul>561* <li>An <code>ItemListener</code> object is registered562* via <code>addItemListener</code>.563* <li>Item events are enabled via <code>enableEvents</code>.564* </ul>565* <p>Note that if the event parameter is <code>null</code>566* the behavior is unspecified and may result in an567* exception.568*569* @param e the item event570* @see java.awt.event.ItemEvent571* @see java.awt.event.ItemListener572* @see #addItemListener573* @see java.awt.Component#enableEvents574* @since JDK1.1575*/576protected void processItemEvent(ItemEvent e) {577ItemListener listener = itemListener;578if (listener != null) {579listener.itemStateChanged(e);580}581}582583/**584* Returns a string representing the state of this <code>Checkbox</code>.585* This method is intended to be used only for debugging purposes, and the586* content and format of the returned string may vary between587* implementations. The returned string may be empty but may not be588* <code>null</code>.589*590* @return the parameter string of this check box591*/592protected String paramString() {593String str = super.paramString();594String label = this.label;595if (label != null) {596str += ",label=" + label;597}598return str + ",state=" + state;599}600601602/* Serialization support.603*/604605/*606* Serialized data version607* @serial608*/609private int checkboxSerializedDataVersion = 1;610611/**612* Writes default serializable fields to stream. Writes613* a list of serializable <code>ItemListeners</code>614* as optional data. The non-serializable615* <code>ItemListeners</code> are detected and616* no attempt is made to serialize them.617*618* @param s the <code>ObjectOutputStream</code> to write619* @serialData <code>null</code> terminated sequence of 0620* or more pairs; the pair consists of a <code>String</code>621* and an <code>Object</code>; the <code>String</code> indicates622* the type of object and is one of the following:623* <code>itemListenerK</code> indicating an624* <code>ItemListener</code> object625*626* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)627* @see java.awt.Component#itemListenerK628* @see #readObject(ObjectInputStream)629*/630private void writeObject(ObjectOutputStream s)631throws java.io.IOException632{633s.defaultWriteObject();634635AWTEventMulticaster.save(s, itemListenerK, itemListener);636s.writeObject(null);637}638639/**640* Reads the <code>ObjectInputStream</code> and if it641* isn't <code>null</code> adds a listener to receive642* item events fired by the <code>Checkbox</code>.643* Unrecognized keys or values will be ignored.644*645* @param s the <code>ObjectInputStream</code> to read646* @exception HeadlessException if647* <code>GraphicsEnvironment.isHeadless</code> returns648* <code>true</code>649* @serial650* @see #removeItemListener(ItemListener)651* @see #addItemListener(ItemListener)652* @see java.awt.GraphicsEnvironment#isHeadless653* @see #writeObject(ObjectOutputStream)654*/655private void readObject(ObjectInputStream s)656throws ClassNotFoundException, IOException, HeadlessException657{658GraphicsEnvironment.checkHeadless();659s.defaultReadObject();660661Object keyOrNull;662while(null != (keyOrNull = s.readObject())) {663String key = ((String)keyOrNull).intern();664665if (itemListenerK == key)666addItemListener((ItemListener)(s.readObject()));667668else // skip value for unrecognized key669s.readObject();670}671}672673/**674* Initialize JNI field and method ids675*/676private static native void initIDs();677678679/////////////////680// Accessibility support681////////////////682683684/**685* Gets the AccessibleContext associated with this Checkbox.686* For checkboxes, the AccessibleContext takes the form of an687* AccessibleAWTCheckbox.688* A new AccessibleAWTCheckbox is created if necessary.689*690* @return an AccessibleAWTCheckbox that serves as the691* AccessibleContext of this Checkbox692* @since 1.3693*/694public AccessibleContext getAccessibleContext() {695if (accessibleContext == null) {696accessibleContext = new AccessibleAWTCheckbox();697}698return accessibleContext;699}700701/**702* This class implements accessibility support for the703* <code>Checkbox</code> class. It provides an implementation of the704* Java Accessibility API appropriate to checkbox user-interface elements.705* @since 1.3706*/707protected class AccessibleAWTCheckbox extends AccessibleAWTComponent708implements ItemListener, AccessibleAction, AccessibleValue709{710/*711* JDK 1.3 serialVersionUID712*/713private static final long serialVersionUID = 7881579233144754107L;714715public AccessibleAWTCheckbox() {716super();717Checkbox.this.addItemListener(this);718}719720/**721* Fire accessible property change events when the state of the722* toggle button changes.723*/724public void itemStateChanged(ItemEvent e) {725Checkbox cb = (Checkbox) e.getSource();726if (Checkbox.this.accessibleContext != null) {727if (cb.getState()) {728Checkbox.this.accessibleContext.firePropertyChange(729AccessibleContext.ACCESSIBLE_STATE_PROPERTY,730null, AccessibleState.CHECKED);731} else {732Checkbox.this.accessibleContext.firePropertyChange(733AccessibleContext.ACCESSIBLE_STATE_PROPERTY,734AccessibleState.CHECKED, null);735}736}737}738739/**740* Get the AccessibleAction associated with this object. In the741* implementation of the Java Accessibility API for this class,742* return this object, which is responsible for implementing the743* AccessibleAction interface on behalf of itself.744*745* @return this object746*/747public AccessibleAction getAccessibleAction() {748return this;749}750751/**752* Get the AccessibleValue associated with this object. In the753* implementation of the Java Accessibility API for this class,754* return this object, which is responsible for implementing the755* AccessibleValue interface on behalf of itself.756*757* @return this object758*/759public AccessibleValue getAccessibleValue() {760return this;761}762763/**764* Returns the number of Actions available in this object.765* If there is more than one, the first one is the "default"766* action.767*768* @return the number of Actions in this object769*/770public int getAccessibleActionCount() {771return 0; // To be fully implemented in a future release772}773774/**775* Return a description of the specified action of the object.776*777* @param i zero-based index of the actions778*/779public String getAccessibleActionDescription(int i) {780return null; // To be fully implemented in a future release781}782783/**784* Perform the specified Action on the object785*786* @param i zero-based index of actions787* @return true if the the action was performed; else false.788*/789public boolean doAccessibleAction(int i) {790return false; // To be fully implemented in a future release791}792793/**794* Get the value of this object as a Number. If the value has not been795* set, the return value will be null.796*797* @return value of the object798* @see #setCurrentAccessibleValue799*/800public Number getCurrentAccessibleValue() {801return null; // To be fully implemented in a future release802}803804/**805* Set the value of this object as a Number.806*807* @return True if the value was set; else False808* @see #getCurrentAccessibleValue809*/810public boolean setCurrentAccessibleValue(Number n) {811return false; // To be fully implemented in a future release812}813814/**815* Get the minimum value of this object as a Number.816*817* @return Minimum value of the object; null if this object does not818* have a minimum value819* @see #getMaximumAccessibleValue820*/821public Number getMinimumAccessibleValue() {822return null; // To be fully implemented in a future release823}824825/**826* Get the maximum value of this object as a Number.827*828* @return Maximum value of the object; null if this object does not829* have a maximum value830* @see #getMinimumAccessibleValue831*/832public Number getMaximumAccessibleValue() {833return null; // To be fully implemented in a future release834}835836/**837* Get the role of this object.838*839* @return an instance of AccessibleRole describing the role of840* the object841* @see AccessibleRole842*/843public AccessibleRole getAccessibleRole() {844return AccessibleRole.CHECK_BOX;845}846847/**848* Get the state set of this object.849*850* @return an instance of AccessibleState containing the current state851* of the object852* @see AccessibleState853*/854public AccessibleStateSet getAccessibleStateSet() {855AccessibleStateSet states = super.getAccessibleStateSet();856if (getState()) {857states.add(AccessibleState.CHECKED);858}859return states;860}861862863} // inner class AccessibleAWTCheckbox864865}866867868