5.4 The JButton Class


JButton is the simplest of the button types, adding very little to what is provided by the AbstractButton class. JButtons are buttons that are not toggled on and off but instead act as push buttons, which invoke some action when clicked. Figure 5-2 shows what these buttons look like in four of the Swing L&Fs.

Figure 5-2. JButtons in four L&Fs
figs/swng2.0502.gif

5.4.1 Properties

The JButton class inherits most of its properties and default values from its superclasses. The exceptions to this are shown in Table 5-9. The model property is set to a new instance of DefaultButtonModel when a JButton is created.

Table 5-9. JButton properties

Property

Data type

get

is

set

Default value

accessibleContexto

AccessibleContext

·

   

JButton.AccessibleJButton( )

defaultButton

boolean

 

·

 

false

defaultCapable

boolean

 

·

·

true

modelo

ButtonModel

·

 

·

DefaultButtonModel( )

UIClassIDo

String

·

   

"ButtonUI"

ooverridden

See also properties from AbstractButton (Table 5-5).

The defaultButton property indicates whether the button is activated by default when some event occurs within the JRootPane containing the button. Typically, the event that would trigger the button would be an Enter key press, but this is actually up to the L&F implementation.

The defaultButton property cannot be set directly. Instead, it is set by telling the JRootPane which button should be the default. (We'll cover JRootPane in Chapter 8 at this point, it's enough to know that the Swing containers JApplet, JDialog, JFrame, and JWindow all use a JRootPane as their primary content container.) If the button is inside one of these Swing containers, this property may be true.

The other new property, defaultCapable, indicates whether the button may be set as a root pane's default button. A button may be treated only as the default button if this property is set to true.

5.4.2 Using the Default Button

Here's a quick example showing how the default button property can be used:

// DefaultButtonExample.java // import javax.swing.*; import java.awt.*; // Example using defaultButton and JRootPane.setDefaultButton( ) public class DefaultButtonExample {   public static void main(String[] args) {     // Create some buttons.     JButton ok = new JButton("OK");     JButton cancel = new JButton("Cancel");     JPanel buttonPanel = new JPanel( );     buttonPanel.add(ok);     buttonPanel.add(cancel);     JLabel msg = new JLabel("Is this OK?", JLabel.CENTER);     // Create a frame, get its root pane, and set the OK button as the default. This     // button is pressed if we press the Enter key while the frame has focus.     JFrame f = new JFrame( );     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     JRootPane root = f.getRootPane( );     root.setDefaultButton(ok);     // Layout and display     Container content = f.getContentPane( );     content.add(msg, BorderLayout.CENTER);     content.add(buttonPanel, BorderLayout.SOUTH);     f.setSize(200,100);     f.setVisible(true);   } }

The first thing we do here is create two buttons and a label. We then create a JFrame and get its "root pane." Next, we call this pane's setDefaultButton( ) method, passing in a reference to the OK button. When this program runs, the OK button is drawn with a different border around it, as shown with the Metal L&F in Figure 5-3. More importantly, when we press Enter while the frame has focus, the OK button is pressed automatically.

Figure 5-3. Default button
figs/swng2.0503.gif

5.4.3 Events

JButton does not define any new events, but it's important to understand which of the events defined by its superclasses are fired when the button is pressed. The most important thing to know about JButton events is that JButtons fire ActionEvents when they are clicked. This type of event is sent after the button is released, and only if the button is still armed (meaning that the cursor is still over the button). The following example creates event listeners for action, change, and item events to show which events are fired when we press the button:

// JButtonEvents.java // import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; public class JButtonEvents {   public static void main(String[] args) {     JButton jb = new JButton("Press Me");     jb.addActionListener(new ActionListener( ) {       public void actionPerformed(ActionEvent ev) {         System.out.println("ActionEvent!");       }     });     jb.addItemListener(new ItemListener( ) {       public void itemStateChanged(ItemEvent ev) {         System.out.println("ItemEvent!");       }     });     jb.addChangeListener(new ChangeListener( ) {       public void stateChanged(ChangeEvent ev) {         System.out.println("ChangeEvent!");       }     });     JFrame f = new JFrame( );     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     f.getContentPane( ).add(jb);     f.pack( );     f.setVisible(true);   } }

