Frames | No Frames |
1: /* BasicMenuBarUI.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.ActionEvent; 43: import java.awt.event.ContainerEvent; 44: import java.awt.event.ContainerListener; 45: import java.awt.event.MouseEvent; 46: import java.beans.PropertyChangeEvent; 47: import java.beans.PropertyChangeListener; 48: 49: import javax.swing.AbstractAction; 50: import javax.swing.Action; 51: import javax.swing.ActionMap; 52: import javax.swing.BoxLayout; 53: import javax.swing.InputMap; 54: import javax.swing.JComponent; 55: import javax.swing.JMenu; 56: import javax.swing.JMenuBar; 57: import javax.swing.LookAndFeel; 58: import javax.swing.MenuElement; 59: import javax.swing.MenuSelectionManager; 60: import javax.swing.SwingUtilities; 61: import javax.swing.UIManager; 62: import javax.swing.event.ChangeEvent; 63: import javax.swing.event.ChangeListener; 64: import javax.swing.event.MouseInputListener; 65: import javax.swing.plaf.ActionMapUIResource; 66: import javax.swing.plaf.ComponentUI; 67: import javax.swing.plaf.MenuBarUI; 68: 69: /** 70: * UI Delegate for JMenuBar. 71: */ 72: public class BasicMenuBarUI extends MenuBarUI 73: { 74: 75: /** 76: * This action is performed for the action command 'takeFocus'. 77: */ 78: private static class FocusAction 79: extends AbstractAction 80: { 81: 82: /** 83: * Creates a new FocusAction. 84: */ 85: FocusAction() 86: { 87: super("takeFocus"); 88: } 89: 90: /** 91: * Performs the action. 92: */ 93: public void actionPerformed(ActionEvent event) 94: { 95: // In the JDK this action seems to pop up the first menu of the 96: // menu bar. 97: JMenuBar menuBar = (JMenuBar) event.getSource(); 98: MenuSelectionManager defaultManager = 99: MenuSelectionManager.defaultManager(); 100: MenuElement me[]; 101: MenuElement subElements[]; 102: JMenu menu = menuBar.getMenu(0); 103: if (menu != null) 104: { 105: me = new MenuElement[3]; 106: me[0] = (MenuElement) menuBar; 107: me[1] = (MenuElement) menu; 108: me[2] = (MenuElement) menu.getPopupMenu(); 109: defaultManager.setSelectedPath(me); 110: } 111: } 112: 113: } 114: 115: protected ChangeListener changeListener; 116: 117: /*ContainerListener that listens to the ContainerEvents fired from menu bar*/ 118: protected ContainerListener containerListener; 119: 120: /*Property change listeners that listener to PropertyChangeEvent from menu bar*/ 121: private PropertyChangeListener propertyChangeListener; 122: 123: /* menu bar for which this UI delegate is for*/ 124: protected JMenuBar menuBar; 125: 126: /* MouseListener that listens to the mouseEvents fired from menu bar*/ 127: private MouseInputListener mouseListener; 128: 129: /** 130: * Creates a new BasicMenuBarUI object. 131: */ 132: public BasicMenuBarUI() 133: { 134: changeListener = createChangeListener(); 135: containerListener = createContainerListener(); 136: propertyChangeListener = new PropertyChangeHandler(); 137: mouseListener = new MouseInputHandler(); 138: } 139: 140: /** 141: * Creates ChangeListener 142: * 143: * @return The ChangeListener 144: */ 145: protected ChangeListener createChangeListener() 146: { 147: return new ChangeHandler(); 148: } 149: 150: /** 151: * Creates ContainerListener() to listen for ContainerEvents 152: * fired by JMenuBar. 153: * 154: * @return The ContainerListener 155: */ 156: protected ContainerListener createContainerListener() 157: { 158: return new ContainerHandler(); 159: } 160: 161: /** 162: * Factory method to create a BasicMenuBarUI for the given {@link 163: * JComponent}, which should be a {@link JMenuBar}. 164: * 165: * @param x The {@link JComponent} a UI is being created for. 166: * 167: * @return A BasicMenuBarUI for the {@link JComponent}. 168: */ 169: public static ComponentUI createUI(JComponent x) 170: { 171: return new BasicMenuBarUI(); 172: } 173: 174: /** 175: * Returns maximum size for the specified menu bar 176: * 177: * @param c component for which to get maximum size 178: * 179: * @return Maximum size for the specified menu bar 180: */ 181: public Dimension getMaximumSize(JComponent c) 182: { 183: // let layout manager calculate its size 184: return null; 185: } 186: 187: /** 188: * Returns maximum allowed size of JMenuBar. 189: * 190: * @param c menuBar for which to return maximum size 191: * 192: * @return Maximum size of the give menu bar. 193: */ 194: public Dimension getMinimumSize(JComponent c) 195: { 196: // let layout manager calculate its size 197: return null; 198: } 199: 200: /** 201: * Returns preferred size of JMenuBar. 202: * 203: * @param c menuBar for which to return preferred size 204: * 205: * @return Preferred size of the give menu bar. 206: */ 207: public Dimension getPreferredSize(JComponent c) 208: { 209: // let layout manager calculate its size 210: return null; 211: } 212: 213: /** 214: * Initializes any default properties that this UI has from the defaults for 215: * the Basic look and feel. 216: */ 217: protected void installDefaults() 218: { 219: LookAndFeel.installBorder(menuBar, "MenuBar.border"); 220: LookAndFeel.installColorsAndFont(menuBar, "MenuBar.background", 221: "MenuBar.foreground", "MenuBar.font"); 222: menuBar.setOpaque(true); 223: } 224: 225: /** 226: * This method installs the keyboard actions for the JMenuBar. 227: */ 228: protected void installKeyboardActions() 229: { 230: // Install InputMap. 231: Object[] bindings = 232: (Object[]) SharedUIDefaults.get("MenuBar.windowBindings"); 233: InputMap inputMap = LookAndFeel.makeComponentInputMap(menuBar, bindings); 234: SwingUtilities.replaceUIInputMap(menuBar, 235: JComponent.WHEN_IN_FOCUSED_WINDOW, 236: inputMap); 237: 238: // Install ActionMap. 239: SwingUtilities.replaceUIActionMap(menuBar, getActionMap()); 240: } 241: 242: /** 243: * Creates and returns the shared action map for JTrees. 244: * 245: * @return the shared action map for JTrees 246: */ 247: private ActionMap getActionMap() 248: { 249: ActionMap am = (ActionMap) UIManager.get("MenuBar.actionMap"); 250: if (am == null) 251: { 252: am = createDefaultActions(); 253: UIManager.getLookAndFeelDefaults().put("MenuBar.actionMap", am); 254: } 255: return am; 256: } 257: 258: /** 259: * Creates the default actions when there are none specified by the L&F. 260: * 261: * @return the default actions 262: */ 263: private ActionMap createDefaultActions() 264: { 265: ActionMapUIResource am = new ActionMapUIResource(); 266: Action action = new FocusAction(); 267: am.put(action.getValue(Action.NAME), action); 268: return am; 269: } 270: 271: /** 272: * This method installs the listeners needed for this UI to function. 273: */ 274: protected void installListeners() 275: { 276: menuBar.addContainerListener(containerListener); 277: menuBar.addPropertyChangeListener(propertyChangeListener); 278: menuBar.addMouseListener(mouseListener); 279: } 280: 281: /** 282: * Installs and initializes all fields for this UI delegate. Any properties 283: * of the UI that need to be initialized and/or set to defaults will be 284: * done now. It will also install any listeners necessary. 285: * 286: * @param c The {@link JComponent} that is having this UI installed. 287: */ 288: public void installUI(JComponent c) 289: { 290: super.installUI(c); 291: menuBar = (JMenuBar) c; 292: menuBar.setLayout(new BoxLayout(menuBar, BoxLayout.X_AXIS)); 293: installDefaults(); 294: installListeners(); 295: installKeyboardActions(); 296: } 297: 298: /** 299: * This method uninstalls the defaults and nulls any objects created during 300: * install. 301: */ 302: protected void uninstallDefaults() 303: { 304: menuBar.setBackground(null); 305: menuBar.setBorder(null); 306: menuBar.setFont(null); 307: menuBar.setForeground(null); 308: } 309: 310: /** 311: * This method reverses the work done in installKeyboardActions. 312: */ 313: protected void uninstallKeyboardActions() 314: { 315: SwingUtilities.replaceUIInputMap(menuBar, 316: JComponent.WHEN_IN_FOCUSED_WINDOW, null); 317: SwingUtilities.replaceUIActionMap(menuBar, null); 318: } 319: 320: /** 321: * Unregisters all the listeners that this UI delegate was using. 322: */ 323: protected void uninstallListeners() 324: { 325: menuBar.removeContainerListener(containerListener); 326: menuBar.removePropertyChangeListener(propertyChangeListener); 327: menuBar.removeMouseListener(mouseListener); 328: } 329: 330: /** 331: * Performs the opposite of installUI. Any properties or resources that need 332: * to be cleaned up will be done now. It will also uninstall any listeners 333: * it has. In addition, any properties of this UI will be nulled. 334: * 335: * @param c The {@link JComponent} that is having this UI uninstalled. 336: */ 337: public void uninstallUI(JComponent c) 338: { 339: uninstallDefaults(); 340: uninstallListeners(); 341: uninstallKeyboardActions(); 342: menuBar = null; 343: } 344: 345: private class ChangeHandler implements ChangeListener 346: { 347: public void stateChanged(ChangeEvent event) 348: { 349: // TODO: What should be done here, if anything? 350: } 351: } 352: 353: /** 354: * This class handles ContainerEvents fired by JMenuBar. It revalidates 355: * and repaints menu bar whenever menu is added or removed from it. 356: */ 357: private class ContainerHandler implements ContainerListener 358: { 359: /** 360: * This method is called whenever menu is added to the menu bar 361: * 362: * @param e The ContainerEvent. 363: */ 364: public void componentAdded(ContainerEvent e) 365: { 366: menuBar.revalidate(); 367: menuBar.repaint(); 368: } 369: 370: /** 371: * This method is called whenever menu is removed from the menu bar. 372: * 373: * @param e The ContainerEvent. 374: */ 375: public void componentRemoved(ContainerEvent e) 376: { 377: menuBar.revalidate(); 378: menuBar.repaint(); 379: } 380: } 381: 382: /** 383: * This class handles PropertyChangeEvents fired from the JMenuBar 384: */ 385: private class PropertyChangeHandler implements PropertyChangeListener 386: { 387: /** 388: * This method is called whenever one of the properties of the MenuBar 389: * changes. 390: * 391: * @param e The PropertyChangeEvent. 392: */ 393: public void propertyChange(PropertyChangeEvent e) 394: { 395: if (e.getPropertyName().equals("borderPainted")) 396: menuBar.repaint(); 397: if (e.getPropertyName().equals("margin")) 398: menuBar.repaint(); 399: } 400: } 401: 402: private class MouseInputHandler implements MouseInputListener 403: { 404: /** 405: * Handles mouse clicked event 406: * 407: * @param e Mouse event 408: */ 409: public void mouseClicked(MouseEvent e) 410: { 411: MenuElement[] me = menuBar.getSubElements(); 412: 413: for (int i = 0; i < me.length; i++) 414: { 415: JMenu menu = menuBar.getMenu(i); 416: if (menu != null) 417: menu.setSelected(false); 418: } 419: } 420: 421: /** 422: * Handles mouse pressed event 423: * 424: * @param e Mouse event 425: */ 426: public void mousePressed(MouseEvent e) 427: { 428: // TODO: What should be done here, if anything? 429: } 430: 431: /** 432: * Handles mouse released event 433: * 434: * @param e Mouse event 435: */ 436: public void mouseReleased(MouseEvent e) 437: { 438: // TODO: What should be done here, if anything? 439: } 440: 441: /** 442: * Handles mouse exited event 443: * 444: * @param e Mouse event 445: */ 446: public void mouseExited(MouseEvent e) 447: { 448: // TODO: What should be done here, if anything? 449: } 450: 451: /** 452: * Handles mouse dragged event 453: * 454: * @param e Mouse event 455: */ 456: public void mouseDragged(MouseEvent e) 457: { 458: // TODO: What should be done here, if anything? 459: } 460: 461: /** 462: * Handles mouse moved event 463: * 464: * @param e Mouse event 465: */ 466: public void mouseMoved(MouseEvent e) 467: { 468: // TODO: What should be done here, if anything? 469: } 470: 471: /** 472: * Handles mouse entered event 473: * 474: * @param e Mouse event 475: */ 476: public void mouseEntered(MouseEvent e) 477: { 478: // TODO: What should be done here, if anything? 479: } 480: } 481: }