|
Second Summer 2002
|
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.
|
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.
|
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);
}
| 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) { }
}
|
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.
|
|
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.
|
|
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.
|
|
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: Jul 25, 2002 by Adrian German for A201