blob: 899cab485ee17838d56a39e3687f0fd7893a5360 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package java.awt;
26
27import java.awt.peer.MenuItemPeer;
28import java.awt.event.*;
29import java.util.EventListener;
30import java.io.ObjectOutputStream;
31import java.io.ObjectInputStream;
32import java.io.IOException;
33import 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 */
71public 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.enable();
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.disable();
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 // Fix For 6185151: Menu shortcuts of all menuitems within a menu
402 // should be disabled when the menu itself is disabled
403 if (s.equals(shortcut) && isItemEnabled()) {
404 // MenuShortcut match -- issue an event on keydown.
405 if (e.getID() == KeyEvent.KEY_PRESSED) {
406 doMenuEvent(e.getWhen(), e.getModifiers());
407 } else {
408 // silently eat key release.
409 }
410 return true;
411 }
412 return false;
413 }
414
415 MenuItem getShortcutMenuItem(MenuShortcut s) {
416 return (s.equals(shortcut)) ? this : null;
417 }
418
419 /**
420 * Enables event delivery to this menu item for events
421 * to be defined by the specified event mask parameter
422 * <p>
423 * Since event types are automatically enabled when a listener for
424 * that type is added to the menu item, this method only needs
425 * to be invoked by subclasses of <code>MenuItem</code> which desire to
426 * have the specified event types delivered to <code>processEvent</code>
427 * regardless of whether a listener is registered.
428 *
429 * @param eventsToEnable the event mask defining the event types
430 * @see java.awt.MenuItem#processEvent
431 * @see java.awt.MenuItem#disableEvents
432 * @see java.awt.Component#enableEvents
433 * @since JDK1.1
434 */
435 protected final void enableEvents(long eventsToEnable) {
436 eventMask |= eventsToEnable;
437 newEventsOnly = true;
438 }
439
440 /**
441 * Disables event delivery to this menu item for events
442 * defined by the specified event mask parameter.
443 *
444 * @param eventsToDisable the event mask defining the event types
445 * @see java.awt.MenuItem#processEvent
446 * @see java.awt.MenuItem#enableEvents
447 * @see java.awt.Component#disableEvents
448 * @since JDK1.1
449 */
450 protected final void disableEvents(long eventsToDisable) {
451 eventMask &= ~eventsToDisable;
452 }
453
454 /**
455 * Sets the command name of the action event that is fired
456 * by this menu item.
457 * <p>
458 * By default, the action command is set to the label of
459 * the menu item.
460 * @param command the action command to be set
461 * for this menu item.
462 * @see java.awt.MenuItem#getActionCommand
463 * @since JDK1.1
464 */
465 public void setActionCommand(String command) {
466 actionCommand = command;
467 }
468
469 /**
470 * Gets the command name of the action event that is fired
471 * by this menu item.
472 * @see java.awt.MenuItem#setActionCommand
473 * @since JDK1.1
474 */
475 public String getActionCommand() {
476 return getActionCommandImpl();
477 }
478
479 // This is final so it can be called on the Toolkit thread.
480 final String getActionCommandImpl() {
481 return (actionCommand == null? label : actionCommand);
482 }
483
484 /**
485 * Adds the specified action listener to receive action events
486 * from this menu item.
487 * If l is null, no exception is thrown and no action is performed.
488 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
489 * >AWT Threading Issues</a> for details on AWT's threading model.
490 *
491 * @param l the action listener.
492 * @see #removeActionListener
493 * @see #getActionListeners
494 * @see java.awt.event.ActionEvent
495 * @see java.awt.event.ActionListener
496 * @since JDK1.1
497 */
498 public synchronized void addActionListener(ActionListener l) {
499 if (l == null) {
500 return;
501 }
502 actionListener = AWTEventMulticaster.add(actionListener, l);
503 newEventsOnly = true;
504 }
505
506 /**
507 * Removes the specified action listener so it no longer receives
508 * action events from this menu item.
509 * If l is null, no exception is thrown and no action is performed.
510 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
511 * >AWT Threading Issues</a> for details on AWT's threading model.
512 *
513 * @param l the action listener.
514 * @see #addActionListener
515 * @see #getActionListeners
516 * @see java.awt.event.ActionEvent
517 * @see java.awt.event.ActionListener
518 * @since JDK1.1
519 */
520 public synchronized void removeActionListener(ActionListener l) {
521 if (l == null) {
522 return;
523 }
524 actionListener = AWTEventMulticaster.remove(actionListener, l);
525 }
526
527 /**
528 * Returns an array of all the action listeners
529 * registered on this menu item.
530 *
531 * @return all of this menu item's <code>ActionListener</code>s
532 * or an empty array if no action
533 * listeners are currently registered
534 *
535 * @see #addActionListener
536 * @see #removeActionListener
537 * @see java.awt.event.ActionEvent
538 * @see java.awt.event.ActionListener
539 * @since 1.4
540 */
541 public synchronized ActionListener[] getActionListeners() {
542 return (ActionListener[])(getListeners(ActionListener.class));
543 }
544
545 /**
546 * Returns an array of all the objects currently registered
547 * as <code><em>Foo</em>Listener</code>s
548 * upon this <code>MenuItem</code>.
549 * <code><em>Foo</em>Listener</code>s are registered using the
550 * <code>add<em>Foo</em>Listener</code> method.
551 *
552 * <p>
553 * You can specify the <code>listenerType</code> argument
554 * with a class literal, such as
555 * <code><em>Foo</em>Listener.class</code>.
556 * For example, you can query a
557 * <code>MenuItem</code> <code>m</code>
558 * for its action listeners with the following code:
559 *
560 * <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>
561 *
562 * If no such listeners exist, this method returns an empty array.
563 *
564 * @param listenerType the type of listeners requested; this parameter
565 * should specify an interface that descends from
566 * <code>java.util.EventListener</code>
567 * @return an array of all objects registered as
568 * <code><em>Foo</em>Listener</code>s on this menu item,
569 * or an empty array if no such
570 * listeners have been added
571 * @exception ClassCastException if <code>listenerType</code>
572 * doesn't specify a class or interface that implements
573 * <code>java.util.EventListener</code>
574 *
575 * @see #getActionListeners
576 * @since 1.3
577 */
578 public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
579 EventListener l = null;
580 if (listenerType == ActionListener.class) {
581 l = actionListener;
582 }
583 return AWTEventMulticaster.getListeners(l, listenerType);
584 }
585
586 /**
587 * Processes events on this menu item. If the event is an
588 * instance of <code>ActionEvent</code>, it invokes
589 * <code>processActionEvent</code>, another method
590 * defined by <code>MenuItem</code>.
591 * <p>
592 * Currently, menu items only support action events.
593 * <p>Note that if the event parameter is <code>null</code>
594 * the behavior is unspecified and may result in an
595 * exception.
596 *
597 * @param e the event
598 * @see java.awt.MenuItem#processActionEvent
599 * @since JDK1.1
600 */
601 protected void processEvent(AWTEvent e) {
602 if (e instanceof ActionEvent) {
603 processActionEvent((ActionEvent)e);
604 }
605 }
606
607 // REMIND: remove when filtering is done at lower level
608 boolean eventEnabled(AWTEvent e) {
609 if (e.id == ActionEvent.ACTION_PERFORMED) {
610 if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
611 actionListener != null) {
612 return true;
613 }
614 return false;
615 }
616 return super.eventEnabled(e);
617 }
618
619 /**
620 * Processes action events occurring on this menu item,
621 * by dispatching them to any registered
622 * <code>ActionListener</code> objects.
623 * This method is not called unless action events are
624 * enabled for this component. Action events are enabled
625 * when one of the following occurs:
626 * <p><ul>
627 * <li>An <code>ActionListener</code> object is registered
628 * via <code>addActionListener</code>.
629 * <li>Action events are enabled via <code>enableEvents</code>.
630 * </ul>
631 * <p>Note that if the event parameter is <code>null</code>
632 * the behavior is unspecified and may result in an
633 * exception.
634 *
635 * @param e the action event
636 * @see java.awt.event.ActionEvent
637 * @see java.awt.event.ActionListener
638 * @see java.awt.MenuItem#enableEvents
639 * @since JDK1.1
640 */
641 protected void processActionEvent(ActionEvent e) {
642 ActionListener listener = actionListener;
643 if (listener != null) {
644 listener.actionPerformed(e);
645 }
646 }
647
648 /**
649 * Returns a string representing the state of this <code>MenuItem</code>.
650 * This method is intended to be used only for debugging purposes, and the
651 * content and format of the returned string may vary between
652 * implementations. The returned string may be empty but may not be
653 * <code>null</code>.
654 *
655 * @return the parameter string of this menu item
656 */
657 public String paramString() {
658 String str = ",label=" + label;
659 if (shortcut != null) {
660 str += ",shortcut=" + shortcut;
661 }
662 return super.paramString() + str;
663 }
664
665
666 /* Serialization support.
667 */
668
669 /**
670 * Menu item serialized data version.
671 *
672 * @serial
673 */
674 private int menuItemSerializedDataVersion = 1;
675
676 /**
677 * Writes default serializable fields to stream. Writes
678 * a list of serializable <code>ActionListeners</code>
679 * as optional data. The non-serializable listeners are
680 * detected and no attempt is made to serialize them.
681 *
682 * @param s the <code>ObjectOutputStream</code> to write
683 * @serialData <code>null</code> terminated sequence of 0
684 * or more pairs; the pair consists of a <code>String</code>
685 * and an <code>Object</code>; the <code>String</code>
686 * indicates the type of object and is one of the following:
687 * <code>actionListenerK</code> indicating an
688 * <code>ActionListener</code> object
689 *
690 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
691 * @see #readObject(ObjectInputStream)
692 */
693 private void writeObject(ObjectOutputStream s)
694 throws IOException
695 {
696 s.defaultWriteObject();
697
698 AWTEventMulticaster.save(s, actionListenerK, actionListener);
699 s.writeObject(null);
700 }
701
702 /**
703 * Reads the <code>ObjectInputStream</code> and if it
704 * isn't <code>null</code> adds a listener to receive
705 * action events fired by the <code>Menu</code> Item.
706 * Unrecognized keys or values will be ignored.
707 *
708 * @param s the <code>ObjectInputStream</code> to read
709 * @exception HeadlessException if
710 * <code>GraphicsEnvironment.isHeadless</code> returns
711 * <code>true</code>
712 * @see #removeActionListener(ActionListener)
713 * @see #addActionListener(ActionListener)
714 * @see #writeObject(ObjectOutputStream)
715 */
716 private void readObject(ObjectInputStream s)
717 throws ClassNotFoundException, IOException, HeadlessException
718 {
719 // HeadlessException will be thrown from MenuComponent's readObject
720 s.defaultReadObject();
721
722 Object keyOrNull;
723 while(null != (keyOrNull = s.readObject())) {
724 String key = ((String)keyOrNull).intern();
725
726 if (actionListenerK == key)
727 addActionListener((ActionListener)(s.readObject()));
728
729 else // 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/////////////////
741// Accessibility support
742////////////////
743
744 /**
745 * Gets the AccessibleContext associated with this MenuItem.
746 * For menu items, the AccessibleContext takes the form of an
747 * AccessibleAWTMenuItem.
748 * A new AccessibleAWTMenuItem instance is created if necessary.
749 *
750 * @return an AccessibleAWTMenuItem that serves as the
751 * AccessibleContext of this MenuItem
752 * @since 1.3
753 */
754 public AccessibleContext getAccessibleContext() {
755 if (accessibleContext == null) {
756 accessibleContext = new AccessibleAWTMenuItem();
757 }
758 return accessibleContext;
759 }
760
761 /**
762 * Inner class of MenuItem used to provide default support for
763 * accessibility. This class is not meant to be used directly by
764 * application developers, but is instead meant only to be
765 * subclassed by menu component developers.
766 * <p>
767 * This class implements accessibility support for the
768 * <code>MenuItem</code> class. It provides an implementation of the
769 * Java Accessibility API appropriate to menu item user-interface elements.
770 * @since 1.3
771 */
772 protected class AccessibleAWTMenuItem extends AccessibleAWTMenuComponent
773 implements AccessibleAction, AccessibleValue
774 {
775 /*
776 * JDK 1.3 serialVersionUID
777 */
778 private static final long serialVersionUID = -217847831945965825L;
779
780 /**
781 * Get the accessible name of this object.
782 *
783 * @return the localized name of the object -- can be null if this
784 * object does not have a name
785 */
786 public String getAccessibleName() {
787 if (accessibleName != null) {
788 return accessibleName;
789 } else {
790 if (getLabel() == null) {
791 return super.getAccessibleName();
792 } else {
793 return getLabel();
794 }
795 }
796 }
797
798 /**
799 * Get the role of this object.
800 *
801 * @return an instance of AccessibleRole describing the role of the
802 * object
803 */
804 public AccessibleRole getAccessibleRole() {
805 return AccessibleRole.MENU_ITEM;
806 }
807
808 /**
809 * Get the AccessibleAction associated with this object. In the
810 * implementation of the Java Accessibility API for this class,
811 * return this object, which is responsible for implementing the
812 * AccessibleAction interface on behalf of itself.
813 *
814 * @return this object
815 */
816 public AccessibleAction getAccessibleAction() {
817 return this;
818 }
819
820 /**
821 * Get the AccessibleValue associated with this object. In the
822 * implementation of the Java Accessibility API for this class,
823 * return this object, which is responsible for implementing the
824 * AccessibleValue interface on behalf of itself.
825 *
826 * @return this object
827 */
828 public AccessibleValue getAccessibleValue() {
829 return this;
830 }
831
832 /**
833 * Returns the number of Actions available in this object. The
834 * default behavior of a menu item is to have one action.
835 *
836 * @return 1, the number of Actions in this object
837 */
838 public int getAccessibleActionCount() {
839 return 1;
840 }
841
842 /**
843 * Return a description of the specified action of the object.
844 *
845 * @param i zero-based index of the actions
846 */
847 public String getAccessibleActionDescription(int i) {
848 if (i == 0) {
849 // [[[PENDING: WDW -- need to provide a localized string]]]
850 return new String("click");
851 } else {
852 return null;
853 }
854 }
855
856 /**
857 * Perform the specified Action on the object
858 *
859 * @param i zero-based index of actions
860 * @return true if the action was performed; otherwise false.
861 */
862 public boolean doAccessibleAction(int i) {
863 if (i == 0) {
864 // Simulate a button click
865 Toolkit.getEventQueue().postEvent(
866 new ActionEvent(MenuItem.this,
867 ActionEvent.ACTION_PERFORMED,
868 MenuItem.this.getActionCommand(),
869 EventQueue.getMostRecentEventTime(),
870 0));
871 return true;
872 } else {
873 return false;
874 }
875 }
876
877 /**
878 * Get the value of this object as a Number.
879 *
880 * @return An Integer of 0 if this isn't selected or an Integer of 1 if
881 * this is selected.
882 * @see javax.swing.AbstractButton#isSelected()
883 */
884 public Number getCurrentAccessibleValue() {
885 return Integer.valueOf(0);
886 }
887
888 /**
889 * Set the value of this object as a Number.
890 *
891 * @return True if the value was set.
892 */
893 public boolean setCurrentAccessibleValue(Number n) {
894 return false;
895 }
896
897 /**
898 * Get the minimum value of this object as a Number.
899 *
900 * @return An Integer of 0.
901 */
902 public Number getMinimumAccessibleValue() {
903 return Integer.valueOf(0);
904 }
905
906 /**
907 * Get the maximum value of this object as a Number.
908 *
909 * @return An Integer of 0.
910 */
911 public Number getMaximumAccessibleValue() {
912 return Integer.valueOf(0);
913 }
914
915 } // class AccessibleAWTMenuItem
916
917}