sparta123
sparta123

Reputation: 31

Check what triggered WindowClosing event

Is there a way to see what exactly triggered WindowClosing event in a JFrame? At the moment getSource(), it seems to only be returning the JFrame:

public void windowClosing(WindowEvent e) {
      JOptionPane.showMessageDialog(null, "event source: " + e.getSource(), "Test", JOptionPane.OK_OPTION);
      methodA();
            } 

I want to know this due to the method dispose() triggering a WindowClosing event. So if a button is clicked which invokes methodA() and then dispose(), dispose() triggers a closing event which is defined to call methodA() as well. This causes methodA() to be called twice and I don't want that.

public void actionPerformed(ActionEvent e) {
        if (e.getSource() == confirmButton) {
            methodA();
            dispose(); //this will trigger window closing and call methodA() again

        }
    }

So the way I want to solve the problem is to check if a specific button named "Confirm" is the one that triggered the closing event. Then I wouldn't want to invoke methodA() so that it's not calledtwice.

If this is impossible, can I at least check whether the close (X) button in the frame is the one that invoked the window closing event?

Thanks

Upvotes: 1

Views: 1037

Answers (1)

dic19
dic19

Reputation: 17971

I want to know this due to the method dispose() triggering a WindowClosing event. So if a button is clicked which invokes methodA() and then dispose(), dispose() triggers a closing event which is defined to call methodA() as well. This causes methodA() to be called twice and I don't want that.

IMHO there's a design mistake here related to the responsibility of each component in the sense that Close button should just do what it is expected to do: close the frame. Or even better dispatch a WINDOW_CLOSING event and let the WindowListener do whatever it has to be done.

If you need to be sure that methodA() is called before close the top-level container (window) then the WindowListener sounds like the right candidate to call that method. I'd set the default close operation to DO_NOTHING_ON_CLOSE and let the listener dispose the window if and only if the necessary conditions are met.

See this approach exemplified here and also consider the following snippet:

JButton closeButton = new JButton("Close");
closeButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        Window window = SwingUtilities.windowForComponent((JButton)e.getSource());
        window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
    }
});

...

JFrame frame = new JFrame("Frame");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {

    @Override
    public void windowClosing(WindowEvent e) {
        // Call methodA() here.
        // If all went ok then dispose the window, otherwise log the 
        // errors/exceptions and notify the user that something went wrong.
        e.getWindow().dispose();
    }
});

Upvotes: 3

Related Questions