Creating an offscreen frame in Java (or: how to avoid a blank menu on a Mac, when all application windows are closed)?

后端 未结 6 1860
囚心锁ツ
囚心锁ツ 2020-12-19 08:55

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.useSc

6条回答
  •  臣服心动
    2020-12-19 09:21

    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);
                }
            });
        }
    }
    

提交回复
热议问题