blob: 5a056de578708bf8d4fccd29a01332281125cf27 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.java.swing.plaf.windows;
27
28import javax.swing.plaf.basic.*;
29import javax.swing.*;
30import javax.swing.plaf.ActionMapUIResource;
31import javax.swing.plaf.ComponentUI;
32import java.awt.event.ActionEvent;
33import java.awt.event.HierarchyEvent;
34import java.awt.event.HierarchyListener;
35import java.awt.event.WindowAdapter;
36import java.awt.event.WindowEvent;
37import java.awt.event.WindowListener;
38import java.awt.event.WindowStateListener;
39
40import java.awt.*;
41
42import com.sun.java.swing.plaf.windows.TMSchema.*;
43import 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 */
55public 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 private static class TakeFocus extends AbstractAction {
138 public void actionPerformed(ActionEvent e) {
139 JMenuBar menuBar = (JMenuBar)e.getSource();
140 JMenu menu = menuBar.getMenu(0);
141 if (menu != null) {
142 MenuSelectionManager msm =
143 MenuSelectionManager.defaultManager();
144 MenuElement path[] = new MenuElement[2];
145 path[0] = (MenuElement)menuBar;
146 path[1] = (MenuElement)menu;
147 msm.setSelectedPath(path);
148
149 // show mnemonics
150 WindowsLookAndFeel.setMnemonicHidden(false);
151 WindowsLookAndFeel.repaintRootPane(menuBar);
152 }
153 }
154 }
155
156 @Override
157 public void paint(Graphics g, JComponent c) {
158 if (WindowsMenuItemUI.isVistaPainting()) {
159 XPStyle xp = XPStyle.getXP();
160 Skin skin;
161 skin = xp.getSkin(c, Part.MP_BARBACKGROUND);
162 int width = c.getWidth();
163 int height = c.getHeight();
164 State state = isActive(c) ? State.ACTIVE : State.INACTIVE;
165 skin.paintSkin(g, 0, 0, width, height, state);
166 } else {
167 super.paint(g, c);
168 }
169 }
170
171 /**
172 * Checks if component belongs to an active window.
173 * @param c component to check
174 * @return true if component belongs to an active window
175 */
176 static boolean isActive(JComponent c) {
177 JRootPane rootPane = c.getRootPane();
178 if (rootPane != null) {
179 Component component = rootPane.getParent();
180 if (component instanceof Window) {
181 return ((Window) component).isActive();
182 }
183 }
184 return true;
185 }
186}