Return to index

Java Basics 3

 

Topics covered include :

  • Swing APIs
  • Import Statements
  • Class Declaration
  • Instance Variables
  • Action Listeners
  • Event Handling

 

In Java Basics 2 you saw how the Applet class provides a Panel component so you can design the applet's user interface. This lesson expands the basic program from Java Basics 2 to give it a user interface using the Java Foundation Classes (JFC) Swing APIs. It also looks at handling user (GUI) events.

 

A Swing-Based GUI Application

In contrast to the applet in which the user interface is attached to a panel object nested in a top-level browser, the Swing application we will develop here attaches its user interface to a panel object nested in a top-level frame object. A frame object is a top-level window that provides a title bar and methods to manage the appearance and behavior of the window.

We will use classes JFrame, JPanel and JButton from the Swing packages.

The Swing code that follows builds this simple application. The window on the left appears when you start the application, and the window on the right shows how the program looks after you have clicked the button.

When Application Starts

 

When Button Clicked


In the following sections we will look, bit by bit, at the source code for our Swing application - class SwingUI.

 

Import Statements

At the start of the source code there are four lines of import statements. These lines indicate which Java API classes the program uses. You could replace the first two of these lines with this one line: import java.awt.*; to import the entire awt package. Import statements tell the compiler where to look to find compiled classes - in what packages classes referred to in the code belong. The code is not actually included in your own classes.

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

Class Declaration

The class declaration comes next and indicates that the top-level frame for the application's user interface is a JFrame and that the class implements the ActionListener interface.

public class SwingUI extends JFrame implements ActionListener { 
    ... 
} 

The JFrame class extends the Frame class that is part of the Abstract Window Toolkit (AWT) APIs. Swing extends the AWT with a full set of GUI components and services, pluggable look and feel capabilities, and assistive technology support. Many Swing classes that extend an AWT equivalent have a preceding 'J' - for example, JButton is the Swing equivalent of class Button in the AWT.

The Java APIs provide classes and interfaces for you to use. An interface defines a set of methods, but does not implement them. The rest of the SwingUI class declaration indicates that this class will implement the ActionListener interface. This means the SwingUI class must implement all methods defined in the ActionListener interface. Fortunately, there is only one, actionPerformed, which is discussed later.

 

Instance Variables

The next lines declare the Swing component classes the SwingUI class uses. These are class scope, instance variables that can be accessed by any method in the instantiated class. In this example, they are initialised in the SwingUI constructor and accessed in the actionPerformed method implementation.

JLabel text; 
JButton button; 
boolean clicked;
 

Constructor

The constructor (shown below) creates the user interface components and JPanel object, adds the components to the JPanel object, adds the panel to our frame (our instance of SwingUI) and adds an event listener (our instance of SwingUI) to the JButton components. The JFrame object (an instance of SwingUI) is created in the main method when the program starts.

   public SwingUI() { 
         clicked = false;
         text = new JLabel("I'm a Simple Program"); 
         button = new JButton("Click Me"); 
         // Add event listener to button 
         button.addActionListener(this); 
         // Create panel 
         JPanel panel = new JPanel(); 
         // Specify layout manager and background color 
         panel.setLayout(new BorderLayout()); 
         panel.setBackground(Color.white); 
         // Add label and button to panel 
         panel.add(BorderLayout.CENTER, text); 
         panel.add(BorderLayout.SOUTH, button); 
         // Add panel to content pane 
         getContentPane().add(panel); 
   }  

When the JPanel object is created, the layout manager and background color are specified. A layout manager determines how user interface components are arranged on the display area.

The code uses the BorderLayout layout manager, which arranges user interface components in the five areas shown at left. To add a component, specify the area (north, south, east, west, or center).

There are a number of other Layout Managers available and in time you will learn how to use these too.

The call to the getContentPane() method of the JFrame class is for adding our GUI panel to the JFrame . With Swing (unlike with AWT), components are not added directly to a JFrame, but to its content pane. Because the layout manager controls the layout of components, it is set on the content pane where the components reside. A content pane provides functionality that allows different types of components to work together in Swing.

 

Event Handling

In addition to implementing the ActionListener interface, you need to add the event listener to the JButton components. The action listener is the SwingUI object - because it implements the ActionListener interface. In this example, when the end user clicks the button, the underlying Java platform services will pass the action (that is, event) to the actionPerformed method.

The component classes have the appropriate add methods to add action listeners to them. The JButton class has an addActionListener method. The parameter passed to addActionListener in the code is 'this', which means 'this class' - so the SwingUI action listener is added to the button so button-generated actions are passed to the actionPerformed method in the SwingUI object.

      button = new JButton("Click Me"); 
      // Add button as an event listener 
      button.addActionListener(this);  

The actionPerformed() method is passed an event object that represents the action event that occurred.

    public void actionPerformed(ActionEvent event) { 
          if (!clicked) { 
                text.setText("Button Clicked"); 
                button.setText("Click Again"); 
                clicked = true; 
          } 
   }

The 'main()' Method

