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