001/* CheckboxMenuItem.java -- A menu option with a checkbox on it.
002   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005  Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.awt;
040
041import java.awt.event.ItemEvent;
042import java.awt.event.ItemListener;
043import java.awt.peer.CheckboxMenuItemPeer;
044import java.util.EventListener;
045
046import javax.accessibility.Accessible;
047import javax.accessibility.AccessibleAction;
048import javax.accessibility.AccessibleContext;
049import javax.accessibility.AccessibleValue;
050
051/**
052  * This class implements a menu item that has a checkbox on it indicating
053  * the selected state of some option.
054  *
055  * @author Aaron M. Renn (arenn@urbanophile.com)
056  * @author Tom Tromey (tromey@redhat.com)
057  */
058public class CheckboxMenuItem extends MenuItem
059  implements ItemSelectable, Accessible
060{
061
062/*
063 * Static Variables
064 */
065
066/**
067 * The number used to generate the name returned by getName.
068 */
069private static transient long next_chkmenuitem_number;
070
071// Serialization constant
072private static final long serialVersionUID = 6190621106981774043L;
073
074/*
075 * Instance Variables
076 */
077
078/**
079  * @serial The state of the checkbox, with <code>true</code> being on and
080  * <code>false</code> being off.
081  */
082private boolean state;
083
084// List of registered ItemListeners
085private transient ItemListener item_listeners;
086
087/*************************************************************************/
088
089/*
090 * Constructors
091 */
092
093/**
094  * Initializes a new instance of <code>CheckboxMenuItem</code> with no
095  * label and an initial state of off.
096  *
097  * @exception HeadlessException If GraphicsEnvironment.isHeadless()
098  * returns true.
099  */
100public
101CheckboxMenuItem()
102{
103  this("", false);
104}
105
106/*************************************************************************/
107
108/**
109  * Initializes a new instance of <code>CheckboxMenuItem</code> with the
110  * specified label and an initial state of off.
111  *
112  * @param label The label of the menu item.
113  *
114  * @exception HeadlessException If GraphicsEnvironment.isHeadless()
115  * returns true.
116  */
117public
118CheckboxMenuItem(String label)
119{
120  this(label, false);
121}
122
123/*************************************************************************/
124
125/**
126  * Initializes a new instance of <code>CheckboxMenuItem</code> with the
127  * specified label and initial state.
128  *
129  * @param label The label of the menu item.
130  * @param state The initial state of the menu item, where <code>true</code>
131  * is on, and <code>false</code> is off.
132  *
133  * @exception HeadlessException If GraphicsEnvironment.isHeadless()
134  * returns true.
135  */
136public
137CheckboxMenuItem(String label, boolean state)
138{
139  super(label);
140  this.state = state;
141
142  if (GraphicsEnvironment.isHeadless())
143    throw new HeadlessException ();
144}
145
146/*************************************************************************/
147
148/*
149 * Instance Methods
150 */
151
152/**
153  * Returns the state of this menu item.
154  *
155  * @return The state of this menu item.
156  */
157public boolean
158getState()
159{
160  return(state);
161}
162
163/*************************************************************************/
164
165/**
166  * Sets the state of this menu item.
167  *
168  * @param state The initial state of the menu item, where <code>true</code>
169  * is on, and <code>false</code> is off.
170  */
171public synchronized void
172setState(boolean state)
173{
174  this.state = state;
175  if (peer != null)
176    {
177      CheckboxMenuItemPeer cp = (CheckboxMenuItemPeer) peer;
178      cp.setState (state);
179    }
180}
181
182/*************************************************************************/
183
184/**
185  * Returns an array of length 1 with the menu item label for this object
186  * if the state is on.  Otherwise <code>null</code> is returned.
187  *
188  * @return An array with this menu item's label if it has a state of on,
189  * or <code>null</code> otherwise.
190  */
191public Object[]
192getSelectedObjects()
193{
194  if (state == false)
195    return(null);
196
197  Object[] obj = new Object[1];
198  obj[0] = getLabel();
199
200  return(obj);
201}
202
203/*************************************************************************/
204
205/**
206  * Create's this object's native peer
207  */
208public synchronized void
209addNotify()
210{
211  if (peer == null)
212    peer = getToolkit().createCheckboxMenuItem(this);
213
214  super.addNotify ();
215}
216
217/*************************************************************************/
218
219/**
220  * Adds the specified listener to the list of registered item listeners
221  * for this object.
222  *
223  * @param listener The listener to add.
224  */
225public synchronized void
226addItemListener(ItemListener listener)
227{
228  item_listeners = AWTEventMulticaster.add(item_listeners, listener);
229
230  enableEvents(AWTEvent.ITEM_EVENT_MASK);
231}
232
233/*************************************************************************/
234
235/**
236  * Removes the specified listener from the list of registered item
237  * listeners for this object.
238  *
239  * @param listener The listener to remove.
240  */
241public synchronized void
242removeItemListener(ItemListener listener)
243{
244  item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
245}
246
247/*************************************************************************/
248
249/**
250  * Processes the specified event by calling <code>processItemEvent()</code>
251  * if it is an instance of <code>ItemEvent</code> or calling the superclass
252  * method otherwise.
253  *
254  * @param event The event to process.
255  */
256protected void
257processEvent(AWTEvent event)
258{
259  if (event instanceof ItemEvent)
260    processItemEvent((ItemEvent)event);
261  else
262    super.processEvent(event);
263}
264
265/*************************************************************************/
266
267/**
268  * Processes the specified event by dispatching it to any registered listeners.
269  *
270  * @param event The event to process.
271  */
272protected void
273processItemEvent(ItemEvent event)
274{
275  if (item_listeners != null)
276    item_listeners.itemStateChanged(event);
277}
278
279void
280dispatchEventImpl(AWTEvent e)
281{
282  if (e instanceof ItemEvent)
283    {
284      synchronized (this)
285        {
286          state = (((ItemEvent) e).getStateChange() == ItemEvent.SELECTED);
287        }
288    }
289
290  if (e.id <= ItemEvent.ITEM_LAST
291      && e.id >= ItemEvent.ITEM_FIRST
292      && (item_listeners != null
293          || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
294    processEvent(e);
295  else
296    super.dispatchEventImpl(e);
297}
298
299/*************************************************************************/
300
301/**
302  * Returns a debugging string for this object.
303  *
304  * @return A debugging string for this object.
305  */
306public String
307paramString()
308{
309  return ("label=" + getLabel() + ",state=" + state
310          + "," + super.paramString());
311}
312
313  /**
314   * Returns an array of all the objects currently registered as FooListeners
315   * upon this <code>CheckboxMenuItem</code>. FooListeners are registered using
316   * the addFooListener method.
317   *
318   * @exception ClassCastException If listenerType doesn't specify a class or
319   * interface that implements java.util.EventListener.
320   */
321  public <T extends EventListener> T[] getListeners (Class<T> listenerType)
322  {
323    if (listenerType == ItemListener.class)
324      return AWTEventMulticaster.getListeners (item_listeners, listenerType);
325
326    return super.getListeners (listenerType);
327  }
328
329  /**
330   * Returns an aray of all item listeners currently registered to this
331   * <code>CheckBoxMenuItem</code>.
332   */
333  public ItemListener[] getItemListeners ()
334  {
335    return (ItemListener[]) getListeners (ItemListener.class);
336  }
337
338
339  protected class AccessibleAWTCheckboxMenuItem extends AccessibleAWTMenuItem
340    implements AccessibleAction, AccessibleValue
341  {
342    // I think the base class provides the necessary implementation
343
344    private static final long serialVersionUID = -1122642964303476L;
345  }
346
347  /**
348   * Gets the AccessibleContext associated with this <code>CheckboxMenuItem</code>.
349   * The context is created, if necessary.
350   *
351   * @return the associated context
352   */
353  public AccessibleContext getAccessibleContext()
354  {
355    /* Create the context if this is the first request */
356    if (accessibleContext == null)
357      accessibleContext = new AccessibleAWTCheckboxMenuItem();
358    return accessibleContext;
359  }
360
361  /**
362   * Generate a unique name for this <code>CheckboxMenuItem</code>.
363   *
364   * @return A unique name for this <code>CheckboxMenuItem</code>.
365   */
366  String generateName()
367  {
368    return "chkmenuitem" + getUniqueLong();
369  }
370
371  private static synchronized long getUniqueLong()
372  {
373    return next_chkmenuitem_number++;
374  }
375
376} // class CheckboxMenuItem