1 /* 2 * Copyright (c) 1997, 2014, 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.sun.java.swing.plaf.windows; 27 28 import javax.swing.plaf.basic.*; 29 import javax.swing.*; 30 import javax.swing.plaf.ActionMapUIResource; 31 import javax.swing.plaf.ComponentUI; 32 import java.awt.event.ActionEvent; 33 import java.awt.event.HierarchyEvent; 34 import java.awt.event.HierarchyListener; 35 import java.awt.event.WindowAdapter; 36 import java.awt.event.WindowEvent; 37 import java.awt.event.WindowListener; 38 import java.awt.event.WindowStateListener; 39 40 import java.awt.*; 41 42 import com.sun.java.swing.plaf.windows.TMSchema.*; 43 import com.sun.java.swing.plaf.windows.XPStyle.*; 44 45 /** 46 * Windows rendition of the component. 47 * <p> 48 * <strong>Warning:</strong> 49 * Serialized objects of this class will not be compatible with 50 * future Swing releases. The current serialization support is appropriate 51 * for short term storage or RMI between applications running the same 52 * version of Swing. A future release of Swing will provide support for 53 * long term persistence. 54 */ 55 public class WindowsMenuBarUI extends BasicMenuBarUI 56 { 57 /* to be accessed on the EDT only */ 58 private WindowListener windowListener = null; 59 private HierarchyListener hierarchyListener = null; 60 private Window window = null; 61 62 public static ComponentUI createUI(JComponent x) { 63 return new WindowsMenuBarUI(); 64 } 65 66 @Override 67 protected void uninstallListeners() { 68 uninstallWindowListener(); 69 if (hierarchyListener != null) { 70 menuBar.removeHierarchyListener(hierarchyListener); 71 hierarchyListener = null; 72 } 73 super.uninstallListeners(); 74 } 75 private void installWindowListener() { 76 if (windowListener == null) { 77 Component component = menuBar.getTopLevelAncestor(); 78 if (component instanceof Window) { 79 window = (Window) component; 80 windowListener = new WindowAdapter() { 81 @Override 82 public void windowActivated(WindowEvent e) { 83 menuBar.repaint(); 84 } 85 @Override 86 public void windowDeactivated(WindowEvent e) { 87 menuBar.repaint(); 88 } 89 }; 90 ((Window) component).addWindowListener(windowListener); 91 } 92 } 93 } 94 private void uninstallWindowListener() { 95 if (windowListener != null && window != null) { 96 window.removeWindowListener(windowListener); 97 } 98 window = null; 99 windowListener = null; 100 } 101 @Override 102 protected void installListeners() { 103 if (WindowsLookAndFeel.isOnVista()) { 104 installWindowListener(); 105 hierarchyListener = 106 new HierarchyListener() { 107 public void hierarchyChanged(HierarchyEvent e) { 108 if ((e.getChangeFlags() 109 & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { 110 if (menuBar.isDisplayable()) { 111 installWindowListener(); 112 } else { 113 uninstallWindowListener(); 114 } 115 } 116 } 117 }; 118 menuBar.addHierarchyListener(hierarchyListener); 119 } 120 super.installListeners(); 121 } 122 123 protected void installKeyboardActions() { 124 super.installKeyboardActions(); 125 ActionMap map = SwingUtilities.getUIActionMap(menuBar); 126 if (map == null) { 127 map = new ActionMapUIResource(); 128 SwingUtilities.replaceUIActionMap(menuBar, map); 129 } 130 map.put("takeFocus", new TakeFocus()); 131 } 132 133 /** 134 * Action that activates the menu (e.g. when F10 is pressed). 135 * Unlike BasicMenuBarUI.TakeFocus, this Action will not show menu popup. 136 */ 137 @SuppressWarnings("serial") // Superclass is not serializable across versions 138 private static class TakeFocus extends AbstractAction { 139 public void actionPerformed(ActionEvent e) { 140 JMenuBar menuBar = (JMenuBar)e.getSource(); 141 JMenu menu = menuBar.getMenu(0); 142 if (menu != null) { 143 MenuSelectionManager msm = 144 MenuSelectionManager.defaultManager(); 145 MenuElement path[] = new MenuElement[2]; 146 path[0] = (MenuElement)menuBar; 147 path[1] = (MenuElement)menu; 148 msm.setSelectedPath(path); 149 150 // show mnemonics 151 WindowsLookAndFeel.setMnemonicHidden(false); 152 WindowsLookAndFeel.repaintRootPane(menuBar); 153 } 154 } 155 } 156 157 @Override 158 public void paint(Graphics g, JComponent c) { 159 XPStyle xp = XPStyle.getXP(); 160 if (WindowsMenuItemUI.isVistaPainting(xp)) { 161 Skin skin; 162 skin = xp.getSkin(c, Part.MP_BARBACKGROUND); 163 int width = c.getWidth(); 164 int height = c.getHeight(); 165 State state = isActive(c) ? State.ACTIVE : State.INACTIVE; 166 skin.paintSkin(g, 0, 0, width, height, state); 167 } else { 168 super.paint(g, c); 169 } 170 } 171 172 /** 173 * Checks if component belongs to an active window. 174 * @param c component to check 175 * @return true if component belongs to an active window 176 */ 177 static boolean isActive(JComponent c) { 178 JRootPane rootPane = c.getRootPane(); 179 if (rootPane != null) { 180 Component component = rootPane.getParent(); 181 if (component instanceof Window) { 182 return ((Window) component).isActive(); 183 } 184 } 185 return true; 186 } 187 }