How do I move my JMenuBar to the screen menu bar on Mac OS X?
Depending on when it's done, setting the property after your program launches may be too late to be effective. Instead, add the setting at launch time.
java -Dapple.laf.useScreenMenuBar=true -jar MyApplication.jar
Alternatively, set the property in your application bundle's Info.plist
, as discussed in Java Deployment Options for Mac OS X, Java Dictionary Info.plist Keys, About Info.plist Keys and Java Runtime System Properties.
<key>Properties</key>
<dict>
<key>apple.laf.useScreenMenuBar</key>
<string>true</string>
...
</dict>
Addendum: As shown below, the problem does not appear using the approach suggested by @Urs Reupke or myself. Your (missing) DesktopMain
may be at fault.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/questions/8955638 */
public class NewMain {
public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty(
"com.apple.mrj.application.apple.menu.about.name", "Name");
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Gabby");
final JPanel dm = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
};
dm.setBorder(BorderFactory.createLineBorder(Color.blue, 10));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(dm);
frame.pack();
frame.setLocationByPlatform(true);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
frame.setVisible(true);
}
});
}
}
Putting JMenu on the Mac menu bar
You can set a System property to do so. The first example on http://developer.apple.com/library/mac/#documentation/Java/Reference/Java_PropertiesRef/Articles/JavaSystemProperties.html mentions to use System.setProperty("apple.laf.useScreenMenuBar", "true");
to put your menu into the menubar.
What is the best way to make an OS X screen JMenuBar work consistently across windows?
You may be able to leverage JDialog
, which inherits its parent's JMenuBar
. To keep the dialogs modeless, you can use
PropertyChangeEvent
to communicate among the dialogs and the mainJFrame
, as suggested here.Action
and Key Bindings to navigate among the dialogs.
Javax JMenuBar with Mac
You can also set the apple.laf.useScreenMenuBar
property to true
in your Info.plist
, as shown here.
Java: How to check whether a JFrame's menu bar is displayed in the systems menubar or in the frame itself?
As shown here, apple.laf.useScreenMenuBar
specifies a Mac OS feature that displays an existing JMenuBar
atop the screen, where a Mac user expects to see it. Although it should be irrelevant to your application, the only time the menu bar is displayed there is when you put it there. A suitable cross-platform predicate might look like this:
if (System.getProperty("os.name").startsWith("Mac OS X")) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("apple.awt.graphics.UseQuartz", "true");
// etc.
}
JMenuBar at the top in MacOSX
Note: This is outdated information - a more recent answer is needed.
Java applications look like traditional java applications even under OS X.
If you want a native look and feel, there are a few tweaks you have to do. This article series describes them.
http://www.oracle.com/technetwork/articles/javase/javatomac-140486.html
http://www.oracle.com/technetwork/java/javatomac2-138389.html
This includes setting the Dock icon and text, and integrating with the Applications menu.
I believe that the OS X "wrap jar as an application" utility with XCode sets all these properties automatically.
Java Menu Bar does not appear
The JMenuItem
quitItem
has not been initialized anywhere, so an exception will be thrown before the JMenuBar
can be added to the JFrame
:
quitItem = new JMenuItem("Quit Game");
quitItem.addActionListener(...);
Aside: Avoid the use of absolute positioning (null
layout) and always use a layout manager.
Problems with JMenuBar when using native Mac OS X MenuBar
Did you set your JDialog's parent object to be the main frame? You shouldn't have to do anything special for the apple menu bar to appear when a jdialog is showing
Is there a way to show KeyBindings with the JMenuBar similar to how is natively shown on MacOS?
See How to Use Menus
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import stackoverflow.Main.TestPane;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
menuBar.add(fileMenu);
fileMenu.add(createMenuItem("New Window", 'N', KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.META_DOWN_MASK)));
fileMenu.add(createMenuItem("New Private Window", 'W', KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
fileMenu.add(createMenuItem("New Tab", 'T', KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.META_DOWN_MASK)));
fileMenu.add(createMenuItem("Open File...", 'O', KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.META_DOWN_MASK)));
fileMenu.add(createMenuItem("Open Location...", 'L', KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.META_DOWN_MASK)));
fileMenu.addSeparator();
fileMenu.add(createMenuItem("Close Window", 'C', KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
fileMenu.add(createMenuItem("Close All Windows", 'A', KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)));
fileMenu.add(createMenuItem("Close Tab", KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_DOWN_MASK)));
fileMenu.add(createMenuItem("Save As...", KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)));
fileMenu.addSeparator();
fileMenu.add(createMenuItem("Share"));
fileMenu.add(createMenuItem("Export as PDF..."));
fileMenu.addSeparator();
fileMenu.add(createMenuItem("Impory From"));
fileMenu.add(createMenuItem("Export Bookmarks..."));
fileMenu.addSeparator();
fileMenu.add(createMenuItem("Print...", 'P', KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.META_DOWN_MASK)));
JFrame frame = new JFrame();
frame.setJMenuBar(menuBar);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public JMenuItem createMenuItem(String text, char mnemonic) {
return createMenuItem(text, mnemonic, null);
}
public JMenuItem createMenuItem(String text, char mnemonic, KeyStroke keyStroke) {
JMenuItem menuItem = new JMenuItem(text);
menuItem.setMnemonic(mnemonic);
menuItem.setAccelerator(keyStroke);
return menuItem;
}
public JMenuItem createMenuItem(String text, KeyStroke keyStroke) {
JMenuItem menuItem = new JMenuItem(text);
menuItem.setAccelerator(keyStroke);
return menuItem;
}
public JMenuItem createMenuItem(String text) {
return new JMenuItem(text);
}
public class TestPane extends JPanel {
public TestPane() {
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
}
You can also make use of Desktop#setDefaultMenuBar
if you'd like to put it in the "native menu bar"
Desktop.getDesktop().setDefaultMenuBar(menuBar);
JFrame frame = new JFrame();
//frame.setJMenuBar(menuBar);
I would recommend becoming familiar with the Desktop
API, as it will be very helpful for you on the Mac platform
Related Topics
Why Call Super() in a Constructor
Recommended Jsf 2.0 Crud Frameworks
What Is the Maximum Depth of the Java Call Stack
How to Execute a Java .Class from the Command Line
Hibernate 5 :- Org.Hibernate.Mappingexception: Unknown Entity
How to Add an Actionlistener Onto a Jbutton in Java
Date and Time Conversion to Some Other Timezone in Java
How to Move My Jmenubar to the Screen Menu Bar on MAC Os X
How to Mark Jtable Cell Input as Invalid
Java Simpledateformat Always Returning January for Month
Calling One Jframe from Another Using Timer Without Any Buttons
How Would You Implement an Lru Cache in Java
How to Convert a Char Array Back to a String
Running Code After Spring Boot Starts
Getting the Filenames of All Files in a Folder
Android Adding Simple Animations While Setvisibility(View.Gone)