Running this program and pressing the button produces the following output:

ChangeEvent! ChangeEvent!

When the button is released, the following additional output is produced:

ActionEvent! ChangeEvent!

The initial change events are fired, indicating that the button is armed and pressed. When the button is released, the action event is fired, along with another change event to indicate that the button is no longer pressed.

Pressing the button a second time results in only a single change event, followed by the action event and change event when the button is released. This is because the button's armed property is still set to true after the button is clicked. This property is set to false again only if you hold the mouse button down and then move the cursor away from the button. If the button is released while the pointer is no longer over the button, no ActionEvent is fired.

In practice, you are typically interested only in the ActionEvents fired by a JButton.

5.4.4 Constructors

public JButton( )

Create a button with no image or text.

public JButton(Action a)

Create a button with property values taken from the specified Action (see Table 5-8), register the Action to receive ActionEvents fired by the button, and register the button as a ChangeListener of the Action. The button adapts to any future changes made to the Action. This is equivalent to instantiating a JButton with the default constructor and then calling its setAction( ) method. (This constructor was introduced with SDK 1.3.)

public JButton(Icon icon)

Create a button displaying the specified icon.

public JButton(String text)

Create a button displaying the specified text.

public JButton(String text, Icon icon)

Create a button displaying the specified text and icon.

5.4.5 Using Actions

The following example creates four Action objects and uses them to create buttons (and to create menu items, just to show how easy it is). Each button (and menu) takes its text, icon, mnemonic, toolTip, and enabled status from the Action. If an Action changes one or more of these, the button (and menu) reflects the change automatically. Figure 5-4 shows an example of this: both the button and the menu item change from "Go to channel 9" in their enabled state to "Go to channel 2" in their disabled state when the user clicks on (or invokes via the mnemonic with Alt-S)[4] the Set `Go to' channel button.

[4] As we noted earlier, the use of the Alt key is actually up to the L&F, but currently, the Swing L&Fs that support button mnemonics use Alt. The Mac L&F does not, so if you run this program on a Mac, the buttons do not display any underlines, and pressing the key combinations has no effect.

Figure 5-4. ActionExample before and after clicking on the Set `Go to' channel button
figs/swng2.0504.gif
// ActionExample.java // import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ActionExample extends JFrame {   public static final int MIN_CHANNEL = 2;   public static final int MAX_CHANNEL = 13;   private int currentChannel = MIN_CHANNEL;   private int favoriteChannel = 9;   private JLabel channelLabel = new JLabel( );   private Action upAction = new UpAction( );   private Action downAction = new DownAction( );   private GotoFavoriteAction gotoFavoriteAction = new GotoFavoriteAction( );   private Action setFavoriteAction = new SetFavoriteAction( );   public class UpAction extends AbstractAction {     public UpAction( ) {       putValue(NAME, "Channel Up");       putValue(SMALL_ICON, new ImageIcon("images/up.gif"));       putValue(SHORT_DESCRIPTION, "Increment the channel number");       putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_U));     }     public void actionPerformed(ActionEvent ae) {       setChannel(currentChannel+1);     }   }   public class DownAction extends AbstractAction {     public DownAction( ) {       putValue(NAME, "Channel Down");       putValue(SMALL_ICON, new ImageIcon("images/down.gif"));       putValue(SHORT_DESCRIPTION, "Decrement the channel number");       putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_D));     }     public void actionPerformed(ActionEvent ae) {       setChannel(currentChannel-1);     }   }   public class GotoFavoriteAction extends AbstractAction {     public GotoFavoriteAction( ) {       putValue(SMALL_ICON, new ImageIcon("images/fav.gif"));       putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_G));       updateProperties( );     }     public void updateProperties( ) {       putValue(NAME, "Go to channel "+favoriteChannel);       putValue(SHORT_DESCRIPTION, "Change the channel to "+favoriteChannel);     }     public void actionPerformed(ActionEvent ae) {       setChannel(favoriteChannel);     }   }   public class SetFavoriteAction extends AbstractAction {     public SetFavoriteAction( ) {       putValue(NAME, "Set 'Go to' channel");       putValue(SMALL_ICON, new ImageIcon("images/set.gif"));       putValue(SHORT_DESCRIPTION, "Make current channel the Favorite channel");       putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_S));     }     public void actionPerformed(ActionEvent ae) {       favoriteChannel = currentChannel;       gotoFavoriteAction.updateProperties( );       setEnabled(false);       gotoFavoriteAction.setEnabled(false);     }   }   public ActionExample( ) {     super("ActionExample");          setChannel(currentChannel); // Enable/disable the Actions as appropriate.     channelLabel.setHorizontalAlignment(JLabel.CENTER);     channelLabel.setFont(new Font("Serif", Font.PLAIN, 32));     getContentPane( ).add(channelLabel, BorderLayout.NORTH);     JPanel buttonPanel = new JPanel(new GridLayout(2, 2, 16, 6));     buttonPanel.setBorder(BorderFactory.createEmptyBorder(6, 16, 16, 16));     getContentPane( ).add(buttonPanel, BorderLayout.CENTER);     buttonPanel.add(new JButton(upAction));     buttonPanel.add(new JButton(gotoFavoriteAction));     buttonPanel.add(new JButton(downAction));     buttonPanel.add(new JButton(setFavoriteAction));     JMenuBar mb = new JMenuBar( );     JMenu menu = new JMenu("Channel");     menu.add(new JMenuItem(upAction));     menu.add(new JMenuItem(downAction));     menu.addSeparator( );     menu.add(new JMenuItem(gotoFavoriteAction));     menu.add(new JMenuItem(setFavoriteAction));     mb.add(menu);     setJMenuBar(mb);   }   public void setChannel(int chan) {     currentChannel = chan;     channelLabel.setText("Now tuned to channel: "+currentChannel);     // Enable/disable the Actions as appropriate.     downAction.setEnabled(currentChannel > MIN_CHANNEL);     upAction.setEnabled(currentChannel < MAX_CHANNEL);     gotoFavoriteAction.setEnabled(currentChannel != favoriteChannel);       setFavoriteAction.setEnabled(currentChannel != favoriteChannel);     }   public static void main(String argv[]) {     JFrame f = new ActionExample( );     f.setSize(400, 180);     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     f.setVisible(true);   } } 

