Responding to User Input - Programming a Graphical User Interface - Sams Teach Yourself Java in 24 Hours, 7th Edition (2014)

Sams Teach Yourself Java in 24 Hours, 7th Edition (2014)

Part IV: Programming a Graphical User Interface

Hour 15. Responding to User Input

THIS HOUR’S TO-DO LIST:

Image Make your programs aware of events.

Image Set up a component so it can cause events.

Image Ignore some components.

Image Find out where events end up in a program.

Image Store information in the interface.

Image Convert values stored in text fields.

The graphical user interface (GUI) you developed during the past two hours can run on its own. Users can click buttons, fill text fields with text, and resize the window. Sooner or later, even the least discriminating user is going to be left wanting more. The GUI that a program offers has to cause things to happen when a mouse click or keyboard entry occurs.

These things become possible when your Java program can respond to user events. This is called event handling and is the main event for this hour.

Getting Your Programs to Listen

A user event in Java is something that happens when a user performs an action with the mouse, keyboard, or another input device.

Before you can receive events, you must learn how to make an object listen. Responding to user events requires the use of one or more EventListener interfaces. Interfaces are a feature of object-oriented programming in Java that enable a class to inherit behavior it would not be able to employ otherwise. They’re like a contract agreement with other classes that guarantees the class will contain specific methods.

An EventListener interface contains methods that receive user input of a specific type.

Adding an EventListener interface requires two things. First, because the listening classes are part of the java.awt.event package, you must make them available with the following statement:

import java.awt.event.*;

Second, the class must use the implements keyword to declare that it supports one or more listening interfaces. The following statement creates a class that uses ActionListener, an interface for responding to button and menu clicks:

public class Graph implements ActionListener {

EventListener interfaces enable a component of a GUI to generate user events. Without one of the listeners in place, a component cannot do anything that can be heard by other parts of a program. A program must include a listener interface for each type of component to which it listens. To have the program respond to a mouse click on a button or the Enter key being pressed in a text field, you must include the ActionListener interface. To respond to the use of a choice list or check boxes, you need the ItemListener interface.

When you require more than one interface in the same class, separate their names with commas after the implements keyword, as in this code:

public class Graph3D implements ActionListener, MouseListener {
// ...
}

Setting Up Components to Be Heard

After you have implemented the interface needed for a particular component, you must cause that component to generate user events. The ActionListener interface listens for action events, such as a button click or the Enter key being pressed.


Note

The this keyword confuses a lot of readers when it is first introduced. this refers to the object in which the keyword appears. So, if you create a LottoMadness class and use this in a statement inside that class, it refers to the LottoMadness object executing the code.


To make a JButton object generate an event, employ the addActionListener() method, as in the following:

JButton fireTorpedos = new JButton("Fire torpedos");
fireTorpedos.addActionListener(this);

This code creates the fireTorpedos button and calls the button’s addActionListener() method. The this keyword used as an argument to the addActionListener() method indicates the current object receives the user event and handles it as needed.

Handling User Events

When a user event is generated by a component that has a listener, a method is called automatically. The method must be found in the class specified when the listener was attached to the component.

Each listener has different methods that are called to receive their events. The ActionListener interface sends events to a method called actionPerformed(). The following is a short example of an actionPerformed() method:

public void actionPerformed(ActionEvent event) {
// method goes here
}

All action events sent in the program go to this method. If only one component in a program can possibly send action events, you can put statements in this method to handle the event. If more than one component can send these events, you need to check the object sent to the method.

An ActionEvent object is sent to the actionPerformed() method. Several classes of objects represent the user events that can be sent in a program. These classes have methods to determine which component caused the event to happen. In the actionPerformed() method, if theActionEvent object is named event, you can identify the component with the following statement:

String cmd = event.getActionCommand();

The getActionCommand() method sends back a string. If the component is a button, the string is the label on the button. If it’s a text field, the string is the text entered in the field. The getSource() method sends back the object that caused the event.

You could use the following actionPerformed() method to receive events from three components: a JButton object called start, a JTextField called speed, and another JTextField called viscosity:

public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == speed) {
// speed field caused event
} else if (source == viscosity) {
// viscosity caused event
} else {
// start caused event
}
}

