javaswingsaf

How to debug a DO_NOTHING_ON_CLOSE failure?


In a swing application I have, as I understand it, told the mainFrame of my application to DO_NOTHING_ON_CLOSE.

public SurveyView(SingleFrameApplication app) throws FileNotFoundException, IOException {
        super(app);

        initComponents();

        JFrame mainFrame = SurveyApp.getApplication().getMainFrame();
        mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        //And on and on it goes...
}

Obviously I'll be adding a window listener and what not to dress it up later, but for now, I just need the window to not close when the X is clicked. But the window DOES close.

It seems so simple of an operation that I can't even think of how to go about debugging it. Am I missing something SUPER obvious?

Edit: And here is the getApplication method within the SurveyApp class:

public static SurveyApp getApplication() {
        return Application.getInstance(SurveyApp.class);
    }

Edit2: Since HoverCraft suggests that mainFrame is not the culprit, maybe an overview of the app structure will point us in the right direction. The entire app is contained in a single JPanel, mainPanel. The panel, in turn, is contained inside public class SurveyView extends FrameView. All of my compenents are added to the panel, which is a card layout which cycles through a few various other JPanels. As I understand it, the close operations are reserved for frames, not for views or panels. Hence why my first thought was to target the main frame of the app.

I know the main frame DOES exist. I tried System.out.println(SurveyApp.getApplication().getMainFrame()) and it output this monster(linebreaks for readability):

javax.swing.JFrame[mainFrame,0,0,0x0,invalid,hidden,
layout=java.awt.BorderLayout,title=Accounting Survey,
resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,
rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,
layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,
alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],
rootPaneCheckingEnabled=true]

And I noticed the title is, in fact, the title that displays in the title bar of my app. But then I saw the DO_NOTHING_ON_CLOSE was set, as it should be, but the app still closed, meaning, I think, Hovercraft is right - this isn't the right target.

Edit3: Further research shows that, indeed, netbeans constructs each panel and adds it to mainPanel and once all panels have been added it calls setComponent(mainPanel);, which I'm assuming is established somewhere else, but a Ctrl-F of the entire program turns up nothing. Does anyone with more experience with netbeans know where all of these methods it uses are defined? If I could find THAT I might be able to figure out what frame needs the no-close set.

Edit4: Alright I think I'm close. The mainPanel is set as the component of the FrameView, which seems to be the wrapper created by a java SingleFrameApplication. I did some reading here: http://bellquel.bo.cnr.it/appframework/org/jdesktop/application/SingleFrameApplication.html and it looks like I was actually correct: the frame created by a SFA is named mainFrame and, according to the docs, "getMainFrame() Returns the JFrame used to show this application." Meaning I AM targetting the right JFrame, and based on my earlier test, the default close operation IS in fact being set to do nothing. So what gives? I'm targetting the correct frame, it is setting the operation correctly, and then it is just being ignored? What could override the default close operation like that?


Solution

  • I just need the window to not close when the X is clicked. But the window DOES close.

    Try this simple code

    EventQueue.invokeLater(new Runnable() {
    
            @Override
            public void run() {
                JFrame frame = new JFrame();                
                frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    
                frame.addWindowListener(new WindowAdapter() {
    
                    @Override
                    public void windowClosing(WindowEvent we) {
                        System.out.println("closing...");
                    }
    
                    @Override
                    public void windowClosed(WindowEvent we) {
                        System.out.println("closed..");
                    }
                });
    
                frame.setVisible(true);
            }
     }
    

    output (when the X is clicked)

    closing...