GNU Classpath (0.18) | ||
Frames | No Frames |
1: /* JMenuItem.java -- 2: Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 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. 10: 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. 15: 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. 20: 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. 25: 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. */ 37: 38: 39: package javax.swing; 40: 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; 51: 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; 62: 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. 72: */ 73: public class JMenuItem extends AbstractButton implements Accessible, 74: MenuElement 75: { 76: private static final long serialVersionUID = -1681004643499461044L; 77: 78: /** Combination of keyboard keys that can be used to activate this menu item */ 79: private KeyStroke accelerator; 80: 81: /** 82: * Creates a new JMenuItem object. 83: */ 84: public JMenuItem() 85: { 86: super(); 87: } 88: 89: /** 90: * Creates a new JMenuItem with the given icon. 91: * 92: * @param icon Icon that will be displayed on the menu item 93: */ 94: public JMenuItem(Icon icon) 95: { 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); 100: } 101: 102: /** 103: * Creates a new JMenuItem with the given label. 104: * 105: * @param text label for the menu item 106: */ 107: public JMenuItem(String text) 108: { 109: this(text, null); 110: } 111: 112: /** 113: * Creates a new JMenuItem associated with the specified action. 114: * 115: * @param action action for this menu item 116: */ 117: public JMenuItem(Action action) 118: { 119: super(); 120: super.setAction(action); 121: } 122: 123: /** 124: * Creates a new JMenuItem with specified text and icon. 125: * Text is displayed to the left of icon by default. 126: * 127: * @param text label for this menu item 128: * @param icon icon that will be displayed on this menu item 129: */ 130: public JMenuItem(String text, Icon icon) 131: { 132: super(); 133: init(text, icon); 134: } 135: 136: /** 137: * Creates a new JMenuItem object. 138: * 139: * @param text label for this menu item 140: * @param mnemonic - Single key that can be used with a 141: * look-and-feel meta key to activate this menu item. However 142: * menu item should be visible on the screen when mnemonic is used. 143: */ 144: public JMenuItem(String text, int mnemonic) 145: { 146: this(text, null); 147: setMnemonic(mnemonic); 148: } 149: 150: private void readObject(ObjectInputStream stream) 151: throws IOException, ClassNotFoundException 152: { 153: } 154: 155: private void writeObject(ObjectOutputStream stream) throws IOException 156: { 157: } 158: 159: /** 160: * Initializes this menu item 161: * 162: * @param text label for this menu item 163: * @param icon icon to be displayed for this menu item 164: */ 165: protected void init(String text, Icon icon) 166: { 167: super.init(text, icon); 168: setModel(new DefaultButtonModel()); 169: 170: // Initializes properties for this menu item, that are different 171: // from Abstract button properties. 172: /* NOTE: According to java specifications paint_border should be set to false, 173: since menu item should not have a border. However running few java programs 174: it seems that menu items and menues can have a border. Commenting 175: out statement below for now. */ 176: //borderPainted = false; 177: focusPainted = false; 178: horizontalAlignment = JButton.LEFT; 179: horizontalTextPosition = JButton.LEFT; 180: } 181: 182: /** 183: * Set the "UI" property of the menu item, which is a look and feel class 184: * responsible for handling menuItem's input events and painting it. 185: * 186: * @param ui The new "UI" property 187: */ 188: public void setUI(MenuItemUI ui) 189: { 190: super.setUI(ui); 191: } 192: 193: /** 194: * This method sets this menuItem's UI to the UIManager's default for the 195: * current look and feel. 196: */ 197: public void updateUI() 198: { 199: MenuItemUI mi = ((MenuItemUI) UIManager.getUI(this)); 200: setUI(mi); 201: invalidate(); 202: } 203: 204: /** 205: * This method returns a name to identify which look and feel class will be 206: * the UI delegate for the menuItem. 207: * 208: * @return The Look and Feel classID. "MenuItemUI" 209: */ 210: public String getUIClassID() 211: { 212: return "MenuItemUI"; 213: } 214: 215: /** 216: * Returns true if button's model is armed and false otherwise. The 217: * button model is armed if menu item has focus or it is selected. 218: * 219: * @return $boolean$ true if button's model is armed and false otherwise 220: */ 221: public boolean isArmed() 222: { 223: return getModel().isArmed(); 224: } 225: 226: /** 227: * Sets menuItem's "ARMED" property 228: * 229: * @param armed DOCUMENT ME! 230: */ 231: public void setArmed(boolean armed) 232: { 233: getModel().setArmed(armed); 234: } 235: 236: /** 237: * Enable or disable menu item. When menu item is disabled, 238: * its text and icon are grayed out if they exist. 239: * 240: * @param enabled if true enable menu item, and disable otherwise. 241: */ 242: public void setEnabled(boolean enabled) 243: { 244: super.setEnabled(enabled); 245: } 246: 247: /** 248: * Return accelerator for this menu item. 249: * 250: * @return $KeyStroke$ accelerator for this menu item. 251: */ 252: public KeyStroke getAccelerator() 253: { 254: return accelerator; 255: } 256: 257: /** 258: * Sets accelerator for this menu item. 259: * 260: * @param keystroke accelerator for this menu item. 261: */ 262: public void setAccelerator(KeyStroke keystroke) 263: { 264: this.accelerator = keystroke; 265: } 266: 267: /** 268: * Configures menu items' properties from properties of the specified action. 269: * This method overrides configurePropertiesFromAction from AbstractButton 270: * to also set accelerator property. 271: * 272: * @param action action to configure properties from 273: */ 274: protected void configurePropertiesFromAction(Action action) 275: { 276: super.configurePropertiesFromAction(action); 277: 278: if (! (this instanceof JMenu) && action != null) 279: setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY))); 280: } 281: 282: /** 283: * Creates PropertyChangeListener to listen for the changes in action 284: * properties. 285: * 286: * @param action action to listen to for property changes 287: * 288: * @return $PropertyChangeListener$ Listener that listens to changes in 289: * action properties. 290: */ 291: protected PropertyChangeListener createActionPropertyChangeListener(Action action) 292: { 293: return new PropertyChangeListener() 294: { 295: public void propertyChange(PropertyChangeEvent e) 296: { 297: Action act = (Action) (e.getSource()); 298: configurePropertiesFromAction(act); 299: } 300: }; 301: } 302: 303: /** 304: * Process mouse events forwarded from MenuSelectionManager. 305: * 306: * @param event event forwarded from MenuSelectionManager 307: * @param path path to the menu element from which event was generated 308: * @param manager MenuSelectionManager for the current menu hierarchy 309: */ 310: public void processMouseEvent(MouseEvent event, MenuElement[] path, 311: MenuSelectionManager manager) 312: { 313: // Fire MenuDragMouseEvents if mouse is being dragged. 314: boolean dragged 315: = (event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0; 316: if (dragged) 317: processMenuDragMouseEvent(createMenuDragMouseEvent(event, path, manager)); 318: 319: switch (event.getID()) 320: { 321: case MouseEvent.MOUSE_CLICKED: 322: break; 323: case MouseEvent.MOUSE_ENTERED: 324: if (isRolloverEnabled()) 325: model.setRollover(true); 326: break; 327: case MouseEvent.MOUSE_EXITED: 328: if (isRolloverEnabled()) 329: model.setRollover(false); 330: 331: // for JMenu last element on the path is its popupMenu. 332: // JMenu shouldn't me disarmed. 333: if (! (path[path.length - 1] instanceof JPopupMenu) && ! dragged) 334: setArmed(false); 335: break; 336: case MouseEvent.MOUSE_PRESSED: 337: if ((event.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) 338: { 339: model.setArmed(true); 340: model.setPressed(true); 341: } 342: break; 343: case MouseEvent.MOUSE_RELEASED: 344: break; 345: case MouseEvent.MOUSE_MOVED: 346: break; 347: case MouseEvent.MOUSE_DRAGGED: 348: break; 349: } 350: } 351: 352: /** 353: * Creates MenuDragMouseEvent. 354: * 355: * @param event MouseEvent that occured while mouse was pressed. 356: * @param path Path the the menu element where the dragging event was 357: * originated 358: * @param manager MenuSelectionManager for the current menu hierarchy. 359: * 360: * @return new MenuDragMouseEvent 361: */ 362: private MenuDragMouseEvent createMenuDragMouseEvent(MouseEvent event, 363: MenuElement[] path, 364: MenuSelectionManager manager) 365: { 366: return new MenuDragMouseEvent((Component) event.getSource(), 367: event.getID(), event.getWhen(), 368: event.getModifiers(), event.getX(), 369: event.getY(), event.getClickCount(), 370: event.isPopupTrigger(), path, manager); 371: } 372: 373: /** 374: * Process key events forwarded from MenuSelectionManager. 375: * 376: * @param event event forwarded from MenuSelectionManager 377: * @param path path to the menu element from which event was generated 378: * @param manager MenuSelectionManager for the current menu hierarchy 379: */ 380: public void processKeyEvent(KeyEvent event, MenuElement[] path, 381: MenuSelectionManager manager) 382: { 383: // Need to implement. 384: } 385: 386: /** 387: * This method fires MenuDragMouseEvents to registered listeners. 388: * Different types of MenuDragMouseEvents are fired depending 389: * on the observed mouse event. 390: * 391: * @param event Mouse 392: */ 393: public void processMenuDragMouseEvent(MenuDragMouseEvent event) 394: { 395: switch (event.getID()) 396: { 397: case MouseEvent.MOUSE_ENTERED: 398: fireMenuDragMouseEntered(event); 399: break; 400: case MouseEvent.MOUSE_EXITED: 401: fireMenuDragMouseExited(event); 402: break; 403: case MouseEvent.MOUSE_DRAGGED: 404: fireMenuDragMouseDragged(event); 405: break; 406: case MouseEvent.MOUSE_RELEASED: 407: fireMenuDragMouseReleased(event); 408: break; 409: } 410: } 411: 412: /** 413: * This method fires MenuKeyEvent to registered listeners. 414: * Different types of MenuKeyEvents are fired depending 415: * on the observed key event. 416: * 417: * @param event DOCUMENT ME! 418: */ 419: public void processMenuKeyEvent(MenuKeyEvent event) 420: { 421: // Need to implement. 422: } 423: 424: /** 425: * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. 426: * 427: * @param event The event signifying that mouse entered menuItem while it was dragged 428: */ 429: protected void fireMenuDragMouseEntered(MenuDragMouseEvent event) 430: { 431: EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); 432: 433: for (int i = 0; i < ll.length; i++) 434: ((MenuDragMouseListener) ll[i]).menuDragMouseEntered(event); 435: } 436: 437: /** 438: * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. 439: * 440: * @param event The event signifying that mouse has exited menu item, while it was dragged 441: */ 442: protected void fireMenuDragMouseExited(MenuDragMouseEvent event) 443: { 444: EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); 445: 446: for (int i = 0; i < ll.length; i++) 447: ((MenuDragMouseListener) ll[i]).menuDragMouseExited(event); 448: } 449: 450: /** 451: * Fires MenuDragMouseEvent to all of the menuItem's MouseInputListeners. 452: * 453: * @param event The event signifying that mouse is being dragged over the menuItem 454: */ 455: protected void fireMenuDragMouseDragged(MenuDragMouseEvent event) 456: { 457: EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); 458: 459: for (int i = 0; i < ll.length; i++) 460: ((MenuDragMouseListener) ll[i]).menuDragMouseDragged(event); 461: } 462: 463: /** 464: * This method fires a MenuDragMouseEvent to all the MenuItem's MouseInputListeners. 465: * 466: * @param event The event signifying that mouse was released while it was dragged over the menuItem 467: */ 468: protected void fireMenuDragMouseReleased(MenuDragMouseEvent event) 469: { 470: EventListener[] ll = listenerList.getListeners(MenuDragMouseListener.class); 471: 472: for (int i = 0; i < ll.length; i++) 473: ((MenuDragMouseListener) ll[i]).menuDragMouseReleased(event); 474: } 475: 476: /** 477: * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. 478: * 479: * @param event The event signifying that key associated with this menu was pressed 480: */ 481: protected void fireMenuKeyPressed(MenuKeyEvent event) 482: { 483: EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); 484: 485: for (int i = 0; i < ll.length; i++) 486: ((MenuKeyListener) ll[i]).menuKeyPressed(event); 487: } 488: 489: /** 490: * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. 491: * 492: * @param event The event signifying that key associated with this menu was released 493: */ 494: protected void fireMenuKeyReleased(MenuKeyEvent event) 495: { 496: EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); 497: 498: for (int i = 0; i < ll.length; i++) 499: ((MenuKeyListener) ll[i]).menuKeyTyped(event); 500: } 501: 502: /** 503: * This method fires a MenuKeyEvent to all the MenuItem's MenuKeyListeners. 504: * 505: * @param event The event signifying that key associated with this menu was typed. 506: * The key is typed when it was pressed and then released 507: */ 508: protected void fireMenuKeyTyped(MenuKeyEvent event) 509: { 510: EventListener[] ll = listenerList.getListeners(MenuKeyListener.class); 511: 512: for (int i = 0; i < ll.length; i++) 513: ((MenuKeyListener) ll[i]).menuKeyTyped(event); 514: } 515: 516: /** 517: * Method of the MenuElement interface. 518: * This method is invoked by MenuSelectionManager when selection of 519: * this menu item has changed. If this menu item was selected then 520: * arm it's model, and disarm the model otherwise. The menu item 521: * is considered to be selected, and thus highlighted when its model 522: * is armed. 523: * 524: * @param changed indicates selection status of this menu item. If changed is 525: * true then menu item is selected and deselected otherwise. 526: */ 527: public void menuSelectionChanged(boolean changed) 528: { 529: Component parent = this.getParent(); 530: if (changed) 531: { 532: model.setArmed(true); 533: 534: if (parent != null && parent instanceof JPopupMenu) 535: ((JPopupMenu) parent).setSelected(this); 536: } 537: else 538: { 539: model.setArmed(false); 540: 541: if (parent != null && parent instanceof JPopupMenu) 542: ((JPopupMenu) parent).getSelectionModel().clearSelection(); 543: } 544: } 545: 546: /** 547: * Method of the MenuElement interface. 548: * 549: * @return $MenuElement[]$ Returns array of sub-components for this menu 550: * item. By default menuItem doesn't have any subcomponents and so 551: * empty array is returned instead. 552: */ 553: public MenuElement[] getSubElements() 554: { 555: return new MenuElement[0]; 556: } 557: 558: /** 559: * Returns reference to the component that will paint this menu item. 560: * 561: * @return $Component$ Component that will paint this menu item. 562: * Simply returns reference to this menu item. 563: */ 564: public Component getComponent() 565: { 566: return this; 567: } 568: 569: /** 570: * Adds a MenuDragMouseListener to this menu item. When mouse 571: * is dragged over the menu item the MenuDragMouseEvents will be 572: * fired, and these listeners will be called. 573: * 574: * @param listener The new listener to add 575: */ 576: public void addMenuDragMouseListener(MenuDragMouseListener listener) 577: { 578: listenerList.add(MenuDragMouseListener.class, listener); 579: } 580: 581: /** 582: * Removes a MenuDragMouseListener from the menuItem's listener list. 583: * 584: * @param listener The listener to remove 585: */ 586: public void removeMenuDragMouseListener(MenuDragMouseListener listener) 587: { 588: listenerList.remove(MenuDragMouseListener.class, listener); 589: } 590: 591: /** 592: * Returns all added MenuDragMouseListener objects. 593: * 594: * @return an array of listeners 595: * 596: * @since 1.4 597: */ 598: public MenuDragMouseListener[] getMenuDragMouseListeners() 599: { 600: return (MenuDragMouseListener[]) listenerList.getListeners(MenuDragMouseListener.class); 601: } 602: 603: /** 604: * Adds an MenuKeyListener to this menu item. This listener will be 605: * invoked when MenuKeyEvents will be fired by this menu item. 606: * 607: * @param listener The new listener to add 608: */ 609: public void addMenuKeyListener(MenuKeyListener listener) 610: { 611: listenerList.add(MenuKeyListener.class, listener); 612: } 613: 614: /** 615: * Removes an MenuKeyListener from the menuItem's listener list. 616: * 617: * @param listener The listener to remove 618: */ 619: public void removeMenuKeyListener(MenuKeyListener listener) 620: { 621: listenerList.remove(MenuKeyListener.class, listener); 622: } 623: 624: /** 625: * Returns all added MenuKeyListener objects. 626: * 627: * @return an array of listeners 628: * 629: * @since 1.4 630: */ 631: public MenuKeyListener[] getMenuKeyListeners() 632: { 633: return (MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class); 634: } 635: 636: /** 637: * A string that describes this JMenuItem. Normally only used 638: * for debugging. 639: * 640: * @return A string describing this JMenuItem 641: */ 642: protected String paramString() 643: { 644: return super.paramString(); 645: } 646: 647: public AccessibleContext getAccessibleContext() 648: { 649: if (accessibleContext == null) 650: accessibleContext = new AccessibleJMenuItem(); 651: 652: return accessibleContext; 653: } 654: 655: protected class AccessibleJMenuItem extends AccessibleAbstractButton 656: implements ChangeListener 657: { 658: private static final long serialVersionUID = 6748924232082076534L; 659: 660: /** 661: * Creates a new AccessibleJMenuItem object. 662: */ 663: AccessibleJMenuItem() 664: { 665: //super(component); 666: } 667: 668: public void stateChanged(ChangeEvent event) 669: { 670: } 671: 672: public AccessibleRole getAccessibleRole() 673: { 674: return AccessibleRole.MENU_ITEM; 675: } 676: } 677: }
GNU Classpath (0.18) |