1

On Mac, apps are expected to "hide" into the dock when clicking the "x" button on the window's title bar, and restore when being clicked on again in the dock.

On Windows and Linux, apps simply terminate upon clicking the "x" button.

How do I replicate this behaviour in a Java Swing application, depending on which operating system the user is on?

tyrondis
  • 3,364
  • 7
  • 32
  • 56

2 Answers2

1

Don't know if there is a better way but you can get the OS system by using:

System.getProperty(...);

Check out the System.getProperties() method for a list of valid properties to query, including the OS.

Then once you have the OS you can use:

frame.setDefaultCloseOperation(...)
camickr
  • 321,443
  • 19
  • 166
  • 288
  • frame.setDefaultCloseOperation(HIDE_ON_CLOSE) seems to do what I want on Mac. However, once the window is minimised into the dock this way, it does not recover anymore. Do you happen to know how to achieve that as well? – tyrondis Jul 25 '23 at 07:32
  • I don't use a Mac so I don't know what the issue would be. – camickr Jul 25 '23 at 14:18
  • Did you try accessing the System Tray (where all the iconified windows lie) ? Something like: https://stackoverflow.com/questions/28920423/show-jframe-when-tray-icon-was-clicked-even-if-minimized – vivek Jul 31 '23 at 09:23
  • 1
    https://stackoverflow.com/questions/70545936/implement-macos-hide-on-quit-behavior-with-jframe-swing this should be helpful – gladiator Aug 03 '23 at 08:19
1

it's easy, just use the WindowListener interface to handle the window closing event and control the behavior based on the operating system, let me explain it with an example, in my example,the MainFrame class extends JFrame and sets the default close operation to DO_NOTHING_ON_CLOSE and the WindowListener is added to handle the window closing event!

check this out:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class MainFrame extends JFrame {

    public MainFrame() {
        setTitle("YOUR APP");
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                handleWindowClosing();
            }
        });
    }

    private void handleWindowClosing() {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("mac")) {
            // Minimize the window on Mac
            setExtendedState(JFrame.ICONIFIED);
        } else {
            // Close the window on other platforms
            dispose();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainFrame frame = new MainFrame();
            frame.setSize(110, 110);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
Freeman
  • 9,464
  • 7
  • 35
  • 58
  • This leads me to the same problem I already had with @camickr's solution. It hide/closes the window correctly, but once it is hidden, I cannot get it to display again. – tyrondis Aug 05 '23 at 08:15
  • 1
    @tyrondis check my answer again plz – Freeman Aug 05 '23 at 08:18
  • getting there. Now it minimises and I can restore the window, however, it also displays the minimising animation on closing, which is not in line with how native apps behave. – tyrondis Aug 05 '23 at 10:34
  • hmmm,the code is fine and should work as expected,when you run the `main()` method, it will create an instance of `MainFrame`, set its size and location, and make it visible on the screen... – Freeman Aug 05 '23 at 11:30