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