All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.roydesign.ui.JScreenMenuBar Maven / Gradle / Ivy

Go to download

MRJ Adapter is a wrapper around built in Java Virtual Machine APIs provided by Apple.

The newest version!
/*******************************************************************************

	File:		JScreenMenuBar.java
	Author:		Steve Roy 
				
	Part of MRJ Adapter, a unified API for easy integration of Mac OS specific
	functionality within your cross-platform Java application.
	
	This library is open source and can be modified and/or distributed under
	the terms of the Artistic License.
	
	
	Change History:
	12/30/02	Created this file - Steve
	02/26/04    Merged into MRJ Adapter - Steve
	04/16/04    Renamed from JMenuBar to JScreenMenuBar - Steve

*******************************************************************************/

package net.roydesign.ui;

import net.roydesign.mac.MRJAdapter;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import java.awt.Component;

/**
 * 

A subclass of {@code javax.swing.JMenuBar} that adds the logistics * needed to make menu bars conform to the Mac OS screen menu bar requirements * without sacrificing the usual way of presenting menu bars on other platforms. * On Mac OS and Mac OS X, the menu bar sits at the top of the screen, contrary * to other platforms that locate a distinct menu bar in each frame. This * difference in UI design makes it challenging to write code that gracefully * handles all platforms, and this class, along with {@code JScreenMenu} * and {@code JScreenMenuItem} improve on the existing Swing classes to * fill the gap.

* *

This works with the introduction of a concept called user frames. The word * "user" here doesn't refer to the computer user but rather to frames that make * use of a menu and a menu item. Rather then if/elsing your code when constructing * your menu bars to handle different platforms, you simply code one menu bar where * you specify which menus and menu items are actually used by which frame classes. * With this in place, you just add an instance of the menu bar to all your frames, * and it will automatically decide by itself which menus and menu items should be * visible or not, and enabled or not, depending on the current platform and whether * the screen menu bar is used. This is all done via the method * addUserFrame() in the {@code JScreenMenu} and * {@code JScreenMenuItem} classes. The behavior is as follows. On the Mac * with the screen menu bar in use, when the host frame is not a user frame, * then the menu or menu item is simply disabled. On other platforms, the menu * is instead removed. This satisfies the requirement of having an all-inclusive * menu bar on the Mac while allowing distinct menu bars on other platforms.

* *

Typically, the most convenient way of using these classes is to subclass * {@code JScreenMenuBar} and then instantiate it for each of your frames.

* *

 * public class MyMenuBar extends JScreenMenuBar
 * {
 *     public MyMenuBar()
 *     {
 *         // All frames get this menu
 *         JScreenMenu m = new JScreenMenu("Foo");
 *         add(m);
 *         
 *         // Even though all frames get the Foo menu, only
 *         // MyFrame gets this menu item
 *         JScreenMenuItem mi = new JScreenMenuItem("Hello");
 *         mi.addUserFrame(MyFrame.class);
 *         m.add(mi);
 *         
 *         // Just MyFrame and MyFrameToo get this menu
 *         m = new JScreenMenu("Bar");
 *         m.addUserFrame(MyFrame.class);
 *         m.addUserFrame(MyFrameToo.class);
 *         add(m);
 *         
 *         // And all frames that get the Bar menu get
 *         // this menu item
 *         mi = new JScreenMenuItem("Bye Bye");
 *         m.add(mi);
 *     }
 * }
 * 
* *

It's important to mention that this set of menu classes doesn't provide * support for shared menus, which developers sometimes request. A shared menu * shares its state within all its displayed instances, meaning for example that * if you disable it, all its instances will be disabled, which might or might * not be what you desire, especially in the context of a document-based user * interface. On the contrary, this set of classes creates separate instances * of menus and menu items, each with its own state, even though they might all * look like the same menu to the user, particularly on Mac OS.

* * @version MRJ Adapter 1.2 */ public class JScreenMenuBar extends JMenuBar { /** * This method is overriden to disable or hide the menus that don't * belong in the menu bar for the parent frame. */ @Override public void addNotify() { // Get the parent frame JFrame f = getParentFrame(); // Check if the frame makes any use of each menu int n = getComponentCount(); for (int i = n - 1; i >= 0; i--) { Component m = getComponent(i); if (m instanceof JScreenMenu && !((JScreenMenu)m).isUsedBy(f)) { if (MRJAdapter.isSwingUsingScreenMenuBar()) m.setEnabled(false); else m.setVisible(false); /** @todo With MRJ 2.x (Swing 1.1.1), the space is not reclaimed */ } } super.addNotify(); } /** * Get the parent frame of the menu. * @return the parent {@code javax.swing.JFrame} */ protected JFrame getParentFrame() { Component comp = getParent(); while (comp != null && !(comp instanceof JFrame)) comp = comp.getParent(); return (JFrame)comp; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy