Spring Semester 2003


Lecture Notes Twenty-Five: Applets. Events. Listeners. See also pp. 395-414 in chapter 10.
Let's write an applet. We've done that before.

Well, OK, here it is:
public class MouseSpyApplet extends Applet {
  public void init() {
    System.out.println("The applet is being initialized...");
  }
  public void start() {
    System.out.println("Applet is now being started..."); 
  }  
} 
Not a very complicated applet...

Yes, and ignore its name for now. I will. Do we need an HTML file?

Of course, but you can supply that yourself. Fair enough.

Today we will talk about event-driven programming. That's a big shift in the paradigm we have been using so far.

Yes: the user is in total control. And will we be using the MouseSpyApplet applet that we wrote above, to start studying event-driven programming?

Yes. Our first goal will be to let the user click with the mouse in the applet, and report what's happening. How are we going to do that?

The mouse will act as an event source. When the user works with it it will produce events.

The events produced by the mouse are objects. They are of type MouseEvent, a class that is defined in the package java.awt.event.

So now you know what to look for, also what to import in your programs. Is this the only event that could be produced in event-driven programming?

No, there are many kinds of events. MouseEvent is just one type.

Yes. Here's the big picture:
I think I need to understand this picture.

Yes. In the beginning there is an event source. That's the mouse for us.

Indeed, and many things could be event sources. But this is where it all starts: the event source.

Yes, the user works with it. And we gave it a number: 1.

Then, we need to listen to the event source, to know when an event happens. So that we can take action, if needed.

Listeners are also objects in Java. Do you need to create (or define) them, or do you just import them or how do you get one?

You need to define them. Why?

Because they contain the part that does the action. OK, then I will probably also have to create them, right?

Yes, to describe the object you need to write a class description. OK, let me write one.
class MouseSpy {

} 

Why can't you name it MouseListener? I've heard the name is taken?

By whom? An interface is called that way.

What's an interface? And what interface is that? An interface is an element of pure design.

Yes, that's true. But let's come up with a more comprehensive definition. It's going to be longer.

No problem, I'll start it: the fundamental units of design in java are the public methods that can be invoked on objects. Interfaces are a way to declare a type consisting only of abstract methods

... that is, methods with no body, ... and constants, enabling any implementation to be written for those methods.

An interface is an expression of pure design... ... and I said it first,

... while a class is a mix of design and implementation. A class can implement the methods of an interface in any way that the designer of the class chooses.

An interface has thus many more possible implementations than a class. Can I see an example?

java.awt.event.MouseListener? Yes, that's the one that took the name.

Here it is:
public interface MouseListener extends EventListener {
  public void mouseClicked (MouseEvent e);
  public void mousePressed (MouseEvent e);
  public void mouseReleased(MouseEvent e);
  public void mouseEntered (MouseEvent e);
  public void mouseExited  (MouseEvent e);
} 
Is that it?

That's it. And it's defined in...

... the java.awt.event package. Now, how do we work with this?

If you want to be a MouseEvent listener you need to implement the interface. I don't, but MouseSpy does.
class MouseSpy implements MouseListener {

} 
Ah, so you say implements instead of extends...

And you need to import the interface too. OK, how about that.
import java.awt.event.*; 

class MouseSpy implements MouseListener {
  public void mouseClicked (MouseEvent e);
  public void mousePressed (MouseEvent e);
  public void mouseReleased(MouseEvent e);
  public void mouseEntered (MouseEvent e);
  public void mouseExited  (MouseEvent e);
} 

Looks better but when you try to compile it it won't. I need to provide an implementation for each of the six methods.

Yes. What would be the easiest? Empty bodies.

Very good, let's do that.
import java.awt.event.*; 

class MouseSpy implements MouseListener {
  public void mouseClicked (MouseEvent e) { }
  public void mousePressed (MouseEvent e) { }
  public void mouseReleased(MouseEvent e) { }
  public void mouseEntered (MouseEvent e) { }
  public void mouseExited  (MouseEvent e) { }
} 
So this is our listener?

Yes. What does it do? Nothing.

Correct. The methods are empty. Now let me see if that compiles and runs.

If you compile the applet program you will see that the compiler won't even touch the listener class. Why?

Because it's not even mentioned there. We need to do step 3.

Step 2 was the definition of the listener, ... and we still need to add something to it, as the methods are currently doing nothing,

... and in step 3 we need to create an actual listener object and register it with the event source. How about this:
import java.applet.*;

public class MouseSpyApplet extends Applet {
    public void init() {
	System.out.println("The applet is being initialized..."); 
	MouseSpy listener = new MouseSpy();
	addMouseListener(listener); 
    } 
    public void start() {
	System.out.println("The applet is being started..."); 
    } 
} 


Looks good, but how did you know of the add mouse listener method? How do you know that an applet has a getWidth() (or a getHeight() )method for that matter?

Aren't they inherited? Same with addMouseListener.

Correct. Let's get back to the methods of the listener. What about them?

Do they remind you of anything? They should remind you of
paint(Graphics g)

