javaswingexitwindowlistener

How can I override the default listener for a JFrame close ('x') button?


I want 3 ways of exiting the application

  1. Key stroke CTRL-Q
  2. Select 'Exit' from menu bar
  3. Close 'x' button on JFrame

What I've done so far is add the even listeners for the first two, but I cannot figure out how to have the JFrame close 'x' button to do the same thing. For now it just exits the application without prompting a confirmation, because it doesn't know how to get to that. I basically want all the frames to be disposed, after the user has confirmed that they want to exit. This happens in the first two cases, simply because their action listeners call an exit() method that confirms exiting, and then proceeds to dispose of all frames.

public class MainWindow extends JFrame {
    ...
    this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    this.addWindowListener(new WindowListener() {
        @Override
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }

    ...

    // this is part of the main menu bar (case #2)
    JMenuItem mntmExit = new JMenuItem("Exit");
    mntmExit.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            MainWindow.this.exit();
        }

    });

    // this is case #1
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {

        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_Q && e.getModifiers() == InputEvent.CTRL_MASK) {
                MainWindow.this.exit();
            }

            return false;
        }

    });
}

// the exit method
private void exit() {
    int confirmed = JOptionPane.showConfirmDialog(this, "Are you sure you want to quit?", "Confirm quit", JOptionPane.YES_NO_OPTION);

    if(confirmed == JOptionPane.YES_OPTION) {
        Frame[] frames = Frame.getFrames();

        for(Frame frame : frames) {
            frame.dispose();
        }
    }
}

Is it possible to assign an action listener to the close button? If not, is there another way I should approach this?


Solution

  • In your windowClosing method, call your exit() method before System.exit().

    That will automatically close out your java program when you click the X.