Buttons that Maintain State

The Swing GUI components contain three types of state buttonsJToggleButton, JCheckBox and JRadioButtonthat have on/off or true/false values. Classes JCheckBox and JRadioButton are subclasses of JToggleButton (Fig. 11.14). A JRadioButton is different from a JCheckBox in that normally several JRadioButtons are grouped together, and are mutually exclusiveonly one in the group can be selected at any time. We first discuss class JCheckBox. The next two subsections also demonstrate that an inner class can access the members of its top-level class.

11.9.1. JCheckBox

The application of Fig. 11.17 and Fig. 11.18 uses two JCheckBox objects to select the desired font style of the text displayed in a JTextField. When selected, one applies a bold style and the other an italic style. If both are selected, the style of the font is bold and italic. When the application initially executes, neither JCheckBox is checked (i.e., they are both false), so the font is plain. Class CheckBoxTest (Fig. 11.18) contains the main method that executes this application.

Figure 11.17. JCheckBox buttons and item events.

(This item is displayed on pages 537 - 538 in the print version)

 1 // Fig. 11.17: CheckBoxFrame.java
 2 // Creating JCheckBox buttons.
 3 import java.awt.FlowLayout;
 4 import java.awt.Font;
 5 import java.awt.event.ItemListener;
 6 import java.awt.event.ItemEvent;
 7 import javax.swing.JFrame;
 8 import javax.swing.JTextField;
 9 import javax.swing.JCheckBox;
10
11 public class CheckBoxFrame extends JFrame
12 {
13 private JTextField textField; // displays text in changing fonts
14 private JCheckBox boldJCheckBox; // to select/deselect bold 
15 private JCheckBox italicJCheckBox; // to select/deselect italic
16
17 // CheckBoxFrame constructor adds JCheckBoxes to JFrame
18 public CheckBoxFrame()
19 {
20 super( "JCheckBox Test" );
21 setLayout( new FlowLayout() ); // set frame layout
22
23 // set up JTextField and set its font
24 textField = new JTextField( "Watch the font style change", 20 );
25 textField.setFont( new Font( "Serif", Font.PLAIN, 14 ) );
26 add( textField ); // add textField to JFrame
27
28 boldJCheckBox = new JCheckBox( "Bold" ); // create bold checkbox
29 italicJCheckBox = new JCheckBox( "Italic" ); // create italic 
30 add( boldJCheckBox ); // add bold checkbox to JFrame
31 add( italicJCheckBox ); // add italic checkbox to JFrame
32
33 // register listeners for JCheckBoxes 
34 CheckBoxHandler handler = new CheckBoxHandler();
35 boldJCheckBox.addItemListener( handler ); 
36 italicJCheckBox.addItemListener( handler ); 
37 } // end CheckBoxFrame constructor
38
39 // private inner class for ItemListener event handling
40 private class CheckBoxHandler implements ItemListener
41 {
42 private int valBold = Font.PLAIN; // controls bold font style
43 private int valItalic = Font.PLAIN; // controls italic font style
44
45 // respond to checkbox events 
46 public void itemStateChanged( ItemEvent event )
47 {
48 // process bold checkbox events
49 if ( event.getSource() == boldJCheckBox )
50 valBold =
51 boldJCheckBox.isSelected() ? Font.BOLD : Font.PLAIN;
52
53 // process italic checkbox events
54 if ( event.getSource() == italicJCheckBox )
55 valItalic =
56 italicJCheckBox.isSelected() ? Font.ITALIC : Font.PLAIN;
57
58 // set text field font
59 textField.setFont(
60 new Font( "Serif", valBold + valItalic, 14 ) );
61 } // end method itemStateChanged
62 } // end private inner class CheckBoxHandler
63 } // end class CheckBoxFrame

Figure 11.18. Test class for CheckBoxFrame.

(This item is displayed on page 538 in the print version)

 1 // Fig. 11.18: CheckBoxTest.java
 2 // Testing CheckBoxFrame.
 3 import javax.swing.JFrame;
 4
 5 public class CheckBoxTest
 6 {
 7 public static void main( String args[] )
 8 {
 9 CheckBoxFrame checkBoxFrame = new CheckBoxFrame();
10 checkBoxFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
11 checkBoxFrame.setSize( 275, 100 ); // set frame size
12 checkBoxFrame.setVisible( true ); // display frame
13 } // end main
14 } // end class CheckBoxTest
 

After the JTextField is created and initialized (Fig. 11.17, line 24), line 25 uses method setFont (inherited by JTextField indirectly from class Component) to set the font of the JTextField to a new object of class Font (package java.awt). The new Font is initialized with "Serif" (a generic font name representing a font such as Times and is supported on all Java platforms), Font.PLAIN style and 14-point size. Next, lines 2829 create two JCheckBox objects. The string passed to the JCheckBox constructor is the checkbox label that appears to the right of the JCheckBox by default.

