The Department of Computer Science & Engineering
cse@buffalo
STUART C. SHAPIRO: CSE 116 B

CSE 116
Introduction To Computer Science for Majors 2
Lecture B
Lecture Notes
Stuart C. Shapiro
Spring, 2003


An Introduction to Swing

Readings

Introduction
java.awt and javax.swing are packages of classes and interfaces for building Java Graphical User Interfaces (GUIs). Swing was created more recently than awt, and many swing classes and interfaces are extensions of those of awt. For example, javax.swing.JFrame is an extension of java.awt.Frame. Whenever there is a swing class that seems to duplicate an awt class, it is generally a good idea to use the swing version, and in these notes, I'll ignore the awt class whenever there is a preferable swing class.

Applications vs. Applets
The top-most windows of applications and applets are different, but from there on down applets and applications work the same way.

The topmost window of an application must be a javax.swing.JFrame. To get a JFrame to appear on the screen, you must call its show method. See EmptyFrame.java.

You probably will want to give your JFrame a size, using setBounds(int xloc, int yloc, int width, int height), and you might also want to give it a title, using the alternate constructor JFrame(String title). See SizedFrame.java.

Finally, so that your application will terminate graciously, you should call setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) on your frame. See TerminatingFrame.java.

Applets are to be run from within browser windows, or by appletviewer.

The topmost class of an applet, below the browser window, must be a javax.swing.JApplet . Whenever an applet is started or revisited, its start() method is called. It may also need the methods init(), which is run when it is first loaded, stop(), and destroy(). However, for simple applets, none of these may be needed. See the java.awt.Applet API. For an example that has no content, see EmptyApplet.java.

The applet is run from within an HTML page using the applet tag, which determines the applet's placement and size. See EmptyApplet.html.

To run appletviewer on an applet named MyApplet, you must have a file named MyApplet.html in the same directory.

Containers and Components
To put any contents into a GUI or an applet, they must be put into some java.awt.Container.

Every JFrame and JApplet comes equipped with a Container called its contentPane, which can be accessed using the method getContentPane(). Essentially all contents of a JFrame or JApplet must be put into its contentPane, or in some container nested, however deeply, within its contentPane.

A simple way to see a contentPane is to give it a background color with the method setBackground(java.awt.Color c).
See ColoredPaneFrame.java, PaneColorer.java, ColoredPaneApplet.java, and ColoredPaneApplet.html.
Notice that both the JFrame and the JApplet use a PaneColorer, passing it their contentPane, and that the PaneColorer does not know whether it is coloring a JFrame's contentPane or a JApplet's contentPane.

From now on, I will illustrate all swing concepts using applets.

The top class for all swing components is the abstract class, javax.swing.JComponent. Fortunately, every JComponent is a java.awt.Container, and every Container is a java.awt.Component, so JComponents can easily be nested inside other JComponents.

To add a component to a container, use the container's add(Component comp) method.
I'll demonstrate this with javax.swing.JPanel, a basic concrete subclass of JComponent. See NestedApplet.java, ComponentNester.java, and NestedApplet.html

Layouts
Every Container has a java.awt.LayoutManager that determines the size and location of its components. You set the layout manager of a container by calling its setLayout(LayoutManager mgr) method.

Giving a container a null layout manager, lets the components determine their own size and location (in the container's coordinate system). See NestedWithLayoutApplet.java, ComponentNesterWithLayout.java, and NestedWithLayoutApplet.html

I will demonstrate a few different layout managers by adding several objects of the class javax.swing.JLabel to a contentPane. A JLabel allows you to display a text string that the user cannot edit.

FlowLayout, set by setLayout(new FlowLayout()), adds components left-to-right, top-down, as you would type words onto a page. See FlowApplet.java, and FlowApplet.html. FlowLayout is the default layout for JPanels.

GridLayout, set by setLayout(new GridLayout(int rows, int cols)), arranges the components in a rectangular grid. See GridApplet.java, and GridApplet.html.

BoxLayout has several variants, including ones to arrange components vertically or horizontally.
To arrange the components of a container, c, vertically, use c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS)). See VerticalApplet.java, and VerticalApplet.html.
To arrange the components of a container, c, horizontally, use c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS)). See HorizontalApplet.java, and HorizontalApplet.html. (Note the clipping---nothing appears outside the bounds of the container.)

Painting and Repainting
As it says in the Java Tutorial section on Painting, "Swing components generally repaint themselves whenever necessary." This includes when their window has been un-iconified, uncovered, moved, or resized, or when the components themselves have been altered in some way by your program. However, this may not be true for awt.Components, and it may occasionally fail for Swing Components. If you need to force a component to repaint itself, call its repaint() method, any components it contains (acting as a container) should also be repainted.

When a component is automatically repainted, its paint(Graphics g) method is invoked. You may override that method for components that need special methods to paint themselves. See the API for java.awt.Graphics to read about the methods that may be invoked on the object g, but you will probably not need to do this for straight-forward graphical programs.

Event-Driven Programs
"Every time the user types a character or pushes a mouse button, an event occurs. Any object can be notified of the event. All it has to do is implement the appropriate interface and be registered as an event listener on the appropriate event source." [Tutorial: Java 1.1 Event Model

For your program to take action when an event occurs, you must have an object of some class that implements a java.util.EventListener interface. Different EventListeners listen for different kinds of events. The EventListener that listens for mouse clicks on a JButton, or typing return in a JTextField is the java.awt.event.ActionListener interface.

An object that implements an EventListener is informed that an event has occurred by having its actionPerformed(ActionEvent e) method called. This method can do anything you think is appropriate as a response to the event. The "source" of the event can be determined with the method e.getSource(), and is the component object, such as the JButton or JTextField, that the user did something to. However, that component must have been registered with the listener by calling its addXxxListener(XxxListener al) method. For example, ColorChangeButtons.java shows a class of ActionListeners, each of which is registered with two JButtons.
See ColorChangeApplet.java and ColorChangeApplet.html for a use of ColorChangeButtons.

Stopping
A "normal" application terminates when its main method terminates. However, an event-driven program must wait until some event happens, and then it must do something special to terminate. I introduced the use of JFrame.EXIT_ON_CLOSE above, but a nicer technique is to use the static method System.exit(int status). If status is 0, this causes a normal termination of the application. If status > 0, this causes an abnormal termination.

For a final example application that uses JTextFields, a JButton, an ActionListener, a pop-up dialog using a JOptionPane, and System.exit(0), see CalculatorFrame.java and CalculatorPanel.java.

First Previous Next

Copyright © 2003 by Stuart C. Shapiro. All rights reserved.

Stuart C. Shapiro <shapiro@cse.buffalo.edu>