You can call the getSource() method on all user events to identify the specific object that caused the event.

Check Box and Combo Box Events

Combo boxes and check boxes require the ItemListener interface. Call the component’s addItemListener() method to make it generate these events. The following statements create a check box called superSize that sends out user events when selected or deselected:

JCheckBox superSize = new JCheckBox("Super Size", true);
superSize.addItemListener(this);

These events are received by the itemStateChanged() method, which takes an ItemEvent object as an argument. To see which object caused the event, you can call the event object’s getItem() method.

To determine whether a check box is selected or deselected, compare the value returned by the getStateChange() method to the constants ItemEvent.SELECTED and ItemEvent.DESELECTED. The following code is an example for an ItemEvent object called item:

public void itemStateChanged(ItemEvent item) {
int status = item.getStateChange();
if (status == ItemEvent.SELECTED) {
// item was selected
}
}

To determine the value selected in a JComboBox object, use getItem() and convert that value to a string, as in the following:

Object which = item.getItem();
String answer = which.toString();

Keyboard Events

When a program must react immediately when a key is pressed, it uses keyboard events and the KeyListener interface.

The first step is to register the component that receives key presses by calling its addKeyListener() method. The argument of the method should be the object that implements the KeyListener interface. If it is the current class, use this as the argument.

An object that handles keyboard events must implement three methods:

Image void keyPressed(KeyEvent)—A method called the moment a key is pressed

Image void keyReleased(KeyEvent)—A method called the moment a key is released

Image void keyTyped(KeyEvent)—A method called after a key has been pressed and released

Each of these has a KeyEvent object as an argument, which has methods to call to find out more about the event. Call the getKeyChar() method to find out which key was pressed. This key is returned as a char value, and it can be used only with letters, numbers, and punctuation.

To monitor any key on the keyboard, including Enter, Home, Page Up, and Page Down, you can call getKeyCode() instead. This method returns an integer value representing the key. You then can call getKeyText() with that integer as an argument to receive a String object containing the name of the key (such as Home, F1, and so on).

Listing 15.1 contains a Java application that draws the most recently pressed key in a label by using the getKeyChar() method. The application implements the KeyListener interface, so there are keyTyped(), keyPressed(), and keyReleased() methods in the class. The only one of these that does anything is keyTyped() in Lines 24–27. Create a new Java file called KeyViewer, enter the listing in NetBeans’ source editor, and save the file.

LISTING 15.1 The Full Text of KeyViewer.java


1: package com.java24hours;
2:
3: import javax.swing.*;
4: import java.awt.event.*;
5: import java.awt.*;
6:
7: public class KeyViewer extends JFrame implements KeyListener {
8: JTextField keyText = new JTextField(80);
9: JLabel keyLabel = new JLabel("Press any key in the text field.");
10:
11: public KeyViewer() {
12: super("KeyViewer");
13: setLookAndFeel();
14: setSize(350, 100);
15: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
16: keyText.addKeyListener(this);
17: BorderLayout bord = new BorderLayout();
18: setLayout(bord);
19: add(keyLabel, BorderLayout.NORTH);
20: add(keyText, BorderLayout.CENTER);
21: setVisible(true);
22: }
23:
24: public void keyTyped(KeyEvent input) {
25: char key = input.getKeyChar();
26: keyLabel.setText("You pressed " + key);
27: }
28:
29: public void keyPressed(KeyEvent txt) {
30: // do nothing
31: }
32:
33: public void keyReleased(KeyEvent txt) {
34: // do nothing
35: }
36:
37: private void setLookAndFeel() {
38: try {
39: UIManager.setLookAndFeel(
40: "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
41: );
42: } catch (Exception exc) {
43: // ignore error
44: }
45: }
46:
47: public static void main(String[] arguments) {
48: KeyViewer frame = new KeyViewer();
49: }
50: }


