BUY THIS BOOK

Safari Books Online

What is this?

Looking to Reprint this content?


Java Swing
Java Swing By Robert Eckstein, Marc Loy, Dave Wood
September 1998
Pages: 1252

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Introducing Swing
Welcome to Swing! By now, you're probably wondering what Swing is, and how you can use it to spice up your Java applications. Or perhaps you're curious as to how the Swing components fit into the overall Java strategy. Then again, maybe you just want to see what all the hype is about. Well, you've come to the right place; this book is all about Swing and its components. So let's dive right in and answer the first question that you're probably asking right now, which is...
If you poke around the Java home page (http://java.sun.com/ ), you'll find Swing advertised as a set of customizable graphical components whose look-and-feel can be dictated at runtime. In reality, however, Swing is much more than this. Swing is the next-generation GUI toolkit that Sun Microsystems is developing to enable enterprise development in Java. By enterprise development, we mean that programmers can use Swing to create large-scale Java applications with a wide array of powerful components. In addition, you can easily extend or modify these components to control their appearance and behavior.
Swing is not an acronym. The name represents the collaborative choice of its designers when the project was kicked off in late 1996. Swing is actually part of a larger family of Java products known as the Java Foundation Classes ( JFC), which incorporate many of the features of Netscape's Internet Foundation Classes (IFC), as well as design aspects from IBM's Taligent division and Lighthouse Design. Swing has been in active development since the beta period of the Java Development Kit (JDK)1.1, circa spring of 1997. The Swing APIs entered beta in the latter half of 1997 and their initial release was in March of 1998. When released, the Swing 1.0 libraries contained nearly 250 classes and 80 interfaces.
Although Swing was developed separately from the core Java Development Kit, it does require at least JDK 1.1.5 to run. Swing builds on the event model introduced in the 1.1 series of JDKs; you cannot use the Swing libraries with the older JDK 1.0.2. In addition, you must have a Java 1.1-enabled browser to support Swing applets.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is Swing?
If you poke around the Java home page (http://java.sun.com/ ), you'll find Swing advertised as a set of customizable graphical components whose look-and-feel can be dictated at runtime. In reality, however, Swing is much more than this. Swing is the next-generation GUI toolkit that Sun Microsystems is developing to enable enterprise development in Java. By enterprise development, we mean that programmers can use Swing to create large-scale Java applications with a wide array of powerful components. In addition, you can easily extend or modify these components to control their appearance and behavior.
Swing is not an acronym. The name represents the collaborative choice of its designers when the project was kicked off in late 1996. Swing is actually part of a larger family of Java products known as the Java Foundation Classes ( JFC), which incorporate many of the features of Netscape's Internet Foundation Classes (IFC), as well as design aspects from IBM's Taligent division and Lighthouse Design. Swing has been in active development since the beta period of the Java Development Kit (JDK)1.1, circa spring of 1997. The Swing APIs entered beta in the latter half of 1997 and their initial release was in March of 1998. When released, the Swing 1.0 libraries contained nearly 250 classes and 80 interfaces.
Although Swing was developed separately from the core Java Development Kit, it does require at least JDK 1.1.5 to run. Swing builds on the event model introduced in the 1.1 series of JDKs; you cannot use the Swing libraries with the older JDK 1.0.2. In addition, you must have a Java 1.1-enabled browser to support Swing applets.
The Java Foundation Classes (JFC) are a suite of libraries designed to assist programmers in creating enterprise applications with Java. The Swing API is only one of five libraries that make up the JFC. The Java Foundation Classes also consist of the Abstract Window Toolkit (AWT), the Accessibility API, the 2D API, and enhanced support for drag-and-drop capabilities. While the Swing API is the primary focus of this book, here is a brief introduction to the other elements in the JFC:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Swing Features
Swing provides many new features for those planning to write large-scale applications in Java. Here is an overview of some of the more popular features.
One of the most exciting aspects of the Swing classes is the ability to dictate the look-and-feel (L&F) of each of the components, even resetting the look-and-feel at runtime. Look-and-feels have become an important issue in GUI development over the past five years. Most users are familiar with the Motif style of user interface, which was common in Windows 3.1 and is still in wide use on Unix platforms. Microsoft has since deviated from that standard with a much more optimized look-and-feel in their Windows 95/98 and NT 4.0 operating systems. In addition, the Macintosh computer system has its own branded look-and-feel, which most Apple users feel comfortable with.
Swing is capable of emulating several look-and-feels, and currently includes support for Windows 98 and Unix Motif. This comes in handy when a user would like to work in the L&F environment which he or she is most comfortable with. In addition, Swing can allow the user to switch look-and-feels at runtime without having to close the current application. This way, a user can experiment to see which L&F is best for them with instantaneous feedback. And, if you're feeling really ambitious as a developer (perhaps a game developer), you can create your own look-and-feel for each one of the Swing components!
Swing comes with a default look-and-feel called "Metal," which was developed while the Swing classes were in the beta-release phase. This look-and-feel combines some of the best graphical elements in today's L&Fs and even adds a few surprises of its own. Figure 1.3 shows an example of several look-and-feels that you can use with Swing, including the new Metal look-and-feel. All Swing L&Fs are built from a set of base classes called the Basic L&F. However, though we may refer to the Basic L&F from time to time, you can't use it on its own.
Figure 1.3: Various look-and-feels in the Java Swing environment
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Swing Packages and Classes
Here is a short description of each package in the Swing libraries.
javax.accessibility
Contains classes and interfaces that can be used to allow assistive technologies to interact with Swing components. Assistive technologies cover a broad range of items, from audible text readers to screen magnification. Although the accessibility classes are technically not part of Swing, they are used extensively throughout the Swing components. We discuss the accessibility package in greater detail in Chapter 25.
javax.swing
Contains the core Swing components, including most of the model interfaces and support classes.
javax.swing.border
Contains the definitions for the abstract border class as well as eight predefined borders. Borders are not components; instead, they are special graphical elements that Swing treats as properties and places around components in place of their insets. If you wish to create your own border, you can subclass one of the existing borders in this package, or you can code a new one from scratch.
javax.swing.colorchooser
Contains support for the JColorChooser component, discussed in Chapter 12.
javax.swing.event
Defines several new listeners and events that Swing components use to communicate asynchronous information between classes. To create your own events, you can subclass various events in this package or write your own event class.
javax.swing.filechooser
Contains support for the JFileChooser component, discussed in Chapter 12.
javax.swing.pending
Contains an assortment of components that aren't ready for prime time, but may be in the future. Play here at your own risk. The contents of the pending package aren't discussed in this book.
javax.swing.plaf
Defines the unique elements that make up the pluggable look-and-feel for each Swing component. Its various subpackages are devoted to rendering the individual look-and-feels for each component on a platform-by-platform basis. (Concrete implementations of the Windows and Motif L&Fs are in subpackages of
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Model-View-Controller Architecture
Swing uses the model-view-controller architecture (MVC) as the fundamental design behind each of its components. Essentially, MVC breaks GUI components into three elements. Each of these elements plays a crucial role in how the component behaves.
Model
The model encompasses the state data for each component. There are different models for different types of components. For example, the model of a scrollbar component might contain information about the current position of its adjustable "thumb," its minimum and maximum values, and the thumb's width (relative to the range of values). A menu, on the other hand, may simply contain a list of the menu items the user can select from. Note that this information remains the same no matter how the component is painted on the screen; model data always exists independent of the component's visual representation.
View
The view refers to how you see the component on the screen. For a good example of how views can differ, look at an application window on two different GUI platforms. Almost all window frames will have a titlebar spanning the top of the window. However, the titlebar may have a close box on the left side (like the older MacOS platform), or it may have the close box on the right side (as in the Windows 95 platform). These are examples of different types of views for the same window object.
Controller
The controller is the portion of the user interface that dictates how the component interacts with events. Events come in many forms — a mouse click, gaining or losing focus, a keyboard event that triggers a specific menu command, or even a directive to repaint part of the screen. The controller decides how each component will react to the event—if it reacts at all.
Figure 1.5 shows how the model, view, and controller work together to create a scrollbar component. The scrollbar uses the information in the model to determine how far into the scrollbar to render the thumb and how wide the thumb should be. Note that the model specifies this information relative to the minimum and the maximum. It does not give the position or width of the thumb in screen pixels—the view calculates that. The view determines exactly where and how to draw the scrollbar, given the proportions offered by the model. The view knows whether it is a horizontal or vertical scrollbar, and it knows exactly how to shadow the end buttons and the thumb. Finally, the controller is responsible for handling mouse events on the component. The controller knows, for example, that dragging the thumb is a legitimate action for a scroll bar, and pushing on the end buttons is acceptable as well. The result is a fully functional MVC scrollbar.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Working with Swing
Our introduction to Swing wouldn't be complete unless we briefly mentioned some caveats of the new libraries. There are two areas to briefly mention: multithreading issues and lightweight/heavyweight issues. Being aware of these issues will help you make informed decisions while working with Swing. Chapter 28, gives you in-depth guidance in these difficult areas.
Shortly before the initial release of Swing, JavaSoft posted an article recommending that developers not use independent threads to change model states in components. Instead, they suggest that once a component has been painted to the screen (or is about to be painted), updates to its model state should only occur from the event-dispatching queue . The event-dispatching queue is a system thread used to communicate events to other components. It handles the posting of GUI events, including those to repaint components.
The issue here is an artifact of the MVC architecture and deals with performance and potential race-conditions. As we mentioned above, a Swing component draws itself based on the state values in its model. However, if the state values change while the component is in the process of repainting, the component can repaint incorrectly—this is unacceptable. To compound matters, placing a lock on the entire model, as well as on some of the critical component data, or even cloning the data in question, could seriously hamper performance for each refresh. The only feasible solution, therefore, is to place state changes in serial with refreshes. This ensures that modifications in component state do not occur at the same time that Swing is repainting any components, and no race conditions will occur.
One of the most frequent issues to come out of the lightweight/heavyweight component debate is the idea of depth, or z-order —that is, a well-defined method for how elements are stacked on the screen. Because of z-order, it is not advisable to mix lightweight and heavyweight components in Swing.
To see why, remember that heavyweight components depend on peer objects used at the operating system level. However, with Swing only the top-level components are heavyweight:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Swing Set Demo
If you're in a hurry to see all the components that Swing has to offer, be sure to check out the Swing Set demonstration provided with the standalone Swing distribution. The demonstration is extremely easy to set up. Assuming you're using JDK 1.1, after downloading and extracting the Swing classes on your computer, you will need to the following:
  1. Edit your CLASSPATH environment variable to include the file swingall.jar, which resides in the base directory of the distribution. Also, set the SWING_HOME environment variable to point to the base directory.
  2. Change directory to the examples/SwingSet directory in the Swing distribution.
  3. Execute the runnit script or runnit.bat file, depending on your platform.
If you are using JDK 1.2, just find the directory demo/SwingSet (unfortunately, it has moved around in different pre-releases) and type java SwingSet. You should immediately see a progress bar indicating that the Swing Set demo is loading. When it finishes, a window appears, similar to the one in Figure 1.8.
Figure 1.8: The Swing Set demo
This demo contains a series of tabs that demonstrate almost all of the components in the Swing libraries. Be sure to check out the internal frames demo and the new Metal look-and-feel. In addition, some of the Swing creators have added "Easter eggs" of their own throughout the Swing Set demo. See if you can find some!
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Reading this Book
We're well aware that most readers don't read the Preface. You have our permission to skip it, provided that you look at the Conventions section. That section is particularly important because in this book, we're experimenting with a few new techniques for explaining the Swing classes. As we said earlier, everything in Swing is a Java Bean. This means that much of an object's behavior is controlled by a set of properties, which are manipulated by accessor methods. For example, the property color would be accessed by the methods getColor() (to find out the color) and setColor() (to change the color). If a property has a boolean value, the get method is often replaced by an is method; for example, the visible property would have methods isVisible() and setVisible().
We found the idea of properties very powerful in helping us understand Swing. Therefore, rather than listing all of a class's accessor methods, we decided to present a table for each class, listing the class's properties and showing the property's data type, which accessor methods are present, whether the property is "bound" (i.e., changing the property generates a PropertyChangeEvent), and the property's default value. This approach certainly saves paper (you didn't really want a 2000 page book, did you?) and should make it easier to understand what a component does and how it is structured. Furthermore, if you're not already in the habit of thinking in terms of the JavaBeans architecture, you should get in the habit. It's a very useful and powerful tool for understanding component design.
The conventions we use in the property tables — plus some other conventions that we use in class diagrams — are explained in the Preface. So we'll let you ignore the rest of the Preface, as long as you familiarize yourself with the conventions we're using.
The next chapter will help you get a jumpstart on Swing by presenting some simple applications that ease the Java AWT developer into the latest additions. In Chapter 3, we continue our discussion by presenting some of the fundamental classes of Swing and discussing how you can use the features inherent in each of these classes to shorten your overall development time. Don't stop now—the best is yet to come!
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Jump Starting a Swing Application
Now that you have an overview of Swing, let's look at a few quick Swing components you can put into your applications right now. This chapter will show you how to add images to buttons, and then go on to the more complicated, but more interesting, internal frames. We won't belabor the theory and background. You'll find everything we talk about now (and tons more we don't discuss here) presented in later chapters in much greater detail. We just want to show you some of the fun stuff right away.
One of the benefits of object-oriented languages is that you can upgrade pieces of a program without rewriting the rest of it. While practice is never as simple as theory, with Swing it's close. You can use most of the Swing components as drop-in replacements for AWT components with ease. The components sport many fancy new features worth exploiting, but they still maintain the functionality of the AWT components you're familiar with. As a general rule, you can stick a "J" in front of your favorite AWT component and put the new class to work as a Swing component. Constructors for components such as JButton, JTextField, and JList can be used with the same arguments and generate the same events as Button, TextField, and List. Some Swing containers, like JFrame, take a bit of extra work, but not much.
One of the first steps a programmer takes when building a modern user interface for commercial or internal use is to add a graphical button. Nice monitors and cheap hardware have made icons almost a necessity. The AWT package in Java does not directly support image buttons, but they are fairly easy to create by extending the Canvas or Component class. However, none of the extensions you write will be compatible with any extensions written by other programmers. The JButton class from the Swing package provides (finally) a standard way to add image buttons.
Undoubtedly, you have some programs lying around that use regular AWT buttons that you'd love to replace with image buttons, but don't have the time or, honestly, the necessity to produce your own image button class. Let's look at a simple application that demonstrates an upgrade path you can use on your own programs.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Upgrading Your Programs
One of the benefits of object-oriented languages is that you can upgrade pieces of a program without rewriting the rest of it. While practice is never as simple as theory, with Swing it's close. You can use most of the Swing components as drop-in replacements for AWT components with ease. The components sport many fancy new features worth exploiting, but they still maintain the functionality of the AWT components you're familiar with. As a general rule, you can stick a "J" in front of your favorite AWT component and put the new class to work as a Swing component. Constructors for components such as JButton, JTextField, and JList can be used with the same arguments and generate the same events as Button, TextField, and List. Some Swing containers, like JFrame, take a bit of extra work, but not much.
One of the first steps a programmer takes when building a modern user interface for commercial or internal use is to add a graphical button. Nice monitors and cheap hardware have made icons almost a necessity. The AWT package in Java does not directly support image buttons, but they are fairly easy to create by extending the Canvas or Component class. However, none of the extensions you write will be compatible with any extensions written by other programmers. The JButton class from the Swing package provides (finally) a standard way to add image buttons.
Undoubtedly, you have some programs lying around that use regular AWT buttons that you'd love to replace with image buttons, but don't have the time or, honestly, the necessity to produce your own image button class. Let's look at a simple application that demonstrates an upgrade path you can use on your own programs.
First, let's look at the code for this very simple application:
// ToolbarFrame1.java
// A simple frame containing a "toolbar" made up of several java.awt.Button
// objects. We'll be converting the Buttons to JButtons in the
// ToolbarFrame2.java file.
//
import java.awt.*;
import java.awt.event.*;

public class ToolbarFrame1 extends Frame implements ActionListener {

  Button cutButton, copyButton, pasteButton;
  public ToolbarFrame1() {
    super("Toolbar Example (AWT)");
    setSize(450, 250);
    addWindowListener(new BasicWindowMonitor());
  
    Panel toolbar = new Panel();
    toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));

    cutButton = new Button("Cut");
    cutButton.addActionListener(this);
    toolbar.add(cutButton);

    copyButton = new Button("Copy");
    copyButton.addActionListener(this);
    toolbar.add(copyButton);

    pasteButton = new Button("Paste");
    pasteButton.addActionListener(this);
    toolbar.add(pasteButton);

    // the new "preferred" BorderLayout add call
    add(toolbar, BorderLayout.NORTH); 
  }

  public void actionPerformed(ActionEvent ae) {
    System.out.println(ae.getActionCommand());
  }

  public static void main(String args[]) {
    ToolbarFrame1 tf1 = new ToolbarFrame1();
    tf1.setVisible(true);
  }
}
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Beyond Buttons
Buttons are very useful, but even with great images forming the buttons, they still lack a certain glamour—every application has buttons. For the next example, let's take a look at something a bit more exciting. (Well, exciting might be a bit of an exaggeration, but it definitely has more impact than buttons.) The Swing package contains a new class called JInternalFrame , which allows you to create free-standing frames with menus, titlebars, and everything else a Frame needs right inside your application.
Before we start coding, here's a brief rundown of the features of an internal frame:
  • Same functions as a normal Frame object, but confined to the visible area of the container it is placed in
  • Can be iconified (icon stays inside main application frame)
  • Can be maximized (frame consumes entire main application frame area)
  • Can be closed using the standard controls for popup windows
  • Can be placed in a "layer," which dictates how the frame displays itself relative to other internal frames (a frame in layer 1 can never hide a frame in layer 2)
Figure 2.6 shows a simple internal frame using the Metal L&F.
Figure 2.6: The SimpleInternalFrame application using the Metal look-and-feel
For this first example, we'll add an empty internal frame to an application. Once that's working, we'll expand the simple frame to create a couple of different types of internal frames and create the framework for a simple application.
One of the prerequisites for using internal frames is that you need a window capable of managing them. The swing package provides the JDesktopPane class for this purpose. You'll see the details of the JDesktopPane in Chapter 9, but for now, here's how to get one started:
// Set up the layered pane
JDesktopPane desktop = new JDesktopPane();
add(desktop, BorderLayout.CENTER);
With the desktop in place, you can create a new internal frame and show it. The JInternalFrame constructor we'll use takes five arguments that tailor the look and functionality of the frame:
public JInternalFrame(String title, 
                      boolean resizable,
                      boolean closable,
                      boolean maximizable,
                      boolean iconifiable);
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
A Bigger Application
Now that you've seen how to create internal frames and played around with them a bit, let's tackle a slightly larger problem. We want to build an application that can pop up internal frames that you can honestly use. This starter application is a web-site manager that shows us a list of HTML pages at a site and, for any of those pages, allows us to pop up the page in a separate frame and edit it. We'll keep the main list of HTML pages in one "site" frame that contains a simple list box.
Once you have a site built up with a couple of pages, you can click on any entry in the list, and if the file exists, we'll create a new "page" frame and load the file into a JTextArea object for you to edit. You can modify the text and then save the file using the File menu in the page frame.
As a bonus, we'll put those cut, copy, and paste icons to use as well. You can manipulate text in any of the open page frames. The icons work as Action objects by looking at the selected text and insertion point of the active frame. (We'll look at the Action class below.) If the active frame is a site frame, nothing happens.
You could certainly add a lot of features to this application and make it a real working program, but we don't want to get mired down in details just yet. (If you want to get really fancy, you could look at some of the editor kits discussed in Chapter 24, and build yourself a real HTML editor.) Figure 2.9 shows the finished application with a couple of frames open.
Figure 2.9: The SiteManager application running (set to use the Metal look-and-feel)
We'll break the code for this application into three separate classes to make it more manageable for discussing. The first class handles the real application frame. The constructor handles all of the interface setup work. It sets up the toolbar, as well as the cut, copy, and paste buttons. It also uses the Metal look-and-feel from the beginning, instead of shifting it on the fly. (You could certainly attach the LnFListener from above, if you wanted to.) Here's the source code:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Swing Component Basics
The previous chapter showed you how easy it was to create some impressive-looking programs with Swing components. Now it's time to dig in a little deeper. We begin this chapter by presenting an overview of Action, a key class in Swing, and briefly discussing ChangeEvent and PropertyChangeEvent, two central event classes in Swing. Finally, we spend the remainder of the chapter introducing the JComponent class, the heart and soul of all Swing components.
Actions are a popular addition to Swing. An action allows a programmer to bundle a commonly used procedure and its bound properties (incl uding an image to represent it) into a single class. This construct comes in handy if an application needs to call upon a particular function from multiple sources. For example, let's say that a Swing programmer creates an action that saves data to disk. The application could then invoke this action from both the Save menu item of the File menu, and the Save button on a toolbar. Both components reference the same action object, which performs the task of saving the data. If the save function is disabled for some reason, this property can be set in the action as well. The menu and toolbar objects are automatically notified that they can no longer save any data, and can relay that information to the user.
Swing containers, such as JMenu, JPopupMenu, and JToolBar, can each accept action objects with their add() methods. When an action is added, these containers automatically create a GUI component, which the add() method then returns to you for customization. For example, a JMenu or a JPopupMenu creates and returns a JMenuItem from an Action, while a JToolBar creates and returns a JButton. The action is then paired with the newly-created GUI component in two ways: the GUI component registers as a PropertyChangeListener for any property changes that might occur in the action object, while the action object registers as an ActionListener on the GUI component. Figure 3.1 shows the interactions between a menu item or toolbar and an
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Understanding Actions
Actions are a popular addition to Swing. An action allows a programmer to bundle a commonly used procedure and its bound properties (incl uding an image to represent it) into a single class. This construct comes in handy if an application needs to call upon a particular function from multiple sources. For example, let's say that a Swing programmer creates an action that saves data to disk. The application could then invoke this action from both the Save menu item of the File menu, and the Save button on a toolbar. Both components reference the same action object, which performs the task of saving the data. If the save function is disabled for some reason, this property can be set in the action as well. The menu and toolbar objects are automatically notified that they can no longer save any data, and can relay that information to the user.
Swing containers, such as JMenu, JPopupMenu, and JToolBar, can each accept action objects with their add() methods. When an action is added, these containers automatically create a GUI component, which the add() method then returns to you for customization. For example, a JMenu or a JPopupMenu creates and returns a JMenuItem from an Action, while a JToolBar creates and returns a JButton. The action is then paired with the newly-created GUI component in two ways: the GUI component registers as a PropertyChangeListener for any property changes that might occur in the action object, while the action object registers as an ActionListener on the GUI component. Figure 3.1 shows the interactions between a menu item or toolbar and an Action.
Figure 3.1: An action in conjunction with a Swing menu item and toolbar
Essentially, this means that if the menu item or button is selected by the user, the functionality inside of the action is invoked. On the other hand, if the action is disabled, it sends a PropertyChangeEvent to both the menu item and the toolbar, causing them to disable and turn gray.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Sending Change Events in Swing
Swing actually uses two different change event classes. The first is the standard java.beans.PropertyChangeEvent class. This class passes a reference to the object, sending the change notification, as well as the property name, its old value, and its new value. The second, javax. swing.event.ChangeEvent, is a lighter version that only passes a reference to the sending object—in other words, the name of the property that changed, as well as the old and new values, are omitted.
Since the ChangeEvent class is not part of the JavaBeans specifications, properties that use this event are not "bound" according to the JavaBeans standard. In order to prevent confusion, properties that use a ChangeEvent to notify listeners of property changes have not been marked as bound in our property tables.
Because the ChangeEvent only includes a reference to the event originator, which never changes, you can always define a single, static ChangeEvent and reuse it over and over when firing events from your component.
The ChangeEvent is a stripped-down version of the java.beans.PropertyChangeEvent class. This class has no methods or properties, only a constructor:

