Chapter 14. Using Swing Components

In the previous chapter, we discussed a number of concepts, including how Java’s user interface facility is put together and how the larger pieces work. You should understand what components and containers are, how you use them to create a display, what events are, how components use them to communicate with the rest of your application, and what layout managers are.

Now that we’re through with the general concepts and background, we’ll get to the fun stuff: how to do things with Swing. We will cover most of the components that the Swing package supplies, how to use these components in applets and applications, and how to build your own components. We will have lots of code and lots of pretty examples to look at.

There’s more material than fits in a single chapter. In this chapter, we’ll cover all the basic user interface components. In the next chapter, we’ll cover some of the more involved topics: text components, trees, tables, and creating your own components.

Buttons and Labels

We’ll start with the simplest components: buttons and labels. Frankly, there isn’t much to say about them. If you’ve seen one button, you’ve seen them all; and you’ve already seen buttons in the applications in Chapter 2 (HelloJava3 and HelloJava4). A button generates an ActionEvent when the user presses it. To receive these events, your program registers an ActionListener , which must implement the actionPerformed( ) method. The argument passed to actionPerformed( ) is the event itself.

There’s one more thing worth saying about buttons, which applies to any component that generates an action event. Java lets us specify an “action command” string for buttons (and other components, like menu items, that can generate action events). The action command is less interesting than it sounds. It is just a String that serves to identify the component that sent the event. By default, the action command of a JButton is the same as its label; it is included in action events, so you can use it to figure out which button an event came from.

To get the action command from an action event, call the event’s getAction-Command( ) method. The following code checks whether the user pressed the Yes button:

public void actionPerformed(ActionEvent e){ 
    if (e.getActionCommand( ).equals("Yes") { 
        //the user pressed "Yes"; do something 
        ... 
    } 
}

You can change the action command by calling the button’s setActionCommand( ) method. The following code changes button myButton’s action command to “confirm”:

myButton.setActionCommand("confirm");

It’s a good idea to get used to setting action commands explicitly; this helps to prevent your code from breaking when you or some other developer " internationalizes” it, or otherwise changes the button’s label. If you rely on the button’s label, your code will stop working as soon as that label changes; a French user might see the label Oui rather than Yes. By setting the action command, you eliminate one source of bugs; for example, the button myButton in the previous example will always generate the action command confirm, regardless of what its label says.

Swing buttons can have an image in addition to a label. The JButton class includes constructors that accept an Icon object, which knows how to draw itself. You can create buttons with captions, images, or both. A handy class called ImageIcon takes care of loading an image for you and can be used to easily add an image to a button. The following example shows how this works:

//file: PictureButton.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PictureButton extends JFrame {

  public PictureButton( ) {
    super("PictureButton v1.0");
    setSize(200, 200);
    setLocation(200, 200);
    
    Icon icon = new ImageIcon("rhino.gif");
    JButton button = new JButton(icon);
    button.addActionListener(new ActionListener( ) {
      public void actionPerformed(ActionEvent ae) {
        System.out.println("Urp!");
      }
    });
    
    Container content = getContentPane( );
    content.setLayout(new FlowLayout( ));
    content.add(button);
  }

  public static void main(String[] args) {
    JFrame f = new PictureButton( );
    f.addWindowListener(new WindowAdapter( ) {
      public void windowClosing(WindowEvent we) { System.exit(0); }
    });
    f.setVisible(true);
  }
}

The example creates an ImageIcon from the rhino.gif file. Then a JButton is created from the ImageIcon. The whole thing is displayed in a JFrame. This example also shows the idiom of using an anonymous inner class as an ActionListener.

There’s even less to be said about JLabel components. They’re just text strings or images housed in a component. There aren’t any special events associated with labels; about all you can do is specify the text’s alignment, which controls the position of the text within the label’s display area. As with buttons, JLabels can be created with Icons if you want to create a picture label. The following code creates some labels with different options:

// default alignment (CENTER)
JLabel label1 = new JLabel("Lions");

// left aligned
JLabel label2 = new JLabel("Tigers", SwingConstants.LEFT);

//label with no text, default alignment
JLabel label3 = new JLabel( );

// create image icon 
Icon icon = new ImageIcon("rhino.gif");

// create image label 
JLabel label4 = new JLabel(icon);

// assigning text to label3
label3.setText("and Bears");

// set alignment 
label3.setHorizontalAlignment(SwingConstants.RIGHT);

The alignment constants are defined in the SwingConstants interface.

Now we’ve built several labels, using a variety of constructors and several of the class’s methods. To display the labels, just add them to a container by calling the container’s add( ) method.

The other characteristics you might like to set on labels, such as changing their font or color, are accomplished using the methods of the Component class, JLabel’s distant ancestor. For example, you can call setFont( ) and setColor( ) on a label, as with any other component.

Given that labels are so simple, why do we need them at all? Why not just draw a text string directly on the container object? Remember that a JLabel is a JComponent. That’s important; it means that labels have the normal complement of methods for setting fonts and colors that we mentioned earlier, as well as the ability to be managed sensibly by a layout manager. Therefore, they’re much more flexible than a text string drawn at an absolute location within a container.

Speaking of layouts—if you use the setText( ) method to change the text of your label, the label’s preferred size may change. But the label’s container will automatically lay out its components when this happens, so you don’t have to worry about it.

Swing can interpret HTML-formatted text in JLabel and JButton labels. The following example shows how to create a button with HTML-formatted text:

JButton button = new JButton(
  "<html>"
  + "S<font size=-1>MALL<font size=+0> "
  + "C<font size=-1>APITALS");

Get Learning Java now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.