GNU Classpath (0.18) | ||
Frames | No Frames |
1: /* BasicMenuUI.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.plaf.basic; 40: 41: import java.awt.Dimension; 42: import java.awt.event.MouseEvent; 43: import java.beans.PropertyChangeEvent; 44: import java.beans.PropertyChangeListener; 45: 46: import javax.swing.JComponent; 47: import javax.swing.JMenu; 48: import javax.swing.JMenuBar; 49: import javax.swing.JMenuItem; 50: import javax.swing.JPopupMenu; 51: import javax.swing.MenuSelectionManager; 52: import javax.swing.UIDefaults; 53: import javax.swing.UIManager; 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.MenuEvent; 59: import javax.swing.event.MenuKeyEvent; 60: import javax.swing.event.MenuKeyListener; 61: import javax.swing.event.MenuListener; 62: import javax.swing.event.MouseInputListener; 63: import javax.swing.plaf.ComponentUI; 64: 65: /** 66: * UI Delegate for JMenu 67: */ 68: public class BasicMenuUI extends BasicMenuItemUI 69: { 70: protected ChangeListener changeListener; 71: 72: /* MenuListener listens to MenuEvents fired by JMenu */ 73: protected MenuListener menuListener; 74: 75: /* PropertyChangeListner that listens to propertyChangeEvents occuring in JMenu*/ 76: protected PropertyChangeListener propertyChangeListener; 77: 78: /** 79: * Creates a new BasicMenuUI object. 80: */ 81: public BasicMenuUI() 82: { 83: mouseInputListener = createMouseInputListener((JMenu) menuItem); 84: menuListener = createMenuListener((JMenu) menuItem); 85: propertyChangeListener = createPropertyChangeListener((JMenu) menuItem); 86: } 87: 88: /** 89: * This method creates a new ChangeListener. 90: * 91: * @return A new ChangeListener. 92: */ 93: protected ChangeListener createChangeListener(JComponent c) 94: { 95: return new ChangeHandler(); 96: } 97: 98: /** 99: * This method creates new MenuDragMouseListener to listen to mouse dragged events 100: * occuring in the Menu 101: * 102: * @param c the menu to listen to 103: * 104: * @return The MenuDrageMouseListener 105: */ 106: protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) 107: { 108: return new MenuDragMouseHandler(); 109: } 110: 111: /** 112: * This method creates new MenuDragKeyListener to listen to key events 113: * 114: * @param c the menu to listen to 115: * 116: * @return The MenuKeyListener 117: */ 118: protected MenuKeyListener createMenuKeyListener(JComponent c) 119: { 120: return new MenuKeyHandler(); 121: } 122: 123: /** 124: * This method creates new MenuListener to listen to menu events 125: * occuring in the Menu 126: * 127: * @param c the menu to listen to 128: * 129: * @return The MenuListener 130: */ 131: protected MenuListener createMenuListener(JComponent c) 132: { 133: return new MenuHandler(); 134: } 135: 136: /** 137: * This method creates new MouseInputListener to listen to mouse input events 138: * occuring in the Menu 139: * 140: * @param c the menu to listen to 141: * 142: * @return The MouseInputListener 143: */ 144: protected MouseInputListener createMouseInputListener(JComponent c) 145: { 146: return new MouseInputHandler(); 147: } 148: 149: /** 150: * This method creates newPropertyChangeListener to listen to property changes 151: * occuring in the Menu 152: * 153: * @param c the menu to listen to 154: * 155: * @return The PropertyChangeListener 156: */ 157: protected PropertyChangeListener createPropertyChangeListener(JComponent c) 158: { 159: return new PropertyChangeHandler(); 160: } 161: 162: /** 163: * This method creates a new BasicMenuUI. 164: * 165: * @param c The JComponent to create a UI for. 166: * 167: * @return A new BasicMenuUI. 168: */ 169: public static ComponentUI createUI(JComponent c) 170: { 171: return new BasicMenuUI(); 172: } 173: 174: /** 175: * Get the component's maximum size. 176: * 177: * @param c The JComponent for which to get maximum size 178: * 179: * @return The maximum size of the component 180: */ 181: public Dimension getMaximumSize(JComponent c) 182: { 183: // If this menu is in a popup menu, treat it like a regular JMenuItem 184: if (!((JMenu)c).isTopLevelMenu()) 185: { 186: JMenuItem menuItem = new JMenuItem(((JMenu)c).getText(), ((JMenu)c).getIcon()); 187: return menuItem.getMaximumSize(); 188: } 189: return c.getPreferredSize(); 190: } 191: 192: /** 193: * Returns the prefix for entries in the {@link UIDefaults} table. 194: * 195: * @return "Menu" 196: */ 197: protected String getPropertyPrefix() 198: { 199: return "Menu"; 200: } 201: 202: /** 203: * Initializes any default properties that this UI has from the defaults for 204: * the Basic look and feel. 205: */ 206: protected void installDefaults() 207: { 208: UIDefaults defaults = UIManager.getLookAndFeelDefaults(); 209: 210: menuItem.setBackground(defaults.getColor("Menu.background")); 211: menuItem.setBorder(defaults.getBorder("Menu.border")); 212: menuItem.setFont(defaults.getFont("Menu.font")); 213: menuItem.setForeground(defaults.getColor("Menu.foreground")); 214: menuItem.setMargin(defaults.getInsets("Menu.margin")); 215: acceleratorFont = defaults.getFont("Menu.acceleratorFont"); 216: acceleratorForeground = defaults.getColor("Menu.acceleratorForeground"); 217: acceleratorSelectionForeground = defaults.getColor("Menu.acceleratorSelectionForeground"); 218: selectionBackground = defaults.getColor("Menu.selectionBackground"); 219: selectionForeground = defaults.getColor("Menu.selectionForeground"); 220: arrowIcon = defaults.getIcon("Menu.arrowIcon"); 221: oldBorderPainted = defaults.getBoolean("Menu.borderPainted"); 222: menuItem.setOpaque(true); 223: } 224: 225: /** 226: * Installs any keyboard actions. The list of keys that need to be bound are 227: * listed in Basic look and feel's defaults. 228: * 229: */ 230: protected void installKeyboardActions() 231: { 232: // FIXME: Need to implement 233: } 234: 235: /** 236: * Creates and registers all the listeners for this UI delegate. 237: */ 238: protected void installListeners() 239: { 240: ((JMenu) menuItem).addMouseListener(mouseInputListener); 241: ((JMenu) menuItem).addMouseMotionListener(mouseInputListener); 242: ((JMenu) menuItem).addMenuListener(menuListener); 243: ((JMenu) menuItem).addMenuDragMouseListener(menuDragMouseListener); 244: } 245: 246: protected void setupPostTimer(JMenu menu) 247: { 248: } 249: 250: /** 251: * This method uninstalls the defaults and sets any objects created during 252: * install to null 253: */ 254: protected void uninstallDefaults() 255: { 256: menuItem.setBackground(null); 257: menuItem.setBorder(null); 258: menuItem.setFont(null); 259: menuItem.setForeground(null); 260: menuItem.setMargin(null); 261: acceleratorFont = null; 262: acceleratorForeground = null; 263: acceleratorSelectionForeground = null; 264: selectionBackground = null; 265: selectionForeground = null; 266: arrowIcon = null; 267: } 268: 269: /** 270: * Uninstalls any keyboard actions. The list of keys used are listed in 271: * Basic look and feel's defaults. 272: */ 273: protected void uninstallKeyboardActions() 274: { 275: // FIXME: Need to implement 276: } 277: 278: /** 279: * Unregisters all the listeners that this UI delegate was using. In 280: * addition, it will also null any listeners that it was using. 281: */ 282: protected void uninstallListeners() 283: { 284: ((JMenu) menuItem).removeMouseListener(mouseInputListener); 285: ((JMenu) menuItem).removeMenuListener(menuListener); 286: ((JMenu) menuItem).removePropertyChangeListener(propertyChangeListener); 287: } 288: 289: /** 290: * This class is used by menus to handle mouse events occuring in the 291: * menu. 292: */ 293: protected class MouseInputHandler implements MouseInputListener 294: { 295: public void mouseClicked(MouseEvent e) 296: { 297: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 298: manager.processMouseEvent(e); 299: } 300: 301: public void mouseDragged(MouseEvent e) 302: { 303: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 304: manager.processMouseEvent(e); 305: } 306: 307: private boolean popupVisible() 308: { 309: JMenuBar mb = (JMenuBar) ((JMenu) menuItem).getParent(); 310: // check if mb.isSelected because if no menus are selected 311: // we don't have to look through the list for popup menus 312: if (!mb.isSelected()) 313: return false; 314: for (int i = 0; i < mb.getMenuCount(); i++) 315: { 316: JMenu m = mb.getMenu(i); 317: if (m != null && m.isPopupMenuVisible()) 318: return true; 319: } 320: return false; 321: } 322: 323: public void mouseEntered(MouseEvent e) 324: { 325: /* When mouse enters menu item, it should be considered selected 326: 327: if (i) if this menu is a submenu in some other menu 328: (ii) or if this menu is in a menu bar and some other menu in a 329: menu bar was just selected and has its popup menu visible. 330: (If nothing was selected, menu should be pressed before 331: it will be selected) 332: */ 333: JMenu menu = (JMenu) menuItem; 334: 335: // NOTE: the following if used to require !menu.isArmed but I could find 336: // no reason for this and it was preventing some JDK-compatible behaviour. 337: // Specifically, if a menu is selected but its popup menu not visible, 338: // and then another menu is selected whose popup menu IS visible, when 339: // the mouse is moved over the first menu, its popup menu should become 340: // visible. 341: 342: if (! menu.isTopLevelMenu() || popupVisible()) 343: { 344: // set new selection and forward this event to MenuSelectionManager 345: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 346: manager.setSelectedPath(getPath()); 347: manager.processMouseEvent(e); 348: } 349: } 350: 351: public void mouseExited(MouseEvent e) 352: { 353: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 354: manager.processMouseEvent(e); 355: } 356: 357: public void mouseMoved(MouseEvent e) 358: { 359: } 360: 361: public void mousePressed(MouseEvent e) 362: { 363: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 364: JMenu menu = (JMenu) menuItem; 365: manager.processMouseEvent(e); 366: 367: // Menu should be displayed when the menu is pressed only if 368: // it is top-level menu 369: if (menu.isTopLevelMenu()) 370: { 371: if (menu.getPopupMenu().isVisible()) 372: // If menu is visible and menu button was pressed.. 373: // then need to cancel the menu 374: manager.clearSelectedPath(); 375: else 376: { 377: // Display the menu 378: int x = 0; 379: int y = menu.getHeight(); 380: 381: manager.setSelectedPath(getPath()); 382: 383: JMenuBar mb = (JMenuBar) menu.getParent(); 384: 385: // set selectedIndex of the selectionModel of a menuBar 386: mb.getSelectionModel().setSelectedIndex(mb.getComponentIndex(menu)); 387: } 388: } 389: } 390: 391: public void mouseReleased(MouseEvent e) 392: { 393: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 394: manager.processMouseEvent(e); 395: } 396: } 397: 398: /** 399: * This class handles MenuEvents fired by the JMenu 400: */ 401: protected class MenuHandler implements MenuListener 402: { 403: /** 404: * This method is called when menu is cancelled. The menu is cancelled 405: * when its popup menu is closed without selection. It clears selected index 406: * in the selectionModel of the menu parent. 407: * 408: * @param e The MenuEvent. 409: */ 410: public void menuCanceled(MenuEvent e) 411: { 412: menuDeselected(e); 413: } 414: 415: /** 416: * This method is called when menu is deselected. It clears selected index 417: * in the selectionModel of the menu parent. 418: * 419: * @param e The MenuEvent. 420: */ 421: public void menuDeselected(MenuEvent e) 422: { 423: JMenu menu = (JMenu) menuItem; 424: if (menu.isTopLevelMenu()) 425: ((JMenuBar) menu.getParent()).getSelectionModel().clearSelection(); 426: else 427: ((JPopupMenu) menu.getParent()).getSelectionModel().clearSelection(); 428: } 429: 430: /** 431: * This method is called when menu is selected. It sets selected index 432: * in the selectionModel of the menu parent. 433: * 434: * @param e The MenuEvent. 435: */ 436: public void menuSelected(MenuEvent e) 437: { 438: JMenu menu = (JMenu) menuItem; 439: if (menu.isTopLevelMenu()) 440: ((JMenuBar) menu.getParent()).setSelected(menu); 441: else 442: ((JPopupMenu) menu.getParent()).setSelected(menu); 443: } 444: } 445: 446: /** 447: * This class handles PropertyChangeEvents fired from the JMenu 448: */ 449: protected class PropertyChangeHandler implements PropertyChangeListener 450: { 451: /** 452: * This method is called whenever one of the properties of the menu item 453: * changes. 454: * 455: * @param e The PropertyChangeEvent. 456: */ 457: public void propertyChange(PropertyChangeEvent e) 458: { 459: } 460: } 461: 462: /** 463: * @deprecated 464: */ 465: public class ChangeHandler implements ChangeListener 466: { 467: public void stateChanged(ChangeEvent e) 468: { 469: // FIXME: It seems that this class is not used anywhere 470: } 471: } 472: 473: /** 474: * This class handles mouse dragged events occuring in the menu. 475: */ 476: protected class MenuDragMouseHandler implements MenuDragMouseListener 477: { 478: /** 479: * This method is invoked when mouse is dragged over the menu item. 480: * 481: * @param e The MenuDragMouseEvent 482: */ 483: public void menuDragMouseDragged(MenuDragMouseEvent e) 484: { 485: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 486: manager.setSelectedPath(e.getPath()); 487: } 488: 489: /** 490: * This method is invoked when mouse enters the menu item while it is 491: * being dragged. 492: * 493: * @param e The MenuDragMouseEvent 494: */ 495: public void menuDragMouseEntered(MenuDragMouseEvent e) 496: { 497: MenuSelectionManager manager = MenuSelectionManager.defaultManager(); 498: manager.setSelectedPath(e.getPath()); 499: } 500: 501: /** 502: * This method is invoked when mouse exits the menu item while 503: * it is being dragged 504: * 505: * @param e The MenuDragMouseEvent 506: */ 507: public void menuDragMouseExited(MenuDragMouseEvent e) 508: { 509: } 510: 511: /** 512: * This method is invoked when mouse was dragged and released 513: * inside the menu item. 514: * 515: * @param e The MenuDragMouseEvent 516: */ 517: public void menuDragMouseReleased(MenuDragMouseEvent e) 518: { 519: } 520: } 521: 522: /** 523: * This class handles key events occuring when menu item is visible on the 524: * screen. 525: */ 526: protected class MenuKeyHandler implements MenuKeyListener 527: { 528: /** 529: * This method is invoked when key has been pressed 530: * 531: * @param e A {@link MenuKeyEvent}. 532: */ 533: public void menuKeyPressed(MenuKeyEvent e) 534: { 535: } 536: 537: /** 538: * This method is invoked when key has been pressed 539: * 540: * @param e A {@link MenuKeyEvent}. 541: */ 542: public void menuKeyReleased(MenuKeyEvent e) 543: { 544: } 545: 546: /** 547: * This method is invoked when key has been typed 548: * It handles the mnemonic key for the menu item. 549: * 550: * @param e A {@link MenuKeyEvent}. 551: */ 552: public void menuKeyTyped(MenuKeyEvent e) 553: { 554: } 555: } 556: }
GNU Classpath (0.18) |