Java - how do I prevent WindowClosing from actually closing the window
Asked Answered
P

7

56

I seem to have the reverse problem to most people. I have the following pretty standard code to see if the user wants to do some saves before closing the window:

  frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
  frame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent ev) {
      boolean close = true;
         // check some files, asking if the user wants to save
         // YES and NO handle OK, but if the user hits Cancel on any file,
         //   I want to abort the close process     
         // So if any of them hit Cancel, I set "close" to false
      if (close) {
          frame.dispose();
          System.exit(0);
         }
       }            
});

No matter what I try, the window always closes when I come out of windowClosing. Changing WindowAdapter to WindowListener doesn't make any difference. What is weird is that the documentation explicitly says "If the program does not explicitly hide or dispose the window while processing this event, the window close operation will be cancelled," but it doesn't work that way for me. Is there some other way of handling the x on the frame? TIA

Polarize answered 30/9, 2011 at 16:52 Comment(3)
I'll bet there's a bug somewhere that will be obvious to you if you simplify your problem as much as possible by creating an sscce. If it doesn't become obvious, then you can post the sscce and we can work on it and better be able to help you.Kristopherkristos
Based on the code provided, your logic to set the close variable is probably wrong. Since it defaults to true it would appear you don't reset it properly. Did you print out the value before the if statement?Chaparro
I just ran into another situation that can cause these symptoms if using Netbeans (8.0). The code auto-generated by Design View will add its own default close operation, which can override the behavior specified in the human-generated code. This can be edited in the JDialog properties box. (leaving this comment for future generations seeking solutions to similar problems, despite not being the answer to Paul's question.)Italianate
C
80

I've just tried this minimal test case:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class Test {

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent ev) {
                //frame.dispose();
            }
        });
        frame.setVisible(true);
    }

}

If I keep the dispose call commented, and hit the close button, the window doesn't exit. Uncomment that and hit the close button, window closes.

I'd have to guess that something is wrong in your logic to set your "close" variable. Try double checking that.

Clemons answered 30/9, 2011 at 17:0 Comment(4)
Thanks, everyone! I found it and indeed it was my problem. Knowing that the simple case worked helped a lot!Polarize
please learn java naming conventions and stick to them - +1 for the shortest test case, though :-)Hsiuhsu
Setting the default close operation was key for me as listed in the above demo and mentioned in other answers.Cockatiel
Clean answer. +1Frasquito
S
26

This is the key, methinks: frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); Makes the difference in the test case I cooked up.

Stinkstone answered 30/9, 2011 at 17:7 Comment(1)
This was key to the whole thing. EXIT_ON_CLOSE seems to override all of the stuff mentioned in the other answers. Thanks Ben!Landlordism
K
7

not sure where is your problem,

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

public class ClosingFrame extends JFrame {

    private JMenuBar MenuBar = new JMenuBar();
    private JFrame frame = new JFrame();
    private static final long serialVersionUID = 1L;
    private JMenu File = new JMenu("File");
    private JMenuItem Exit = new JMenuItem("Exit");

    public ClosingFrame() {
        File.add(Exit);
        MenuBar.add(File);
        Exit.addActionListener(new ExitListener());
        WindowListener exitListener = new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                int confirm = JOptionPane.showOptionDialog(frame,
                        "Are You Sure to Close this Application?",
                        "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                        JOptionPane.QUESTION_MESSAGE, null, null, null);
                if (confirm == JOptionPane.YES_OPTION) {
                    System.exit(1);
                }
            }
        };
        frame.addWindowListener(exitListener);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setJMenuBar(MenuBar);
        frame.setPreferredSize(new Dimension(400, 300));
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

    private class ExitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            int confirm = JOptionPane.showOptionDialog(frame,
                    "Are You Sure to Close this Application?",
                    "Exit Confirmation", JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE, null, null, null);
            if (confirm == JOptionPane.YES_OPTION) {
                System.exit(1);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ClosingFrame cf = new ClosingFrame();
            }
        });
    }
}
Karmakarmadharaya answered 30/9, 2011 at 17:12 Comment(1)
Don't use magic numbers. What does confirm == 0 mean? Intead you should use confirm == JOptionPane.YES_OPTION for easier understanding.Chaparro
O
5

For the handling of this thing do:
if the user selects yes then use setDefaultCloseOperation(DISPOSE_ON_CLOSE); within the curly braces of that if else

if a cancel is selected then use setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

Consider example:

int safe = JOptionPane.showConfirmDialog(null, "titleDetails!",  "title!!", JOptionPane.YES_NO_CANCEL_OPTION);

if(safe == JOptionPane.YES_OPTION){
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);//yes

} else if (safe == JOptionPane.CANCEL_OPTION) {
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);//cancel
} else {
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);//no
}
Olwen answered 4/4, 2014 at 19:47 Comment(1)
thank you if i put this code in the closing event will prevent the dialog from closingClaro
H
1

Not sure where your problem is, but this works for me!

frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent evt) {
                            int res=JOptionPane.showConfirmDialog(null,
                                    "Do you want to exit.?");
                            if(res==JOptionPane.YES_OPTION){
                                    Cal.this.dispose();
                            }
            }                               
        });
Hickox answered 31/5, 2015 at 5:27 Comment(0)
S
1

To solve the same problem I tried the very first answer of this article. As separate application it works, but not in my case. Maybe difference is in JFrame(in answer) and FrameView (my case).

public class MyApp extends SingleFrameApplication { // application class of my project
  ...
  protected static MyView mainForm; // main form of application
  ... 
}  
public class MyView extends FrameView {
    ...
    //Adding this listener solves the problem. 
    MyApp.getInstance().addExitListener(new ExitListener() {

      @Override
      public boolean canExit(EventObject event) {
        boolean res = false;
        int reply = JOptionPane.showConfirmDialog(null,
                "Are You sure?", "", JOptionPane.YES_NO_OPTION);
        if (reply == JOptionPane.YES_OPTION) {
          res = true;
        }
        return res;
      }
      @Override
      public void willExit(EventObject event) {
      }
    });
    ...
}   
Sickly answered 10/8, 2015 at 12:37 Comment(0)
T
0

setDefaultCloseOperation() method helps in the problem .https://chortle.ccsu.edu/java5/Notes/chap56/ch56_9.html

view this link

Toogood answered 12/4, 2016 at 19:50 Comment(1)
While link-only answers are answers, it is better to put the explanation in the answer and use the link as a reference, since links can break.Glanville

© 2022 - 2024 — McMap. All rights reserved.