Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

Event Handling

Making those GUIs do something!

Less dumb GUIs


We've seen how to build "dumb GUIs", i.e. windows full of components that don't do anything. It's now time to see how to get GUIs to respond to user actions like clicking on a button, typing text or dragging the mouse. These things are called events, and responding to them is called event handling.
2

The event loop


In a GUI-based program, all processing revolves around something called the event loop:
1. The program sits there, waiting for the user to do something 2. The user does something (generates an event) 3. The program responds in some way. 4. Go back to 1.
3

Event handling in Java


In Java, event handling is based on listeners. A listener is an object with a method which contains the code we want to run when an event happens.

Events, Components, Listeners


A listener object is associated with one or more of the GUI components on the screen. When an event happens to a component, that event is passed on to all the listeners for that component. Some of these listeners might then respond to the event. When they have done this, they go back to listening.
5

Associating a listener with a component


To tell a component object to use a certain listener object, you call a special method, like these: void addActionListener(ActionListener l) void addMouseListener(MouseListener l) These are methods in the Component class.
6

Let's look at the types


The addActionListener method takes an object of type ActionListener as its parameter. ActionListener is the name of an interface. That means that to create an appropriate listener, we need to implement the ActionListener interface.
7

Look at the documentation!


You absolutely cannot go much further with GUI programming without being familiar with looking things up in the online API documentation. If you don't know where to find it, find out! That's your next exercise

A look at ActionListener
A quick look at the documentation reveals that ActionListener is very simple. It has one method:
public void actionPerformed(ActionEvent e);

To implement this interface, we just need to write a class with a method like this.
9

The recipe for event handling


Here are the steps we need to take to handle events:
Write a class MyListener which implements ActionListener (or whatever). Set up a GUI as before. Create a MyListener object. Associate the MyListener object with the component we want to respond to, using addActionListener.
10

That's all the theory


That's all there is to event handling. We now need to
See what kinds of events and listeners there are. Practice programming with event handlers. Learn a couple more ways to organise code which help with this sort of work.

11

Button Presses
A simple form of event is the pressing of a button. This generates an ActionEvent, which we listen for with an ActionListener. Let's write one!

12

Simple ActionListener
implements keyword

public class FirstActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Event handled!"); } } code to run when the button is pressed

13

Using it on a GUI
1. Create a button:
JButton button = new JButton("Press me");

2. Create a listener:
ActionListener listener = new FirstActionListener();

3. Attach the listener to the button:


button.addActionListener(listener);

14

Detour: a design decision


In the Dumb GUI code examples, we created a JFrame object and then added various components to its content pane. A slightly different design is to write a class which is a subclass of JFrame, and contains code to add components to its own content pane.

15

New design example


public class MyGUI extends JFrame { // code to set up the GUI public void init() { Container pane = this.getContentPane(); pane.add(new JButton("Press me")); } }

16

Using this subclass


We can now use this subclass by
creating a MyGUI object calling its init() method to set things up calling its setVisible method (inherited from JFrame).

This makes sense because our GUI is a special kind of window, i.e. one with a button on it! It will turn out to be a useful design later.
17

Not a very good program!


Our listener does its job, but it's not very good. The user presses a button on the GUI, but gets output on the terminal. Usually the output would go somewhere on the GUI! Let's make it happen
18

Sending the output to the GUI


We first need a place to send the output. We will use a JTextField on the GUI. This is easy to add to the GUI: just create the object and add it to the content pane.
JTextField display = new JTextField(8); pane.add(display);
19

Changing the listener


The more difficult part is updating the listener so that it sends the output to the textfield. We can put text into a textfield using e.g.
display.setText("I handled the event!");

20

How does the listener know where to send the output?


The biggest problem we have is that the listener class is separate from the GUI class. This means that the listener class cannot access the variable display. This in turn means it cannot access the JTextField object, so it cannot send the output there.
21

Solution: pass a reference


The solution is
Give the listener a variable which will store a JTextField; this is where it will send the output. Arrange for this variable to hold the same text field object that we put on the GUI.

This can be done via a constructor.

22

The new listener


public class SecondActionListener implements ActionListener { private JTextField output; public SecondActionListener(JTextField out) { output = out; } public void actionPerformed(ActionEvent e){ output.setText("I handled the event!"); } }
23

Using the new listener


To use this listener, we have to pass it the output textfield:
JTextField display = new JTextField(20); ActionListener listener = new SecondActionListener(display);

The rest is just as before. It works! This is a very important example. Please make sure you understand it.
24

Doing "more interesting" things


It is now a simple matter to do something more interesting, like counting the number of button presses. To do this, we need a listener that keeps track of the number of times the button has been pressed. This is done using a field, of course.
25

CountListener
public class CountListener implements ActionListener { private JTextField output; private int count; public CountListener(JTextField out) { count = 0; output = out; } continued on next slide

26

CountListener continued

public void actionPerformed (ActionEvent e) { count = count + 1; output.setText("Number of presses: " + count); } }

27

It works, but
This program works, but the user can type text into the textfield. This is not what we want, because we're using the textfield for output, not input. You can fix it with
display.setEditable(false);

28

Getting input
A common thing to want to do is to get input from the user and do something interesting with it. We will now try this, but we will be doing something very boring with the input: measuring the length of the input string, and displaying the answer.

29

The GUI
We will use a very simple GUI: two textfields (one for input, one for output) and a button to say "do it!".

30

GUI code
Container pane=this.getContentPane(); pane.setLayout(new FlowLayout()); JTextField input = new JTextField(20); pane.add(input); JButton button = new JButton("Calculate length"); pane.add(button); JTextField display=new JTextField(20); display.setEditable(false); pane.add(display);
31

Adding a listener
We need to set things up so that when the user presses the button, our program
1. fetches the text from the first textfield 2. counts the length of this string 3. displays this number in the second textfield

We will do this by attaching a listener to the button.


32

Listener design
What information will our listener need to store to do this work? It needs to know
where to find the input where to send the output

It does not need to store the input anywhere, or remember anything from one press to the next.
33

Listener design, continued


Our listener will therefore have two fields:
private JTextField input; private JTextField output;

These will be initialized through the constructor:


public StringLengthListener(JTextField in, JTextField out) { constructor code }
34

Two variables called input


In our program, there are two variables called input:
in the GUI code in the listener code

As it happens, they are going to contain (point to) the same JTextField object. They are not the same variable, and will not contain the same thing unless we make it so. Let's make it so!
35

Handling the event


It is relatively easy to write the code to handle the button-press now:
String inputString = input.getText(); int length = inputString.length(); output.setText("Length is " + length);

36

Shorter version
Those three lines can be abbreviated to:
output.setText("Length is " + input.getText().length());

Make sure you understand this line!

37

Finishing the listener


To complete the listener, we just have to put the event-handling code into the actionPerformed method.
public void actionPerformed(ActionEvent e) { String inputString = input.getText(); int length = inputString.length(); output.setText("Length is " + length); }
38

Creating and attaching the listener


Finally, our GUI setup needs to create a listener object and attach it to the button:
ActionListener listener = new StringLengthListener(input, display); button.addActionListener(listener);

Study this example carefully!

39

Summary
To respond to events, we create listener objects. A listener is an object whose class implements an appropriate interface. ActionListener is the interface used to listen for button presses. The method actionPerformed contains the code to run when a button is pressed. The listener is attached to a GUI component using addActionListener.
40

You might also like