Using the JFC/Swing Packages |
TheHelloSwing
application introduced in the previous section is a simple one. It brings up a window that looks like this: Each time the user clicks the button, the label is updated. You can find the whole program inHelloSwing.java
.This page discusses the program in detail, explaining the following aspects:
- Importing Swing packages
- Choosing the look and feel
- Setting up windows
- Setting up Swing components
- Handling events
- Dealing with thread issues
- Supporting assistive technologies
Importing Swing Packages
The following line imports the main Swing package:import com.sun.java.swing.*;Swing programs also need classes from the two main AWT packages:
import java.awt.*; import java.awt.event.*;You might wonder why the Swing packages don't have a
java
prefix. The answer is that because Swing isn't part of JDK 1.1, Swing for JDK 1.1 requires a non-java
prefix such ascom.sun.java.
To simplify migrating Swing programs to JDK 1.2, the package name remains the same in JDK 1.2. Despite the unusual package names, Swing is core to JDK 1.2.
Choosing the Look and Feel
Here's the code thatHelloSwing
uses to set its look and feel:The preceding code essentially says, "I don't care what look and feel the user has chosen (if any) -- use the cross-platform look and feel." Although it's somewhat impolite to override the user's choice of look and feel, it sometimes makes sense. The cross-platform look and feel is called the JavaTM Look and Feel (formerly known by the codename "Metal").try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { System.err.println("Couldn't use the cross-platform " + "look and feel: " + e); }To find the platform-specific look and feel, use the
getSystemLookAndFeelClassName
method. On PCs running Windows, this method returns the Windows look and feel. On machines running Solaris, it returns CDE/Motif.You don't have to set the look and feel that your program uses. By default, every Swing program uses the Java Look and Feel. The user can also specify a preferred look and feel, the name of which is saved in a file named
swing.properties
, [PENDING: check filename] and is automatically used by Swing programs that don't set the look and feel.Setting Up Windows
In general, Swing programs implement their primary windows withJFrame
objects. TheJFrame
class is a subclass of the AWT'sFrame
class; it adds some features found only in Swing. See How to Make Frames (Main Windows) for information aboutJFrame
features.Here's the
HelloSwing
code that deals with itsJFrame
:The code looks much like the code for using apublic class HelloSwing extends JFrame implements ActionListener { ... public HelloSwing() { super("HelloSwing"); ... JPanel pane = new JPanel(); ... setContentPane(pane); } ... public static void main(String[] args) { JFrame frame = new HelloSwing(); WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; frame.addWindowListener(l); frame.pack(); frame.setVisible(true); } }Frame
. As for aFrame
, you instantiate the frame class, add a window listener to it, callpack
on it, and then make it visible.The only difference between the preceding code and the code you'd use for a
Frame
is in adding components to theJFrame
. You can't directly add components to aJFrame
. Instead, you either add components to theJFrame
's content pane, or you provide a new content pane.A content pane is a
Container
that, generally speaking, contains all of the frame's visible components except for the menu bar (if any). To get aJFrame
's content pane, use thegetContentPane
method. To set its content pane, as the preceding example does, use thesetContentPane
method.Setting Up Swing Components
TheHelloSwing
program explicitly instantiates four Swing components: aJFrame
, aJButton
, aJLabel
, and aJPanel
. This subsection discusses the button, label, and panel.Here's the code that initializes the button:
The first line creates the button. The second sets the letter "i" as the mnemonic that the user can use to simulate a click of the button. For example, in the Java Look and Feel, typing [PENDING: Alt-i?] results in a button click. The third line registers an event handler for the button click. You'll see the event handler code in Handling Events. Finally, the next lines describe the button, so that assistive technologies can give help to people trying to use the button. You'll find out more about this in Supporting Assistive Technologies.JButton button = new JButton("I'm a Swing button!"); button.setMnemonic('i'); button.addActionListener(this); button.getAccessibleContext().setAccessibleDescription( "When you click this button, the label is updated " + "to display the total number of button clicks.");Here's the code that initializes and manipulates the label:
...//where instance variables are declared: private JLabel label; private static String labelPrefix = "Number of button clicks: "; private int numClicks = 0; ...//in GUI initialization code: label = new JLabel(labelPrefix + "0 "); ...//in the event handler for button clicks: label.setText(labelPrefix + numClicks);Finally, here's the code that initializes the panel:
The preceding code creates theJPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30)); pane.setLayout(new GridLayout(0, 1)); pane.add(button); pane.add(label);JPanel
object, gives it a border, sets its layout manager to one that will put the panel's contents in a single column, and adds the button and label to the panel.The code that sets the border uses a feature provided by the
JComponent
class, which isJPanel
's superclass and the source of many of Swing's features. The feature is that eachJComponent
can have one or more borders. See How to Use Borders for information about using the various types of borders.The panel in
HelloSwing
happens to use an invisible border to put extra padding around it: 30 extra pixels on the top, left, and right, and 10 extra pixels on the bottom.Handling Events
TheHelloSwing
example contains two event handlers. One handles button clicks (action events) and the other handles window closing. If you're already familiar with the 1.1 AWT event handling system, then the following code fromHelloSwing
should be familiar:import java.awt.event.*; ... public class HelloSwing extends JFrame implements ActionListener { ... button.addActionListener(this); ... public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); } public static void main(String[] args) { ... WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }; frame.addWindowListener(l); ... } }If you aren't familiar with 1.1 event handling, then you can read about it in The 1.1 AWT Event Model. Swing introduces some new event types, which you'll encounter as you read further in this lesson.
Swing also adds some automatic window-close handling to
JFrame
, so that you don't always have to implement a window listener. See How to Make Frames (Main Windows) for details.Dealing with Thread Issues
TheHelloSwing
program is thread-safe. Once its GUI is visible, its only GUI manipulation (updating the label) occurs in an event handler. Because the event handler runs in the same thread that performs all event handling and painting for the application, there's no possibility that two threads will try to manipulate the GUI at once.However, it's easy to introduce thread problems into a program. For example, if you add code to the end of
HelloSwing
'smain
method that reads a file and then callslabel.setText
, then you've introduced a potential thread problem, even though your program doesn't create its own threads. The problem might show up if the user presses the button onscreen just before themain
method'ssetText
call occurs. In this case, the label's text might be set or drawn improperly, since two threads (the event handling thread and the main thread) would be trying to set the text at once.See Threads and Swing for information about thread safety in Swing.
Supporting Assistive Technologies
The only code inHelloSwing
that exists solely to support assistive technologies is this:In addition, the following lines set information that can be used by assistive technologies:button.getAccessibleContext().setAccessibleDescription( "When you click this button, the label is updated " + "to display the total number of button clicks.");The preceding lines set text information to be displayed by the component. Thanks to the accessibility support built intosuper("HelloSwing"); JButton button = new JButton("I'm a Swing button!"); label = new JLabel(labelPrefix + "0 "); label.setText(labelPrefix + numClicks);JFrame
,JButton
, andJLabel
(and all the other Swing components), assistive technologies can easily get this text -- or even the text associated with a specific part of a component. Assistive technologies also automatically grab the tool tip text (if any) associated with a component and can use it to describe the component to the user.You might be wondering what exactly assistive technologies are, and why you should care. Primarily, assistive technologies exist to enable people with permanent or temporary disabilities to use the computer. For example, if you get carpal tunnel syndrome, you can use assistive technologies to accomplish your work without using your hands.
Assistive technologies -- voice interfaces, screen readers, alternate input devices, and so on -- are useful not only for disabled people, but also for people using computers in non-office environments. For example, if you're driving your car, you might use assistive technologies to check your e-mail, using only voice input and output. The accessibility information can be used for other tools, as well, such as automated GUI testers.
Here are a few things you can do to make your program work as well as possible with assistive technologies:
- Use tool tips, wherever they make sense.
- Specify keyboard mnemonics wherever possible. (A good test is to hide your mouse and try to use your program with only the keyboard.)
- Whenever you have a
JLabel
that displays a mnemonic for another component (such as a text field), use thesetLabelFor
method so that assistive technologies can find the component that the label is associated with.- Use the
setDescription
method to provide a text description for allImageIcon
s in your program.- If you don't provide a tool tip for a component, use the
setAccessibleDescription
method to provide a description that assistive technologies can give the user. SeeHelloSwing.java
for an example.- If a component doesn't display a short string (which serves as its default name), specify a name with the
setAccessibleName
method. You might want to do this for image-only buttons, panels that provide logical groupings, text areas, and so on.- If a bunch of components form a logical group, try to put them into one Swing container. For example, use a
JPanel
to contain all the radio buttons in a radio button group.
Using the JFC/Swing Packages |