Merge from the pain train
[official-gcc.git] / libjava / javax / swing / JMenuItem.java
blob0ea38e0f7ba1f57e65bc3c0af2110e189408720e
1 /* JMenuItem.java --
2 Copyright (C) 2002, 2004, 2005 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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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 java.awt.Component;
42 import java.awt.event.InputEvent;
43 import java.awt.event.KeyEvent;
44 import java.awt.event.MouseEvent;
45 import java.beans.PropertyChangeEvent;
46 import java.beans.PropertyChangeListener;
47 import java.io.IOException;
48 import java.io.ObjectInputStream;
49 import java.io.ObjectOutputStream;
50 import java.util.EventListener;
52 import javax.accessibility.Accessible;
53 import javax.accessibility.AccessibleContext;
54 import javax.accessibility.AccessibleRole;
55 import javax.swing.event.ChangeEvent;
56 import javax.swing.event.ChangeListener;
57 import javax.swing.event.MenuDragMouseEvent;
58 import javax.swing.event.MenuDragMouseListener;
59 import javax.swing.event.MenuKeyEvent;
60 import javax.swing.event.MenuKeyListener;
61 import javax.swing.plaf.MenuItemUI;
63 /**
64 * JMenuItem represents element in the menu. It inherits most of
65 * its functionality from AbstractButton, however its behavior somewhat
66 * varies from it. JMenuItem fire different kinds of events.
67 * PropertyChangeEvents are fired when menuItems properties are modified;
68 * ChangeEvents are fired when menuItem's state changes and actionEvents are
69 * fired when menu item is selected. In addition to this events menuItem also
70 * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over
71 * the menu item or associated key with menu item is invoked respectively.
73 public class JMenuItem extends AbstractButton implements Accessible,
74 MenuElement
76 private static final long serialVersionUID = -1681004643499461044L;
78 /** Combination of keyboard keys that can be used to activate this menu item */
79 private KeyStroke accelerator;
81 /**
82 * Creates a new JMenuItem object.
84 public JMenuItem()
86 super(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(null, icon);
102 * Creates a new JMenuItem with the given label.
104 * @param text label for the menu item
106 public JMenuItem(String text)
108 super(text, null);
112 * Creates a new JMenuItem associated with the specified action.
114 * @param action action for this menu item
116 public JMenuItem(Action action)
118 super(null, null);
119 super.setAction(action);
123 * Creates a new JMenuItem with specified text and icon.
124 * Text is displayed to the left of icon by default.
126 * @param text label for this menu item
127 * @param icon icon that will be displayed on this menu item
129 public JMenuItem(String text, Icon icon)
131 super(text, icon);
135 * Creates a new JMenuItem object.
137 * @param text label for this menu item
138 * @param mnemonic - Single key that can be used with a
139 * look-and-feel meta key to activate this menu item. However
140 * menu item should be visible on the screen when mnemonic is used.
142 public JMenuItem(String text, int mnemonic)
144 super(text, null);
145 setMnemonic(mnemonic);
148 private void readObject(ObjectInputStream stream)
149 throws IOException, ClassNotFoundException
153 private void writeObject(ObjectOutputStream stream) throws IOException
158 * Initializes this menu item
160 * @param text label for this menu item
161 * @param icon icon to be displayed for this menu item
163 protected void init(String text, Icon icon)
165 super.init(text, icon);
167 // Initializes properties for this menu item, that are different
168 // from Abstract button properties.
169 /* NOTE: According to java specifications paint_border should be set to false,
170 since menu item should not have a border. However running few java programs
171 it seems that menu items and menues can have a border. Commenting
172 out statement below for now. */
173 //borderPainted = false;
174 focusPainted = false;
175 horizontalAlignment = JButton.LEFT;
176 horizontalTextPosition = JButton.LEFT;
180 * Set the "UI" property of the menu item, which is a look and feel class
181 * responsible for handling menuItem's input events and painting it.
183 * @param ui The new "UI" property
185 public void setUI(MenuItemUI ui)
187 super.setUI(ui);
191 * This method sets this menuItem's UI to the UIManager's default for the
192 * current look and feel.
194 public void updateUI()
196 MenuItemUI mi = ((MenuItemUI) UIManager.getUI(this));
197 setUI(mi);
198 invalidate();
202 * This method returns a name to identify which look and feel class will be
203 * the UI delegate for the menuItem.
205 * @return The Look and Feel classID. "MenuItemUI"
207 public String getUIClassID()
209 return "MenuItemUI";
213 * Returns true if button's model is armed and false otherwise. The
214 * button model is armed if menu item has focus or it is selected.
216 * @return $boolean$ true if button's model is armed and false otherwise
218 public boolean isArmed()
220 return getModel().isArmed();
224 * Sets menuItem's "ARMED" property
226 * @param armed DOCUMENT ME!
228 public void setArmed(boolean armed)
230 getModel().setArmed(armed);
234 * Enable or disable menu item. When menu item is disabled,
235 * its text and icon are grayed out if they exist.
237 * @param enabled if true enable menu item, and disable otherwise.
239 public void setEnabled(boolean enabled)
241 super.setEnabled(enabled);
245 * Return accelerator for this menu item.
247 * @return $KeyStroke$ accelerator for this menu item.
249 public KeyStroke getAccelerator()
251 return accelerator;
255 * Sets accelerator for this menu item.
257 * @param keystroke accelerator for this menu item.
259 public void setAccelerator(KeyStroke keystroke)
261 this.accelerator = keystroke;
265 * Configures menu items' properties from properties of the specified action.
266 * This method overrides configurePropertiesFromAction from AbstractButton
267 * to also set accelerator property.
269 * @param action action to configure properties from
271 protected void configurePropertiesFromAction(Action action)
273 super.configurePropertiesFromAction(action);
275 if (! (this instanceof JMenu) && action != null)
276 setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
280 * Creates PropertyChangeListener to listen for the changes in action
281 * properties.
283 * @param action action to listen to for property changes
285 * @return $PropertyChangeListener$ Listener that listens to changes in
286 * action properties.
288 protected PropertyChangeListener createActionPropertyChangeListener(Action action)
290 return new PropertyChangeListener()
292 public void propertyChange(PropertyChangeEvent e)
294 Action act = (Action) (e.getSource());
295 configurePropertiesFromAction(act);
301 * Process mouse events forwarded from MenuSelectionManager.
303 * @param event event forwarded from MenuSelectionManager
304 * @param path path to the menu element from which event was generated
305 * @param manager MenuSelectionManager for the current menu hierarchy
307 public void processMouseEvent(MouseEvent event, MenuElement[] path,
308 MenuSelectionManager manager)
310 // Fire MenuDragMouseEvents if mouse is being dragged.
311 boolean dragged
312 = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0;
313 if (dragged)
314 processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager));
316 switch (event.getID())
318 case MouseEvent.MOUSE_CLICKED:
319 break;
320 case MouseEvent.MOUSE_ENTERED:
321 if (isRolloverEnabled())
322 model.setRollover(true);
323 break;
324 case MouseEvent.MOUSE_EXITED:
325 if (isRolloverEnabled())
326 model.setRollover(false);
328 // for JMenu last element on the path is its popupMenu.
329 // JMenu shouldn't me disarmed.
330 if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged)
331 setArmed(false);
332 break;
333 case MouseEvent.MOUSE_PRESSED:
334 if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0)
336 model.setArmed(true);
337 model.setPressed(true);
339 break;
340 case MouseEvent.MOUSE_RELEASED:
341 break;
342 case MouseEvent.MOUSE_MOVED:
343 break;
344 case MouseEvent.MOUSE_DRAGGED:
345 break;
350 * Creates MenuDragMouseEvent.
352 * @param event MouseEvent that occured while mouse was pressed.
353 * @param path Path the the menu element where the dragging event was
354 * originated
355 * @param manager MenuSelectionManager for the current menu hierarchy.
357 * @return new MenuDragMouseEvent
359 private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event,
360 MenuElement[] path,
361 MenuSelectionManager manager)
363 return new MenuDragMouseEvent((Component) event.getSource(),
364 event.getID(), event.getWhen(),
365 event.getModifiers(), event.getX(),
366 event.getY(), event.getClickCount(),
367 event.isPopupTrigger(), path, manager);
371 * Process key events forwarded from MenuSelectionManager.
373 * @param event event forwarded from MenuSelectionManager
374 * @param path path to the menu element from which event was generated
375 * @param manager MenuSelectionManager for the current menu hierarchy
377 public void processKeyEvent(KeyEvent event, MenuElement[] path,
378 MenuSelectionManager manager)
380 // Need to implement.
384 * This method fires MenuDragMouseEvents to registered listeners.
385 * Different types of MenuDragMouseEvents are fired depending
386 * on the observed mouse event.
388 * @param event Mouse
390 public void processMenuDragMouseEvent(MenuDragMouseEvent event)
392 switch (event.getID())
394 case MouseEvent.MOUSE_ENTERED:
395 fireMenuDragMouseEntered(event);
396 break;
397 case MouseEvent.MOUSE_EXITED:
398 fireMenuDragMouseExited(event);
399 break;
400 case MouseEvent.MOUSE_DRAGGED:
401 fireMenuDragMouseDragged(event);
402 break;
403 case MouseEvent.MOUSE_RELEASED:
404 fireMenuDragMouseReleased(event);
405 break;
410 * This method fires MenuKeyEvent to registered listeners.
411 * Different types of MenuKeyEvents are fired depending
412 * on the observed key event.
414 * @param event DOCUMENT ME!
416 public void processMenuKeyEvent(MenuKeyEvent event)
418 // Need to implement.
422 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
424 * @param event The event signifying that mouse entered menuItem while it was dragged
426 protected void fireMenuDragMouseEntered(MenuDragMouseEvent event)
428 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
430 for (int i = 0; i < ll.length; i++)
431 ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event);
435 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
437 * @param event The event signifying that mouse has exited menu item, while it was dragged
439 protected void fireMenuDragMouseExited(MenuDragMouseEvent event)
441 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
443 for (int i = 0; i < ll.length; i++)
444 ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event);
448 * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners.
450 * @param event The event signifying that mouse is being dragged over the menuItem
452 protected void fireMenuDragMouseDragged(MenuDragMouseEvent event)
454 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
456 for (int i = 0; i < ll.length; i++)
457 ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event);
461 * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners.
463 * @param event The event signifying that mouse was released while it was dragged over the menuItem
465 protected void fireMenuDragMouseReleased(MenuDragMouseEvent event)
467 EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class);
469 for (int i = 0; i < ll.length; i++)
470 ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event);
474 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
476 * @param event The event signifying that key associated with this menu was pressed
478 protected void fireMenuKeyPressed(MenuKeyEvent event)
480 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
482 for (int i = 0; i < ll.length; i++)
483 ((MenuKeyListener) ll[i]).menuKeyPressed(event);
487 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
489 * @param event The event signifying that key associated with this menu was released
491 protected void fireMenuKeyReleased(MenuKeyEvent event)
493 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
495 for (int i = 0; i < ll.length; i++)
496 ((MenuKeyListener) ll[i]).menuKeyTyped(event);
500 * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners.
502 * @param event The event signifying that key associated with this menu was typed.
503 * The key is typed when it was pressed and then released
505 protected void fireMenuKeyTyped(MenuKeyEvent event)
507 EventListener[] ll = listenerList.getListeners(MenuKeyListener.class);
509 for (int i = 0; i < ll.length; i++)
510 ((MenuKeyListener) ll[i]).menuKeyTyped(event);
514 * Method of the MenuElement interface.
515 * This method is invoked by MenuSelectionManager when selection of
516 * this menu item has changed. If this menu item was selected then
517 * arm it's model, and disarm the model otherwise. The menu item
518 * is considered to be selected, and thus highlighted when its model
519 * is armed.
521 * @param changed indicates selection status of this menu item. If changed is
522 * true then menu item is selected and deselected otherwise.
524 public void menuSelectionChanged(boolean changed)
526 Component parent = this.getParent();
527 if (changed)
529 model.setArmed(true);
531 if (parent != null && parent instanceof JPopupMenu)
532 ((JPopupMenu) parent).setSelected(this);
534 else
536 model.setArmed(false);
538 if (parent != null && parent instanceof JPopupMenu)
539 ((JPopupMenu) parent).getSelectionModel().clearSelection();
544 * Method of the MenuElement interface.
546 * @return $MenuElement[]$ Returns array of sub-components for this menu
547 * item. By default menuItem doesn't have any subcomponents and so
548 * empty array is returned instead.
550 public MenuElement[] getSubElements()
552 return new MenuElement[0];
556 * Returns reference to the component that will paint this menu item.
558 * @return $Component$ Component that will paint this menu item.
559 * Simply returns reference to this menu item.
561 public Component getComponent()
563 return this;
567 * Adds a MenuDragMouseListener to this menu item. When mouse
568 * is dragged over the menu item the MenuDragMouseEvents will be
569 * fired, and these listeners will be called.
571 * @param listener The new listener to add
573 public void addMenuDragMouseListener(MenuDragMouseListener listener)
575 listenerList.add(MenuDragMouseListener.class, listener);
579 * Removes a MenuDragMouseListener from the menuItem's listener list.
581 * @param listener The listener to remove
583 public void removeMenuDragMouseListener(MenuDragMouseListener listener)
585 listenerList.remove(MenuDragMouseListener.class, listener);
589 * Returns all added MenuDragMouseListener objects.
591 * @return an array of listeners
593 * @since 1.4
595 public MenuDragMouseListener[] getMenuDragMouseListeners()
597 return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class);
601 * Adds an MenuKeyListener to this menu item. This listener will be
602 * invoked when MenuKeyEvents will be fired by this menu item.
604 * @param listener The new listener to add
606 public void addMenuKeyListener(MenuKeyListener listener)
608 listenerList.add(MenuKeyListener.class, listener);
612 * Removes an MenuKeyListener from the menuItem's listener list.
614 * @param listener The listener to remove
616 public void removeMenuKeyListener(MenuKeyListener listener)
618 listenerList.remove(MenuKeyListener.class, listener);
622 * Returns all added MenuKeyListener objects.
624 * @return an array of listeners
626 * @since 1.4
628 public MenuKeyListener[] getMenuKeyListeners()
630 return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class);
634 * A string that describes this JMenuItem. Normally only used
635 * for debugging.
637 * @return A string describing this JMenuItem
639 protected String paramString()
641 return super.paramString();
644 public AccessibleContext getAccessibleContext()
646 if (accessibleContext == null)
647 accessibleContext = new AccessibleJMenuItem();
649 return accessibleContext;
652 protected class AccessibleJMenuItem extends AccessibleAbstractButton
653 implements ChangeListener
655 private static final long serialVersionUID = 6748924232082076534L;
658 * Creates a new AccessibleJMenuItem object.
660 AccessibleJMenuItem()
662 //super(component);
665 public void stateChanged(ChangeEvent event)
669 public AccessibleRole getAccessibleRole()
671 return AccessibleRole.MENU_ITEM;