Section 3.2.1.1: Constructor

public ChangeEvent(Object source)
The constructor for the ChangeEvent class. It takes only a single object, which represents the entity sending the event.
The ChangeEvent class extends the java.util.EventObject class. This object contains the getSource() method, which you can use to access the source object that fired the event.
Objects that intend to receive change events must implement the com.sun.java. swing.event.ChangeListener interface. They can then register to receive ChangeEvent objects from a publisher class. The ChangeListener interface only consists of one method:

Section 3.2.2.1: Method

public abstract void stateChanged(ChangeEvent e)
Implemented in a listener object to receive
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The JComponent Class
JComponent is an abstract class that almost all Swing components extend; it provides much of the underlying functionality common throughout the Swing component library. Just as the java.awt.Component class serves as the guiding framework for most of the AWT components, the javax.swing.JComponent class serves an identical role for the Swing components. We should note that the JComponent class extends java.awt.Container (which in turn extends java.awt.Component), so it is accurate to say that Swing components carry with them a great deal of AWT functionality as well.
Because JComponent extends Container, many Swing components can serve as containers for other AWT and Swing components. These components may be added using the traditional add() method of Container. In addition, they can be positioned with any Java layout manager while inside the container. The terminology remains the same as well: components that are added to a container are said to be its children; the container is the parent of those components. Following the analogy, any component that is higher in the tree is said to be its ancestor, while any component that is lower is said to be its descendant.
Recall that Swing components are considered "lightweight." In other words, they do not rely on corresponding peer objects within the operating system to render themselves. As we mentioned in Chapter 1, lightweight components draw themselves using the standard features of the abstract Graphics object, which not only decreases the amount of memory each component uses, but allows components to have transparent portions and take on nonrectangular shapes. And, of course, lightweight components are free from a dedicated look-and-feel.
It's not out of the question to say that a potential benefit of using lightweight components is a decrease in testing time. This is because the functionality necessary to implement lightweight components in the Java virtual machine is significantly less than that of heavyweight components. Heavyweight components must be individually mapped to their own native peers. On the other hand, one need only implement a single lightweight peer on each OS for all the Swing components to work correctly. Hence, there is a far greater chance that lightweight components will execute as expected on any operating system and not require rounds of testing for each platform.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Labels and Icons
We'll begin our look at the Swing components with the JLabel class. In addition, we'll look at Swing's new Icon interface and an implementation of this interface called ImageIcon. With just these few new constructs, you'll begin to see how much Swing has done to improve UI development in Java.
Swing allows you to create labels that can contain text, images, or both. We'll begin this chapter with a look at the JLabel class.
The JLabel class allows you to add basic, nonfunctional labels to a user interface. Because of their inherent simplicity, there is no model class for JLabel components. Figure 4.1 shows a class diagram for JLabel. We'll get into the two relations to Icon a little later.
Figure 4.1: JLabel class diagram
Unlike java.awt.Label objects, JLabel objects may consist of both text and graphics (icons). For simple text labels, the interface to JLabel is very similar to that of java.awt.Label. The code to create and display a very simple text label looks like this:
// 
               
               SimpleJLabelExample.java
