Path: blob/master/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java
41153 views
/*1* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.eawt;2627import java.awt.Container;28import java.awt.Frame;293031import javax.swing.JFrame;32import javax.swing.JLayeredPane;33import javax.swing.JMenuBar;34import javax.swing.plaf.MenuBarUI;3536import com.apple.laf.ScreenMenuBar;37import sun.awt.AWTAccessor;38import sun.lwawt.macosx.CMenuBar;3940import com.apple.laf.AquaMenuBarUI;4142class _AppMenuBarHandler {43private static final int MENU_ABOUT = 1;44private static final int MENU_PREFS = 2;4546private static native void nativeSetMenuState(final int menu, final boolean visible, final boolean enabled);47private static native void nativeSetDefaultMenuBar(final long menuBarPeer);48private static native void nativeActivateDefaultMenuBar(final long menuBarPeer);4950static final _AppMenuBarHandler instance = new _AppMenuBarHandler();51static _AppMenuBarHandler getInstance() {52return instance;53}5455private static ScreenMenuBar defaultMenuBar;5657// callback from the native delegate -init function58private static void initMenuStates(final boolean aboutMenuItemVisible,59final boolean aboutMenuItemEnabled,60final boolean prefsMenuItemVisible,61final boolean prefsMenuItemEnabled) {62synchronized (instance) {63instance.aboutMenuItemVisible = aboutMenuItemVisible;64instance.aboutMenuItemEnabled = aboutMenuItemEnabled;65instance.prefsMenuItemVisible = prefsMenuItemVisible;66instance.prefsMenuItemEnabled = prefsMenuItemEnabled;67}68}6970_AppMenuBarHandler() { }7172boolean aboutMenuItemVisible;73boolean aboutMenuItemEnabled;7475boolean prefsMenuItemVisible;76boolean prefsMenuItemEnabled;77boolean prefsMenuItemExplicitlySet;7879void setDefaultMenuBar(final JMenuBar menuBar) {80installDefaultMenuBar(menuBar);81}8283static boolean isMenuBarActivationNeeded() {84// scan the current frames, and see if any are foreground85final Frame[] frames = Frame.getFrames();86for (final Frame frame : frames) {87if (frame.isVisible() && !isFrameMinimized(frame)) {88return false;89}90}9192return true;93}9495static boolean isFrameMinimized(final Frame frame) {96return (frame.getExtendedState() & Frame.ICONIFIED) != 0;97}9899static void installDefaultMenuBar(final JMenuBar menuBar) {100101if (menuBar == null) {102// intentionally clearing the default menu103if (defaultMenuBar != null) {104defaultMenuBar.removeNotify();105defaultMenuBar = null;106}107nativeSetDefaultMenuBar(0);108return;109}110111Container parent = menuBar.getParent();112if (parent instanceof JLayeredPane) {113((JLayeredPane) parent).remove(menuBar);114}115116MenuBarUI ui = menuBar.getUI();117if (!(ui instanceof AquaMenuBarUI)) {118ui = new AquaMenuBarUI();119menuBar.setUI(ui);120}121122final AquaMenuBarUI aquaUI = (AquaMenuBarUI)ui;123final ScreenMenuBar screenMenuBar = aquaUI.getScreenMenuBar();124if (screenMenuBar == null) {125// Aqua is installed, but we aren't using the screen menu bar126throw new IllegalStateException("Application.setDefaultMenuBar() only works if apple.laf.useScreenMenuBar=true");127}128129if (screenMenuBar != defaultMenuBar) {130if (defaultMenuBar != null) {131defaultMenuBar.removeNotify();132}133defaultMenuBar = screenMenuBar;134screenMenuBar.addNotify();135}136137final Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(screenMenuBar);138if (!(peer instanceof CMenuBar)) {139// such a thing should not be possible140throw new IllegalStateException("Unable to determine native menu bar from provided JMenuBar");141}142143// grab the pointer to the CMenuBar, and retain it in native144((CMenuBar) peer).execute(_AppMenuBarHandler::nativeSetDefaultMenuBar);145146// if there is no currently active frame, install the default menu bar in the application main menu147if (isMenuBarActivationNeeded()) {148((CMenuBar) peer).execute(_AppMenuBarHandler::nativeActivateDefaultMenuBar);149}150}151152void setAboutMenuItemVisible(final boolean present) {153synchronized (this) {154if (aboutMenuItemVisible == present) return;155aboutMenuItemVisible = present;156}157158nativeSetMenuState(MENU_ABOUT, aboutMenuItemVisible, aboutMenuItemEnabled);159}160161void setPreferencesMenuItemVisible(final boolean present) {162synchronized (this) {163prefsMenuItemExplicitlySet = true;164if (prefsMenuItemVisible == present) return;165prefsMenuItemVisible = present;166}167nativeSetMenuState(MENU_PREFS, prefsMenuItemVisible, prefsMenuItemEnabled);168}169170void setAboutMenuItemEnabled(final boolean enable) {171synchronized (this) {172if (aboutMenuItemEnabled == enable) return;173aboutMenuItemEnabled = enable;174}175nativeSetMenuState(MENU_ABOUT, aboutMenuItemVisible, aboutMenuItemEnabled);176}177178void setPreferencesMenuItemEnabled(final boolean enable) {179synchronized (this) {180prefsMenuItemExplicitlySet = true;181if (prefsMenuItemEnabled == enable) return;182prefsMenuItemEnabled = enable;183}184nativeSetMenuState(MENU_PREFS, prefsMenuItemVisible, prefsMenuItemEnabled);185}186187boolean isAboutMenuItemVisible() {188return aboutMenuItemVisible;189}190191boolean isPreferencesMenuItemVisible() {192return prefsMenuItemVisible;193}194195boolean isAboutMenuItemEnabled() {196return aboutMenuItemEnabled;197}198199boolean isPreferencesMenuItemEnabled() {200return prefsMenuItemEnabled;201}202}203204205