Skip to main content

Persistent JMenuBar in OS X anyone?

6 replies [Last post]
davidweaverking
Offline
Joined: 2008-08-26

Hi, I'm writing an app for some mac users in my company and I'm having problems making the JMenuBar for the app stick around when the JFrame it's assigned to goes away. In a normal mac app the MenuBar would stay visible allowing the user to reopen a window or leave the program running, etc. I have code like the following

public void CreateMainWindow() {<br />
        //Create and set up the window.<br />
        JFrame frame = new JFrame("Test Window");<br />
        frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);</p>
<p>        //Add contents to the window.<br />
        frame.add(ContentPanel);<br />
        frame.setJMenuBar(new MyJMenuBar());</p>
<p>        //Display the window.<br />
        frame.pack();<br />
        frame.setVisible(true);<br />
}

When the JFrame closes the program keeps running like it should but the menu goes away. Any ideas?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
davidweaverking
Offline
Joined: 2008-08-26

So I made some progress....maybe. Given the following code

[code]public class myClass extends JFrame {
private JPanel ContentPanel;

public myClass() {
super();
ContentPanel = new MyContentPanel();
CreateMainWindow();
}

public void CreateMainWindow() {
//Create and set up the window.
JWindow window = new JWindow(this);

//Add contents to the window.
window.getContentPane().add(ContentPanel);
window.pack();
window.setVisible(true);

this.setJMenuBar(new MyJMenuBar(this));
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

//Display the window.
this.pack();
this.setVisible(true);
}
}[/code]

I can keep the menubar around all the time which is good but the child window isn't decorated like the JFrame was (ie. no border, title bar, or close/maximize/minimize buttons plus it's not re-sizable or movable). Any ideas on how to make a JWindow look and feel like a JFrame?

walterln
Offline
Joined: 2007-04-17

I've no experience with Macs, but if the menu bar stays for a hidden JWindow, just keep that hidden from the start and show another JFrame as main window for the user? Probably screws up menu shortcut keys though.

nico_v_c
Offline
Joined: 2006-10-04

This won't work because the menu of the JFrame will be shown when it has the focus. Maybe you can switch to an invisible window when the JFrame is hidden? That should be possible with a WindowListener on the JFrame.

davidweaverking
Offline
Joined: 2008-08-26

As per your suggestion I wrote the following code...

[code]public class myClass extends JFrame implements WindowListener {
private JPanel ContentPanel;

public myClass() {
super();
ContentPanel = new MyContentPanel();
CreateMainWindow();
}

public void CreateMainWindow() {
this.addWindowListener(this);

//Add contents to the window.
this.add(ContentPanel);

this.setJMenuBar(new MyJMenuBar());
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

//Display the window.
this.pack();
this.setVisible(true);
}

public void windowClosing(WindowEvent e) {
JWindow dummy = new JWindow();
dummy.addWindowListener(this);

dummy.getContentPane().add(new MyJMenuBar());

dummy.pack();
dummy.setVisible(true);
}

...unused WindowListener methods...
}[/code]

This works great except that in OS X the menu bar is at the top of the screen, not the top of the window. I set a system variable (-Dapple.laf.useScreenMenuBar="true" set with a VM argument) that makes the change for the JFrame but it doesn't work for the JWindow because the JMenuBar is added as a normal component and not with the designated setJMenuBar() method. The shortcut keys work great but the menu is just in the wrong place on the JWindow. I tried using a JFrame instead but there's no way (or at least I haven't found one) to hide the window but keep the menu visible.

Clear as mud? Thanks for the help. Y'all are great :D

nico_v_c
Offline
Joined: 2006-10-04

OK, I had a closer look because I'm soon starting a project where I might need the same feature, and this solution works for me:

[code]
public void windowClosing(WindowEvent e) {
JFrame dummy = new JFrame();
dummy.setUndecorated(true);
dummy.setJMenuBar(new MyJMenuBar());
dummy.pack();
dummy.setVisible(true);
}
[/code]

davidweaverking
Offline
Joined: 2008-08-26

Worked like a charm! Thanks so much.