//
import javax.swing*;

public class SimpleJLabelExample {
  public static void main(String[] args) {
    JLabel label = new JLabel("A Very Simple Text Label");

    JFrame frame = new JFrame();
    frame.addWindowListener(new BasicWindowMonitor());
    frame.getContentPane().add(label);
    frame.pack();
    frame.setVisible(true);
  }
}
Running this simple program produces the display shown in Figure 4.2.
Figure 4.2: A simple JLabel

Section 4.1.1.1: Properties

The JLabel class contains the properties shown in Table 4.1. The icon and disabledIcon properties specify the icon to be displayed by default and when the label is disabled respectively. If no disabledIcon is specified, a grayscale version of the default icon is created automatically. The font property is shown in this table only because the setFont() method is overridden to call repaint() after calling super.setFont().
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Labels
Swing allows you to create labels that can contain text, images, or both. We'll begin this chapter with a look at the JLabel class.
The JLabel class allows you to add basic, nonfunctional labels to a user interface. Because of their inherent simplicity, there is no model class for JLabel components. Figure 4.1 shows a class diagram for JLabel. We'll get into the two relations to Icon a little later.
Figure 4.1: JLabel class diagram
Unlike java.awt.Label objects, JLabel objects may consist of both text and graphics (icons). For simple text labels, the interface to JLabel is very similar to that of java.awt.Label. The code to create and display a very simple text label looks like this:
// 
               
               SimpleJLabelExample.java