When you run the application, it should resemble Figure 15.1.

Image

FIGURE 15.1 Handling keyboard events in a program.

Enabling and Disabling Components

You might have seen a component in a program that appears shaded instead of its normal appearance.

Shading indicates that users cannot do anything to the component because it is disabled. Disabling and enabling components is accomplished with the setEnabled() method of the component. A Boolean value is sent as an argument to the method, so setEnabled(true) enables a component for use, and setEnabled(false) disables it.

The following statements create buttons with the labels Previous, Next, and Finish and disable the first button:

JButton previousButton = new JButton("Previous");
JButton nextButton = new JButton("Next");
JButton finishButton = new JButton("Finish");
previousButton.setEnabled(false);

This method is an effective way to prevent a component from sending a user event when it shouldn’t. For example, if you’re writing a Java application that collects a user’s address using text fields, you could disable a Save Address button until the user provided a street address, city, state, and ZIP code.

Completing a Graphical Application

To see how Swing’s event-handling classes work in a Java program, you finish LottoMadness, the lottery simulation begun during Hour 14, “Laying Out a User Interface.”

At this point, LottoMadness is just a GUI. You can click buttons and enter text into text boxes, but nothing happens in response. In this workshop, you create LottoEvent, a new class that receives user input, conducts lotto drawings, and keeps track of the number of times you win. When the class is complete, you add a few lines to LottoMadness so that it makes use of LottoEvent. It often is convenient to divide Swing projects in this manner, with the GUI in one class and the event-handling methods in another.

The purpose of this application is to assess the user’s chance of winning a six-number lotto drawing in a lifetime. Figure 15.2 shows a screen capture of the program as it runs.

Image

FIGURE 15.2 Running the LottoMadness application.

Instead of using probability to figure this problem out, the computer conducts drawings in rapid succession and doesn’t stop until there’s a winner. Because the 6-out-of-6 win is extremely unlikely, the program also reports on any combination of three, four, or five winning numbers.

The interface includes 12 text fields for lotto numbers and two check boxes labeled Quick Pick and Personal. Six text fields, disabled for input, are used to display the winning numbers of each drawing. The other six text fields are for the user’s choice of numbers. Selecting the Quick Pick box chooses six random numbers for a user. Selecting Personal enables the user to select desired numbers.

Three buttons control the activity of the program: Stop, Play, and Reset. When the Play button is pressed, the program starts a thread called playing and generates Lotto drawings.

Pressing the Stop button stops the thread, and pressing Reset clears all fields so the user can start over. You learn about threads in Hour 19, “Creating a Threaded Program.”

The LottoEvent class implements three interfaces: ActionListener, ItemListener, and Runnable. The Runnable interface relates to threads and is covered in Hour 19. The listeners are needed to listen to user events generated by the application’s buttons and check boxes. The program does not need to listen to any events related to the text fields because they are used strictly to store the user’s choice of numbers. The user interface handles this storage automatically.

The class requires the use of the main Swing package, javax.swing, and Java’s event-handling package, java.awt.event.

The class has two instance variables:

Image gui, a LottoMadness object

Image playing, a Thread object used to conduct continuous lotto drawings

The gui variable is used to communicate with the LottoMadness object that contains the program’s GUI. When you need to make a change to the interface or retrieve a value from one of its text fields, you use the gui object’s instance variables.

For example, the play instance variable of LottoMadness represents the Play button. To disable this button in LottoEvent, you can use the following statement:

gui.play.setEnabled(false);

You can use the next statement to retrieve the value of the JTextField object got3:

String got3value = gui.got3.getText();

Listing 15.2 contains the full text of the LottoEvent class. Create a new Java file called LottoEvent in NetBeans to hold the source code.

