«^»
2.9. Stage F: closing the window

Although this has achieved our goal of altering the JTextField component whenever the JButton component is clicked, there is one other thing that we ought to do. Up until now, the only way in which we have been able to terminate the execution of the program has been to press Ctrl/C. With this example, it may be useful to terminate the execution when the user closes the window.

In the same way that an ActionListener object is created to handle clicks on the JButton, we can establish an object which is responsible for handling events on a window. Unlike the ActionListener interface where we only had to provide one method, the WindowListener interface requires us to provide seven methods to provide for seven events concerning the manipulation of windows. The details are given on java.awt.event.WindowListener's WWW page which is at javaapi:java/awt/event/WindowListener.html.

Here is a class that implements the WindowListener interface:

0109: //                                               // ExitOnWindowClosing.java
0110: // Stage F: implementing the WindowListener interface.
0111: // Barry Cornelius, 22nd November 1999
0112: import java.awt.       Window;
0113: import java.awt.event. WindowEvent;
0114: import java.awt.event. WindowListener;
0115: public class ExitOnWindowClosing implements WindowListener
0116: {
0117:    public void windowActivated(final WindowEvent pWindowEvent)
0118:    {
0119:    }
0120:    public void windowClosed(final WindowEvent pWindowEvent)
0121:    {
0122:    }
0123:    public void windowClosing(final WindowEvent pWindowEvent)
0124:    {
0125:       final Window tWindow = pWindowEvent.getWindow();
0126:       tWindow.setVisible(false);
0127:       tWindow.dispose();
0128:       System.exit(0);
0129:    }
0130:    public void windowDeactivated(final WindowEvent pWindowEvent)
0131:    {
0132:    }
0133:    public void windowDeiconified(final WindowEvent pWindowEvent)
0134:    {
0135:    }
0136:    public void windowIconified(final WindowEvent pWindowEvent)
0137:    {
0138:    }
0139:    public void windowOpened(final WindowEvent pWindowEvent)
0140:    {
0141:    }
0142: }

Note that this class has the implements clause implements WindowListener and has method declarations for each of the seven methods.

Because we only want to do something special when a window is about to close, some code has been provided for the windowClosing method whereas the other six method declarations have empty blocks.

When using the ActionListener interface, we had to:

We have to do similar things when using the WindowListener interface.

Consider this version of the GetDateProg program:

0143: //                                                       // GetDateProg.java
0144: // Stage F: using a WindowListener to handle a window-closing event.
0145: // Barry Cornelius, 22nd November 1999
0146: import java.awt.    BorderLayout;
0147: import java.awt.    Container;
0148: import javax.swing. JButton;
0149: import javax.swing. JFrame;
0150: import javax.swing. JTextField;
0151: public class GetDateProg
0152: {
0153:    public static void main(final String[] pArgs)
0154:    {
0155:       final JFrame tJFrame = new JFrame("GetDateProg: Stage F");
0156:       final JTextField tJTextField = new JTextField("hello", 35);
0157:       final JButton tJButton = new JButton("Get Date");
0158:       final JButtonListener tJButtonListener = new JButtonListener(tJTextField);
0159:       tJButton.addActionListener(tJButtonListener);
0160:       final Container tContentPane = tJFrame.getContentPane();
0161:       tContentPane.add(tJTextField, BorderLayout.NORTH);
0162:       tContentPane.add(tJButton, BorderLayout.SOUTH);
0163:       final ExitOnWindowClosing tExitOnWindowClosing =
0164:                                                new ExitOnWindowClosing();
0165:       tJFrame.addWindowListener(tExitOnWindowClosing);
0166:       tJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
0167:       tJFrame.pack();
0168:       tJFrame.setVisible(true);
0169:    }
0170: }

This program includes code that creates an ExitOnWindowClosing object:

ExitOnWindowClosing tExitOnWindowClosing = new ExitOnWindowClosing();
and registers this object as a listener for window events on the window associated with the tJFrame object:
tJFrame.addWindowListener(tExitOnWindowClosing);
The following statement (from the GetDateProg program) ensures that, when the user clicks on the window's close button, the window is not removed from the screen:
tJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
This is to ensure that the program retains control: the window will only be removed when the program executes setVisible with an argument of false.

Now when the user manipulates the window, one of the methods of the ExitOnWindowClosing class will get executed. Most of these do not do anything. However, when the user clicks on the button to close the window, the code of the following method declaration gets executed:

public void windowClosing(final WindowEvent pWindowEvent)
{
   final Window tWindow = pWindowEvent.getWindow();
   tWindow.setVisible(false);
   tWindow.dispose();
   System.exit(0);
}
You can see that when the windowClosing method is called, some object (that is of the class WindowEvent) is passed as an argument to windowClosing. This object contains details of what caused the window event to take place. The WindowEvent class has various methods that can be applied to this WindowEvent object: one of these is called getWindow. So, the first statement of the windowClosing method makes tWindow point to the Window object associated with the window being closed. For GetDateProg, this is the JFrame object that was created by its main method.

A reference variable (that is of a class type) can point to an object of its class or an object of any subclass. Here, tWindow, a reference variable of the class type java.awt.Window is pointing to an object of the class javax.swing.JFrame, one of the subclasses of java.awt.Window.

The next statement of the windowClosing method calls the setVisible method. The call of setVisible with argument false ensures that the window is no longer displayed on the screen. When a Window object (such as a JFrame object) is created, some other objects are created. The call of dispose indicates that the space for these objects is no longer required. Although in general it is useful to do this, it is unnecessary in this program as the call of dispose is followed by the call of System.exit that terminates the program.