//
import javax.swing*;

public class SimpleJLabelExample {
  public static void main(String[] args) {
    JLabel label = new JLabel("A Very Simple Text Label");

    JFrame frame = new JFrame();
    frame.addWindowListener(new BasicWindowMonitor());
    frame.getContentPane().add(label);
    frame.pack();
    frame.setVisible(true);
  }
}
Running this simple program produces the display shown in Figure 4.2.
Figure 4.2: A simple JLabel

Section 4.1.1.1: Properties

The JLabel class contains the properties shown in Table 4.1. The icon and disabledIcon properties specify the icon to be displayed by default and when the label is disabled respectively. If no disabledIcon is specified, a grayscale version of the default icon is created automatically. The font property is shown in this table only because the setFont() method is overridden to call repaint() after calling super.setFont().
Table 4.1: JLabel Properties
Property
Data Type
get
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Icons
Swing introduces the concept of an icon for use in a variety of components. The Icon interface and ImageIcon class make dealing with simple images extremely easy.
The Icon interface is very simple, specifying just three methods used to determine the size of the Icon and to display it. Implementors of this interface are free to store and display the image in any way, providing a great deal of flexibility. In other words, icons don't have to be bitmaps or GIF images, but are free to render themselves any way they choose; as we'll see later, an icon can simply draw on the component if that's more efficient. The examples at the end of this section show a couple of different ways the interface might be implemented.