When the user clicks a JCheckBox, an ItemEvent occurs. This event can be handled by an ItemListener object, which must implement method itemStateChanged. In this example, the event handling is performed by an instance of private inner class CheckBoxHandler (lines 4062). Lines 3436 create an instance of class CheckBoxHandler and register it with method addItemListener as the listener for both the JCheckBox objects.

Lines 4243 declare instance variables for the inner class CheckBoxHandler. Together, these variables represent the font style for the text displayed in the JTextField. Initially both are Font.PLAIN to indicate that the font is not bold and is not italic. Method itemStateChanged (lines 4661) is called when the user clicks the bold or the italic JCheckBox. The method uses event.getSource() to determine which JCheckBox the user clicked. If it was the boldJCheckBox, line 51 uses JCheckBox method isSelected to determine if the JCheckBox is selected (i.e., it is checked). If the checkbox is selected, local variable valBold is assigned Font.BOLD; otherwise, it is assigned Font.PLAIN. A similar statement executes if the user clicks the italicJCheckBox. If the italicJCheckBox is selected, local variable valItalic is assigned Font.ITALIC; otherwise, it is assigned Font.PLAIN. Lines 5960 change the font of the JTextField, using the same font name and point size. The sum of valBold and valItalic represents the JTextField's new font style. Each of the Font constants represents a unique value. Font.PLAIN has the value 0, so if both valBold and valItalic are set to Font.PLAIN, the font will have the plain style. If one of the values is Font.BOLD or Font.ITALIC, the font will be bold or italic accordingly. If one is BOLD and the other is ITALIC, the font will be both bold and italic.

Relationship Between an Inner Class and Its Top-Level Class

You may have noticed that class CheckBoxHandler used variables boldJCheckBox (Fig. 11.17, lines 49 and 51), italicJCheckBox (lines 54 and 56) and textField (line 59) even though these variables are not declared in the inner class. An inner class has a special relationship with its top-level classthe inner class is allowed to access directly all the instance variables and methods of the top-level class. Method itemStateChanged (line 4661) of class CheckBoxHandler uses this relationship to determine which JCheckBox is the event source, to determine the state of a JCheckBox and to set the font on the JTextField. Notice that none of the code in inner class CheckBoxHandler requires a reference to the top-level class object.

11.9.2. JRadioButton

Radio buttons (declared with class JRadioButton) are similar to check boxes in that they have two statesselected and not selected (also called deselected). However, radio buttons normally appear as a group in which only one button can be selected at a time (see output of Fig. 11.20). Selecting a different radio button forces all others to be deselected. Radio buttons are used to represent mutually exclusive options (i.e., multiple options in the group cannot be selected at the same time). The logical relationship between radio buttons is maintained by a ButtonGroup object (package javax.swing), which itself is not a GUI component. A ButtonGroup object organizes a group of buttons and is not itself displayed in a user interface. Rather, the individual JRadioButton objects from the group are displayed in the GUI.

Common Programming Error 11.3

Adding a ButtonGroup object (or an object of any other class that does not derive from Component) to a container results in a compilation error.

The application of Fig. 11.19 and Fig. 11.20 is similar to that of Fig. 11.17 and Fig. 11.18. The user can alter the font style of a JTextField's text. The application uses radio buttons that permit only a single font style in the group to be selected at a time. Class RadioButtonTest (Fig. 11.20) contains the main method that executes this application.

Figure 11.19. JRadioButtons and ButtonGroups.

(This item is displayed on pages 540 - 541 in the print version)

 1 // Fig. 11.19: RadioButtonFrame.java
 2 // Creating radio buttons using ButtonGroup and JRadioButton.
 3 import java.awt.FlowLayout;
 4 import java.awt.Font;
 5 import java.awt.event.ItemListener;
 6 import java.awt.event.ItemEvent;
 7 import javax.swing.JFrame;
 8 import javax.swing.JTextField;
 9 import javax.swing.JRadioButton;
