blob: b55a01c53b3c3eaaa64a69424f62e90562bf42e9 [file] [log] [blame]
/*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.java.swing.plaf.windows;
import javax.swing.plaf.basic.*;
import javax.swing.*;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import java.awt.event.ActionEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.*;
import com.sun.java.swing.plaf.windows.TMSchema.*;
import com.sun.java.swing.plaf.windows.XPStyle.*;
/**
* Windows rendition of the component.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is appropriate
* for short term storage or RMI between applications running the same
* version of Swing. A future release of Swing will provide support for
* long term persistence.
*/
public class WindowsMenuBarUI extends BasicMenuBarUI
{
/* to be accessed on the EDT only */
private WindowListener windowListener = null;
private HierarchyListener hierarchyListener = null;
private Window window = null;
public static ComponentUI createUI(JComponent x) {
return new WindowsMenuBarUI();
}
@Override
protected void uninstallListeners() {
uninstallWindowListener();
if (hierarchyListener != null) {
menuBar.removeHierarchyListener(hierarchyListener);
hierarchyListener = null;
}
super.uninstallListeners();
}
private void installWindowListener() {
if (windowListener == null) {
Component component = menuBar.getTopLevelAncestor();
if (component instanceof Window) {
window = (Window) component;
windowListener = new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
menuBar.repaint();
}
@Override
public void windowDeactivated(WindowEvent e) {
menuBar.repaint();
}
};
((Window) component).addWindowListener(windowListener);
}
}
}
private void uninstallWindowListener() {
if (windowListener != null && window != null) {
window.removeWindowListener(windowListener);
}
window = null;
windowListener = null;
}
@Override
protected void installListeners() {
if (WindowsLookAndFeel.isOnVista()) {
installWindowListener();
hierarchyListener =
new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags()
& HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
if (menuBar.isDisplayable()) {
installWindowListener();
} else {
uninstallWindowListener();
}
}
}
};
menuBar.addHierarchyListener(hierarchyListener);
}
super.installListeners();
}
protected void installKeyboardActions() {
super.installKeyboardActions();
ActionMap map = SwingUtilities.getUIActionMap(menuBar);
if (map == null) {
map = new ActionMapUIResource();
SwingUtilities.replaceUIActionMap(menuBar, map);
}
map.put("takeFocus", new TakeFocus());
}
/**
* Action that activates the menu (e.g. when F10 is pressed).
* Unlike BasicMenuBarUI.TakeFocus, this Action will not show menu popup.
*/
private static class TakeFocus extends AbstractAction {
public void actionPerformed(ActionEvent e) {
JMenuBar menuBar = (JMenuBar)e.getSource();
JMenu menu = menuBar.getMenu(0);
if (menu != null) {
MenuSelectionManager msm =
MenuSelectionManager.defaultManager();
MenuElement path[] = new MenuElement[2];
path[0] = (MenuElement)menuBar;
path[1] = (MenuElement)menu;
msm.setSelectedPath(path);
// show mnemonics
WindowsLookAndFeel.setMnemonicHidden(false);
WindowsLookAndFeel.repaintRootPane(menuBar);
}
}
}
@Override
public void paint(Graphics g, JComponent c) {
XPStyle xp = XPStyle.getXP();
if (WindowsMenuItemUI.isVistaPainting(xp)) {
Skin skin;
skin = xp.getSkin(c, Part.MP_BARBACKGROUND);
int width = c.getWidth();
int height = c.getHeight();
State state = isActive(c) ? State.ACTIVE : State.INACTIVE;
skin.paintSkin(g, 0, 0, width, height, state);
} else {
super.paint(g, c);
}
}
/**
* Checks if component belongs to an active window.
* @param c component to check
* @return true if component belongs to an active window
*/
static boolean isActive(JComponent c) {
JRootPane rootPane = c.getRootPane();
if (rootPane != null) {
Component component = rootPane.getParent();
if (component instanceof Window) {
return ((Window) component).isActive();
}
}
return true;
}
}