A checkbox is a labeled toggle switch. Each time the user clicks it, its state toggles between checked and unchecked. Swing implements the checkbox as a special kind of button. Radio buttons are similar to checkboxes, but they are usually arranged in groups. Click on one radio button in the group, and the others automatically turn off. They are named for the preset buttons on old car radios.
Checkboxes and radio buttons are represented by instances of
JCheckBox
and JRadioButton
,
respectively. Radio buttons can be tethered together using an
instance of another class called
ButtonGroup
. By now you’re probably well into
the swing of things (no pun intended) and could easily master these
classes on your own. We’ll use an example to illustrate a
different way of dealing with the state of components and to show off
a few more things about containers.
A JCheckBox
sends
ItemEvent
s when it’s pushed. Since a checkbox
is a kind of button, it also fires
ActionEvent
s when it
becomes checked. For something like a checkbox, we might want to be
lazy and check on the state of the buttons only at some later time,
such as when the user commits an action. It’s like filling out
a form; you can change your choices until you submit the form.
The following application, DriveThrough
, lets us
check off selections on a fast food menu, as shown in Figure 14.1. DriveThrough
prints
the results when we press the Place
Order button. Therefore, we can ignore all the events
generated by our
checkboxes and radio
buttons and listen only for the action events generated by the
regular button.
//file: DriveThrough.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DriveThrough { public static void main(String[] args) { JFrame f = new JFrame("Lister v1.0"); f.setSize(300, 150); f.setLocation(200, 200); f.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent we) { System.exit(0); } }); JPanel entreePanel = new JPanel( ); final ButtonGroup entreeGroup = new ButtonGroup( ); JRadioButton radioButton; entreePanel.add(radioButton = new JRadioButton("Beef")); radioButton.setActionCommand("Beef"); entreeGroup.add(radioButton); entreePanel.add(radioButton = new JRadioButton("Chicken")); radioButton.setActionCommand("Chicken"); entreeGroup.add(radioButton); entreePanel.add(radioButton = new JRadioButton("Veggie", true)); radioButton.setActionCommand("Veggie"); entreeGroup.add(radioButton); final JPanel condimentsPanel = new JPanel( ); condimentsPanel.add(new JCheckBox("Ketchup")); condimentsPanel.add(new JCheckBox("Mustard")); condimentsPanel.add(new JCheckBox("Pickles")); JPanel orderPanel = new JPanel( ); JButton orderButton = new JButton("Place Order"); orderPanel.add(orderButton); Container content = f.getContentPane( ); content.setLayout(new GridLayout(3, 1)); content.add(entreePanel); content.add(condimentsPanel); content.add(orderPanel); orderButton.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent ae) { String entree = entreeGroup.getSelection().getActionCommand( ); System.out.println(entree + " sandwich"); Component[] components = condimentsPanel.getComponents( ); for (int i = 0; i < components.length; i++) { JCheckBox cb = (JCheckBox)components[i]; if (cb.isSelected( )) System.out.println("With " + cb.getText( )); } } }); f.setVisible(true); } }
DriveThrough
lays out three panels. The
radio buttons in the
entreePanel
are tied together through a
ButtonGroup
object. We add( )
the
buttons to a ButtonGroup
to make them mutually
exclusive. The ButtonGroup
object is an odd
animal. One expects it to be a container or a component, but it
isn’t; it’s simply a helper object that allows only one
RadioButton
to be selected at a time.
In this example, the button group forces you to choose a beef,
chicken, or veggie entree, but not more than one. The condiment
choices, which are
JCheckBox
es, aren’t in a button group, so you
can request any combination of ketchup, mustard, and pickles on your
sandwich.
When the Place Order button is pushed, we receive an
ActionEvent
in the actionPerformed( )
method of our inner ActionListener
. At
this point, we gather the information in the radio buttons and
checkboxes and print it. actionPerformed( )
simply
reads the state of the various buttons. We could have saved
references to the buttons in a number of ways; this example
demonstrates two. First, we find out which entree was selected. To do
so, we call the
ButtonGroup
’s getSelection( )
method. This returns a ButtonModel
,
upon which we immediately call getActionCommand( )
.
This returns the action command as we set it when we created the
radio buttons. The action commands for the buttons are the
entrée names, which is exactly what we need.
To
find out which condiments were selected, we use a more complicated
procedure. The problem is that condiments aren’t mutually
exclusive, so we don’t have the convenience of a
ButtonGroup
. Instead, we ask the condiments
JPanel
for a list of its components. The
getComponents( )
method returns an array of
references to the container’s child components. We’ll use
this to loop over the components and print the results. We cast each
element of the array back to JCheckBox
and call
its isSelected( )
method to see if the checkbox is on
or off. If we were dealing with different types of components in the
array, we could determine each component’s type with the
instanceof
operator.
Get Learning Java now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.