Section 4.2.1.1: Properties

The Icon interface defines the properties listed in Table 4.3. The iconHeight and iconWidth properties specify the size of the Icon in pixels.
Table 4.3: Icon Properties
Property
Data Type
get
is
set
bound
Default Value
iconHeight
int
•
iconWidth
int
•
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: Buttons
Buttons are simple UI components used to generate events when the user presses them. In AWT, buttons were very basic, able to display only simple text strings. In much the same way as JLabel provided improvements over java.awt.Label, the Swing button classes improve on java.awt.Button and java.awt.Checkbox by introducing the ability to display icons, text, or both. In this section, we'll introduce both the ButtonModel interface and DefaultButtonModel class (which define the state of the button). Next, we'll look at the AbstractButton class (which defines much of the functionality for all button types). Finally, we'll look at four concrete subclasses of AbstractButton and see how they can be grouped together using a ButtonGroup.
Figure 5.1 shows the class hierarchy, with significant relationships between the button-related Swing classes. Notice that, as we discussed in the introductory chapters, each button (AbstractButton) keeps a reference to a ButtonModel, which represents its state.
Figure 5.1: Swing Button class diagram
The JMenuItem class shown here (and its subclasses, not shown) is not covered in this chapter. Instead, they are covered in Chapter 14.
The state of any Swing button is maintained by a ButtonModel object. This interface defines methods for reading and writing the model's properties and for adding and removing various types of event listeners.

