IntroductionIn the last lesson we developed an applet that used a text field to allow the user to interact with the applet -- by typing in a string which the applet would then display in red. We discovered this was clumsy, though: in order to change the display, we had to force the applet to be redrawn (for example, by hiding the window and then bringing it back into view. In this lesson, we will revise our solution and make it much more elegant, and we'll explore some other forms of input. |
EventsOne way to describe what we're doing is to say that we're developing a Graphical User Interface (or GUI, pronounced "gooey") for our applet: that is, the user interacts with the applet via graphical components, in this case the text field. Most modern software uses this approach: most likely your favorite word processor makes heavy use of buttons, menus, text fields, etc. Of course, your word processor doesn't have the same problem our applet does -- when you type something in, it appears immediately on the screen without you having to minimize and maximize the window. How does that work? In essence, the word processing program "knows" when you hit a key or click the mouse, and, more importantly, it knows what to do in response to your actions.If you look at our applet from the last lesson, though, you'll see that there's no connection between what the applet does and what (or when) the user types. Whenever the paint() method is called, the display is refreshed -- but that doesn't really have anything to do with when the user has typed something in -- we could even imagine the paint() method being called in the middle of when the user is typing in a string! What we need to is some way of making sure the paint() method is called whenever the user is done entering a string. This is the concept of an event. In general, an event is simply an occurrence to which a program might need to respond. In our case, we're interested in the kinds of events that indicate that the user has provided our applet with some form of input. Specifically, we're interested in knowing when a user is entering text into a text field; we can also imagine wanting to know, for example, if the user uses the mouse to click on a button. In this lesson, we will modify our applet to respond to certain events: this is known as event-driven programming. |
Responding to EventsWorking with events is complicated because for every event that needs a response, there are three objects involved.First, the object causing the event, or the event source; in our case, the TextField object. We don't have to worry much about this object (other than creating it like we did in the previous lesson); every TextField knows how to signal that an event has occurred. Second, the object that should respond to the event. This object is referred to as the listener, since it "listens" for the event to happen. The event source object must designate the listener object for the event, and every listener needs to have a special method that can respond to the event that is being listened for -- writing this method is usually the most difficult part of working with events. And third, the object representing the event itself. Yes, even events are modeled as objects! We don't have to worry much about the details of these objects, though -- they are created automatically by the event source. In our example, the TextField object text is the event source, and we know the event object itself will be automatically generated by text. But what object should be the listener? To figure this out, we just need to idenitfy which object needs to know when the user is done typing. Remember, the reason we started doing this is the first place is that the applet's paint() method was not being called at the correct point. So in order to fix this problem, it is the applet itself that needs to listen for these events! To indicate that our applet can listen for events, we modify it as follows: public class TryInput extends Applet implements ActionListener {This says that the applet can listen for events, but it doesn't say which events, exactly, it will listen for. Remember that the event source has to designate a listener: we do that by adding an instruction to the init() method: public void init(){We send a message to the text object, telling to register this as an ActionListener for events generated by text. Remember that this essentially means "myself" -- so in this statement, the applet is sending a message to text, saying "Register me as a listener for your events." Finally, the applet must include a method called actionPerformed() which actually responds to the event. In our case, when the user types in the text field and triggers the event by pressing "Enter", we want the screen to be redrawn. We do that by invoking the repaint() method, which causes paint() to be re-invoked: public void actionPerformed(ActionEvent e){Notice that this method receives a parameter of type ActionEvent -- this is the event object that is created by the event source (text). Listeners always take the event they listen for as a parameter, since sometimes the details of the event are important. But in this case, since there's only one event we're interested in, all we need to know is that the event happened. |
The full appletNow we can put all the pieces together. Here is the full applet; note that we have to add another import statement to handle all the special event objects:import java.awt.*;Try it out for yourself |