001: /*
002: * @(#)Checkbox.java 1.59 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package java.awt;
028:
029: import sun.awt.peer.CheckboxPeer;
030: import sun.awt.PeerBasedToolkit;
031: import java.awt.event.*;
032: import java.io.ObjectOutputStream;
033: import java.io.ObjectInputStream;
034: import java.io.IOException;
035: import java.util.EventListener;
036: import java.awt.AWTEventMulticaster;
037:
038: /**
039: * A check box is a graphical component that can be in either an
040: * "on" (<code>true</code>) or "off" (<code>false</code>) state.
041: * Clicking on a check box changes its state from
042: * "on" to "off," or from "off" to "on."
043: * <p>
044: * The following code example creates a set of check boxes in
045: * a grid layout:
046: * <p>
047: * <hr><blockquote><pre>
048: * setLayout(new GridLayout(3, 1));
049: * add(new Checkbox("one", null, true));
050: * add(new Checkbox("two"));
051: * add(new Checkbox("three"));
052: * </pre></blockquote><hr>
053: * <p>
054: * This image depicts the check boxes and grid layout
055: * created by this code example:
056: * <p>
057: * <img src="images-awt/Checkbox-1.gif"
058: * ALIGN=center HSPACE=10 VSPACE=7>
059: * <p>
060: * The button labeled <code>one</code> is in the "on" state, and the
061: * other two are in the "off" state. In this example, which uses the
062: * <code>GridLayout</code> class, the states of the three check
063: * boxes are set independently.
064: * <p>
065: * Alternatively, several check boxes can be grouped together under
066: * the control of a single object, using the
067: * <code>CheckboxGroup</code> class.
068: * In a check box group, at most one button can be in the "on"
069: * state at any given time. Clicking on a check box to turn it on
070: * forces any other check box in the same group that is on
071: * into the "off" state.
072: *
073: * @version 1.51 08/19/02
074: * @author Sami Shaio
075: * @see java.awt.GridLayout
076: * @see java.awt.CheckboxGroup
077: * @since JDK1.0
078: */
079: public class Checkbox extends Component implements ItemSelectable {
080: /**
081: * The label of the Checkbox.
082: */
083: String label;
084: /**
085: * The state of the Checkbox.
086: */
087: boolean state;
088: /**
089: * The check box group.
090: */
091: CheckboxGroup group;
092: transient ItemListener itemListener;
093: private static final String base = "checkbox";
094: private static int nameCounter = 0;
095: /*
096: * JDK 1.1 serialVersionUID
097: */
098: private static final long serialVersionUID = 7270714317450821763L;
099:
100: /**
101: * Helper function for setState and CheckboxGroup.setSelectedCheckbox
102: * Should remain package-private.
103: */
104: void setStateInternal(boolean state) {
105: this .state = state;
106: CheckboxPeer peer = (CheckboxPeer) this .peer;
107: if (peer != null) {
108: peer.setState(state);
109: }
110: }
111:
112: /**
113: * Creates a check box with no label. The state of this
114: * check box is set to "off," and it is not part of any
115: * check box group.
116: * @since JDK1.0
117: */
118: public Checkbox() {
119: this ("", false, null);
120: }
121:
122: /**
123: * Creates a check box with the specified label. The state
124: * of this check box is set to "off," and it is not part of
125: * any check box group.
126: * @param label a string label for this check box,
127: * or <code>null</code> for no label.
128: * @since JDK1.0
129: */
130: public Checkbox(String label) {
131: this (label, false, null);
132: }
133:
134: /**
135: * Creates a check box with the specified label. The state
136: * of this check box is as specified by the <code>state</code>
137: * argument, and it is not part of any check box group.
138: * @param label a string label for this check box,
139: * or <code>null</code> for no label.
140: * @param state the initial state of this check box.
141: * @since JDK1.0
142: */
143: public Checkbox(String label, boolean state) {
144: this (label, state, null);
145: }
146:
147: /**
148: * Creates a check box with the specified label, in the specified
149: * check box group, and set to the specified state.
150:
151: * @param label a string label for this check box,
152: * or <code>null</code> for no label.
153: * @param state the initial state of this check box.
154: * @param group a check box group for this check box,
155: * or <code>null</code> for no group.
156: * @since JDK1.1
157: */
158: public Checkbox(String label, boolean state, CheckboxGroup group) {
159: this .label = label;
160: this .state = state;
161: this .group = group;
162: if (state && (group != null)) {
163: group.setSelectedCheckbox(this );
164: }
165: }
166:
167: /**
168: * Constructs a Checkbox with the specified label, set to the
169: * specified state, and in the specified check box group.
170: */
171: public Checkbox(String label, CheckboxGroup group, boolean state) {
172: this (label, state, group);
173: }
174:
175: /**
176: * Construct a name for this component. Called by getName() when the
177: * name is null.
178: */
179: String constructComponentName() {
180: return base + nameCounter++;
181: }
182:
183: /**
184: * Creates the peer of the Checkbox. The peer allows you to change the
185: * look of the Checkbox without changing its functionality.
186: * @see java.awt.Toolkit#createCheckbox(java.awt.Checkbox)
187: * @see java.awt.Component#getToolkit()
188: * @since JDK1.0
189: */
190: public void addNotify() {
191: synchronized (getTreeLock()) {
192: if (peer == null)
193: peer = ((PeerBasedToolkit) getToolkit())
194: .createCheckbox(this );
195: super .addNotify();
196: }
197: }
198:
199: /**
200: * Gets the label of this check box.
201: * @return the label of this check box, or <code>null</code>
202: * if this check box has no label.
203: * @see java.awt.Checkbox#setLabel
204: * @since JDK1.0
205: */
206: public String getLabel() {
207: return label;
208: }
209:
210: /**
211: * Sets this check box's label to be the string argument.
212: * @param label a string to set as the new label, or
213: * <code>null</code> for no label.
214: * @see java.awt.Checkbox#getLabel
215: * @since JDK1.0
216: */
217: public synchronized void setLabel(String label) {
218: this .label = label;
219: CheckboxPeer peer = (CheckboxPeer) this .peer;
220: if (peer != null) {
221: peer.setLabel(label);
222: }
223: }
224:
225: /**
226: * Determines whether this check box is in the "on" or "off" state.
227: * The boolean value <code>true</code> indicates the "on" state,
228: * and <code>false</code> indicates the "off" state.
229: * @return the state of this check box, as a boolean value.
230: * @see java.awt.Checkbox#setState
231: * @since JDK1.0
232: */
233: public boolean getState() {
234: return state;
235: }
236:
237: /**
238: * Sets the state of this check box to the specified state.
239: * The boolean value <code>true</code> indicates the "on" state,
240: * and <code>false</code> indicates the "off" state.
241: * @param state the boolean state of the check box.
242: * @see java.awt.Checkbox#getState
243: * @since JDK1.0
244: */
245: public void setState(boolean state) {
246: /* Cannot hold check box lock when calling group.setSelectedCheckbox. */
247: CheckboxGroup group = this .group;
248: if (group != null) {
249: if (state) {
250: group.setSelectedCheckbox(this );
251: } else if (group.getSelectedCheckbox() == this ) {
252: state = true;
253: }
254: }
255: setStateInternal(state);
256: }
257:
258: /**
259: * Returns the an array (length 1) containing the checkbox
260: * label or null if the checkbox is not selected.
261: * @see ItemSelectable
262: */
263: public Object[] getSelectedObjects() {
264: if (state) {
265: Object[] items = new Object[1];
266: items[0] = label;
267: return items;
268: }
269: return null;
270: }
271:
272: /**
273: * Determines this check box's group.
274: * @return this check box's group, or <code>null</code>
275: * if the check box is not part of a check box group.
276: * @see java.awt.Checkbox#setCheckboxGroup
277: * @since JDK1.0
278: */
279: public CheckboxGroup getCheckboxGroup() {
280: return group;
281: }
282:
283: /**
284: * Sets this check box's group to be the specified check box group.
285: * If this check box is already in a different check box group,
286: * it is first taken out of that group.
287: * @param g the new check box group, or <code>null</code>
288: * to remove this check box from any check box group.
289: * @see java.awt.Checkbox#getCheckboxGroup
290: * @since JDK1.0
291: */
292: public void setCheckboxGroup(CheckboxGroup g) {
293: // 6257119 : Brought over the code from j2se 1.4.2 to fix the
294: // bug
295: CheckboxGroup oldGroup;
296: boolean oldState;
297:
298: /* Do nothing if this check box has already belonged
299: * to the check box group g.
300: */
301: if (this .group == g) {
302: return;
303: }
304:
305: synchronized (this ) {
306: oldGroup = this .group;
307: oldState = getState();
308:
309: this .group = g;
310: CheckboxPeer peer = (CheckboxPeer) this .peer;
311: if (peer != null) {
312: peer.setCheckboxGroup(g);
313: }
314: if (this .group != null && getState()) {
315: if (this .group.getSelectedCheckbox() != null) {
316: setState(false);
317: } else {
318: this .group.setSelectedCheckbox(this );
319: }
320: }
321: }
322:
323: /* Locking check box below could cause deadlock with
324: * CheckboxGroup's setSelectedCheckbox method.
325: *
326: * Fix for 4726853 by kdm@sparc.spb.su
327: * Here we should check if this check box was selected
328: * in the previous group and set selected check box to
329: * null for that group if so.
330: */
331: if (oldGroup != null && oldState) {
332: oldGroup.setSelectedCheckbox(null);
333: }
334: // 6257119
335: }
336:
337: /**
338: * Adds the specified item listener to receive item events from
339: * this check box.
340: * @param l the item listener.
341: * @see java.awt.event.ItemEvent
342: * @see java.awt.event.ItemListener
343: * @see java.awt.Checkbox#removeItemListener
344: * @since JDK1.1
345: */
346: public synchronized void addItemListener(ItemListener l) {
347: itemListener = AWTEventMulticaster.add(itemListener, l);
348: newEventsOnly = true;
349: }
350:
351: /**
352: * Removes the specified item listener so that the item listener
353: * no longer receives item events from this check box.
354: * @param l the item listener.
355: * @see java.awt.event.ItemEvent
356: * @see java.awt.event.ItemListener
357: * @see java.awt.Checkbox#addItemListener
358: * @since JDK1.1
359: */
360: public synchronized void removeItemListener(ItemListener l) {
361: itemListener = AWTEventMulticaster.remove(itemListener, l);
362: }
363:
364: /**
365: * Returns an array of all the item listeners
366: * registered on this checkbox.
367: *
368: * @return all of this checkbox's <code>ItemListener</code>s
369: * or an empty array if no item
370: * listeners are currently registered
371: *
372: * @see #addItemListener
373: * @see #removeItemListener
374: * @see java.awt.event.ItemEvent
375: * @see java.awt.event.ItemListener
376: * @since 1.4
377: */
378: public synchronized ItemListener[] getItemListeners() {
379: return (ItemListener[]) AWTEventMulticaster.getListeners(
380: (EventListener) itemListener, ItemListener.class);
381: }
382:
383: // REMIND: remove when filtering is done at lower level
384: boolean eventEnabled(AWTEvent e) {
385: if (e.id == ItemEvent.ITEM_STATE_CHANGED) {
386: if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0
387: || itemListener != null) {
388: return true;
389: }
390: return false;
391: }
392: return super .eventEnabled(e);
393: }
394:
395: /**
396: * Processes events on this check box.
397: * If the event is an instance of <code>ItemEvent</code>,
398: * this method invokes the <code>processItemEvent</code> method.
399: * Otherwise, it calls its superclass's <code>processEvent</code> method.
400: * @param e the event.
401: * @see java.awt.event.ItemEvent
402: * @see java.awt.Checkbox#processItemEvent
403: * @since JDK1.1
404: */
405: protected void processEvent(AWTEvent e) {
406: if (e instanceof ItemEvent) {
407: processItemEvent((ItemEvent) e);
408: return;
409: }
410: super .processEvent(e);
411: }
412:
413: /**
414: * Processes item events occurring on this check box by
415: * dispatching them to any registered
416: * <code>ItemListener</code> objects.
417: * <p>
418: * This method is not called unless item events are
419: * enabled for this component. Item events are enabled
420: * when one of the following occurs:
421: * <p><ul>
422: * <li>An <code>ItemListener</code> object is registered
423: * via <code>addItemListener</code>.
424: * <li>Item events are enabled via <code>enableEvents</code>.
425: * </ul>
426: * @param e the item event.
427: * @see java.awt.event.ItemEvent
428: * @see java.awt.event.ItemListener
429: * @see java.awt.Checkbox#addItemListener
430: * @see java.awt.Component#enableEvents
431: * @since JDK1.1
432: */
433: protected void processItemEvent(ItemEvent e) {
434: if (itemListener != null) {
435: itemListener.itemStateChanged(e);
436: }
437: }
438:
439: /**
440: * Returns the parameter string representing the state of
441: * this check box. This string is useful for debugging.
442: * @return the parameter string of this check box.
443: * @since JDK1.0
444: */
445: protected String paramString() {
446: String str = super .paramString();
447: String label = this .label;
448: if (label != null) {
449: str += ",label=" + label;
450: }
451: return str + ",state=" + state;
452: }
453:
454: /* Serialization support.
455: */
456:
457: private int checkboxSerializedDataVersion = 1;
458:
459: private void writeObject(ObjectOutputStream s)
460: throws java.io.IOException {
461: s.defaultWriteObject();
462: AWTEventMulticaster.save(s, itemListenerK, itemListener);
463: s.writeObject(null);
464: }
465:
466: private void readObject(ObjectInputStream s)
467: throws ClassNotFoundException, IOException {
468: s.defaultReadObject();
469: Object keyOrNull;
470: while (null != (keyOrNull = s.readObject())) {
471: String key = ((String) keyOrNull).intern();
472: if (itemListenerK == key)
473: addItemListener((ItemListener) (s.readObject()));
474: else
475: // skip value for unrecognized key
476: s.readObject();
477: }
478: }
479: }
|