Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / JMenuItem.java
blob272c1cfe6ce8b9755ec6444be8fbdd63e2d62215
1 /* JMenuItem.java --
2 Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import gnu.classpath.NotImplementedException;
43 import java.awt.Component;
44 import java.awt.event.InputEvent;
45 import java.awt.event.KeyEvent;
46 import java.awt.event.MouseEvent;
47 import java.beans.PropertyChangeEvent;
48 import java.beans.PropertyChangeListener;
49 import java.util.EventListener;
51 import javax.accessibility.Accessible;
52 import javax.accessibility.AccessibleContext;
53 import javax.accessibility.AccessibleRole;
54 import javax.swing.event.ChangeEvent;
55 import javax.swing.event.ChangeListener;
56 import javax.swing.event.MenuDragMouseEvent;
57 import javax.swing.event.MenuDragMouseListener;
58 import javax.swing.event.MenuKeyEvent;
59 import javax.swing.event.MenuKeyListener;
60 import javax.swing.plaf.MenuItemUI;
62 /**
63 * JMenuItem represents element in the menu. It inherits most of
64 * its functionality from AbstractButton, however its behavior somewhat
65 * varies from it. JMenuItem fire different kinds of events.
66 * PropertyChangeEvents are fired when menuItems properties are modified;
67 * ChangeEvents are fired when menuItem's state changes and actionEvents are
68 * fired when menu item is selected. In addition to this events menuItem also
69 * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
70 * the menu item or associated key with menu item is invoked respectively.
72 public class JMenuItem extends AbstractButton implements Accessible,
73 MenuElement
75 private static final long serialVersionUID = -1681004643499461044L;
77 /** Combination of keyboard keys that can be used to activate this menu item */
78 private KeyStroke accelerator;
80 /**
81 * Creates a new JMenuItem object.
83 public JMenuItem()
85 super();
86 init(null, null);
89 /**
90 * Creates a new JMenuItem with the given icon.
92 * @param icon Icon that will be displayed on the menu item
94 public JMenuItem(Icon icon)
96 // FIXME: The requestedFocusEnabled property should
97 // be set to false, when only icon is set for menu item.
98 super();
99 init(null, icon);
103 * Creates a new JMenuItem with the given label.
105 * @param text label for the menu item
107 public JMenuItem(String text)
109 this(text, null);
113 * Creates a new JMenuItem associated with the specified action.
115 * @param action action for this menu item
117 public JMenuItem(Action action)
119 super();
120 super.setAction(action);
121 init(null, null);
122 if (action != null)
124 String name = (String) action.getValue(Action.NAME);
125 if (name != null)
126 setName(name);
128 KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
129 if (accel != null)
130 setAccelerator(accel);
132 Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY);
133 if (mnemonic != null)
134 setMnemonic(mnemonic.intValue());
136 String command = (String) action.getValue(Action.ACTION_COMMAND_KEY);
137 if (command != null)
138 setActionCommand(command);
143 * Creates a new JMenuItem with specified text and icon.
144 * Text is displayed to the left of icon by default.
146 * @param text label for this menu item
147 * @param icon icon that will be displayed on this menu item
149 public JMenuItem(String text, Icon icon)
151 super();
152 init(text, icon);
156 * Creates a new JMenuItem object.
158 * @param text label for this menu item
159 * @param mnemonic - Single key that can be used with a
160 * look-and-feel meta key to activate this menu item. However
161 * menu item should be visible on the screen when mnemonic is used.
163 public JMenuItem(String text, int mnemonic)
165 this(text, null);
166 setMnemonic(mnemonic);
170 * Initializes this menu item
172 * @param text label for this menu item
173 * @param icon icon to be displayed for this menu item
175 protected void init(String text, Icon icon)
177 super.init(text, icon);
178 setModel(new DefaultButtonModel());
180 // Initializes properties for this menu item, that are different
181 // from Abstract button properties.
182 /* NOTE: According to java specifications paint_border should be set to false,
183 since menu item should not have a border. However running few java programs
184 it seems that menu items and menues can have a border. Commenting
185 out statement below for now. */
186 //borderPainted = false;
187 focusPainted = false;
188 horizontalAlignment = JButton.LEFT;
189 horizontalTextPosition = JButton.TRAILING;
193 * Set the "UI" property of the menu item, which is a look and feel class
194 * responsible for handling menuItem's input events and painting it.
196 * @param ui The new "UI" property
198 public void setUI(MenuItemUI ui)
200 super.setUI(ui);
204 * This method sets this menuItem's UI to the UIManager's default for the
205 * current look and feel.
207 public void updateUI()
209 setUI((MenuItemUI) UIManager.getUI(this));
213 * This method returns a name to identify which look and feel class will be
214 * the UI delegate for the menuItem.
216 * @return The Look and Feel classID. "MenuItemUI"
218 public String getUIClassID()
220 return "MenuItemUI";
224 * Returns true if button's model is armed and false otherwise. The
225 * button model is armed if menu item has focus or it is selected.
227 * @return $boolean$ true if button's model is armed and false otherwise
229 public boolean isArmed()
231 return getModel().isArmed();
235 * Sets menuItem's "ARMED" property
237 * @param armed DOCUMENT ME!
239 public void setArmed(boolean armed)
241 getModel().setArmed(armed);
245 * Enable or disable menu item. When menu item is disabled,
246 * its text and icon are grayed out if they exist.
248 * @param enabled if true enable menu item, and disable otherwise.
250 public void setEnabled(boolean enabled)
252 super.setEnabled(enabled);
256 * Return accelerator for this menu item.
258 * @return $KeyStroke$ accelerator for this menu item.
260 public KeyStroke getAccelerator()
262 return accelerator;
266 * Sets the key combination which invokes the menu item's action
267 * listeners without navigating the menu hierarchy. Note that when the
268 * keyboard accelerator is typed, it will work whether or not the
269 * menu is currently displayed.
271 * @param keystroke accelerator for this menu item.
273 public void setAccelerator(KeyStroke keystroke)
275 KeyStroke old = this.accelerator;
276 this.accelerator = keystroke;
277 firePropertyChange ("accelerator", old, keystroke);
281 * Configures menu items' properties from properties of the specified action.
282 * This method overrides configurePropertiesFromAction from AbstractButton
283 * to also set accelerator property.
285 * @param action action to configure properties from
287 protected void configurePropertiesFromAction(Action action)
289 super.configurePropertiesFromAction(action);
291 if (! (this instanceof JMenu) && action != null)
293 setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
294 if (accelerator != null)
295 super.registerKeyboardAction(action, accelerator,
296 JComponent.WHEN_IN_FOCUSED_WINDOW);
301 * Creates PropertyChangeListener to listen for the changes in action
302 * properties.
304 * @param action action to listen to for property changes
306 * @return $PropertyChangeListener$ Listener that listens to changes in
307 * action properties.
309 protected PropertyChangeListener createActionPropertyChangeListener(Action action)
311 return new PropertyChangeListener()
313 public void propertyChange(PropertyChangeEvent e)
315 Action act = (Action) (e.getSource());
316 configurePropertiesFromAction(act);
322 * Process mouse events forwarded from MenuSelectionManager.
324 * @param event event forwarded from MenuSelectionManager
325 * @param path path to the menu element from which event was generated
326 * @param manager MenuSelectionManager for the current menu hierarchy
328 public void processMouseEvent(MouseEvent event, MenuElement[] path,
329 MenuSelectionManager manager)
331 // Fire MenuDragMouseEvents if mouse is being dragged.
332 boolean dragged
333 = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0;
334 if (dragged)
335 processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager));
337 switch (event.getID())
339 case MouseEvent.MOUSE_CLICKED:
340 break;
341 case MouseEvent.MOUSE_ENTERED:
342 if (isRolloverEnabled())
343 model.setRollover(true);
344 break;
345 case MouseEvent.MOUSE_EXITED:
346 if (isRolloverEnabled())
347 model.setRollover(false);
349 // for JMenu last element on the path is its popupMenu.
350 // JMenu shouldn't me disarmed.
351 if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged)
352 setArmed(false);
353 break;
354 case MouseEvent.MOUSE_PRESSED:
355 if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
357 model.setArmed(true);
358 model.setPressed(true);
360 break;
361 case MouseEvent.MOUSE_RELEASED:
362 break;
363 case MouseEvent.MOUSE_MOVED:
364 break;
365 case MouseEvent.MOUSE_DRAGGED:
366 break;
371 * Creates MenuDragMouseEvent.
373 * @param event MouseEvent that occured while mouse was pressed.
374 * @param path Path the the menu element where the dragging event was
375 * originated
376 * @param manager MenuSelectionManager for the current menu hierarchy.
378 * @return new MenuDragMouseEvent
380 private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event,
381 MenuElement[] path,
382 MenuSelectionManager manager)
384 return new MenuDragMouseEvent((Component) event.getSource(),
385 event.getID(), event.getWhen(),
386 event.getModifiers(), event.getX(),
387 event.getY(), event.getClickCount(),
388 event.isPopupTrigger(), path, manager);
392 * Process key events forwarded from MenuSelectionManager.
394 * @param event event forwarded from MenuSelectionManager
395 * @param path path to the menu element from which event was generated
396 * @param manager MenuSelectionManager for the current menu hierarchy
398 public void processKeyEvent(KeyEvent event, MenuElement[] path,
399 MenuSelectionManager manager)
401 MenuKeyEvent e = new MenuKeyEvent(event.getComponent(), event.getID(),
402 event.getWhen(), event.getModifiers(),
403 event.getKeyCode(), event.getKeyChar(),
404 path, manager);
405 processMenuKeyEvent(e);
407 // Consume original key event, if the menu key event has been consumed.
408 if (e.isConsumed())
409 event.consume();
413 * This method fires MenuDragMouseEvents to registered listeners.
414 * Different types of MenuDragMouseEvents are fired depending
415 * on the observed mouse event.
417 * @param event Mouse
419 public void processMenuDragMouseEvent(MenuDragMouseEvent event)
421 switch (event.getID())
423 case MouseEvent.MOUSE_ENTERED:
424 fireMenuDragMouseEntered(event);
425 break;
426 case MouseEvent.MOUSE_EXITED:
427 fireMenuDragMouseExited(event);
428 break;
429 case MouseEvent.MOUSE_DRAGGED:
430 fireMenuDragMouseDragged(event);
431 break;
432 case MouseEvent.MOUSE_RELEASED:
433 fireMenuDragMouseReleased(event);
434 break;
439 * This method fires MenuKeyEvent to registered listeners.
440 * Different types of MenuKeyEvents are fired depending
441 * on the observed key event.
443 * @param event DOCUMENT ME!
445 public void processMenuKeyEvent(MenuKeyEvent event)
447 switch (event.getID())
449 case KeyEvent.KEY_PRESSED:
450 fireMenuKeyPressed(event);
451 break;
452 case KeyEvent.KEY_RELEASED:
453 fireMenuKeyReleased(event);
454 break;
455 case KeyEvent.KEY_TYPED:
456 fireMenuKeyTyped(event);
457 break;
458 default:
459 break;
464 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
466 * @param event The event signifying that mouse entered menuItem while it was dragged
468 protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
470 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
472 for (int i = 0; i < ll.length; i++)
473 ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
477 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
479 * @param event The event signifying that mouse has exited menu item, while it was dragged
481 protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
483 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
485 for (int i = 0; i < ll.length; i++)
486 ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
490 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
492 * @param event The event signifying that mouse is being dragged over the menuItem
494 protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
496 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
498 for (int i = 0; i < ll.length; i++)
499 ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
503 * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
505 * @param event The event signifying that mouse was released while it was dragged over the menuItem
507 protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
509 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
511 for (int i = 0; i < ll.length; i++)
512 ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
516 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
518 * @param event The event signifying that key associated with this menu was pressed
520 protected void fireMenuKeyPressed(MenuKeyEvent event)
522 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
524 for (int i = 0; i < ll.length; i++)
525 ((MenuKeyListener) ll[i]).menuKeyPressed(event);
529 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
531 * @param event The event signifying that key associated with this menu was released
533 protected void fireMenuKeyReleased(MenuKeyEvent event)
535 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
537 for (int i = 0; i < ll.length; i++)
538 ((MenuKeyListener) ll[i]).menuKeyTyped(event);
542 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
544 * @param event The event signifying that key associated with this menu was typed.
545 * The key is typed when it was pressed and then released
547 protected void fireMenuKeyTyped(MenuKeyEvent event)
549 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
551 for (int i = 0; i < ll.length; i++)
552 ((MenuKeyListener) ll[i]).menuKeyTyped(event);
556 * Method of the MenuElement interface.
557 * This method is invoked by MenuSelectionManager when selection of
558 * this menu item has changed. If this menu item was selected then
559 * arm it's model, and disarm the model otherwise. The menu item
560 * is considered to be selected, and thus highlighted when its model
561 * is armed.
563 * @param changed indicates selection status of this menu item. If changed is
564 * true then menu item is selected and deselected otherwise.
566 public void menuSelectionChanged(boolean changed)
568 Component parent = this.getParent();
569 if (changed)
571 model.setArmed(true);
573 if (parent != null && parent instanceof JPopupMenu)
574 ((JPopupMenu) parent).setSelected(this);
576 else
578 model.setArmed(false);
580 if (parent != null && parent instanceof JPopupMenu)
581 ((JPopupMenu) parent).getSelectionModel().clearSelection();
586 * Method of the MenuElement interface.
588 * @return $MenuElement[]$ Returns array of sub-components for this menu
589 * item. By default menuItem doesn't have any subcomponents and so
590 * empty array is returned instead.
592 public MenuElement[] getSubElements()
594 return new MenuElement[0];
598 * Returns reference to the component that will paint this menu item.
600 * @return $Component$ Component that will paint this menu item.
601 * Simply returns reference to this menu item.
603 public Component getComponent()
605 return this;
609 * Adds a MenuDragMouseListener to this menu item. When mouse
610 * is dragged over the menu item the MenuDragMouseEvents will be
611 * fired, and these listeners will be called.
613 * @param listener The new listener to add
615 public void addMenuDragMouseListener(MenuDragMouseListener listener)
617 listenerList.add(MenuDragMouseListener.class, listener);
621 * Removes a MenuDragMouseListener from the menuItem's listener list.
623 * @param listener The listener to remove
625 public void removeMenuDragMouseListener(MenuDragMouseListener listener)
627 listenerList.remove(MenuDragMouseListener.class, listener);
631 * Returns all added MenuDragMouseListener objects.
633 * @return an array of listeners
635 * @since 1.4
637 public MenuDragMouseListener[] getMenuDragMouseListeners()
639 return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
643 * Adds an MenuKeyListener to this menu item. This listener will be
644 * invoked when MenuKeyEvents will be fired by this menu item.
646 * @param listener The new listener to add
648 public void addMenuKeyListener(MenuKeyListener listener)
650 listenerList.add(MenuKeyListener.class, listener);
654 * Removes an MenuKeyListener from the menuItem's listener list.
656 * @param listener The listener to remove
658 public void removeMenuKeyListener(MenuKeyListener listener)
660 listenerList.remove(MenuKeyListener.class, listener);
664 * Returns all added MenuKeyListener objects.
666 * @return an array of listeners
668 * @since 1.4
670 public MenuKeyListener[] getMenuKeyListeners()
672 return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
676 * Returns a string describing the attributes for the <code>JToolTip</code>
677 * component, for use in debugging. The return value is guaranteed to be
678 * non-<code>null</code>, but the format of the string may vary between
679 * implementations.
681 * @return A string describing the attributes of the <code>JMenuItem</code>.
683 protected String paramString()
685 // calling super seems to be sufficient here...
686 return super.paramString();
690 * Returns the object that provides accessibility features for this
691 * <code>JMenuItem</code> component.
693 * @return The accessible context (an instance of
694 * {@link AccessibleJMenuItem}).
696 public AccessibleContext getAccessibleContext()
698 if (accessibleContext == null)
699 accessibleContext = new AccessibleJMenuItem();
701 return accessibleContext;
705 * Provides the accessibility features for the <code>JMenuItem</code>
706 * component.
708 * @see JMenuItem#getAccessibleContext()
710 protected class AccessibleJMenuItem extends AccessibleAbstractButton
711 implements ChangeListener
713 private static final long serialVersionUID = 6748924232082076534L;
716 * Creates a new <code>AccessibleJMenuItem</code> instance.
718 AccessibleJMenuItem()
720 //super(component);
723 public void stateChanged(ChangeEvent event)
724 throws NotImplementedException
726 // TODO: What should be done here, if anything?
730 * Returns the accessible role for the <code>JMenuItem</code> component.
732 * @return {@link AccessibleRole#MENU_ITEM}.
734 public AccessibleRole getAccessibleRole()
736 return AccessibleRole.MENU_ITEM;