1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.laf; 27 28 import java.awt.*; 29 import java.security.AccessController; 30 31 import javax.swing.*; 32 import javax.swing.plaf.ComponentUI; 33 import javax.swing.plaf.basic.BasicMenuBarUI; 34 35 import sun.lwawt.macosx.LWCToolkit; 36 import sun.security.action.GetBooleanAction; 37 import sun.security.action.GetPropertyAction; 38 39 // MenuBar implementation for Mac L&F 40 public class AquaMenuBarUI extends BasicMenuBarUI implements ScreenMenuBarProvider { 41 // Utilities 42 public void uninstallUI(final JComponent c) { 43 if (fScreenMenuBar != null) { 44 final JFrame frame = (JFrame)(c.getTopLevelAncestor()); 45 if (frame.getMenuBar() == fScreenMenuBar) { 46 frame.setMenuBar((MenuBar)null); 47 } 48 fScreenMenuBar = null; 49 } 50 super.uninstallUI(c); 51 } 52 53 // Create PLAF 54 public static ComponentUI createUI(final JComponent c) { 55 return new AquaMenuBarUI(); 56 } 57 58 // [3320390] -- If the screen menu bar is in use, don't register keyboard actions that 59 // show the menus when F10 is pressed. 60 protected void installKeyboardActions() { 61 if (!useScreenMenuBar) { 62 super.installKeyboardActions(); 63 } 64 } 65 66 protected void uninstallKeyboardActions() { 67 if (!useScreenMenuBar) { 68 super.uninstallKeyboardActions(); 69 } 70 } 71 72 // Paint Methods 73 public void paint(final Graphics g, final JComponent c) { 74 AquaMenuPainter.instance().paintMenuBarBackground(g, c.getWidth(), c.getHeight(), c); 75 } 76 77 public Dimension getPreferredSize(final JComponent c) { 78 if (isScreenMenuBar((JMenuBar)c)) { 79 if (setScreenMenuBar((JFrame)(c.getTopLevelAncestor()))) { 80 return new Dimension(0, 0); 81 } 82 } 83 return null; 84 } 85 86 void clearScreenMenuBar(final JFrame frame) { 87 if (useScreenMenuBar) { 88 frame.setMenuBar(null); 89 } 90 } 91 92 boolean setScreenMenuBar(final JFrame frame) { 93 if (useScreenMenuBar) { 94 try { 95 getScreenMenuBar(); 96 } catch(final Throwable t) { 97 return false; 98 } 99 100 frame.setMenuBar(fScreenMenuBar); 101 } 102 103 return true; 104 } 105 106 public ScreenMenuBar getScreenMenuBar() { 107 // Lazy init of member variables means we should use a synchronized block. 108 synchronized(this) { 109 if (fScreenMenuBar == null) fScreenMenuBar = new ScreenMenuBar(this.menuBar); 110 } 111 return fScreenMenuBar; 112 } 113 114 // JMenuBars are in frame unless we're using ScreenMenuBars *and* it's 115 // been set by JFrame.setJMenuBar 116 // unless the JFrame has a normal java.awt.MenuBar (it's possible!) 117 // Other JMenuBars appear where the programmer puts them - top of window or elsewhere 118 public static final boolean isScreenMenuBar(final JMenuBar c) { 119 final javax.swing.plaf.ComponentUI ui = c.getUI(); 120 if (ui instanceof AquaMenuBarUI) { 121 if (!((AquaMenuBarUI)ui).useScreenMenuBar) return false; 122 123 final Component parent = c.getTopLevelAncestor(); 124 if (parent instanceof JFrame) { 125 final MenuBar mb = ((JFrame)parent).getMenuBar(); 126 final boolean thisIsTheJMenuBar = (((JFrame)parent).getJMenuBar() == c); 127 if (mb == null) return thisIsTheJMenuBar; 128 return (mb instanceof ScreenMenuBar && thisIsTheJMenuBar); 129 } 130 } 131 return false; 132 } 133 134 ScreenMenuBar fScreenMenuBar; 135 boolean useScreenMenuBar = getScreenMenuBarProperty(); 136 137 static boolean getScreenMenuBarProperty() { 138 // Do not allow AWT to set the screen menu bar if it's embedded in another UI toolkit 139 if (LWCToolkit.isEmbedded()) return false; 140 if (AccessController.doPrivileged( 141 new GetBooleanAction(AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar"))) { 142 return true; 143 } 144 if (AccessController.doPrivileged( 145 new GetBooleanAction(AquaLookAndFeel.sOldPropertyPrefix + "useScreenMenuBar"))) { 146 System.err.println(AquaLookAndFeel.sOldPropertyPrefix + 147 "useScreenMenuBar has been deprecated. Please switch to " + 148 AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar"); 149 return true; 150 } 151 return false; 152 } 153 }