001 /*
002 * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package java.awt;
026
027 import java.awt.peer.MenuItemPeer;
028 import java.awt.event.*;
029 import java.util.EventListener;
030 import java.io.ObjectOutputStream;
031 import java.io.ObjectInputStream;
032 import java.io.IOException;
033 import javax.accessibility.*;
034
035 /**
036 * All items in a menu must belong to the class
037 * <code>MenuItem</code>, or one of its subclasses.
038 * <p>
039 * The default <code>MenuItem</code> object embodies
040 * a simple labeled menu item.
041 * <p>
042 * This picture of a menu bar shows five menu items:
043 * <IMG SRC="doc-files/MenuBar-1.gif" alt="The following text describes this graphic."
044 * ALIGN=CENTER HSPACE=10 VSPACE=7>
045 * <br CLEAR=LEFT>
046 * The first two items are simple menu items, labeled
047 * <code>"Basic"</code> and <code>"Simple"</code>.
048 * Following these two items is a separator, which is itself
049 * a menu item, created with the label <code>"-"</code>.
050 * Next is an instance of <code>CheckboxMenuItem</code>
051 * labeled <code>"Check"</code>. The final menu item is a
052 * submenu labeled <code>"More Examples"</code>,
053 * and this submenu is an instance of <code>Menu</code>.
054 * <p>
055 * When a menu item is selected, AWT sends an action event to
056 * the menu item. Since the event is an
057 * instance of <code>ActionEvent</code>, the <code>processEvent</code>
058 * method examines the event and passes it along to
059 * <code>processActionEvent</code>. The latter method redirects the
060 * event to any <code>ActionListener</code> objects that have
061 * registered an interest in action events generated by this
062 * menu item.
063 * <P>
064 * Note that the subclass <code>Menu</code> overrides this behavior and
065 * does not send any event to the frame until one of its subitems is
066 * selected.
067 *
068 * @version 1.101, 05/05/07
069 * @author Sami Shaio
070 */
071 public class MenuItem extends MenuComponent implements Accessible {
072
073 static {
074 /* ensure that the necessary native libraries are loaded */
075 Toolkit.loadLibraries();
076 if (!GraphicsEnvironment.isHeadless()) {
077 initIDs();
078 }
079 }
080
081 /**
082 * A value to indicate whether a menu item is enabled
083 * or not. If it is enabled, <code>enabled</code> will
084 * be set to true. Else <code>enabled</code> will
085 * be set to false.
086 *
087 * @serial
088 * @see #isEnabled()
089 * @see #setEnabled(boolean)
090 */
091 boolean enabled = true;
092
093 /**
094 * <code>label</code> is the label of a menu item.
095 * It can be any string.
096 *
097 * @serial
098 * @see #getLabel()
099 * @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)
192 throws HeadlessException {
193 this .label = label;
194 this .shortcut = s;
195 }
196
197 /**
198 * Construct a name for this MenuComponent. Called by getName() when
199 * the name is null.
200 */
201 String constructComponentName() {
202 synchronized (MenuItem.class) {
203 return base + nameCounter++;
204 }
205 }
206
207 /**
208 * Creates the menu item's peer. The peer allows us to modify the
209 * appearance of the menu item without changing its functionality.
210 */
211 public void addNotify() {
212 synchronized (getTreeLock()) {
213 if (peer == null)
214 peer = Toolkit.getDefaultToolkit().createMenuItem(this );
215 }
216 }
217
218 /**
219 * Gets the label for this menu item.
220 * @return the label of this menu item, or <code>null</code>
221 if this menu item has no label.
222 * @see java.awt.MenuItem#setLabel
223 * @since JDK1.0
224 */
225 public String getLabel() {
226 return label;
227 }
228
229 /**
230 * Sets the label for this menu item to the specified label.
231 * @param label the new label, or <code>null</code> for no label.
232 * @see java.awt.MenuItem#getLabel
233 * @since JDK1.0
234 */
235 public synchronized void setLabel(String label) {
236 this .label = label;
237 MenuItemPeer peer = (MenuItemPeer) this .peer;
238 if (peer != null) {
239 peer.setLabel(label);
240 }
241 }
242
243 /**
244 * Checks whether this menu item is enabled.
245 * @see java.awt.MenuItem#setEnabled
246 * @since JDK1.0
247 */
248 public boolean isEnabled() {
249 return enabled;
250 }
251
252 /**
253 * Sets whether or not this menu item can be chosen.
254 * @param b if <code>true</code>, enables this menu item;
255 * if <code>false</code>, disables it.
256 * @see java.awt.MenuItem#isEnabled
257 * @since JDK1.1
258 */
259 public synchronized void setEnabled(boolean b) {
260 enable(b);
261 }
262
263 /**
264 * @deprecated As of JDK version 1.1,
265 * replaced by <code>setEnabled(boolean)</code>.
266 */
267 @Deprecated
268 public synchronized void enable() {
269 enabled = true;
270 MenuItemPeer peer = (MenuItemPeer) this .peer;
271 if (peer != null) {
272 peer.enable();
273 }
274 }
275
276 /**
277 * @deprecated As of JDK version 1.1,
278 * replaced by <code>setEnabled(boolean)</code>.
279 */
280 @Deprecated
281 public void enable(boolean b) {
282 if (b) {
283 enable();
284 } else {
285 disable();
286 }
287 }
288
289 /**
290 * @deprecated As of JDK version 1.1,
291 * replaced by <code>setEnabled(boolean)</code>.
292 */
293 @Deprecated
294 public synchronized void disable() {
295 enabled = false;
296 MenuItemPeer peer = (MenuItemPeer) this .peer;
297 if (peer != null) {
298 peer.disable();
299 }
300 }
301
302 /**
303 * Get the <code>MenuShortcut</code> object associated with this
304 * menu item,
305 * @return the menu shortcut associated with this menu item,
306 * or <code>null</code> if none has been specified.
307 * @see java.awt.MenuItem#setShortcut
308 * @since JDK1.1
309 */
310 public MenuShortcut getShortcut() {
311 return shortcut;
312 }
313
314 /**
315 * Set the <code>MenuShortcut</code> object associated with this
316 * menu item. If a menu shortcut is already associated with
317 * this menu item, it is replaced.
318 * @param s the menu shortcut to associate
319 * with this menu item.
320 * @see java.awt.MenuItem#getShortcut
321 * @since JDK1.1
322 */
323 public void setShortcut(MenuShortcut s) {
324 shortcut = s;
325 MenuItemPeer peer = (MenuItemPeer) this .peer;
326 if (peer != null) {
327 peer.setLabel(label);
328 }
329 }
330
331 /**
332 * Delete any <code>MenuShortcut</code> object associated
333 * with this menu item.
334 * @since JDK1.1
335 */
336 public void deleteShortcut() {
337 shortcut = null;
338 MenuItemPeer peer = (MenuItemPeer) this .peer;
339 if (peer != null) {
340 peer.setLabel(label);
341 }
342 }
343
344 /*
345 * Delete a matching MenuShortcut associated with this MenuItem.
346 * Used when iterating Menus.
347 */
348 void deleteShortcut(MenuShortcut s) {
349 if (s.equals(shortcut)) {
350 shortcut = null;
351 MenuItemPeer peer = (MenuItemPeer) this .peer;
352 if (peer != null) {
353 peer.setLabel(label);
354 }
355 }
356 }
357
358 /*
359 * The main goal of this method is to post an appropriate event
360 * to the event queue when menu shortcut is pressed. However,
361 * in subclasses this method may do more than just posting
362 * an event.
363 */
364 void doMenuEvent(long when, int modifiers) {
365 Toolkit.getEventQueue().postEvent(
366 new ActionEvent(this , ActionEvent.ACTION_PERFORMED,
367 getActionCommand(), when, modifiers));
368 }
369
370 /*
371 * Returns true if the item and all its ancestors are
372 * enabled, false otherwise
373 */
374 private final boolean isItemEnabled() {
375 // Fix For 6185151: Menu shortcuts of all menuitems within a menu
376 // should be disabled when the menu itself is disabled
377 if (!isEnabled()) {
378 return false;
379 }
380 MenuContainer container = getParent_NoClientCode();
381 do {
382 if (!(container instanceof Menu)) {
383 return true;
384 }
385 Menu menu = (Menu) container;
386 if (!menu.isEnabled()) {
387 return false;
388 }
389 container = menu.getParent_NoClientCode();
390 } while (container != null);
391 return true;
392 }
393
394 /*
395 * Post an ActionEvent to the target (on
396 * keydown) and the item is enabled.
397 * Returns true if there is an associated shortcut.
398 */
399 boolean handleShortcut(KeyEvent e) {
400 MenuShortcut s = new MenuShortcut(e.getKeyCode(), (e
401 .getModifiers() & InputEvent.SHIFT_MASK) > 0);
402 // Fix For 6185151: Menu shortcuts of all menuitems within a menu
403 // should be disabled when the menu itself is disabled
404 if (s.equals(shortcut) && isItemEnabled()) {
405 // MenuShortcut match -- issue an event on keydown.
406 if (e.getID() == KeyEvent.KEY_PRESSED) {
407 doMenuEvent(e.getWhen(), e.getModifiers());
408 } else {
409 // silently eat key release.
410 }
411 return true;
412 }
413 return false;
414 }
415
416 MenuItem getShortcutMenuItem(MenuShortcut s) {
417 return (s.equals(shortcut)) ? this : null;
418 }
419
420 /**
421 * Enables event delivery to this menu item for events
422 * to be defined by the specified event mask parameter
423 * <p>
424 * Since event types are automatically enabled when a listener for
425 * that type is added to the menu item, this method only needs
426 * to be invoked by subclasses of <code>MenuItem</code> which desire to
427 * have the specified event types delivered to <code>processEvent</code>
428 * regardless of whether a listener is registered.
429 *
430 * @param eventsToEnable the event mask defining the event types
431 * @see java.awt.MenuItem#processEvent
432 * @see java.awt.MenuItem#disableEvents
433 * @see java.awt.Component#enableEvents
434 * @since JDK1.1
435 */
436 protected final void enableEvents(long eventsToEnable) {
437 eventMask |= eventsToEnable;
438 newEventsOnly = true;
439 }
440
441 /**
442 * Disables event delivery to this menu item for events
443 * defined by the specified event mask parameter.
444 *
445 * @param eventsToDisable the event mask defining the event types
446 * @see java.awt.MenuItem#processEvent
447 * @see java.awt.MenuItem#enableEvents
448 * @see java.awt.Component#disableEvents
449 * @since JDK1.1
450 */
451 protected final void disableEvents(long eventsToDisable) {
452 eventMask &= ~eventsToDisable;
453 }
454
455 /**
456 * Sets the command name of the action event that is fired
457 * by this menu item.
458 * <p>
459 * By default, the action command is set to the label of
460 * the menu item.
461 * @param command the action command to be set
462 * for this menu item.
463 * @see java.awt.MenuItem#getActionCommand
464 * @since JDK1.1
465 */
466 public void setActionCommand(String command) {
467 actionCommand = command;
468 }
469
470 /**
471 * Gets the command name of the action event that is fired
472 * by this menu item.
473 * @see java.awt.MenuItem#setActionCommand
474 * @since JDK1.1
475 */
476 public String getActionCommand() {
477 return getActionCommandImpl();
478 }
479
480 // This is final so it can be called on the Toolkit thread.
481 final String getActionCommandImpl() {
482 return (actionCommand == null ? label : actionCommand);
483 }
484
485 /**
486 * Adds the specified action listener to receive action events
487 * from this menu item.
488 * If l is null, no exception is thrown and no action is performed.
489 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
490 * >AWT Threading Issues</a> for details on AWT's threading model.
491 *
492 * @param l the action listener.
493 * @see #removeActionListener
494 * @see #getActionListeners
495 * @see java.awt.event.ActionEvent
496 * @see java.awt.event.ActionListener
497 * @since JDK1.1
498 */
499 public synchronized void addActionListener(ActionListener l) {
500 if (l == null) {
501 return;
502 }
503 actionListener = AWTEventMulticaster.add(actionListener, l);
504 newEventsOnly = true;
505 }
506
507 /**
508 * Removes the specified action listener so it no longer receives
509 * action events from this menu item.
510 * If l is null, no exception is thrown and no action is performed.
511 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
512 * >AWT Threading Issues</a> for details on AWT's threading model.
513 *
514 * @param l the action listener.
515 * @see #addActionListener
516 * @see #getActionListeners
517 * @see java.awt.event.ActionEvent
518 * @see java.awt.event.ActionListener
519 * @since JDK1.1
520 */
521 public synchronized void removeActionListener(ActionListener l) {
522 if (l == null) {
523 return;
524 }
525 actionListener = AWTEventMulticaster.remove(actionListener, l);
526 }
527
528 /**
529 * Returns an array of all the action listeners
530 * registered on this menu item.
531 *
532 * @return all of this menu item's <code>ActionListener</code>s
533 * or an empty array if no action
534 * listeners are currently registered
535 *
536 * @see #addActionListener
537 * @see #removeActionListener
538 * @see java.awt.event.ActionEvent
539 * @see java.awt.event.ActionListener
540 * @since 1.4
541 */
542 public synchronized ActionListener[] getActionListeners() {
543 return (ActionListener[]) (getListeners(ActionListener.class));
544 }
545
546 /**
547 * Returns an array of all the objects currently registered
548 * as <code><em>Foo</em>Listener</code>s
549 * upon this <code>MenuItem</code>.
550 * <code><em>Foo</em>Listener</code>s are registered using the
551 * <code>add<em>Foo</em>Listener</code> method.
552 *
553 * <p>
554 * You can specify the <code>listenerType</code> argument
555 * with a class literal, such as
556 * <code><em>Foo</em>Listener.class</code>.
557 * For example, you can query a
558 * <code>MenuItem</code> <code>m</code>
559 * for its action listeners with the following code:
560 *
561 * <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>
562 *
563 * If no such listeners exist, this method returns an empty array.
564 *
565 * @param listenerType the type of listeners requested; this parameter
566 * should specify an interface that descends from
567 * <code>java.util.EventListener</code>
568 * @return an array of all objects registered as
569 * <code><em>Foo</em>Listener</code>s on this menu item,
570 * or an empty array if no such
571 * listeners have been added
572 * @exception ClassCastException if <code>listenerType</code>
573 * doesn't specify a class or interface that implements
574 * <code>java.util.EventListener</code>
575 *
576 * @see #getActionListeners
577 * @since 1.3
578 */
579 public <T extends EventListener> T[] getListeners(
580 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 /* Serialization support.
668 */
669
670 /**
671 * Menu item serialized data version.
672 *
673 * @serial
674 */
675 private int menuItemSerializedDataVersion = 1;
676
677 /**
678 * Writes default serializable fields to stream. Writes
679 * a list of serializable <code>ActionListeners</code>
680 * as optional data. The non-serializable listeners are
681 * detected and no attempt is made to serialize them.
682 *
683 * @param s the <code>ObjectOutputStream</code> to write
684 * @serialData <code>null</code> terminated sequence of 0
685 * or more pairs; the pair consists of a <code>String</code>
686 * and an <code>Object</code>; the <code>String</code>
687 * indicates the type of object and is one of the following:
688 * <code>actionListenerK</code> indicating an
689 * <code>ActionListener</code> object
690 *
691 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
692 * @see #readObject(ObjectInputStream)
693 */
694 private void writeObject(ObjectOutputStream s) throws IOException {
695 s.defaultWriteObject();
696
697 AWTEventMulticaster.save(s, actionListenerK, actionListener);
698 s.writeObject(null);
699 }
700
701 /**
702 * Reads the <code>ObjectInputStream</code> and if it
703 * isn't <code>null</code> adds a listener to receive
704 * action events fired by the <code>Menu</code> Item.
705 * Unrecognized keys or values will be ignored.
706 *
707 * @param s the <code>ObjectInputStream</code> to read
708 * @exception HeadlessException if
709 * <code>GraphicsEnvironment.isHeadless</code> returns
710 * <code>true</code>
711 * @see #removeActionListener(ActionListener)
712 * @see #addActionListener(ActionListener)
713 * @see #writeObject(ObjectOutputStream)
714 */
715 private void readObject(ObjectInputStream s)
716 throws ClassNotFoundException, IOException,
717 HeadlessException {
718 // HeadlessException will be thrown from MenuComponent's readObject
719 s.defaultReadObject();
720
721 Object keyOrNull;
722 while (null != (keyOrNull = s.readObject())) {
723 String key = ((String) keyOrNull).intern();
724
725 if (actionListenerK == key)
726 addActionListener((ActionListener) (s.readObject()));
727
728 else
729 // skip value for unrecognized key
730 s.readObject();
731 }
732 }
733
734 /**
735 * Initialize JNI field and method IDs
736 */
737 private static native void initIDs();
738
739 /////////////////
740 // Accessibility support
741 ////////////////
742
743 /**
744 * Gets the AccessibleContext associated with this MenuItem.
745 * For menu items, the AccessibleContext takes the form of an
746 * AccessibleAWTMenuItem.
747 * A new AccessibleAWTMenuItem instance is created if necessary.
748 *
749 * @return an AccessibleAWTMenuItem that serves as the
750 * AccessibleContext of this MenuItem
751 * @since 1.3
752 */
753 public AccessibleContext getAccessibleContext() {
754 if (accessibleContext == null) {
755 accessibleContext = new AccessibleAWTMenuItem();
756 }
757 return accessibleContext;
758 }
759
760 /**
761 * Inner class of MenuItem used to provide default support for
762 * accessibility. This class is not meant to be used directly by
763 * application developers, but is instead meant only to be
764 * subclassed by menu component developers.
765 * <p>
766 * This class implements accessibility support for the
767 * <code>MenuItem</code> class. It provides an implementation of the
768 * Java Accessibility API appropriate to menu item user-interface elements.
769 * @since 1.3
770 */
771 protected class AccessibleAWTMenuItem extends
772 AccessibleAWTMenuComponent implements AccessibleAction,
773 AccessibleValue {
774 /*
775 * JDK 1.3 serialVersionUID
776 */
777 private static final long serialVersionUID = -217847831945965825L;
778
779 /**
780 * Get the accessible name of this object.
781 *
782 * @return the localized name of the object -- can be null if this
783 * object does not have a name
784 */
785 public String getAccessibleName() {
786 if (accessibleName != null) {
787 return accessibleName;
788 } else {
789 if (getLabel() == null) {
790 return super .getAccessibleName();
791 } else {
792 return getLabel();
793 }
794 }
795 }
796
797 /**
798 * Get the role of this object.
799 *
800 * @return an instance of AccessibleRole describing the role of the
801 * object
802 */
803 public AccessibleRole getAccessibleRole() {
804 return AccessibleRole.MENU_ITEM;
805 }
806
807 /**
808 * Get the AccessibleAction associated with this object. In the
809 * implementation of the Java Accessibility API for this class,
810 * return this object, which is responsible for implementing the
811 * AccessibleAction interface on behalf of itself.
812 *
813 * @return this object
814 */
815 public AccessibleAction getAccessibleAction() {
816 return this ;
817 }
818
819 /**
820 * Get the AccessibleValue associated with this object. In the
821 * implementation of the Java Accessibility API for this class,
822 * return this object, which is responsible for implementing the
823 * AccessibleValue interface on behalf of itself.
824 *
825 * @return this object
826 */
827 public AccessibleValue getAccessibleValue() {
828 return this ;
829 }
830
831 /**
832 * Returns the number of Actions available in this object. The
833 * default behavior of a menu item is to have one action.
834 *
835 * @return 1, the number of Actions in this object
836 */
837 public int getAccessibleActionCount() {
838 return 1;
839 }
840
841 /**
842 * Return a description of the specified action of the object.
843 *
844 * @param i zero-based index of the actions
845 */
846 public String getAccessibleActionDescription(int i) {
847 if (i == 0) {
848 // [[[PENDING: WDW -- need to provide a localized string]]]
849 return new String("click");
850 } else {
851 return null;
852 }
853 }
854
855 /**
856 * Perform the specified Action on the object
857 *
858 * @param i zero-based index of actions
859 * @return true if the action was performed; otherwise false.
860 */
861 public boolean doAccessibleAction(int i) {
862 if (i == 0) {
863 // Simulate a button click
864 Toolkit
865 .getEventQueue()
866 .postEvent(
867 new ActionEvent(
868 MenuItem.this ,
869 ActionEvent.ACTION_PERFORMED,
870 MenuItem.this
871 .getActionCommand(),
872 EventQueue
873 .getMostRecentEventTime(),
874 0));
875 return true;
876 } else {
877 return false;
878 }
879 }
880
881 /**
882 * Get the value of this object as a Number.
883 *
884 * @return An Integer of 0 if this isn't selected or an Integer of 1 if
885 * this is selected.
886 * @see javax.swing.AbstractButton#isSelected()
887 */
888 public Number getCurrentAccessibleValue() {
889 return Integer.valueOf(0);
890 }
891
892 /**
893 * Set the value of this object as a Number.
894 *
895 * @return True if the value was set.
896 */
897 public boolean setCurrentAccessibleValue(Number n) {
898 return false;
899 }
900
901 /**
902 * Get the minimum value of this object as a Number.
903 *
904 * @return An Integer of 0.
905 */
906 public Number getMinimumAccessibleValue() {
907 return Integer.valueOf(0);
908 }
909
910 /**
911 * Get the maximum value of this object as a Number.
912 *
913 * @return An Integer of 0.
914 */
915 public Number getMaximumAccessibleValue() {
916 return Integer.valueOf(0);
917 }
918
919 } // class AccessibleAWTMenuItem
920
921 }
|