CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
Responding to User Events
The graphical user interface that you developed during the past hour can run on its own without any changes. Buttons can be clicked, text fields filled with text, and the applet window can be resized with wild abandon. Sooner or later, however, even the least discriminating user is going to be left wanting more. The graphical user interface that a program offers has to cause things to happen when a mouse click or keyboard entry occurs. Text areas and other components must be updated to show what's happening as the program runs.
These things are possible when your Java program can respond to user events. An event is something that happens when a program runs, and user events are things that a user causes by using the mouse, keyboard, or another input device. Responding to user events often is called event-handling, and it's the activity you'll be learning about during this hour.
The following topics will be covered:
Making your programs aware of events
Setting up a component so it can cause events
Components that can be ignored
Where events end up in a program
Storing information in the interface
Using numeric variables with text fields
Getting Your Programs to Listen
Responding to user events in a Java program requires the use of one or more EventListener interfaces. As you might recall from using the Runnable interface for multithreaded programs, interfaces are special classes that enable a class of objects to inherit behavior that it would not be able to use otherwise. Adding an EventListener interface involves two things right away. First, because the listening classes are part of the java.awt.event group of classes, you must make them available with the following statement:
import java.awt.event.*;
Secondly, the class must use the implements statement to declare that it will be using one or more listening interfaces. The following statement creates a class that uses ActionListener, an interface used with buttons and other components:
public class Graph extends java.applet.Applet implements ActionListener
All action events sent in the program will 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 use the object that is sent to the method.
In this case, an ActionEvent object is sent to the actionPerformed() method. There are several different classes of objects that represent the user events that can be sent in a program. These classes have methods you can use to determine which component caused the event to happen. In the actionPerformed() method, if the ActionEvent object is named evt, you can identify the component with the following statement:
String cmd = evt.getActionCommand();
The getActionCommand() method sends back a string. If the component is a button, the string will be the label that is on the button. If it's a text field, the string will be 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 Button object called start, a TextField called speed, and another TextField called viscosity:
void public actionPerformed(ActionEvent evt) else if (source == viscosity) else
// start caused event
You can use the getSource() method with all types of user events to identify the specific object that caused the event.
Check Box and Choice Events
Choice lists and check boxes require the ItemListener interface. To make one of these components generate events, use the addItemListener() method. For example, the following statements create a check box called superSize and cause it to send out user events when selected or deselected:
Checkbox superSize = new Checkbox('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 use the getItem() method.
To determine whether a check box is selected or deselected, use the getStateChange() method with the constants ItemEvent.SELECTED and ItemEvent.DESELECTED. The following is an example for an ItemEvent object called item:
int status = item.getStateChange();
if (status == ItemEvent.SELECTED)
// item was selected
To determine the value that has been selected in a Choice object, use getItem() and convert that value to a string, as in the following:
Object which = item.getItem();
String answer = (String) which;
Other Text Field Events
If you want to check on a text field or text area after its value has been changed, use the TextListener interface. The addTextListener() method makes a text component actively generate user events, and the textValueChanged() method receives the events. The following example receives events from TextField objects called address and zipCode:
public void textValueChanged(TextEvent txt) else
String newZipCode = zipCode.getText();
The getText() method is used with text components to retrieve their values. The setText() method can set the value of a text field or text area.
Enabling and Disabling Components
You may have seen a component in a program that appears shaded instead of its normal appearance. This shading indicates that users cannot do anything to the component because it is disabled. Disabling and enabling components as a program runs is done 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 a component.
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 applet that takes a user's address in text fields, you might want to disable a Continue button until all of the fields have some kind of value.
Workshop: A Little Lotto Madness
For more examples of how event-handling works in the context of a Java program, you will finish the Lotto applet that you began during Hour 19, 'Building a Simple User Interface.' The name of the applet will be changed from LottoGUI to LottoMadness to reflect its status as a program. The purpose of this applet is to assess the user's chances of winning a six-number Lotto drawing in a lifetime. Figure 20.1 shows a screen capture of the program as it continues to run.
Instead of using probability to figure out this problem, the computer will take a more anecdotal approach: It will conduct drawing after drawing after drawing until you win. Because the 6-out-of-6 win is extremely unlikely, the program also will report on any combination of three, four, or five winning numbers.
The interface that you created includes 12 text fields for Lotto numbers and two check boxes labeled Quick Pick and Personal. Six of the text fields are disabled from input; they will be used to display the winning numbers of each drawing. The other six text fields are for the user's choice of numbers. If the user wants to select six numbers manually, he should select the Personal check box. If he selects the Quick Pick box instead, six random numbers will appear in the text fields.
Figure 20.1. <../art/20/20tja01.jpg> The LottoMadness applet continues to run.
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 as fast as it can. Pressing the Stop button stops the thread, and pressing Reset clears all fields so the user can start the number-crunching all over again.
The LottoMadness applet implements three interfaces: ActionListener, ItemListener, and Runnable. The first two are needed to listen to user events generated by the buttons and check boxes on the applet. The program does not need to listen to any events related to the text fields, because they will be used strictly to store the user's choice of numbers. The user interface handles this function automatically.
Listing 20.1 shows the full text of the LottoMadness applet. The shaded lines in the listing were unchanged from LottoGUI.java. The unshaded statements are what must be added to respond to user events and run the Lotto drawings.
Making this program aware of user events for some components requires only a few additions. The class statement in Lines 4-6 is changed to use the interfaces. Lines 46-51 add the listeners that are needed for the two check boxes and three button components. One line is added to the program in the init() method where components are placed on the user interface. In Line 77, the stop object is disabled with the setEnabled(false) method. Because no drawings are taking place when the program begins running, the Stop button should not be usable at that point.
The following methods are used in the program to accomplish specific tasks:
Lines 146-156: The clearAllFields() method causes all text fields in the applet to be emptied out. This method is handled when the Reset button is pressed.
Lines 159-162: 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 some of them as numbers.
Lines 165-169: The numberGone() method takes three arguments--a single number from a Lotto drawing, an array that holds several TextField objects, and a count integer. This method makes sure that each number in a drawing hasn't been selected already in the same drawing.
Lines 172-178: The matchedOne() method takes two arguments--a TextField object and an array of six TextField objects. This method checks to see whether one of the user's numbers is a winner.
The actionPerformed() method of the applet receives the action events caused when the user presses Stop, Play, or Reset. The getActionCommand() method retrieves the label of the button, which is used to determine which component was pressed. Pressing the Play button causes four components to be disabled so that they do not interfere with the drawings as they are taking place. Pressing Stop reverses this by enabling every component except for the Stop button.
The itemStateChanged()method receives the user events caused when one of the check boxes is selected. The getItem() method sends back an Object, which is converted to a string to determine the label of the check box.
One last thing to note about the LottoMadness applet is the lack of variables used to keep track of things like the number of drawings, winning counts, and Lotto number text fields. This element of user interface programming differs from other types of programs. You can use the interface to store values and display them automatically.
Load the original LottoGUI.java program into your word processor and save the file under the new name LottoMadness.java. After changing the class statement to reflect the new name of the program and the interfaces it will use, insert all of the non-shaded lines from Listing 20.1 and save the file.
Listing 20.1. The full text of LottoMadness.java.
1: import java.awt.*;
2: import java.awt.event.*;
3:
4: public class LottoMadness extends java.applet.Applet
5: implements ItemListener, ActionListener,
6: Runnable
67: row2.add(winnersLabel);
68: for (int i = 0; i < 6; i++)
73: add(row2);
74:
75: FlowLayout layout3 = new FlowLayout(FlowLayout.CENTER, 10, 10);
76: row3.setLayout(layout3);
77: stop.setEnabled(false);
78: row3.add(stop);
79: row3.add(play);
80: row3.add(reset);
81: add(row3);
82:
83: GridLayout layout4 = new GridLayout(2, 3, 20, 10);
84: row4.setLayout(layout4);
85: row4.add(got3Label);
86: got3.setEditable(false);
87: row4.add(got3);
88: row4.add(got4Label);
89: got4.setEditable(false);
90: row4.add(got4);
91: row4.add(got5Label);
92: got5.setEditable(false);
93: row4.add(got5);
94: row4.add(got6Label);
95: got6.setEditable(false);
96: row4.add(got6);
97: row4.add(drawingsLabel);
98: drawings.setEditable(false);
99: row4.add(drawings);
row4.add(yearsLabel);
years.setEditable(false);
row4.add(years);
add(row4);
}
public void actionPerformed(ActionEvent event)
if (command == 'Stop')
}
public void itemStateChanged(ItemEvent event) while (numberGone(pick, numbers, i));
numbers[i].setText('' + pick);
}
} else
}
void clearAllFields()
got3.setText(null);
got4.setText(null);
got5.setText(null);
got6.setText(null);
drawings.setText(null);
years.setText(null);
}
void addOneToField(TextField field)
boolean numberGone(int num, TextField[] pastNums, int count)
boolean matchedOne(TextField win, TextField[] allPicks)
return false;
}
public void run() while (numberGone(ball, winners, i));
winners[i].setText('' + ball);
if (matchedOne(winners[i], numbers))
matches++;
}
switch (matches)
}
}
After saving the LottoMadness.java file, load the file LottoGUI.html
into your word processor and make one change--the text LottoGUI.class
should be LottoMadness.class.
Save it under the new name LottoMadness.html. Compile the LottoMadness
applet with the javac compiler tool and then try out the applet by
loading its Web page into the appletviewer.
Summary
Using the Abstract Windowing Toolkit and Java's event-handling features, you can create a professional-looking program with a modest amount of programming. Although the LottoMadness applet is longer than many of the examples you have worked on during the last 20 hours, half of the program was comprised of statements to build the interface.
If you spend some time running the LottoMadness applet, you will become even more bitter and envious about the good fortune of the people who win these six-number lottery drawings. The run of the program shown in Figure 20.1 indicates that you could blow 27 grand and the best 266 years of your life buying tickets, only to win a handful of 4-of-6 and 3-of-6 prizes. In comparison to those odds, the chance to make Java programming skills pay off almost seems like a sure thing.
Q&A
Q Is there a
way to use different colors in an interface?
A You can
use Color objects to change the
appearance of each component in several ways. The setBackground() method designates the background
elements, and setForeground() sets foreground elements. You must use these
methods with the components themselves. The setBackground() method of the applet will
not change the color of containers and components within the applet.
Q Do you need to do anything with the paint() or repaint() method to indicate
that a text field has been changed?
A After the setText() method of a text component is used to change its value, nothing else
needs to be done. The Abstract Windowing Toolkit handles the updating that is
necessary to show the new value.
Quiz
After the LottoMadness program has soured you on games of chance, play a game of skill by answering the following questions.
Questions
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' class of objects
will handle the events.
3. Which component stores user input
as integers?
(a) TextArea
(b) TextField
(c) Neither does
Answers
b.
2. c. If the name of another class were used as an argument instead of the this statement, that class would
receive the events and be expected to handle them.
3. c. TextField and TextArea components store their values as text, so their values must be
converted before they can be used as integers, floating-point numbers, or other
nontext values.
Activities
If the main event of this hour didn't provide enough action for your taste, interface with the following activities:
Add a text field to the LottoMadness applet that works in conjunction with a Thread.sleep() statement to slow down the rate at which drawings are conducted.
Use the TextListener interface and related methods to make sure that users of LottoMadness enter valid numbers from 1 to 50 for the drawings.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 762
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved