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    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath 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 for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.awt;
040    
041    import java.awt.event.ItemEvent;
042    import java.awt.event.ItemListener;
043    import java.awt.peer.CheckboxMenuItemPeer;
044    import java.util.EventListener;
045    
046    import javax.accessibility.Accessible;
047    import javax.accessibility.AccessibleAction;
048    import javax.accessibility.AccessibleContext;
049    import 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      */
058    public 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     */
069    private static transient long next_chkmenuitem_number;
070    
071    // Serialization constant
072    private 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      */
082    private boolean state;
083    
084    // List of registered ItemListeners
085    private 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      */
100    public
101    CheckboxMenuItem()
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      */
117    public
118    CheckboxMenuItem(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      */
136    public
137    CheckboxMenuItem(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      */
157    public boolean
158    getState()
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      */
171    public synchronized void
172    setState(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      */
191    public Object[]
192    getSelectedObjects()
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      */
208    public synchronized void
209    addNotify()
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      */
225    public synchronized void
226    addItemListener(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      */
241    public synchronized void
242    removeItemListener(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      */
256    protected void
257    processEvent(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      */
272    protected void
273    processItemEvent(ItemEvent event)
274    {
275      if (item_listeners != null)
276        item_listeners.itemStateChanged(event);
277    }
278    
279    void
280    dispatchEventImpl(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      */
306    public String
307    paramString()
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