LISTING 15.2 The Full Text of LottoEvent.java


1: package com.java24hours;
2:
3: import javax.swing.*;
4: import java.awt.event.*;
5:
6: public class LottoEvent implements ItemListener, ActionListener,
7: Runnable {
8:
9: LottoMadness gui;
10: Thread playing;
11:
12: public LottoEvent(LottoMadness in) {
13: gui = in;
14: }
15:
16: public void actionPerformed(ActionEvent event) {
17: String command = event.getActionCommand();
18: if (command.equals("Play")) {
19: startPlaying();
20: }
21: if (command.equals("Stop")) {
22: stopPlaying();
23: }
24: if (command.equals("Reset")) {
25: clearAllFields();
26: }
27: }
28:
29: void startPlaying() {
30: playing = new Thread(this);
31: playing.start();
32: gui.play.setEnabled(false);
33: gui.stop.setEnabled(true);
34: gui.reset.setEnabled(false);
35: gui.quickpick.setEnabled(false);
36: gui.personal.setEnabled(false);
37: }
38:
39: void stopPlaying() {
40: gui.stop.setEnabled(false);
41: gui.play.setEnabled(true);
42: gui.reset.setEnabled(true);
43: gui.quickpick.setEnabled(true);
44: gui.personal.setEnabled(true);
45: playing = null;
46: }
47:
48: void clearAllFields() {
49: for (int i = 0; i < 6; i++) {
50: gui.numbers[i].setText(null);
51: gui.winners[i].setText(null);
52: }
53: gui.got3.setText("0");
54: gui.got4.setText("0");
55: gui.got5.setText("0");
56: gui.got6.setText("0");
57: gui.drawings.setText("0");
58: gui.years.setText("0");
59: }
60:
61: public void itemStateChanged(ItemEvent event) {
62: Object item = event.getItem();
63: if (item == gui.quickpick) {
64: for (int i = 0; i < 6; i++) {
65: int pick;
66: do {
67: pick = (int) Math.floor(Math.random() * 50 + 1);
68: } while (numberGone(pick, gui.numbers, i));
69: gui.numbers[i].setText("" + pick);
70: }
71: } else {
72: for (int i = 0; i < 6; i++) {
73: gui.numbers[i].setText(null);
74: }
75: }
76: }
77:
78: void addOneToField(JTextField field) {
79: int num = Integer.parseInt("0" + field.getText());
80: num++;
81: field.setText("" + num);
82: }
83:
84: boolean numberGone(int num, JTextField[] pastNums, int count) {
85: for (int i = 0; i < count; i++) {
86: if (Integer.parseInt(pastNums[i].getText()) == num) {
87: return true;
88: }
89: }
90: return false;
91: }
92:
93: boolean matchedOne(JTextField win, JTextField[] allPicks) {
94: for (int i = 0; i < 6; i++) {
95: String winText = win.getText();
96: if ( winText.equals( allPicks[i].getText() ) ) {
97: return true;
98: }
99: }
100: return false;
101: }
102:
103: public void run() {
104: Thread thisThread = Thread.currentThread();
105: while (playing == thisThread) {
106: addOneToField(gui.drawings);
107: int draw = Integer.parseInt(gui.drawings.getText());
108: float numYears = (float)draw / 104;
109: gui.years.setText("" + numYears);
110:
111: int matches = 0;
112: for (int i = 0; i < 6; i++) {
113: int ball;
114: do {
115: ball = (int) Math.floor(Math.random() * 50 + 1);
116: } while (numberGone(ball, gui.winners, i));
117: gui.winners[i].setText("" + ball);
118: if (matchedOne(gui.winners[i], gui.numbers)) {
119: matches++;
120: }
121: }
122: switch (matches) {
123: case 3:
124: addOneToField(gui.got3);
125: break;
126: case 4:
127: addOneToField(gui.got4);
128: break;
129: case 5:
130: addOneToField(gui.got5);
131: break;
132: case 6:
133: addOneToField(gui.got6);
134: gui.stop.setEnabled(false);
135: gui.play.setEnabled(true);
136: playing = null;
137: }
138: try {
139: Thread.sleep(100);
140: } catch (InterruptedException e) {
141: // do nothing
142: }
143: }
144: }
145: }


