java - swing - windowlistener

harveytech picture harveytech · Sep 2, 2011 · Viewed 7k times · Source

If I'm creating a class, and I will load an object of that class in my JFrame (the class is basically a panel with button and text objects, but that doesn't matter much) that isn't instantiated until my public static void main(String[] args) { (which is below the class code), how do I associate WindowListener and other listeners to that JFrame since it's not apart of the original class?

Normally when I have this issue Eclipse tells me to make that JFrame or other object static and call it universally, but I tried that and I don't think it worked with an instance of JFrame.

I've read through http://download.oracle.com/javase/tutorial/uiswing/events/windowlistener.html and other tutorials but I want a general answer as much an an answer to this specific question for my app, because I run into this a lot.

Thank you to anyone who can help or anyone who reads this!

Answer

Ben picture Ben · Sep 2, 2011

Showing us your existing code would make it clearer what you are trying to do, but it sounds as if you have one class that both represents your panel and also contains your main method. That is possible but I would not recommend it because it obscures the structure of the application, although it is a popular technique in tutorials because it enables everything to fit into one file.

A WindowListener represents any object that needs to respond to window events, i.e. changes in the state of the window (a JFrame in this case) when it is activated, iconified etc. The listener may also represent a graphical component but need not do so.

Here is a very simple example that I hope will illustrate the concepts. Let's create a class representing a type of panel containing a JLabel that will display the number of window events that have occurred so far. It will also implement WindowListener so that it can be notified of these events and increment a counter each time one occurs.

You should be able to compile and run this code as it is, and then watch the counter change if you minimize/maximize the window, click on other windows and so on.

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

public class TestPanel extends JPanel implements WindowListener {
    private JLabel label = new JLabel("No window events yet");
    private int numEvents = 0;

    public TestPanel() {this.add(label);}

    private void update() {
        label.setText(String.format("%d events",numEvents));
    }

    public void windowOpened(WindowEvent e) {
        numEvents++;
        update();
    }

    // ... similar implementations of the other WindowListener methods ...
}

Then we need a main program to instantiate one of our panels and display it in a JFrame.

import javax.swing.*;

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndDisplayGui();
            }
        });
    }

    private static void createAndDisplayGui() {
        JFrame frame = new JFrame("Test Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TestPanel panel = new TestPanel();
        frame.add(panel);               // add the panel as a component in the frame
        frame.addWindowListener(panel); // add the panel as a listener to the frame
        frame.pack();                   // lay out and size the frame
        frame.setVisible(true);         // display the frame
    }
}