Home > Mobile >  Implement macOS hide on quit behavior with JFrame/Swing
Implement macOS hide on quit behavior with JFrame/Swing

Time:01-01

I'm trying to implement a "iconify on quit" behavior in my Java JFrame app, like most native macOS apps have, but I'm quite stumped.

I've tried doing

Window.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent Event) {
        System.out.println("Closed on macOS, iconifiying");
        Window.setExtendedState(Frame.ICONIFIED);
    }
});

and closing the window on quit with (as well as adding a window listener that calls setVisible(false))

Window.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

The former didn't work because it looks like it's minimized and creates 2 separate icons. The latter didn't because I couldn't find a way to detect when the dock icon is clicked to unhide the window. I'd prefer this method if I could figure out how to do so. Does anybody know how to?

CodePudding user response:

Oh, I forgot to really specify what the behavior I'm trying to mimic really was. When you press the quit button on macOS, the window is made invisible. When you click the app's icon in the dock the window should be made visible again.

You really should read the JavaDocs, that and little bit of Googling brought me around to this simple example...

import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.desktop.AppReopenedEvent;
import java.awt.desktop.AppReopenedListener;
import java.awt.desktop.QuitStrategy;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Test {

    public static void main(String[] args) {
        new Test();

        Desktop.getDesktop().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                Desktop.getDesktop().addAppEventListener(new AppReopenedListener() {
                    @Override
                    public void appReopened(AppReopenedEvent e) {
                        frame.setVisible(true);
                    }

                });
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBorder(new EmptyBorder(32, 32, 32, 32));
            setLayout(new GridBagLayout());
            add(new JLabel("Now you see me"));
        }

    }
}
  • Related