The LottoEvent class has one constructor: LottoEvent(LottoMadness). The LottoMadness object specified as an argument identifies the object that is relying on LottoEvent to handle user events and conduct drawings.

The following methods are used in the class:

Image The clearAllFields() method causes all text fields in the application to be emptied out. This method is handled when the user clicks the Reset button.

Image The addOneToField() method converts a text field to an integer, increments it by one, and converts it back into a text field. Because all text fields are stored as strings, you have to take special steps to use them in expressions.

Image The numberGone() method takes three arguments: a single number from a lotto drawing, an array that holds several JTextField objects, and a count integer. This method makes sure that each number in a drawing hasn’t been selected already in the same drawing.

Image The matchedOne() method takes two arguments: a JTextField object and an array of six JTextField objects. This method checks to see whether one of the user’s numbers matches the numbers from the current lotto drawing.

The application’s actionPerformed() method receives the action events when the user clicks a button. The getActionCommand() method retrieves the label of the button to determine which component was clicked.

Clicking the Play button causes the startPlaying() method to be called. This method disables four components. Clicking Stop causes the stopPlaying() method to be called, which enables every component except for the Stop button.

The itemStateChanged() method receives user events triggered by the selection of the Quick Pick or Personal check boxes. The getItem() method sends back an Object that represents the check box that was clicked. If it’s the Quick Pick check box, six random numbers from 1 to 50 are assigned to the user’s lotto numbers. Otherwise, the text fields that hold the user’s numbers are cleared out.

The LottoEvent class uses numbers from 1 to 50 for each ball in the lotto drawings. This is established in Line 115, which multiplies the Math.random() method by 50, adds 1 to the total, and uses this as an argument to the Math.floor() method. The end result is a random integer from 1 to 50. If you replace 50 with a different number here and on Line 67, you could use LottoMadness for lottery contests that generate a wider or smaller range of values.

The LottoMadness project lacks variables used to keep track of things such as the number of drawings, winning counts, and lotto number text fields. Instead, the interface stores values and displays them automatically.

To finish the project, reopen LottoMadness.java in NetBeans. You only need to add six lines to make it work with the LottoEvent class.

First, add a new instance variable to hold a LottoEvent object:

LottoEvent lotto = new LottoEvent(this);

Next, in the LottoMadness() constructor, call the addItemListener() and addActionListener() methods of each user interface component that can receive user input:

// Add listeners
quickpick.addItemListener(lotto);
personal.addItemListener(lotto);
stop.addActionListener(lotto);
play.addActionListener(lotto);
reset.addActionListener(lotto);

These statements should be added near the end of the constructor, right before the call to setVisible(true) that makes it visible.

Listing 15.3 contains the full text of LottoMadness.java after you have made the changes. The lines you added are shaded—the rest is unchanged from the previous hour.

LISTING 15.3 The Full Text of LottoMadness.java


