| /* JMenuItem.java -- |
| Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing; |
| |
| import java.awt.Component; |
| import java.awt.event.InputEvent; |
| import java.awt.event.KeyEvent; |
| import java.awt.event.MouseEvent; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.util.EventListener; |
| |
| import javax.accessibility.Accessible; |
| import javax.accessibility.AccessibleContext; |
| import javax.accessibility.AccessibleRole; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.event.MenuDragMouseEvent; |
| import javax.swing.event.MenuDragMouseListener; |
| import javax.swing.event.MenuKeyEvent; |
| import javax.swing.event.MenuKeyListener; |
| import javax.swing.plaf.MenuItemUI; |
| |
| /** |
| * JMenuItem represents element in the menu. It inherits most of |
| * its functionality from AbstractButton, however its behavior somewhat |
| * varies from it. JMenuItem fire different kinds of events. |
| * PropertyChangeEvents are fired when menuItems properties are modified; |
| * ChangeEvents are fired when menuItem's state changes and actionEvents are |
| * fired when menu item is selected. In addition to this events menuItem also |
| * fire MenuDragMouseEvent and MenuKeyEvents when mouse is dragged over |
| * the menu item or associated key with menu item is invoked respectively. |
| */ |
| public class JMenuItem extends AbstractButton implements Accessible, |
| MenuElement |
| { |
| private static final long serialVersionUID = -1681004643499461044L; |
| |
| /** Combination of keyboard keys that can be used to activate this menu item */ |
| private KeyStroke accelerator; |
| |
| /** |
| * Creates a new JMenuItem object. |
| */ |
| public JMenuItem() |
| { |
| super(null, null); |
| } |
| |
| /** |
| * Creates a new JMenuItem with the given icon. |
| * |
| * @param icon Icon that will be displayed on the menu item |
| */ |
| public JMenuItem(Icon icon) |
| { |
| // FIXME: The requestedFocusEnabled property should |
| // be set to false, when only icon is set for menu item. |
| super(null, icon); |
| } |
| |
| /** |
| * Creates a new JMenuItem with the given label. |
| * |
| * @param text label for the menu item |
| */ |
| public JMenuItem(String text) |
| { |
| super(text, null); |
| } |
| |
| /** |
| * Creates a new JMenuItem associated with the specified action. |
| * |
| * @param action action for this menu item |
| */ |
| public JMenuItem(Action action) |
| { |
| super(null, null); |
| super.setAction(action); |
| } |
| |
| /** |
| * Creates a new JMenuItem with specified text and icon. |
| * Text is displayed to the left of icon by default. |
| * |
| * @param text label for this menu item |
| * @param icon icon that will be displayed on this menu item |
| */ |
| public JMenuItem(String text, Icon icon) |
| { |
| super(text, icon); |
| } |
| |
| /** |
| * Creates a new JMenuItem object. |
| * |
| * @param text label for this menu item |
| * @param mnemonic - Single key that can be used with a |
| * look-and-feel meta key to activate this menu item. However |
| * menu item should be visible on the screen when mnemonic is used. |
| */ |
| public JMenuItem(String text, int mnemonic) |
| { |
| super(text, null); |
| setMnemonic(mnemonic); |
| } |
| |
| private void readObject(ObjectInputStream stream) |
| throws IOException, ClassNotFoundException |
| { |
| } |
| |
| private void writeObject(ObjectOutputStream stream) throws IOException |
| { |
| } |
| |
| /** |
| * Initializes this menu item |
| * |
| * @param text label for this menu item |
| * @param icon icon to be displayed for this menu item |
| */ |
| protected void init(String text, Icon icon) |
| { |
| super.init(text, icon); |
| |
| // Initializes properties for this menu item, that are different |
| // from Abstract button properties. |
| /* NOTE: According to java specifications paint_border should be set to false, |
| since menu item should not have a border. However running few java programs |
| it seems that menu items and menues can have a border. Commenting |
| out statement below for now. */ |
| //borderPainted = false; |
| focusPainted = false; |
| horizontalAlignment = JButton.LEFT; |
| horizontalTextPosition = JButton.LEFT; |
| } |
| |
| /** |
| * Set the "UI" property of the menu item, which is a look and feel class |
| * responsible for handling menuItem's input events and painting it. |
| * |
| * @param ui The new "UI" property |
| */ |
| public void setUI(MenuItemUI ui) |
| { |
| super.setUI(ui); |
| } |
| |
| /** |
| * This method sets this menuItem's UI to the UIManager's default for the |
| * current look and feel. |
| */ |
| public void updateUI() |
| { |
| MenuItemUI mi = ((MenuItemUI) UIManager.getUI(this)); |
| setUI(mi); |
| invalidate(); |
| } |
| |
| /** |
| * This method returns a name to identify which look and feel class will be |
| * the UI delegate for the menuItem. |
| * |
| * @return The Look and Feel classID. "MenuItemUI" |
| */ |
| public String getUIClassID() |
| { |
| return "MenuItemUI"; |
| } |
| |
| /** |
| * Returns true if button's model is armed and false otherwise. The |
| * button model is armed if menu item has focus or it is selected. |
| * |
| * @return $boolean$ true if button's model is armed and false otherwise |
| */ |
| public boolean isArmed() |
| { |
| return getModel().isArmed(); |
| } |
| |
| /** |
| * Sets menuItem's "ARMED" property |
| * |
| * @param armed DOCUMENT ME! |
| */ |
| public void setArmed(boolean armed) |
| { |
| getModel().setArmed(armed); |
| } |
| |
| /** |
| * Enable or disable menu item. When menu item is disabled, |
| * its text and icon are grayed out if they exist. |
| * |
| * @param enabled if true enable menu item, and disable otherwise. |
| */ |
| public void setEnabled(boolean enabled) |
| { |
| super.setEnabled(enabled); |
| } |
| |
| /** |
| * Return accelerator for this menu item. |
| * |
| * @return $KeyStroke$ accelerator for this menu item. |
| */ |
| public KeyStroke getAccelerator() |
| { |
| return accelerator; |
| } |
| |
| /** |
| * Sets accelerator for this menu item. |
| * |
| * @param keystroke accelerator for this menu item. |
| */ |
| public void setAccelerator(KeyStroke keystroke) |
| { |
| this.accelerator = keystroke; |
| } |
| |
| /** |
| * Configures menu items' properties from properties of the specified action. |
| * This method overrides configurePropertiesFromAction from AbstractButton |
| * to also set accelerator property. |
| * |
| * @param action action to configure properties from |
| */ |
| protected void configurePropertiesFromAction(Action action) |
| { |
| super.configurePropertiesFromAction(action); |
| |
| if (! (this instanceof JMenu) && action != null) |
| setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY))); |
| } |
| |
| /** |
| * Creates PropertyChangeListener to listen for the changes in action |
| * properties. |
| * |
| * @param action action to listen to for property changes |
| * |
| * @return $PropertyChangeListener$ Listener that listens to changes in |
| * action properties. |
| */ |
| protected PropertyChangeListener createActionPropertyChangeListener(Action action) |
| { |
| return new PropertyChangeListener() |
| { |
| public void propertyChange(PropertyChangeEvent e) |
| { |
| Action act = (Action) (e.getSource()); |
| configurePropertiesFromAction(act); |
| } |
| }; |
| } |
| |
| /** |
| * Process mouse events forwarded from MenuSelectionManager. |
| * |
| * @param event event forwarded from MenuSelectionManager |
| * @param path path to the menu element from which event was generated |
| * @param manager MenuSelectionManager for the current menu hierarchy |
| */ |
| public void processMouseEvent(MouseEvent event, MenuElement[] path, |
| MenuSelectionManager manager) |
| { |
| // Fire MenuDragMouseEvents if mouse is being dragged. |
| boolean dragged |
| = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0; |
| if (dragged) |
| processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager)); |
| |
| switch (event.getID()) |
| { |
| case MouseEvent.MOUSE_CLICKED: |
| break; |
| case MouseEvent.MOUSE_ENTERED: |
| if (isRolloverEnabled()) |
| model.setRollover(true); |
| break; |
| case MouseEvent.MOUSE_EXITED: |
| if (isRolloverEnabled()) |
| model.setRollover(false); |
| |
| // for JMenu last element on the path is its popupMenu. |
| // JMenu shouldn't me disarmed. |
| if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged) |
| setArmed(false); |
| break; |
| case MouseEvent.MOUSE_PRESSED: |
| if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) |
| { |
| model.setArmed(true); |
| model.setPressed(true); |
| } |
| break; |
| case MouseEvent.MOUSE_RELEASED: |
| break; |
| case MouseEvent.MOUSE_MOVED: |
| break; |
| case MouseEvent.MOUSE_DRAGGED: |
| break; |
| } |
| } |
| |
| /** |
| * Creates MenuDragMouseEvent. |
| * |
| * @param event MouseEvent that occured while mouse was pressed. |
| * @param path Path the the menu element where the dragging event was |
| * originated |
| * @param manager MenuSelectionManager for the current menu hierarchy. |
| * |
| * @return new MenuDragMouseEvent |
| */ |
| private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event, |
| MenuElement[] path, |
| MenuSelectionManager manager) |
| { |
| return new MenuDragMouseEvent((Component) event.getSource(), |
| event.getID(), event.getWhen(), |
| event.getModifiers(), event.getX(), |
| event.getY(), event.getClickCount(), |
| event.isPopupTrigger(), path, manager); |
| } |
| |
| /** |
| * Process key events forwarded from MenuSelectionManager. |
| * |
| * @param event event forwarded from MenuSelectionManager |
| * @param path path to the menu element from which event was generated |
| * @param manager MenuSelectionManager for the current menu hierarchy |
| */ |
| public void processKeyEvent(KeyEvent event, MenuElement[] path, |
| MenuSelectionManager manager) |
| { |
| // Need to implement. |
| } |
| |
| /** |
| * This method fires MenuDragMouseEvents to registered listeners. |
| * Different types of MenuDragMouseEvents are fired depending |
| * on the observed mouse event. |
| * |
| * @param event Mouse |
| */ |
| public void processMenuDragMouseEvent(MenuDragMouseEvent event) |
| { |
| switch (event.getID()) |
| { |
| case MouseEvent.MOUSE_ENTERED: |
| fireMenuDragMouseEntered(event); |
| break; |
| case MouseEvent.MOUSE_EXITED: |
| fireMenuDragMouseExited(event); |
| break; |
| case MouseEvent.MOUSE_DRAGGED: |
| fireMenuDragMouseDragged(event); |
| break; |
| case MouseEvent.MOUSE_RELEASED: |
| fireMenuDragMouseReleased(event); |
| break; |
| } |
| } |
| |
| /** |
| * This method fires MenuKeyEvent to registered listeners. |
| * Different types of MenuKeyEvents are fired depending |
| * on the observed key event. |
| * |
| * @param event DOCUMENT ME! |
| */ |
| public void processMenuKeyEvent(MenuKeyEvent event) |
| { |
| // Need to implement. |
| } |
| |
| /** |
| * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. |
| * |
| * @param event The event signifying that mouse entered menuItem while it was dragged |
| */ |
| protected void fireMenuDragMouseEntered(MenuDragMouseEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event); |
| } |
| |
| /** |
| * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. |
| * |
| * @param event The event signifying that mouse has exited menu item, while it was dragged |
| */ |
| protected void fireMenuDragMouseExited(MenuDragMouseEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event); |
| } |
| |
| /** |
| * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. |
| * |
| * @param event The event signifying that mouse is being dragged over the menuItem |
| */ |
| protected void fireMenuDragMouseDragged(MenuDragMouseEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event); |
| } |
| |
| /** |
| * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners. |
| * |
| * @param event The event signifying that mouse was released while it was dragged over the menuItem |
| */ |
| protected void fireMenuDragMouseReleased(MenuDragMouseEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event); |
| } |
| |
| /** |
| * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. |
| * |
| * @param event The event signifying that key associated with this menu was pressed |
| */ |
| protected void fireMenuKeyPressed(MenuKeyEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuKeyListener) ll[i]).menuKeyPressed(event); |
| } |
| |
| /** |
| * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. |
| * |
| * @param event The event signifying that key associated with this menu was released |
| */ |
| protected void fireMenuKeyReleased(MenuKeyEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuKeyListener) ll[i]).menuKeyTyped(event); |
| } |
| |
| /** |
| * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. |
| * |
| * @param event The event signifying that key associated with this menu was typed. |
| * The key is typed when it was pressed and then released |
| */ |
| protected void fireMenuKeyTyped(MenuKeyEvent event) |
| { |
| EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); |
| |
| for (int i = 0; i < ll.length; i++) |
| ((MenuKeyListener) ll[i]).menuKeyTyped(event); |
| } |
| |
| /** |
| * Method of the MenuElement interface. |
| * This method is invoked by MenuSelectionManager when selection of |
| * this menu item has changed. If this menu item was selected then |
| * arm it's model, and disarm the model otherwise. The menu item |
| * is considered to be selected, and thus highlighted when its model |
| * is armed. |
| * |
| * @param changed indicates selection status of this menu item. If changed is |
| * true then menu item is selected and deselected otherwise. |
| */ |
| public void menuSelectionChanged(boolean changed) |
| { |
| Component parent = this.getParent(); |
| if (changed) |
| { |
| model.setArmed(true); |
| |
| if (parent != null && parent instanceof JPopupMenu) |
| ((JPopupMenu) parent).setSelected(this); |
| } |
| else |
| { |
| model.setArmed(false); |
| |
| if (parent != null && parent instanceof JPopupMenu) |
| ((JPopupMenu) parent).getSelectionModel().clearSelection(); |
| } |
| } |
| |
| /** |
| * Method of the MenuElement interface. |
| * |
| * @return $MenuElement[]$ Returns array of sub-components for this menu |
| * item. By default menuItem doesn't have any subcomponents and so |
| * empty array is returned instead. |
| */ |
| public MenuElement[] getSubElements() |
| { |
| return new MenuElement[0]; |
| } |
| |
| /** |
| * Returns reference to the component that will paint this menu item. |
| * |
| * @return $Component$ Component that will paint this menu item. |
| * Simply returns reference to this menu item. |
| */ |
| public Component getComponent() |
| { |
| return this; |
| } |
| |
| /** |
| * Adds a MenuDragMouseListener to this menu item. When mouse |
| * is dragged over the menu item the MenuDragMouseEvents will be |
| * fired, and these listeners will be called. |
| * |
| * @param listener The new listener to add |
| */ |
| public void addMenuDragMouseListener(MenuDragMouseListener listener) |
| { |
| listenerList.add(MenuDragMouseListener.class, listener); |
| } |
| |
| /** |
| * Removes a MenuDragMouseListener from the menuItem's listener list. |
| * |
| * @param listener The listener to remove |
| */ |
| public void removeMenuDragMouseListener(MenuDragMouseListener listener) |
| { |
| listenerList.remove(MenuDragMouseListener.class, listener); |
| } |
| |
| /** |
| * Returns all added MenuDragMouseListener objects. |
| * |
| * @return an array of listeners |
| * |
| * @since 1.4 |
| */ |
| public MenuDragMouseListener[] getMenuDragMouseListeners() |
| { |
| return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class); |
| } |
| |
| /** |
| * Adds an MenuKeyListener to this menu item. This listener will be |
| * invoked when MenuKeyEvents will be fired by this menu item. |
| * |
| * @param listener The new listener to add |
| */ |
| public void addMenuKeyListener(MenuKeyListener listener) |
| { |
| listenerList.add(MenuKeyListener.class, listener); |
| } |
| |
| /** |
| * Removes an MenuKeyListener from the menuItem's listener list. |
| * |
| * @param listener The listener to remove |
| */ |
| public void removeMenuKeyListener(MenuKeyListener listener) |
| { |
| listenerList.remove(MenuKeyListener.class, listener); |
| } |
| |
| /** |
| * Returns all added MenuKeyListener objects. |
| * |
| * @return an array of listeners |
| * |
| * @since 1.4 |
| */ |
| public MenuKeyListener[] getMenuKeyListeners() |
| { |
| return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class); |
| } |
| |
| /** |
| * A string that describes this JMenuItem. Normally only used |
| * for debugging. |
| * |
| * @return A string describing this JMenuItem |
| */ |
| protected String paramString() |
| { |
| return super.paramString(); |
| } |
| |
| public AccessibleContext getAccessibleContext() |
| { |
| if (accessibleContext == null) |
| accessibleContext = new AccessibleJMenuItem(); |
| |
| return accessibleContext; |
| } |
| |
| protected class AccessibleJMenuItem extends AccessibleAbstractButton |
| implements ChangeListener |
| { |
| private static final long serialVersionUID = 6748924232082076534L; |
| |
| /** |
| * Creates a new AccessibleJMenuItem object. |
| */ |
| AccessibleJMenuItem() |
| { |
| //super(component); |
| } |
| |
| public void stateChanged(ChangeEvent event) |
| { |
| } |
| |
| public AccessibleRole getAccessibleRole() |
| { |
| return AccessibleRole.MENU_ITEM; |
| } |
| } |
| } |