5.4.6 Fancy Buttons

While looking at AbstractButton, we learned that quite a few things can be done with Swing buttons to make them more visually interesting. In this example, we'll see how we can spice up a user interface by adding rollover and selected icons to our buttons. We'll also take away the button borders, focus painting, and fill content area to give our display a nice clean look.

// FancyButton.java // import javax.swing.*; import java.awt.*; public class FancyButton extends JButton {   // Create a JButton that does not show focus, does not paint a border, and displays   // different icons when rolled over and pressed.   public FancyButton(Icon icon, Icon pressed, Icon rollover) {     super(icon);     setFocusPainted(false);     setRolloverEnabled(true);     setRolloverIcon(rollover);     setPressedIcon(pressed);     setBorderPainted(false);     setContentAreaFilled(false);   }   // A simple test program    public static void main(String[] args) {     FancyButton b1 = new FancyButton(       new ImageIcon("images/redcube.gif"),       new ImageIcon("images/redpaw.gif"),       new ImageIcon("images/reddiamond.gif"));     FancyButton b2 = new FancyButton(       new ImageIcon("images/bluecube.gif"),       new ImageIcon("images/bluepaw.gif"),       new ImageIcon("images/bluediamond.gif"));     JFrame f = new JFrame( );     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     Container c = f.getContentPane( );     c.setLayout(new FlowLayout( ));     c.add(b1);     c.add(b2);     f.pack( );     f.setVisible(true);   } }

Figure 5-5 shows our new button class with the different states of the buttons. Of course, this is just one fancy button implementation. You can create your own special button classes using some or all of the features shown in FancyButton, as well as other features, such as adding icons for other button states.

Figure 5-5. Buttons using "rollover" and "pressed" icons
figs/swng2.0505.gif


Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net