1: package com.java24hours;
2:
3: import java.awt.*;
4: import javax.swing.*;
5:
6: public class LottoMadness extends JFrame {
7: LottoEvent lotto = new LottoEvent(this);
8:
9: // set up row 1
10: JPanel row1 = new JPanel();
11: ButtonGroup option = new ButtonGroup();
12: JCheckBox quickpick = new JCheckBox("Quick Pick", false);
13: JCheckBox personal = new JCheckBox("Personal", true);
14: // set up row 2
15: JPanel row2 = new JPanel();
16: JLabel numbersLabel = new JLabel("Your picks: ", JLabel.RIGHT);
17: JTextField[] numbers = new JTextField[6];
18: JLabel winnersLabel = new JLabel("Winners: ", JLabel.RIGHT);
19: JTextField[] winners = new JTextField[6];
20: // set up row 3
21: JPanel row3 = new JPanel();
22: JButton stop = new JButton("Stop");
23: JButton play = new JButton("Play");
24: JButton reset = new JButton("Reset");
25: // set up row 4
26: JPanel row4 = new JPanel();
27: JLabel got3Label = new JLabel("3 of 6: ", JLabel.RIGHT);
28: JTextField got3 = new JTextField("0");
29: JLabel got4Label = new JLabel("4 of 6: ", JLabel.RIGHT);
30: JTextField got4 = new JTextField("0");
31: JLabel got5Label = new JLabel("5 of 6: ", JLabel.RIGHT);
32: JTextField got5 = new JTextField("0");
33: JLabel got6Label = new JLabel("6 of 6: ", JLabel.RIGHT);
34: JTextField got6 = new JTextField("0", 10);
35: JLabel drawingsLabel = new JLabel("Drawings: ", JLabel.RIGHT);
36: JTextField drawings = new JTextField("0");
37: JLabel yearsLabel = new JLabel("Years: ", JLabel.RIGHT);
38: JTextField years = new JTextField("0");
39:
40: public LottoMadness() {
41: super("Lotto Madness");
42:
43: setSize(550, 400);
44: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
45: GridLayout layout = new GridLayout(5, 1, 10, 10);
46: setLayout(layout);
47:
48: // Add listeners
49: quickpick.addItemListener(lotto);
50: personal.addItemListener(lotto);
51: stop.addActionListener(lotto);
52: play.addActionListener(lotto);
53: reset.addActionListener(lotto);
54:
55: FlowLayout layout1 = new FlowLayout(FlowLayout.CENTER,
56: 10, 10);
57: option.add(quickpick);
58: option.add(personal);
59: row1.setLayout(layout1);
60: row1.add(quickpick);
61: row1.add(personal);
62: add(row1);
63:
64: GridLayout layout2 = new GridLayout(2, 7, 10, 10);
65: row2.setLayout(layout2);
66: row2.add(numbersLabel);
67: for (int i = 0; i < 6; i++) {
68: numbers[i] = new JTextField();
69: row2.add(numbers[i]);
70: }
71: row2.add(winnersLabel);
72: for (int i = 0; i < 6; i++) {
73: winners[i] = new JTextField();
74: winners[i].setEditable(false);
75: row2.add(winners[i]);
76: }
77: add(row2);
78:
79: FlowLayout layout3 = new FlowLayout(FlowLayout.CENTER,
80: 10, 10);
81: row3.setLayout(layout3);
82: stop.setEnabled(false);
83: row3.add(stop);
84: row3.add(play);
85: row3.add(reset);
86: add(row3);
87:
88: GridLayout layout4 = new GridLayout(2, 3, 20, 10);
89: row4.setLayout(layout4);
90: row4.add(got3Label);
91: got3.setEditable(false);
92: row4.add(got3);
93: row4.add(got4Label);
94: got4.setEditable(false);
95: row4.add(got4);
96: row4.add(got5Label);
97: got5.setEditable(false);
98: row4.add(got5);
99: row4.add(got6Label);
100: got6.setEditable(false);
101: row4.add(got6);
102: row4.add(drawingsLabel);
103: drawings.setEditable(false);
104: row4.add(drawings);
105: row4.add(yearsLabel);
106: years.setEditable(false);
107: row4.add(years);
108: add(row4);
109:
110: setVisible(true);
111: }
112:
113: private static void setLookAndFeel() {
114: try {
115: UIManager.setLookAndFeel(
116: "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
117: );
118: } catch (Exception exc) {
119: // ignore error
120: }
121: }
122:
123: public static void main(String[] arguments) {
124: LottoMadness.setLookAndFeel();
125: LottoMadness frame = new LottoMadness();
126: }
127: }



Note