Section 5.1.1.1: Properties

The properties for the ButtonModel interface are listed in Table 5.1. The actionCommand property specifies the name of the command to be sent as part of the ActionEvent fired when the button is pressed. This can be used by event handlers that are listening to multiple buttons, to determine which button has been pressed. The group property contains a reference to the ButtonGroup that contains the button (if any).
Table 5.1: ButtonModel Properties
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Buttons
Buttons are simple UI components used to generate events when the user presses them. In AWT, buttons were very basic, able to display only simple text strings. In much the same way as JLabel provided improvements over java.awt.Label, the Swing button classes improve on java.awt.Button and java.awt.Checkbox by introducing the ability to display icons, text, or both. In this section, we'll introduce both the ButtonModel interface and DefaultButtonModel class (which define the state of the button). Next, we'll look at the AbstractButton class (which defines much of the functionality for all button types). Finally, we'll look at four concrete subclasses of AbstractButton and see how they can be grouped together using a ButtonGroup.
Figure 5.1 shows the class hierarchy, with significant relationships between the button-related Swing classes. Notice that, as we discussed in the introductory chapters, each button (AbstractButton) keeps a reference to a ButtonModel, which represents its state.
Figure 5.1: Swing Button class diagram
The JMenuItem class shown here (and its subclasses, not shown) is not covered in this chapter. Instead, they are covered in Chapter 14.
The state of any Swing button is maintained by a ButtonModel object. This interface defines methods for reading and writing the model's properties and for adding and removing various types of event listeners.

