4

I am creating a window that I need to close it by only clicking a button.
For that I'm using
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE) mehod.

But the problem is my Mac is closing that window when I click command + q.
Here is a code:

package screen.saver;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;

public class ScreenSaver {

    public static void main(final String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        JFrame screenSaverFrame = new JFrame();
        screenSaverFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        screenSaverFrame.setUndecorated(true);
        screenSaverFrame.setResizable(false);

        JButton closeWindow = new JButton("Close window");
        closeWindow.addActionListener(e -> {
            screenSaverFrame.dispose();
        });

        screenSaverFrame.add(closeWindow, BorderLayout.CENTER);
        screenSaverFrame.validate();
        GraphicsEnvironment.getLocalGraphicsEnvironment()
                .getDefaultScreenDevice()
                .setFullScreenWindow(screenSaverFrame);
    }
}
Valeme
  • 139
  • 8
  • *"But the problem is my Mac is closing that window when I click command + q"* - Yes, that's how it works, CMD+Q is terminating the process – MadProgrammer Nov 28 '17 at 07:22
  • But I don't what it to be closed by command + q. I want to close it only by button – Valeme Nov 28 '17 at 07:24
  • Why? What did your users do to you? – MadProgrammer Nov 28 '17 at 07:24
  • I just want to lock my screen every 30 minutes for making breaks. – Valeme Nov 28 '17 at 07:31
  • 1
    I would suggest having a look at ` Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);` and `Application.getApplication().disableSuddenTermination();` - see [this example](https://stackoverflow.com/questions/2061194/swing-on-osx-how-to-trap-command-q) for more details – MadProgrammer Nov 28 '17 at 07:31
  • *"I just want to lock my screen every 30 minutes for making breaks"* - This won't stop you, because you could CMD+Tab to get to other processes – MadProgrammer Nov 28 '17 at 07:33
  • It won't switch to another application by cmd + Tab. I have already checked it. )) It is only reacting on cmd + q – Valeme Nov 28 '17 at 07:34
  • @MadProgrammer thanks for [this example](https://stackoverflow.com/questions/2061194/swing-on-osx-how-to-trap-command-q). It worked. – Valeme Nov 28 '17 at 07:43

1 Answers1

6

Apple provides a couple of useful APIs. Start by having a look at Java for OS X v10.6 Update 3 and 10.5 Update 8 Release Notes and this example for more details.

In particular, what you're really interested in

Sudden Termination

Java applications on OS X v10.6 can now opt-in to being suddenly terminated by the OS to speed log-out and shut down. Apps can raise and lower their sudden termination count with the enableSuddenTermination() and disableSuddenTermination() methods on the com.apple.eawt.Application class. More information on Sudden Termination is available in NSProcessInfo Class Reference. (5756768)

Default Quit Action

Applications can now request that the eAWT send WindowClosing events to all open windows instead of calling System.exit(0) when the user choose Quit from the application menu. By setting the apple.eawt.quitStrategy system property to CLOSE_ALL_WINDOWS, the eAWT will send a close event to every window in back-to-front order (3198576).

This should allow you to better control how the app is terminated, for example...

import com.apple.eawt.Application;
import com.apple.eawt.FullScreenUtilities;
import com.apple.eawt.QuitStrategy;
import java.awt.EventQueue;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Test {

    public static void main(String[] args) {
        Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
        Application.getApplication().disableSuddenTermination();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.setUndecorated(true);
                FullScreenUtilities.setWindowCanFullScreen(frame, true);
                frame.setLayout(new GridBagLayout());
                JButton close = new JButton("Close me");
                close.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        frame.dispose();
                    }
                });
                frame.add(close);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosed(WindowEvent e) {
                        System.out.println("Closed");
                    }

                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.out.println("Closing");
                    }

                });
                frame.setLocationRelativeTo(null);
                //Application.getApplication().requestToggleFullScreen(frame);
                //frame.setVisible(true);
                GraphicsEnvironment.getLocalGraphicsEnvironment()
                                .getDefaultScreenDevice()
                                .setFullScreenWindow(frame);
            }
        });
    }
}

When pressing CMD+Q, the windowClosing event is triggered, meaning the only way to terminate the app is tap the close button

Java 9

It should be noted that, for those people lucky enough to be using it, Java 9 adds much of the support which was previously found in com.apple.eawt to the API via the java.awt.Desktop API

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • By the way, how about other OS – Valeme Nov 28 '17 at 07:50
  • If you want run it on other os’s, you’ll need to use reflection to make it work (as it’ll crash otherwise). Using DO_NOTHING “should” work on Windows, but you’ll have to test it – MadProgrammer Nov 28 '17 at 07:53