Next: None. Up: Composing GUIs. Previous: Layouts.


Case study: Temperature conversion

This example illustrates the use of the JPanel and GridLayout classes. It creates a simple temperature conversion program that looks like the following.

The way this program works is that you type a temperature into either blank, press Enter, and then the converted temperature appears in the other.

To accomplish this, I set up the JFrame container to use a one-column, two-row grid. In each row of the grid, I placed a panel. The panel uses its default FlowLayout layout and contains both a label component and a text field component.

 1  import java.awt.*;
 2  import java.awt.event.*;
 3  import javax.swing.*;
   
 4  public class TempConvert extends JFrame
 5          implements WindowListener, ActionListener {
 6      private JTextField fahr_field;
 7      private JTextField cels_field;
   
 8      public TempConvert() {
 9          super("Temperature Conversion");
10          addWindowListener(this);
   
11          fahr_field = new JTextField(8);
12          fahr_field.addActionListener(this);
   
13          cels_field = new JTextField(8);
14          cels_field.addActionListener(this);
   
15          Container contents = getContentPane();
16          contents.setLayout(new GridLayout(2, 1));
   
17          JPanel panel = new JPanel();
18          panel.add(new JLabel("Fahrenheit: "));
19          panel.add(fahr_field);
20          contents.add(panel);
   
21          panel = new JPanel();
22          panel.add(new JLabel("Celsius: "));
23          panel.add(cels_field);
24          contents.add(panel);
   
25          pack();
26      }
   
27      public void actionPerformed(ActionEvent evt) {
28          if(evt.getSource() == fahr_field) {
29              try {
30                  double temp = Double.parseDouble(fahr_field.getText());
31                  double val = (temp - 32) / 1.8;
32                  cels_field.setText("" + Math.rint(val * 100) / 100);
33              } catch(NumberFormatException e) { }
34          } else if(evt.getSource() == cels_field) {
35              try {
36                  double temp = Double.parseDouble(cels_field.getText());
37                  double val = 1.8 * temp + 32;
38                  fahr_field.setText("" + Math.rint(val * 100) / 100);
39              } catch(NumberFormatException e) { }
40          }
41      }
   
42      public void windowActivated(WindowEvent e) {}
43      public void windowClosed(WindowEvent e) {}
44      public void windowClosing(WindowEvent e) {
45          System.exit(0);
46      }
47      public void windowDeactivated(WindowEvent e) {}
48      public void windowDeiconified(WindowEvent e) {}
49      public void windowIconified(WindowEvent e) {}
50      public void windowOpened(WindowEvent e)  {}
   
51      public static void main(String[] args) {
52          (new TempConvert()).show();
53      }
54  }

Lines 9 and 11: JFrame and JTextField constructor methods

Lines 9 and 11 illustrate some new constructor methods for the JFrame and JTextField classes.

JFrame(String title)
Creates a window whose title is title.

JTextField(int width)
Creates a text field sized to show width characters. (This doesn't limit the size of the letters, as the field will scroll left and right to accomodate more. But you're only guaranteed to be able to see width characters at a time.)

Line 12: The JTextField action listener

Notice how we're defining an ActionListener for a text field in Line 12. If you add an ActionListener to a text field, its actionPerformed() method occurs whenever the user types Enter into the text field.

Lines 10 and 42-50: Window listeners

We've seen ActionListeners, an interface for defining what happens when an action is performed on an object. There are many other listeners available in Swing, however. In this program, we're defining a WindowListener, which listens for events on a window.

Unlike the ActionListener interface, which has only one method in it, the WindowListener interface includes many methods.

import java.awt.event.*;
public interface WindowListener {
    public void windowActivated(WindowEvent e);
    public void windowClosed(WindowEvent e);
    public void windowClosing(WindowEvent e);
    public void windowDeactivated(WindowEvent e);
    public void windowDeiconified(WindowEvent e);
    public void windowIconified(WindowEvent e);
    public void windowOpened(WindowEvent e);
}

In line 10, we register the TempConvert object being constructed as its own window listener. This obligates us to have the TempConvert class implement the WindowListener interface (line 5), and this obligates us to define all of the methods defined by the WindowListener interface (lines 42-50).

Actually, we ignore all of these window events except one: When the user clicks on the window's close box, the windowClosing() method of its window listeners are called. In line 45, we instruct the program to exit entirely when this occurs.

Lines 18 and 22: The JLabel class

The last new thing that this program illustrates is a use of the JLabel class, which simply represents a string that you want to appear in the window. In line 18, we use the constructor method that takes a String parameter (the string to be displayed), and we immediately add it into the window.

With most of the components we add into the window, we have had instance variables to remember them. But there's no point in trying to remember this component: After we put it into the window, we're not going to touch it again.


Next: None. Up: Composing GUIs. Previous: Layouts.