Section 5.1.1.1: Properties

The properties for the ButtonModel interface are listed in Table 5.1. The actionCommand property specifies the name of the command to be sent as part of the ActionEvent fired when the button is pressed. This can be used by event handlers that are listening to multiple buttons, to determine which button has been pressed. The group property contains a reference to the ButtonGroup that contains the button (if any).
Table 5.1: ButtonModel Properties
Property
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 6: Bounded Range Components
This chapter groups several Swing components together by the model that drives them: the bounded-range model. Bounded-range components in Swing include JSlider, JProgressBar, and JScrollBar. In addition, we discuss two classes that make use of progress bars: ProgressMonitor and ProgressMonitorInputStream. These classes display status dialogs using a JOptionPane that you can assign to a variety of tasks.
Components that make use of the bounded-range model typically consist of an integer value that is constrained within two integer boundaries. The lower boundary, the minimum , should always be less than or equal to the model's current value. In addition, the model's value should always be less than the upper boundary, the maximum. The model's value can cover more than one unit; this size is referred to as its extent . With bounded range, the user is allowed to adjust the value of the model according to the rules of the component. If the value violates any of the rules, the model can adjust the values accordingly.
The interface javax.swing.BoundedRangeModel outlines the data model for such an object. The interface is very similar to the java.awt.Adjustable interface presented in AWT 1.1 and retains many of its characteristics. Objects implementing the BoundedRangeModel interface must contain an adjustable integer value, an extent, and a minimum and maximum. Swing contains three bounded-range components: JScrollBar, JSlider, and JProgressBar. These components are shown in Figure 6.1.
Figure 6.1: Bounded-range components in Swing
Table 6.1 shows the properties of the BoundedRangeModel interface.
Table 6.1: BoundedRangeModel Properties
Property
Data Type
get
is
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Bounded-Range Model
Components that make use of the bounded-range model typically consist of an integer value that is constrained within two integer boundaries. The lower boundary, the minimum , should always be less than or equal to the model's current value. In addition, the model's value should always be less than the upper boundary, the maximum. The model's value can cover more than one unit; this size is referred to as its extent . With bounded range, the user is allowed to adjust the value of the model according to the rules of the component. If the value violates any of the rules, the model can adjust the values accordingly.
The interface javax.swing.BoundedRangeModel outlines the data model for such an object. The interface is very similar to the java.awt.Adjustable interface presented in AWT 1.1 and retains many of its characteristics. Objects implementing the BoundedRangeModel interface must contain an adjustable integer value, an extent, and a minimum and maximum. Swing contains three bounded-range components: JScrollBar, JSlider, and JProgressBar. These components are shown in Figure 6.1.
Figure 6.1: Bounded-range components in Swing
Table 6.1 shows the properties of the BoundedRangeModel interface.
Table 6.1: BoundedRangeModel Properties
Property
Data Type
get
is
set
bound
Default Value
minimum
int
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The JScrollBar Class
JScrollBar is the Swing implementation of a scrollbar. It is the lightweight successor to the AWT 1.1 counterpart java.awt.Scrollbar, and is intended as a direct replacement for programmers converting their applications to Swing. The JScrollBar class is shown with various look-and-feels in Figure 6.3.
Figure 6.3: Scrollbars in the three look-and-feels
To program with a scrollbar, it is important to understand its anatomy. Scrollbars are composed of a rectangular tab, called a slider or thumb, located between two arrow buttons. The arrow buttons on either end increment or decrement the slider's position by an adjustable number of units, generally one. In addition, clicking in the area between the thumb and the end buttons (often called the paging area) moves the slider one block, or ten units by default. The user can modify the value of the scrollbar in one of three ways: by dragging the thumb in either direction, by pushing on either of the arrow buttons, or by clicking in the paging area.
As with AWT, scrollbars can have one of two orientations: horizontal or vertical. Figure 6.4 provides an illustration of a horizontal scrollbar. JScrollBar makes use of the bounded-range model to represent the scrollbar's data. The assignment of each bounded-range property is also shown in Figure 6.5. The minimum and maximum of the scrollbar fall on the interior edges of the arrow buttons. The scrollbar's value is defined as the left (or top) edge of the slider. Finally, the extent of the scrollbar defines the width of the thumb in relation to the total range. (The older Adjustable interface referred to the extent property as the "visible amount.") Note that horizontal scrollbars increment to the right and vertical scrollbars increment downward.
Figure 6.4: Anatomy of a horizontal scrollbar
Figure 6.5: JScrollBar class diagram
Table 6.3 shows the properties of the JScrollBar component. Most of these properties come from the java.awt.Adjustable interface. The
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The JSlider Class
The JSlider class represents a graphical slider, a new component in Swing. Like scrollbars, sliders can have either a horizontal or a vertical orientation. With sliders, however, you can enhance their appearance with both tick marks and labels. The class hierarchy is illustrated in Figure 6.8.
Figure 6.8: JSlider class diagram
The JSlider class allows you to set the spacing of two types of tick marks: major and minor. Major tick marks are longer than minor tick marks and are generally used at wider intervals. Figure 6.9 shows various sliders that can be composed in Swing.
Figure 6.9: Various sliders in Swing
The setPaintTicks() method sets a boolean, which is used to activate or deactivate the slider's tick marks. In some look-and-feels, the slider changes from a rectangular shape to a pointer when tick marks are activated. This is often done to give the user a more accurate representation of where the slider falls.