How to detect when a specific window is closed in java

9k views Asked by At

I'm pretty new to Java and I've tried looking this up but couldn't really find any thing that helped. I'm wondering how I could detect when a specific window is closed? I've been using windowClosing() but this applies to any window that is closed, and so the event that I would want to happen as a result of window A closing also happens if window B closes. How do I go about detecting only if window A is closed? Sorry if this is worded badly, I don't know that much Java terminology. Thanks in advance :)

package gui_login;

//awt classes
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

//swing classes
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JOptionPane;
import javax.swing.JButton;

public class windowtest implements ActionListener, WindowListener
{
//get JFrame
    JFrame JFrame = new JFrame();

    public static JFrame frameA = new JFrame("FrameA");
    public static JFrame frameB = new JFrame("FrameB");
    static windowtest windowtest = new windowtest();

public static void main(String[] args) 
{
    windowtest.frames();
}

public void frames()
{
    frameA.setLayout(new FlowLayout());
    frameA.setSize(220, 130);
    frameA.setVisible(true);
    frameA.addWindowListener(this);

    frameB.setLayout(new FlowLayout());
    frameB.setSize(220, 130);
    frameB.setVisible(true);
    frameB.addWindowListener(this);
}

public void windowClosing(WindowEvent e) {
    System.out.println("Yo");
}
public void windowActivated(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void actionPerformed(ActionEvent e) {
}
}
1

There are 1 answers

0
MadProgrammer On BEST ANSWER

Because both frameA and frameB are using the same instance of WindowListener (this), when either frame is closed, your WindowListener is notified (of both/either).

You could use WindowEvent#getSource to get the source of the event, but a easier solution might be to give each frame their own instance of a WindowListener, this way, you don't need to make assumptions about what's going

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class WindowTest {
//get JFrame

    JFrame JFrame = new JFrame();

    public static JFrame frameA = new JFrame("FrameA");
    public static JFrame frameB = new JFrame("FrameB");
    static WindowTest windowtest = new WindowTest();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                windowtest.frames();
            }
        });
    }

    public void frames() {
        frameA.setLayout(new FlowLayout());
        frameA.setSize(220, 130);
        frameA.setVisible(true);
        frameA.addWindowListener(new WindowAdapter() {

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

            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("A has closed");
            }

        });

        frameB.setLayout(new FlowLayout());
        frameB.setSize(220, 130);
        frameB.setVisible(true);
        frameB.addWindowListener(new WindowAdapter() {

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

            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("B has closed");
            }

        });
    }
}

You may not have seen anonymous classes before, take a look at Anonymous Classes

Generally speaking, it's no longer required that you implement interfaces which don't provide direct functionality to your class (like you have with ActionListener and WindowListener), the reasoning is, the methods which these interfaces require you to implement are public, but no one should really be calling them directly.

This allows you to "hide" the implementation details internally to your class and prevents possible mis-use by unknown callers

You may also want to take a look at Nested Classes