Who calls them? The event source, basically.

Really? No, not really.

Then who calls them? The event source, but indirectly.

What do you mean by that? The event source notifies the listener, actually.

And who calls the methods? The system does.

How? Event source says to system:
"I have this listener, I need to pass this info (an event) to it, could you do that for me, please?"

And the appropriate method of the listener is called with the actual event as a parameter. Yes, the actual event is passed as the parameter to your methods.

You define the methods. And they provide the events.

So you can work on them. Neat.

Just like paint is called with the actual Graphics context as a parameter. The system gives you the context and you need to supply the definition of what should be done with it.

Let's summarize. When you define a listener object you need to provide some definitions for what it should do, if it's notified that an event has occured.

Then you need to create an actual listener object, and register it with the event source. Which in this case will be the applet object, because it will be in direct contact with the mouse.

Fair enough. Let's define the methods now, and make it happen.

Just like Graphics objects the MouseEvent also have specific functionality and behaviour. g, for example, was able to draw.

e can give you the x and y coordinates of the MouseEvent ... if e is of type MouseEvent

Here's where MouseEvent is in the hierarcy of events:
Oh, boy. Are we also going to talk about window events today?

Yes, and here's another hierarchy:
Ha! Now our own classes are pictured in blue.

Yes, and some methods are pictured in red, ... next to the classes which define them.

They're inherited by the subclasses, ... and it's important to know they are not redefined.

So they're as they should be. Yes. Let's finish the listener now.
import java.awt.event.*; 

class MouseSpy implements MouseListener {

    public void mouseClicked (MouseEvent e) { 
	System.out.println("Mouse clicked at: " + 
			   e.getX() + " " + e.getY());
    } 
    public void mousePressed (MouseEvent e) { 
	System.out.println("Mouse pressed at: " + 
			   e.getX() + " " + e.getY());
    } 
    public void mouseReleased(MouseEvent e) { 
	System.out.println("Mouse released at: " + 
			   e.getX() + " " + e.getY());
    } 
    public void mouseEntered (MouseEvent e) { 
	System.out.println("Mouse entered at: " + 
			   e.getX() + " " + e.getY());
    } 
    public void mouseExited  (MouseEvent e) { 
	System.out.println("Mouse exited at: " + 
			   e.getX() + " " + e.getY());
    } 

} 

We already have the applet. Yes, so once you compile the applet you should run the appletviewer on the HTML file and everything should be working well.

Can we also write standalone graphical applications? You mean, not applets?

Yes, something with main. Yes, but then you need to provide your own window.

Which is provided by the appletviewer or by the browser for applets. I can see Window in the hierarchy above.

You can start from it, and extend it. Extend it like we extended applets.

Yes, start from something already complex, and add your customizations to make it work the way you want it. But is it a good idea to start directly from Window?

Then start from JFrame which is a more evolved type of window that has a title and a border.
Sounds better already.
import javax.swing.*;

class EmptyFrame extends JFrame {
  public EmptyFrame() {
    final int WIDTH  = 300; // default 
    final int HEIGHT = 300; //     values 
    setSize(WIDTH, HEIGHT); 
  } 
} 

class FrameTest {
  public static void main(String[] args) {
    EmptyFrame f = new EmptyFrame(); 
    f.setTitle("This is my title."); 
    f.show(); 
  } 
} 

If you run this what happens? The frame overstays its welcome.

It never goes away? Why?

You need a window listener that realizes you have told it to go away. I need to implement a MouseListener again?

No, not a mouse listener, because we are not interested in the mouse here. Ah, so I need to implement a window listener.

What's that interface again? WindowListener from the same package as the interface for mouse listeners.

Fortunately there are adapter classes. That you can extend.

Which already have all methods defined, and empty. So you can override the one that you want to define.

I want to see the code. Here it is.
import javax.swing.*; 
import java.awt.event.*; 

class EmptyFrame extends JFrame {
  public EmptyFrame() {
    final int WIDTH  = 300; // default 
    final int HEIGHT = 300; //     values 
    setSize(WIDTH, HEIGHT); 
    WindowCloser w = new WindowCloser(); 
    addWindowListener(w); 
  } 
} 

class FrameTest {
  public static void main(String[] args) {
    EmptyFrame f = new EmptyFrame(); 
    f.setTitle("This is my title."); 
    f.show(); 
  } 
} 

class WindowCloser extends WindowAdapter {
  public void windowClosing(WindowEvent e) {
    System.exit(0); 
  } 
} 

Very good, the new code is in blue. As always.

Could I have used the same method with the mouse? Yes, if there is an adapter for the listener you implemented.

And is there one? Yes, there is, but you need to be sure of that.

Is this the only way we can do it? What do you mean, we already did it in two ways: by implementing a interface and by extending an adapter.

Is there a third way? Yes, you could use inner classes.

Very good. Is there a fourth way? Yes, you can make the frame or the applet be its own listener.

Which method is best? It depends on what you want to do.

I would like to take a break. For that they all behave the same.


Last updated: Apr 11, 2003 by Adrian German for A201