10 import javax.swing.ButtonGroup;
11
12 public class RadioButtonFrame extends JFrame
13 {
14 private JTextField textField; // used to display font changes
15 private Font plainFont; // font for plain text
16 private Font boldFont; // font for bold text
17 private Font italicFont; // font for italic text
18 private Font boldItalicFont; // font for bold and italic text
19 private JRadioButton plainJRadioButton; // selects plain text 
20 private JRadioButton boldJRadioButton; // selects bold text 
21 private JRadioButton italicJRadioButton; // selects italic text 
22 private JRadioButton boldItalicJRadioButton; // bold and italic 
23 private ButtonGroup radioGroup; // buttongroup to hold radio buttons
24
25 // RadioButtonFrame constructor adds JRadioButtons to JFrame
26 public RadioButtonFrame()
27 {
28 super( "RadioButton Test" );
29 setLayout( new FlowLayout() ); // set frame layout
30
31 textField = new JTextField( "Watch the font style change", 25 );
32 add( textField ); // add textField to JFrame
33
34 // create radio buttons
35 plainJRadioButton = new JRadioButton( "Plain", true ); 
36 boldJRadioButton = new JRadioButton( "Bold", false ); 
37 italicJRadioButton = new JRadioButton( "Italic", false ); 
38 boldItalicJRadioButton = new JRadioButton( "Bold/Italic", false );
39 add( plainJRadioButton ); // add plain button to JFrame
40 add( boldJRadioButton ); // add bold button to JFrame
41 add( italicJRadioButton ); // add italic button to JFrame
42 add( boldItalicJRadioButton ); // add bold and italic button
43
44 // create logical relationship between JRadioButtons 
45 radioGroup = new ButtonGroup(); // create ButtonGroup 
46 radioGroup.add( plainJRadioButton ); // add plain to group 
47 radioGroup.add( boldJRadioButton ); // add bold to group 
48 radioGroup.add( italicJRadioButton ); // add italic to group 
49 radioGroup.add( boldItalicJRadioButton ); // add bold and italic
50
51 // create font objects
52 plainFont = new Font( "Serif", Font.PLAIN, 14 );
53 boldFont = new Font( "Serif", Font.BOLD, 14 );
54 italicFont = new Font( "Serif", Font.ITALIC, 14 );
55 boldItalicFont = new Font( "Serif", Font.BOLD + Font.ITALIC, 14 );
56 textField.setFont( plainFont ); // set initial font to plain
57
58 // register events for JRadioButtons 
59 plainJRadioButton.addItemListener( 
60  new RadioButtonHandler( plainFont ) ); 
61 boldJRadioButton.addItemListener( 
62  new RadioButtonHandler( boldFont ) ); 
63 italicJRadioButton.addItemListener( 
64  new RadioButtonHandler( italicFont ) ); 
65 boldItalicJRadioButton.addItemListener( 
66  new RadioButtonHandler( boldItalicFont ) );
67 } // end RadioButtonFrame constructor
68
69 // private inner class to handle radio button events
70 private class RadioButtonHandler implements ItemListener
71 {
72 private Font font; // font associated with this listener
73
74 public RadioButtonHandler( Font f )
75 {
76 font = f; // set the font of this listener
77 } // end constructor RadioButtonHandler
78
79 // handle radio button events
80 public void itemStateChanged( ItemEvent event )
81 {
82 textField.setFont( font ); // set font of textField
83 } // end method itemStateChanged
84 } // end private inner class RadioButtonHandler
85 } // end class RadioButtonFrame

Figure 11.20. Test class for RadioButtonFrame.

(This item is displayed on page 542 in the print version)

 1 // Fig. 11.20: RadioButtonTest.java
 2 // Testing RadioButtonFrame.
 3 import javax.swing.JFrame;
 4
 5 public class RadioButtonTest
 6 {
 7 public static void main( String args[] )
 8 {
 9 RadioButtonFrame radioButtonFrame = new RadioButtonFrame();
10 radioButtonFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
11 radioButtonFrame.setSize( 300, 100 ); // set frame size
12 radioButtonFrame.setVisible( true ); // display frame
13 } // end main
14 } // end class RadioButtonTest
 

Lines 3542 in the constructor (Fig. 11.19) create four JRadioButton objects and add them to the JFrame. Each JRadioButton is created with a constructor call like that in line 35. This constructor specifies the label that appears to the right of the JRadioButton by default and the initial state of the JRadioButton. A TRue second argument indicates that the JRadioButton should appear selected when it is displayed.

Line 45 instantiates ButtonGroup object radioGroup. This object is the "glue" that forms the logical relationship between the four JRadioButton objects and allows only one of the four to be selected at a time. It is possible that no JRadioButtons in a ButtonGroup are selected, but this can only occur if no preselected JRadioButtons are added to the ButtonGroup and the user has not selected a JRadioButton yet. Lines 4649 use ButtonGroup method add to associate each of the JRadioButtons with radioGroup. If more than one selected JRadioButton object is added to the group, the selected one that was added first will be selected when the GUI is displayed.

JRadioButtons, like JCheckBoxes, generate ItemEvents when they are clicked. Lines 5966 create four instances of inner class RadioButtonHandler (declared at lines 7084). In this example, each event listener object is registered to handle the ItemEvent generated when the user clicks a particular JRadioButton. Notice that each RadioButtonHandler object is initialized with a particular Font object (created in lines 5255).

Class RadioButtonHandler (line 7084) implements interface ItemListener so it can handle ItemEvents generated by the JRadioButtons. The constructor stores the Font object it receives as an argument in the event-listener object's instance variable font (declared at line 72). When the user clicks a JRadioButton, radioGroup turns off the previously selected JRadioButton and method itemStateChanged (line 8083) sets the font in the JTextField to the Font stored in the JRadioButton's corresponding event-listener object. Notice that line 82 of inner class RadioButtonHandler uses the top-level class's textField instance variable to set the font.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

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