History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/MenuItem.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/MenuItem.java+919−0
@@ -0,0 +1,919 @@
1+/*
2+ * Copyright (c) 1995, 2009, 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.MenuItemPeer;
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+ * All items in a menu must belong to the class
38+ * <code>MenuItem</code>, or one of its subclasses.
39+ * <p>
40+ * The default <code>MenuItem</code> object embodies
41+ * a simple labeled menu item.
42+ * <p>
43+ * This picture of a menu bar shows five menu items:
44+ * <IMG SRC="doc-files/MenuBar-1.gif" alt="The following text describes this graphic."
45+ * ALIGN=CENTER HSPACE=10 VSPACE=7>
46+ * <br CLEAR=LEFT>
47+ * The first two items are simple menu items, labeled
48+ * <code>"Basic"</code> and <code>"Simple"</code>.
49+ * Following these two items is a separator, which is itself
50+ * a menu item, created with the label <code>"-"</code>.
51+ * Next is an instance of <code>CheckboxMenuItem</code>
52+ * labeled <code>"Check"</code>. The final menu item is a
53+ * submenu labeled <code>"More&nbsp;Examples"</code>,
54+ * and this submenu is an instance of <code>Menu</code>.
55+ * <p>
56+ * When a menu item is selected, AWT sends an action event to
57+ * the menu item. Since the event is an
58+ * instance of <code>ActionEvent</code>, the <code>processEvent</code>
59+ * method examines the event and passes it along to
60+ * <code>processActionEvent</code>. The latter method redirects the
61+ * event to any <code>ActionListener</code> objects that have
62+ * registered an interest in action events generated by this
63+ * menu item.
64+ * <P>
65+ * Note that the subclass <code>Menu</code> overrides this behavior and
66+ * does not send any event to the frame until one of its subitems is
67+ * selected.
68+ *
69+ * @author Sami Shaio
70+ */
71+public class MenuItem extends MenuComponent implements Accessible {
72+
73+ static {
74+ /* ensure that the necessary native libraries are loaded */
75+ Toolkit.loadLibraries();
76+ if (!GraphicsEnvironment.isHeadless()) {
77+ initIDs();
78+ }
79+ }
80+
81+ /**
82+ * A value to indicate whether a menu item is enabled
83+ * or not. If it is enabled, <code>enabled</code> will
84+ * be set to true. Else <code>enabled</code> will
85+ * be set to false.
86+ *
87+ * @serial
88+ * @see #isEnabled()
89+ * @see #setEnabled(boolean)
90+ */
91+ boolean enabled = true;
92+
93+ /**
94+ * <code>label</code> is the label of a menu item.
95+ * It can be any string.
96+ *
97+ * @serial
98+ * @see #getLabel()
99+ * @see #setLabel(String)
100+ */
101+ String label;
102+
103+ /**
104+ * This field indicates the command tha has been issued
105+ * by a particular menu item.
106+ * By default the <code>actionCommand</code>
107+ * is the label of the menu item, unless it has been
108+ * set using setActionCommand.
109+ *
110+ * @serial
111+ * @see #setActionCommand(String)
112+ * @see #getActionCommand()
113+ */
114+ String actionCommand;
115+
116+ /**
117+ * The eventMask is ONLY set by subclasses via enableEvents.
118+ * The mask should NOT be set when listeners are registered
119+ * so that we can distinguish the difference between when
120+ * listeners request events and subclasses request them.
121+ *
122+ * @serial
123+ */
124+ long eventMask;
125+
126+ transient ActionListener actionListener;
127+
128+ /**
129+ * A sequence of key stokes that ia associated with
130+ * a menu item.
131+ * Note :in 1.1.2 you must use setActionCommand()
132+ * on a menu item in order for its shortcut to
133+ * work.
134+ *
135+ * @serial
136+ * @see #getShortcut()
137+ * @see #setShortcut(MenuShortcut)
138+ * @see #deleteShortcut()
139+ */
140+ private MenuShortcut shortcut = null;
141+
142+ private static final String base = "menuitem";
143+ private static int nameCounter = 0;
144+
145+ /*
146+ * JDK 1.1 serialVersionUID
147+ */
148+ private static final long serialVersionUID = -21757335363267194L;
149+
150+ /**
151+ * Constructs a new MenuItem with an empty label and no keyboard
152+ * shortcut.
153+ * @exception HeadlessException if GraphicsEnvironment.isHeadless()
154+ * returns true.
155+ * @see java.awt.GraphicsEnvironment#isHeadless
156+ * @since JDK1.1
157+ */
158+ public MenuItem() throws HeadlessException {
159+ this("", null);
160+ }
161+
162+ /**
163+ * Constructs a new MenuItem with the specified label
164+ * and no keyboard shortcut. Note that use of "-" in
165+ * a label is reserved to indicate a separator between
166+ * menu items. By default, all menu items except for
167+ * separators are enabled.
168+ * @param label the label for this menu item.
169+ * @exception HeadlessException if GraphicsEnvironment.isHeadless()
170+ * returns true.
171+ * @see java.awt.GraphicsEnvironment#isHeadless
172+ * @since JDK1.0
173+ */
174+ public MenuItem(String label) throws HeadlessException {
175+ this(label, null);
176+ }
177+
178+ /**
179+ * Create a menu item with an associated keyboard shortcut.
180+ * Note that use of "-" in a label is reserved to indicate
181+ * a separator between menu items. By default, all menu
182+ * items except for separators are enabled.
183+ * @param label the label for this menu item.
184+ * @param s the instance of <code>MenuShortcut</code>
185+ * associated with this menu item.
186+ * @exception HeadlessException if GraphicsEnvironment.isHeadless()
187+ * returns true.
188+ * @see java.awt.GraphicsEnvironment#isHeadless
189+ * @since JDK1.1
190+ */
191+ public MenuItem(String label, MenuShortcut s) throws HeadlessException {
192+ this.label = label;
193+ this.shortcut = s;
194+ }
195+
196+ /**
197+ * Construct a name for this MenuComponent. Called by getName() when
198+ * the name is null.
199+ */
200+ String constructComponentName() {
201+ synchronized (MenuItem.class) {
202+ return base + nameCounter++;
203+ }
204+ }
205+
206+ /**
207+ * Creates the menu item's peer. The peer allows us to modify the
208+ * appearance of the menu item without changing its functionality.
209+ */
210+ public void addNotify() {
211+ synchronized (getTreeLock()) {
212+ if (peer == null)
213+ peer = Toolkit.getDefaultToolkit().createMenuItem(this);
214+ }
215+ }
216+
217+ /**
218+ * Gets the label for this menu item.
219+ * @return the label of this menu item, or <code>null</code>
220+ if this menu item has no label.
221+ * @see java.awt.MenuItem#setLabel
222+ * @since JDK1.0
223+ */
224+ public String getLabel() {
225+ return label;
226+ }
227+
228+ /**
229+ * Sets the label for this menu item to the specified label.
230+ * @param label the new label, or <code>null</code> for no label.
231+ * @see java.awt.MenuItem#getLabel
232+ * @since JDK1.0
233+ */
234+ public synchronized void setLabel(String label) {
235+ this.label = label;
236+ MenuItemPeer peer = (MenuItemPeer)this.peer;
237+ if (peer != null) {
238+ peer.setLabel(label);
239+ }
240+ }
241+
242+ /**
243+ * Checks whether this menu item is enabled.
244+ * @see java.awt.MenuItem#setEnabled
245+ * @since JDK1.0
246+ */
247+ public boolean isEnabled() {
248+ return enabled;
249+ }
250+
251+ /**
252+ * Sets whether or not this menu item can be chosen.
253+ * @param b if <code>true</code>, enables this menu item;
254+ * if <code>false</code>, disables it.
255+ * @see java.awt.MenuItem#isEnabled
256+ * @since JDK1.1
257+ */
258+ public synchronized void setEnabled(boolean b) {
259+ enable(b);
260+ }
261+
262+ /**
263+ * @deprecated As of JDK version 1.1,
264+ * replaced by <code>setEnabled(boolean)</code>.
265+ */
266+ @Deprecated
267+ public synchronized void enable() {
268+ enabled = true;
269+ MenuItemPeer peer = (MenuItemPeer)this.peer;
270+ if (peer != null) {
271+ peer.setEnabled(true);
272+ }
273+ }
274+
275+ /**
276+ * @deprecated As of JDK version 1.1,
277+ * replaced by <code>setEnabled(boolean)</code>.
278+ */
279+ @Deprecated
280+ public void enable(boolean b) {
281+ if (b) {
282+ enable();
283+ } else {
284+ disable();
285+ }
286+ }
287+
288+ /**
289+ * @deprecated As of JDK version 1.1,
290+ * replaced by <code>setEnabled(boolean)</code>.
291+ */
292+ @Deprecated
293+ public synchronized void disable() {
294+ enabled = false;
295+ MenuItemPeer peer = (MenuItemPeer)this.peer;
296+ if (peer != null) {
297+ peer.setEnabled(false);
298+ }
299+ }
300+
301+ /**
302+ * Get the <code>MenuShortcut</code> object associated with this
303+ * menu item,
304+ * @return the menu shortcut associated with this menu item,
305+ * or <code>null</code> if none has been specified.
306+ * @see java.awt.MenuItem#setShortcut
307+ * @since JDK1.1
308+ */
309+ public MenuShortcut getShortcut() {
310+ return shortcut;
311+ }
312+
313+ /**
314+ * Set the <code>MenuShortcut</code> object associated with this
315+ * menu item. If a menu shortcut is already associated with
316+ * this menu item, it is replaced.
317+ * @param s the menu shortcut to associate
318+ * with this menu item.
319+ * @see java.awt.MenuItem#getShortcut
320+ * @since JDK1.1
321+ */
322+ public void setShortcut(MenuShortcut s) {
323+ shortcut = s;
324+ MenuItemPeer peer = (MenuItemPeer)this.peer;
325+ if (peer != null) {
326+ peer.setLabel(label);
327+ }
328+ }
329+
330+ /**
331+ * Delete any <code>MenuShortcut</code> object associated
332+ * with this menu item.
333+ * @since JDK1.1
334+ */
335+ public void deleteShortcut() {
336+ shortcut = null;
337+ MenuItemPeer peer = (MenuItemPeer)this.peer;
338+ if (peer != null) {
339+ peer.setLabel(label);
340+ }
341+ }
342+
343+ /*
344+ * Delete a matching MenuShortcut associated with this MenuItem.
345+ * Used when iterating Menus.
346+ */
347+ void deleteShortcut(MenuShortcut s) {
348+ if (s.equals(shortcut)) {
349+ shortcut = null;
350+ MenuItemPeer peer = (MenuItemPeer)this.peer;
351+ if (peer != null) {
352+ peer.setLabel(label);
353+ }
354+ }
355+ }
356+
357+ /*
358+ * The main goal of this method is to post an appropriate event
359+ * to the event queue when menu shortcut is pressed. However,
360+ * in subclasses this method may do more than just posting
361+ * an event.
362+ */
363+ void doMenuEvent(long when, int modifiers) {
364+ Toolkit.getEventQueue().postEvent(
365+ new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
366+ getActionCommand(), when, modifiers));
367+ }
368+
369+ /*
370+ * Returns true if the item and all its ancestors are
371+ * enabled, false otherwise
372+ */
373+ private final boolean isItemEnabled() {
374+ // Fix For 6185151: Menu shortcuts of all menuitems within a menu
375+ // should be disabled when the menu itself is disabled
376+ if (!isEnabled()) {
377+ return false;
378+ }
379+ MenuContainer container = getParent_NoClientCode();
380+ do {
381+ if (!(container instanceof Menu)) {
382+ return true;
383+ }
384+ Menu menu = (Menu)container;
385+ if (!menu.isEnabled()) {
386+ return false;
387+ }
388+ container = menu.getParent_NoClientCode();
389+ } while (container != null);
390+ return true;
391+ }
392+
393+ /*
394+ * Post an ActionEvent to the target (on
395+ * keydown) and the item is enabled.
396+ * Returns true if there is an associated shortcut.
397+ */
398+ boolean handleShortcut(KeyEvent e) {
399+ MenuShortcut s = new MenuShortcut(e.getKeyCode(),
400+ (e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
401+ MenuShortcut sE = new MenuShortcut(e.getExtendedKeyCode(),
402+ (e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
403+ // Fix For 6185151: Menu shortcuts of all menuitems within a menu
404+ // should be disabled when the menu itself is disabled
405+ if ((s.equals(shortcut) || sE.equals(shortcut)) && isItemEnabled()) {
406+ // MenuShortcut match -- issue an event on keydown.
407+ if (e.getID() == KeyEvent.KEY_PRESSED) {
408+ doMenuEvent(e.getWhen(), e.getModifiers());
409+ } else {
410+ // silently eat key release.
411+ }
412+ return true;
413+ }
414+ return false;
415+ }
416+
417+ MenuItem getShortcutMenuItem(MenuShortcut s) {
418+ return (s.equals(shortcut)) ? this : null;
419+ }
420+
421+ /**
422+ * Enables event delivery to this menu item for events
423+ * to be defined by the specified event mask parameter
424+ * <p>
425+ * Since event types are automatically enabled when a listener for
426+ * that type is added to the menu item, this method only needs
427+ * to be invoked by subclasses of <code>MenuItem</code> which desire to
428+ * have the specified event types delivered to <code>processEvent</code>
429+ * regardless of whether a listener is registered.
430+ *
431+ * @param eventsToEnable the event mask defining the event types
432+ * @see java.awt.MenuItem#processEvent
433+ * @see java.awt.MenuItem#disableEvents
434+ * @see java.awt.Component#enableEvents
435+ * @since JDK1.1
436+ */
437+ protected final void enableEvents(long eventsToEnable) {
438+ eventMask |= eventsToEnable;
439+ newEventsOnly = true;
440+ }
441+
442+ /**
443+ * Disables event delivery to this menu item for events
444+ * defined by the specified event mask parameter.
445+ *
446+ * @param eventsToDisable the event mask defining the event types
447+ * @see java.awt.MenuItem#processEvent
448+ * @see java.awt.MenuItem#enableEvents
449+ * @see java.awt.Component#disableEvents
450+ * @since JDK1.1
451+ */
452+ protected final void disableEvents(long eventsToDisable) {
453+ eventMask &= ~eventsToDisable;
454+ }
455+
456+ /**
457+ * Sets the command name of the action event that is fired
458+ * by this menu item.
459+ * <p>
460+ * By default, the action command is set to the label of
461+ * the menu item.
462+ * @param command the action command to be set
463+ * for this menu item.
464+ * @see java.awt.MenuItem#getActionCommand
465+ * @since JDK1.1
466+ */
467+ public void setActionCommand(String command) {
468+ actionCommand = command;
469+ }
470+
471+ /**
472+ * Gets the command name of the action event that is fired
473+ * by this menu item.
474+ * @see java.awt.MenuItem#setActionCommand
475+ * @since JDK1.1
476+ */
477+ public String getActionCommand() {
478+ return getActionCommandImpl();
479+ }
480+
481+ // This is final so it can be called on the Toolkit thread.
482+ final String getActionCommandImpl() {
483+ return (actionCommand == null? label : actionCommand);
484+ }
485+
486+ /**
487+ * Adds the specified action listener to receive action events
488+ * from this menu item.
489+ * If l is null, no exception is thrown and no action is performed.
490+ * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
491+ * >AWT Threading Issues</a> for details on AWT's threading model.
492+ *
493+ * @param l the action listener.
494+ * @see #removeActionListener
495+ * @see #getActionListeners
496+ * @see java.awt.event.ActionEvent
497+ * @see java.awt.event.ActionListener
498+ * @since JDK1.1
499+ */
500+ public synchronized void addActionListener(ActionListener l) {
501+ if (l == null) {
502+ return;
503+ }
504+ actionListener = AWTEventMulticaster.add(actionListener, l);
505+ newEventsOnly = true;
506+ }
507+
508+ /**
509+ * Removes the specified action listener so it no longer receives
510+ * action events from this menu item.
511+ * If l is null, no exception is thrown and no action is performed.
512+ * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
513+ * >AWT Threading Issues</a> for details on AWT's threading model.
514+ *
515+ * @param l the action listener.
516+ * @see #addActionListener
517+ * @see #getActionListeners
518+ * @see java.awt.event.ActionEvent
519+ * @see java.awt.event.ActionListener
520+ * @since JDK1.1
521+ */
522+ public synchronized void removeActionListener(ActionListener l) {
523+ if (l == null) {
524+ return;
525+ }
526+ actionListener = AWTEventMulticaster.remove(actionListener, l);
527+ }
528+
529+ /**
530+ * Returns an array of all the action listeners
531+ * registered on this menu item.
532+ *
533+ * @return all of this menu item's <code>ActionListener</code>s
534+ * or an empty array if no action
535+ * listeners are currently registered
536+ *
537+ * @see #addActionListener
538+ * @see #removeActionListener
539+ * @see java.awt.event.ActionEvent
540+ * @see java.awt.event.ActionListener
541+ * @since 1.4
542+ */
543+ public synchronized ActionListener[] getActionListeners() {
544+ return (ActionListener[])(getListeners(ActionListener.class));
545+ }
546+
547+ /**
548+ * Returns an array of all the objects currently registered
549+ * as <code><em>Foo</em>Listener</code>s
550+ * upon this <code>MenuItem</code>.
551+ * <code><em>Foo</em>Listener</code>s are registered using the
552+ * <code>add<em>Foo</em>Listener</code> method.
553+ *
554+ * <p>
555+ * You can specify the <code>listenerType</code> argument
556+ * with a class literal, such as
557+ * <code><em>Foo</em>Listener.class</code>.
558+ * For example, you can query a
559+ * <code>MenuItem</code> <code>m</code>
560+ * for its action listeners with the following code:
561+ *
562+ * <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>
563+ *
564+ * If no such listeners exist, this method returns an empty array.
565+ *
566+ * @param listenerType the type of listeners requested; this parameter
567+ * should specify an interface that descends from
568+ * <code>java.util.EventListener</code>
569+ * @return an array of all objects registered as
570+ * <code><em>Foo</em>Listener</code>s on this menu item,
571+ * or an empty array if no such
572+ * listeners have been added
573+ * @exception ClassCastException if <code>listenerType</code>
574+ * doesn't specify a class or interface that implements
575+ * <code>java.util.EventListener</code>
576+ *
577+ * @see #getActionListeners
578+ * @since 1.3
579+ */
580+ public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
581+ EventListener l = null;
582+ if (listenerType == ActionListener.class) {
583+ l = actionListener;
584+ }
585+ return AWTEventMulticaster.getListeners(l, listenerType);
586+ }
587+
588+ /**
589+ * Processes events on this menu item. If the event is an
590+ * instance of <code>ActionEvent</code>, it invokes
591+ * <code>processActionEvent</code>, another method
592+ * defined by <code>MenuItem</code>.
593+ * <p>
594+ * Currently, menu items only support action events.
595+ * <p>Note that if the event parameter is <code>null</code>
596+ * the behavior is unspecified and may result in an
597+ * exception.
598+ *
599+ * @param e the event
600+ * @see java.awt.MenuItem#processActionEvent
601+ * @since JDK1.1
602+ */
603+ protected void processEvent(AWTEvent e) {
604+ if (e instanceof ActionEvent) {
605+ processActionEvent((ActionEvent)e);
606+ }
607+ }
608+
609+ // REMIND: remove when filtering is done at lower level
610+ boolean eventEnabled(AWTEvent e) {
611+ if (e.id == ActionEvent.ACTION_PERFORMED) {
612+ if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
613+ actionListener != null) {
614+ return true;
615+ }
616+ return false;
617+ }
618+ return super.eventEnabled(e);
619+ }
620+
621+ /**
622+ * Processes action events occurring on this menu item,
623+ * by dispatching them to any registered
624+ * <code>ActionListener</code> objects.
625+ * This method is not called unless action events are
626+ * enabled for this component. Action events are enabled
627+ * when one of the following occurs:
628+ * <p><ul>
629+ * <li>An <code>ActionListener</code> object is registered
630+ * via <code>addActionListener</code>.
631+ * <li>Action events are enabled via <code>enableEvents</code>.
632+ * </ul>
633+ * <p>Note that if the event parameter is <code>null</code>
634+ * the behavior is unspecified and may result in an
635+ * exception.
636+ *
637+ * @param e the action event
638+ * @see java.awt.event.ActionEvent
639+ * @see java.awt.event.ActionListener
640+ * @see java.awt.MenuItem#enableEvents
641+ * @since JDK1.1
642+ */
643+ protected void processActionEvent(ActionEvent e) {
644+ ActionListener listener = actionListener;
645+ if (listener != null) {
646+ listener.actionPerformed(e);
647+ }
648+ }
649+
650+ /**
651+ * Returns a string representing the state of this <code>MenuItem</code>.
652+ * This method is intended to be used only for debugging purposes, and the
653+ * content and format of the returned string may vary between
654+ * implementations. The returned string may be empty but may not be
655+ * <code>null</code>.
656+ *
657+ * @return the parameter string of this menu item
658+ */
659+ public String paramString() {
660+ String str = ",label=" + label;
661+ if (shortcut != null) {
662+ str += ",shortcut=" + shortcut;
663+ }
664+ return super.paramString() + str;
665+ }
666+
667+
668+ /* Serialization support.
669+ */
670+
671+ /**
672+ * Menu item serialized data version.
673+ *
674+ * @serial
675+ */
676+ private int menuItemSerializedDataVersion = 1;
677+
678+ /**
679+ * Writes default serializable fields to stream. Writes
680+ * a list of serializable <code>ActionListeners</code>
681+ * as optional data. The non-serializable listeners are
682+ * detected and no attempt is made to serialize them.
683+ *
684+ * @param s the <code>ObjectOutputStream</code> to write
685+ * @serialData <code>null</code> terminated sequence of 0
686+ * or more pairs; the pair consists of a <code>String</code>
687+ * and an <code>Object</code>; the <code>String</code>
688+ * indicates the type of object and is one of the following:
689+ * <code>actionListenerK</code> indicating an
690+ * <code>ActionListener</code> object
691+ *
692+ * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
693+ * @see #readObject(ObjectInputStream)
694+ */
695+ private void writeObject(ObjectOutputStream s)
696+ throws IOException
697+ {
698+ s.defaultWriteObject();
699+
700+ AWTEventMulticaster.save(s, actionListenerK, actionListener);
701+ s.writeObject(null);
702+ }
703+
704+ /**
705+ * Reads the <code>ObjectInputStream</code> and if it
706+ * isn't <code>null</code> adds a listener to receive
707+ * action events fired by the <code>Menu</code> Item.
708+ * Unrecognized keys or values will be ignored.
709+ *
710+ * @param s the <code>ObjectInputStream</code> to read
711+ * @exception HeadlessException if
712+ * <code>GraphicsEnvironment.isHeadless</code> returns
713+ * <code>true</code>
714+ * @see #removeActionListener(ActionListener)
715+ * @see #addActionListener(ActionListener)
716+ * @see #writeObject(ObjectOutputStream)
717+ */
718+ private void readObject(ObjectInputStream s)
719+ throws ClassNotFoundException, IOException, HeadlessException
720+ {
721+ // HeadlessException will be thrown from MenuComponent's readObject
722+ s.defaultReadObject();
723+
724+ Object keyOrNull;
725+ while(null != (keyOrNull = s.readObject())) {
726+ String key = ((String)keyOrNull).intern();
727+
728+ if (actionListenerK == key)
729+ addActionListener((ActionListener)(s.readObject()));
730+
731+ else // skip value for unrecognized key
732+ s.readObject();
733+ }
734+ }
735+
736+ /**
737+ * Initialize JNI field and method IDs
738+ */
739+ private static native void initIDs();
740+
741+
742+/////////////////
743+// Accessibility support
744+////////////////
745+
746+ /**
747+ * Gets the AccessibleContext associated with this MenuItem.
748+ * For menu items, the AccessibleContext takes the form of an
749+ * AccessibleAWTMenuItem.
750+ * A new AccessibleAWTMenuItem instance is created if necessary.
751+ *
752+ * @return an AccessibleAWTMenuItem that serves as the
753+ * AccessibleContext of this MenuItem
754+ * @since 1.3
755+ */
756+ public AccessibleContext getAccessibleContext() {
757+ if (accessibleContext == null) {
758+ accessibleContext = new AccessibleAWTMenuItem();
759+ }
760+ return accessibleContext;
761+ }
762+
763+ /**
764+ * Inner class of MenuItem used to provide default support for
765+ * accessibility. This class is not meant to be used directly by
766+ * application developers, but is instead meant only to be
767+ * subclassed by menu component developers.
768+ * <p>
769+ * This class implements accessibility support for the
770+ * <code>MenuItem</code> class. It provides an implementation of the
771+ * Java Accessibility API appropriate to menu item user-interface elements.
772+ * @since 1.3
773+ */
774+ protected class AccessibleAWTMenuItem extends AccessibleAWTMenuComponent
775+ implements AccessibleAction, AccessibleValue
776+ {
777+ /*
778+ * JDK 1.3 serialVersionUID
779+ */
780+ private static final long serialVersionUID = -217847831945965825L;
781+
782+ /**
783+ * Get the accessible name of this object.
784+ *
785+ * @return the localized name of the object -- can be null if this
786+ * object does not have a name
787+ */
788+ public String getAccessibleName() {
789+ if (accessibleName != null) {
790+ return accessibleName;
791+ } else {
792+ if (getLabel() == null) {
793+ return super.getAccessibleName();
794+ } else {
795+ return getLabel();
796+ }
797+ }
798+ }
799+
800+ /**
801+ * Get the role of this object.
802+ *
803+ * @return an instance of AccessibleRole describing the role of the
804+ * object
805+ */
806+ public AccessibleRole getAccessibleRole() {
807+ return AccessibleRole.MENU_ITEM;
808+ }
809+
810+ /**
811+ * Get the AccessibleAction associated with this object. In the
812+ * implementation of the Java Accessibility API for this class,
813+ * return this object, which is responsible for implementing the
814+ * AccessibleAction interface on behalf of itself.
815+ *
816+ * @return this object
817+ */
818+ public AccessibleAction getAccessibleAction() {
819+ return this;
820+ }
821+
822+ /**
823+ * Get the AccessibleValue associated with this object. In the
824+ * implementation of the Java Accessibility API for this class,
825+ * return this object, which is responsible for implementing the
826+ * AccessibleValue interface on behalf of itself.
827+ *
828+ * @return this object
829+ */
830+ public AccessibleValue getAccessibleValue() {
831+ return this;
832+ }
833+
834+ /**
835+ * Returns the number of Actions available in this object. The
836+ * default behavior of a menu item is to have one action.
837+ *
838+ * @return 1, the number of Actions in this object
839+ */
840+ public int getAccessibleActionCount() {
841+ return 1;
842+ }
843+
844+ /**
845+ * Return a description of the specified action of the object.
846+ *
847+ * @param i zero-based index of the actions
848+ */
849+ public String getAccessibleActionDescription(int i) {
850+ if (i == 0) {
851+ // [[[PENDING: WDW -- need to provide a localized string]]]
852+ return "click";
853+ } else {
854+ return null;
855+ }
856+ }
857+
858+ /**
859+ * Perform the specified Action on the object
860+ *
861+ * @param i zero-based index of actions
862+ * @return true if the action was performed; otherwise false.
863+ */
864+ public boolean doAccessibleAction(int i) {
865+ if (i == 0) {
866+ // Simulate a button click
867+ Toolkit.getEventQueue().postEvent(
868+ new ActionEvent(MenuItem.this,
869+ ActionEvent.ACTION_PERFORMED,
870+ MenuItem.this.getActionCommand(),
871+ EventQueue.getMostRecentEventTime(),
872+ 0));
873+ return true;
874+ } else {
875+ return false;
876+ }
877+ }
878+
879+ /**
880+ * Get the value of this object as a Number.
881+ *
882+ * @return An Integer of 0 if this isn't selected or an Integer of 1 if
883+ * this is selected.
884+ * @see javax.swing.AbstractButton#isSelected()
885+ */
886+ public Number getCurrentAccessibleValue() {
887+ return Integer.valueOf(0);
888+ }
889+
890+ /**
891+ * Set the value of this object as a Number.
892+ *
893+ * @return True if the value was set.
894+ */
895+ public boolean setCurrentAccessibleValue(Number n) {
896+ return false;
897+ }
898+
899+ /**
900+ * Get the minimum value of this object as a Number.
901+ *
902+ * @return An Integer of 0.
903+ */
904+ public Number getMinimumAccessibleValue() {
905+ return Integer.valueOf(0);
906+ }
907+
908+ /**
909+ * Get the maximum value of this object as a Number.
910+ *
911+ * @return An Integer of 0.
912+ */
913+ public Number getMaximumAccessibleValue() {
914+ return Integer.valueOf(0);
915+ }
916+
917+ } // class AccessibleAWTMenuItem
918+
919+}