Creating an offscreen frame in Java (or: how to avoid a blank menu on a Mac, when all application windows are closed)?
hidden, java, macos, menu, window
Solution
You should definitely consider WizardOfOdds' very helpful answer. Using "The Application Menu" correctly will help, and it's easy to set up a minimal `Info.plist` to get started. A persistent `File` menu will allow your application to open a new window when others are closed. This answer links to a simple example.
Although Apple's Human Interface Guidelines are an excellent guide to what your users will expect, you can certainly experiment with the approach you suggested in your question. In particular, you might try `setLocation(Short.MIN_VALUE, Short.MIN_VALUE)` on the invisible window. In addition, you might want to respond to a `WindowEvent` in some special way if it signals the close of the last visible window.
Addendum: When your listener sees the last visible window close, create a new, empty application window. Alternatively, move the invisible window onscreen and make it visible until the user decides how to proceed.
Addendum: Mac OS X helpfully prevents a visible window form being moved offscreen, but it's easy to put an invisible window in limbo, as shown below.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class FrameTest extends JFrame {
private static FrameTest marco;
private static FrameTest polo;
private static class MyPanel extends JPanel {
public MyPanel() {
super(true);
final JToggleButton b = new JToggleButton("Test");
b.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (b.isSelected()) {
polo.setLocation(100, 100);
polo.setVisible(true);
}
else {
polo.setVisible(false);
polo.setLocation(Short.MIN_VALUE, Short.MIN_VALUE);
}
}
});
this.add(b);
}
}
public FrameTest(String title) {
super(title);
this.setLayout(new BorderLayout());
this.add(new MyPanel());
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
marco = new FrameTest("Marco");
marco.setLocationRelativeTo(null);
marco.setVisible(true);
polo = new FrameTest("Polo");
polo.setLocation(Short.MIN_VALUE, Short.MIN_VALUE);
}
});
}
}
Problem
I am making a Mac application, and I want my menu bar to look right. Any Mac user knows the menu bar should be in the top screen menu. Setting `apple.laf.useScreenMenuBar` to `true` in the property list file gets rid of the in-frame menu bars and moves the menu bar of the current focused window to the screen menu. However, when all windows are hidden or when there are no windows, there are no menu bars to move to the top, and you just get a blank menu. I heard a solution to this was to create an offscreen window that is focused when no others are. The only purpose of it would be its menu, so that it could fill in when the others are gone. However, I've been getting loads of problems. I can't seem to move the window off the screen because Macs won't let you set the coordinates to something past the size of the screen; it just cuts it off and positions it at the edge instead. Is there something else I have to do to make an offscreen window?