The book’s website at www.java24hours.com contains a link to an applet version of the LottoMadness program. The applet has run 410,732,244 drawings, which equals 3.9 million years of twice-weekly drawings. There have been 6,364,880 3-out-of-6 winners, 337,285 4-out-of-6 winners, 6,476 5-out-of-6 winners, and 51 6-out-of-6 winners (roughly one out of every 8 million drawings). The first person to win this fictional lottery was Bill Teer. His numbers were 3, 7, 1, 15, 34, and 43, and it only took him 241,225 drawings (2,319.47 years) to win.


After you add the shaded lines, you can run the application, which is capable of testing your lotto skills for thousands of years. As you might expect, these lotteries are an exercise in futility. The chance of winning a 6-out-of-6 lotto drawing in a lifetime is extremely slim, even if you live as long as a biblical figure.

Summary

You can create a professional-looking program with a modest amount of programming by using Swing. Although the LottoMadness application is longer than many of the examples you have worked in during the last 14 hours, half of the program was composed of statements to build the interface.

If you spend some time running the application, you become even more bitter and envious about the good fortune of the people who win these six-number lottery drawings.

My most recent run of the program indicates that I could blow $27,000 and the best 266 years of my life buying tickets, only to win a handful of 4-out-of-6 and 3-out-of-6 prizes. In comparison to those odds, the chance to make your Java programming skills pay off is practically a sure thing.

Workshop

Q&A

Q. Do you need to do anything with the paint() method or repaint() to indicate that a text field has been changed?

A. After the setText() method of a text component is used to change its value, you don’t need to do anything else. Swing handles the updating necessary to show the new value.

Q. Why do you often import a class and also one of its subclasses, as in Listing 15.1 when you import java.awt.* and java.awt.event.*? Could the first of these statements include the second?

A. Though the names of the java.awt and java.awt.event packages look like they are related, there’s no such thing as inheritance for packages in Java. One package cannot be a subpackage of another.

When you use an asterisk in an import statement, you are making all the classes in a package available in a program.

The asterisk works only on classes, not packages. The most a single import statement can load is the classes of a single package.

Q. Why is the actor Michael J. Fox identified by his middle initial?

A. There already was a Michael Fox in the Screen Actor’s Guild, forcing the future Family Ties and Back to the Future star to choose another name for his professional work. Michael Andrew Fox is his real name, but he didn’t like the sound of Andrew or Andy Fox—and calling himself Michael A. Fox sounded like he was admiring his own good looks.

He settled on Michael J. Fox as an homage to the character actor Michael J. Pollard.

The other Michael Fox was an actor who appeared on episodes of Perry Mason, Burke’s Law, and numerous other TV shows and movies until his death in 1996.

Quiz

After the LottoMadness program has soured you on games of chance, play a game of skill by answering the following questions.

1. Why are action events called by that name?

A. They occur in reaction to something else.

B. They indicate that some kind of action should be taken in response.

C. They honor cinematic adventurer Action Jackson.

2. What does this signify as the argument to an addActionListener() method?

A. this listener should be used when an event occurs.

B. this event takes precedence over others.

C. this object handles the events.

3. Which text component stores user input as integers?

A. JTextField

B. JTextArea

C. Neither A nor B

Answers

1. B. Action events include the click of a button and the selection of an item from a pull-down menu.

2. C. The this keyword refers to the current object. If the name of an object is used as an argument instead of the this statement, that object would receive the events and be expected to handle them.

3. C. JTextField and JTextArea components store their values as text, so you must convert their values before you can use them as integers, floating-point numbers, or other nontext values.

Activities

If the main event of this hour didn’t provide enough action for your tastes, interface with the following activities:

Image Add a text field to the LottoMadness application that works in conjunction with the Thread.sleep() statement in the LottoEvent class to slow down the rate that drawings are conducted.

Image Modify the LottoMadness project so it draws five numbers from 1 to 90.

To see Java programs that implement these activities, visit the book’s website at www.java24hours.com.