Cover | Table of Contents | Colophon
JColorChooser component,
discussed in Chapter 12.JFileChooser component,
discussed in Chapter 12.pending package aren't
discussed in this book.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.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.
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().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.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.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.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.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.// 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);
}
}JInternalFrame
, which allows you to create
free-standing frames with menus, titlebars, and everything else a
Frame needs right inside your application.Frame object, but
confined to the visible area of the container it is placed in
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);
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);JTextArea object for you to edit. You can modify
the text and then save the file using the File menu in the page
frame.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.
LnFListener from above, if
you wanted to.) Here's the source code: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.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 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.
PropertyChangeEvent to both the menu item and the
toolbar, causing them to disable and turn gray.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.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.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.ChangeEvent is a stripped-down version of the
java.beans.PropertyChangeEvent class. This class
has no methods or properties, only a constructor:ChangeEvent class. It
takes only a single object, which represents the entity sending the
event.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.
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: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.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.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.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.JLabel class.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.
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);
}
}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().JLabel class.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.
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);
}
}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().|
Property
|
Data Type
|
get
|
|---|
Icon interface and
ImageIcon class make dealing with simple images
extremely easy.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.Icon interface defines the properties listed
in Table 4.3. The iconHeight
and iconWidth properties specify the size of the
Icon in pixels.|
Property
|
Data Type
|
get
|
is
|
set
|
bound
|
Default Value
|
|---|---|---|---|---|---|---|
iconHeight
|
int
|
•
| ||||
iconWidth
|
int
|
•
|
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.AbstractButton) keeps a reference to a
ButtonModel, which represents its state.
JMenuItem class shown here (and its
subclasses, not shown) is not covered in this chapter. Instead, they
are covered in Chapter 14.ButtonModel object. This interface
defines methods for reading and writing the model's properties
and for adding and removing various types of event listeners.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).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.AbstractButton) keeps a reference to a
ButtonModel, which represents its state.
JMenuItem class shown here (and its
subclasses, not shown) is not covered in this chapter. Instead, they
are covered in Chapter 14.ButtonModel object. This interface
defines methods for reading and writing the model's properties
and for adding and removing various types of event listeners.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).|
Property |
|---|
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.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.
BoundedRangeModel interface.|
Property
|
Data Type
|
get
|
is
|
|---|
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.
BoundedRangeModel interface.|
Property
|
Data Type
|
get
|
is
|
set
|
bound
|
Default Value
|
|---|---|---|---|---|---|---|
minimum
|
int
|
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.
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.
JScrollBar component. Most of these properties
come from the java.awt.Adjustable interface. 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.
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.
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.