In our class, the main() method - which is called by the JVM to start the program - creates the top-level frame, sets the frame's title, and includes code that lets the end user close the window using the frame menu or the frame's top-corner 'close' button.

 public static void main(String[] args) { 
       // Create top-level frame 
       SwingUI frame = new SwingUI(); 
       frame.setTitle("Example Swing Application"); 

 

       // This code lets you close the window 
       WindowListener wl = new WindowAdapter() { 
             public void windowClosing(WindowEvent e) { 
                   System.exit(0); 
             } 
       }; 
       frame.addWindowListener(wl); 

 

       // This code sizes the frame (as small as possible) and makes it visible 
       frame.pack(); 
       frame.setVisible(true); 
} 

The code for closing the window shows an easy way to add event handling functionality to a program. If the event listener interface you need provides more functionality than the program actually uses, use an adapter class. The Java APIs provide adapter classes for all listener interfaces with more than one method. In this way, you can use the adapter class instead of the listener interface and implement (override) only the methods you actually need. In the example, the WindowListener interface has 7 methods but our program needs only the windowClosing() method, so it makes sense to use the WindowAdapter class instead.

This code extends the WindowAdapter class and overrides the windowClosing() method. The 'new' keyword creates an anonymous instance of the extended inner class. It is anonymous because you are not assigning a name to the class and you cannot create another instance of the class without executing the code again. It is an inner class because the extended class definition is nested within the SwingUI class.

This approach takes only a few lines of code, while implementing the WindowListener interface would require 6 empty method implementations. Don't forget to add the WindowAdapter object to the frame object so that the frame object will listen for window events.

  WindowListener wl = new WindowAdapter() { 
       // The instantiation of object wl is elaborated to include this code: 
       public void windowClosing(WindowEvent e) { 
              System.exit(0); 
       } 
 };  
 frame.addWindowListener(wl);   

An alternative is to define our own new class extending class WindowAdapter :

  public class MyWinAdapter extends WindowAdapter { 
        public void windowClosing(WindowEvent e) { 
               System.exit(0); 
        } 
  }  

and then add a new instance of it as our frame listener :

  frame.addWindowListener(new MyWinAdapter());  

We don't need to keep a reference to this instance so we can simply write 'new MyWinAdapter()' directly into the method call argument.

If this class is not needed elsewhere it can be an 'inner class' and written within our main class SwingUI, like a method. However, so that this class can be used whenever we need a frame closer, we could write it in a separate file called MyWinAdapter.java.

We could even put this class into a separate package to make reuse even easier. Rather than copying the class each time we want to use it, we simply use an import statement to tell the compiler (and interpreter) where to find the class.

 

Applets Revisited

In short, the main differences between an applet and an application are the following:

  • Applets are designed to run in a web browser.
  • An applet class extends class Applet or JApplet while an application class extends class Frame or JFrame (or is a non-GUI, console application).
  • An applet has no main() method.
  • The application constructor is replaced in an applet by the init() and start() methods (which effectively also take the place of method main()).

An important difference between Swing applets and applications (those that extend class JApplet or JFrame) and non-Swing applets and applications (those that extend class Applet or Frame) is that GUI components are added directly to class Applet or Frame, whereas GUI components are added to the contentPane of class JApplet or JFrame. The contentPane is obtained with method getContentPane(), called on the JApplet or JFrame instance.

Here is the complete source code listing :

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

 

public class SwingUI extends JFrame implements ActionListener { 
      // Class-scope instance variables (identifiers) 
      JLabel text; 
      JButton button; 
      boolean clicked = false; 

 

      // Constructor 
      public SwingUI() { 
             text = new JLabel("I'm a Simple Program"); 
             button = new JButton("Click Me"); 

 

             // Add event listener to button 
             button.addActionListener(this); 
       
             // Create panel to hold button and label 
             JPanel panel = new JPanel(); 

 

             // Specify layout manager and background color 
             panel.setLayout(new BorderLayout()); 
             panel.setBackground(Color.white); 

 

             // Add label and button to panel 
             panel.add(BorderLayout.CENTER, text); 
             panel.add(BorderLayout.SOUTH, button); 

 

             // Add panel to content pane 
             getContentPane().add(panel); 
      } 
    
      public void actionPerformed(ActionEvent event) { 
            if (!clicked) { 
                  text.setText("Button Clicked"); 
                  button.setText("Click Again"); 
                  clicked = true; 
            } 
      } 
    
      public static void main(String[] args) { 
             // Create top-level frame and set title 
             SwingUI frame = new SwingUI(); 
             frame.setTitle("Example Swing Application"); 

 

             // This code lets you close the window 
             WindowListener wl = new WindowAdapter() { 
                   public void windowClosing(WindowEvent e) { 
                         System.exit(0); 
                   } 
             }; 
             frame.addWindowListener(wl); 

 

             // This code sizes the frame (as small as possible) and makes it visible 
             frame.pack(); 
             frame.setVisible(true); 
      } 
} 

 

Download and run ...

An improved version of the applet project is available for download as a TJI project on our web site - in the 'Resources' page.

Simply download the zip file and then choose 'Project Import' from the 'Project' menu. Select the zip file and the project will be imported and setup automatically. Now simply click on the 'Run' button to compile and run the applet.

 

Note : Some parts of this document were based on 'Essentials of the Java Programming Language' a book by Monica Pawlan, also on-line at Sun's java site.

Return to index