Section 6.4
Mouse Events
EVENTS ARE CENTRAL to programming for
a graphical user interface. A GUI program doesn't have a
main() routine that outlines what will happen when
the program is run, in a step-by-step process from beginning
to end. Instead, the program must be prepared to respond to
various kinds of events that can happen at unpredictable
times and in an order that the program doesn't control. The most
basic kinds of events are generated by the mouse and keyboard.
The user can press any key on the keyboard, move the
mouse, or press a button on the mouse. The user can do any of
these things at any time, and the computer has to respond
appropriately.
In Java, events are represented by objects. When an event occurs,
the system collects all the information relevant to the event and
constructs an object to contain that information. Different types
of events are represented by objects belonging to different classes.
For example, when the user presses one of the buttons on a mouse,
an object belonging to a class called MouseEvent is
constructed. The object contains information such as the
GUI component on which the user clicked, the (x,y) coordinates
of the point in the component where the click occurred, and which button
on the mouse was pressed. When the user
presses a key on the keyboard, a KeyEvent is created.
After the event object is constructed, it is passed as a parameter
to a designated subroutine. By writing that subroutine, the
programmer says what should happen when the event occurs.
As a Java programmer, you get a fairly high-level view of events.
There is lot of processing that goes on between the time that the user
presses a key or moves the mouse and the time that a subroutine in your
program is called to respond to the event. Fortunately, you don't need
to know much about that processing. But you should understand this
much: Even though your GUI program doesn't have a main() routine,
there is a sort of main routine running somewhere that executes
a loop of the form
while the program is still running:
Wait for the next event to occur
Call a subroutine to handle the event
This loop is called an event loop. Every
GUI program has an event loop. In Java, you don't have to write the loop.
It's part of "the system." If you write a GUI program in
some other language, you might have to provide a main routine
that runs an event loop.
In this section, we'll look at handling mouse events in Java, and we'll
cover the framework for handling events in general. The next
section will cover keyboard events. Java also has other types of
events, which are produced by GUI components. These will be introduced
in Section 6 and covered in detail in
Section 7.3.
For an event to have any effect, a program must detect the event
and react to it. In order to detect an event, the program must
"listen" for it. Listening for events is something that
is done by an object called an event listener.
An event listener object must contain instance methods for handling
the events for which it listens. For example, if an object is to
serve as a listener for events of type MouseEvent,
then it must contain the following method (among several others):
public void mousePressed(MouseEvent evt) { . . . }
The body of the method defines how the object responds when
it is notified that a mouse button has been pressed. The parameter,
evt, contains information about the event. This information can
be used by the listener object to determine its response.
The methods that are required in a mouse event listener are specified in
an interface named MouseListener. To be used as a listener
for mouse events, an object must implement this MouseListener
interface. Java
interfaces were covered in Section 5.6.
(To review briefly: An interface in Java is just a list of instance methods.
A class can "implement" an interface by doing two things. First, the class must
be declared to implement the interface, as in "class MyListener
implements MouseListener" or "class RandomStrings extends
JApplet implements MouseListener". Second, the class must
include a definition for each instance method specified in the interface.
An interface can be used as the type for a variable or formal
parameter. We say that an object implements the MouseListener
interface if it belongs to a class that implements the MouseListener
interface. Note that it is not enough for the object to include the
specified methods. It must also belong to a class that is specifically declared
to implement the interface.)
Every event in Java is associated with a GUI component. For example, when the
user presses a button on the mouse, the associated component is the one that the user
clicked on. Before a
listener object can "hear" events associated with a given component,
the listener object must be registered with the component. If a
MouseListener object, mListener, needs to hear mouse events
associated with a component object, comp, the listener must be
registered with the component by calling
"comp.addMouseListener(mListener);".
The addMouseListener() method is an instance method in the class,
Component, and so can be used with any GUI component object.
In our first few examples, we will listen for events on a JPanel that is
being used as the drawing surface of a JApplet.
The event classes, such as MouseEvent, and the listener
interfaces, such as MouseListener, are defined in the package
java.awt.event. This means that if you want to work with events,
you should include the line "import java.awt.event.*;"
at the beginning of your source code file.
Admittedly, there is a large number of details to tend to
when you want to use events. To summarize, you must
- Put the import specification "import java.awt.event.*;"
at the beginning of your source code;
- Declare that some class implements the appropriate listener interface,
such as MouseListener;
- Provide definitions in that class for the subroutines from the interface;
- Register the listener object with the component that will generate the events
by calling a method such as addMouseListener() in the component.
Any object can act as an event listener, provided that it implements the appropriate interface.
A component can listen for the events that it itself generates.
An applet can listen for events from
components that are contained in the applet. A special class can be created
just for the purpose of defining a listening object. Many people consider it
to be good form to use anonymous nested classes to define listening objects.
(See Section 5.6 for information on anonymous
nested classes.) You will see all of these patterns in examples in this textbook.
MouseEvent and MouseListener
The MouseListener interface specifies five different
instance methods:
public void mousePressed(MouseEvent evt);
public void mouseReleased(MouseEvent evt);
public void mouseClicked(MouseEvent evt);
public void mouseEntered(MouseEvent evt);
public void mouseExited(MouseEvent evt);
The mousePressed method is called as soon as the user presses
down on one of the mouse buttons, and mouseReleased is called
when the user releases a button. These are the two methods that are
most commonly used, but any mouse listener object must define
all five methods. You can leave the body of a method empty if
you don't want to define a response. The mouseClicked method is
called if the user presses a mouse button and then releases it quickly, without moving
the mouse. (When the user does this, all three routines -- mousePressed, mouseReleased,
and mouseClicked -- will be called in that order.)
In most cases, you should define mousePressed
instead of mouseClicked. The mouseEntered and
mouseExited methods are called
when the mouse cursor enters or leaves the component. For example, if you want
the component to change appearance whenever the user moves the mouse
over the component, you could define these two methods.
As an example, let's look at an applet that does something when the
user clicks on it. Here's an improved version of the RandomStrings applet from the
end of the previous section. In this version,
the applet will redraw itself when you click on it:
For this version of the applet, we need to make four changes in the
source code. First, add the line "import java.awt.event.*;"
before the class definition. Second, declare that some class implements
the MouseListener interface. If we want to use the applet itself
as the listener, we would do this by saying:
class RandomStrings extends JApplet implements MouseListener { ...
Third, define the five methods of the MouseListener interface. Only
mousePressed will do anything. We want to repaint the drawing surface of
the applet when the user clicks the mouse. The drawing surface is represented in this
applet by an instance variable named drawingSurface, so the mousePressed()
just needs to call drawingSurface.repaint() to force the drawing surface to be redrawn.
The other mouse listener methods are empty. The following methods are added to the applet
class definition:
public void mousePressed(MouseEvent evt) {
// When user presses the mouse, tell the system to
// call the drawing surface's paintComponent() method.
drawingSurface.repaint();
}
// The following empty routines are required by the
// MouseListener interface:
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseReleased(MouseEvent evt) { }
Fourth and finally, the applet must be registered to listen for mouse events. Since the
drawing surface fills the entire applet, it is actually the drawing surface on which
the user clicks. We want the applet to listen for mouse events on the drawing surface.
This can be arranged by adding this line to the applet's init() method:
drawingSurface.addMouseListener(this);
This calls the addMouseListener() method in the drawing surface object.
It tells that object where to send the mouse events that it generates.
The parameter to this method is the object that will be listening for the events.
In this case, the listening object is the applet itself. The special variable
"this" is used here to refer to the applet. (See Section 5.5.
When used in the definition of an instance method, "this" refers to the object that
contains the method.)
We could make all these changes in the source code of the original RandomStrings
applet. However, since we are supposed to be doing object-oriented programming,
it might be instructive to write a subclass that contains the changes. This will
let us build on previous work and concentrate just on the modifications.
Here's the actual source code for the above applet. It uses "super",
another special variable from Section 5.5.
import java.awt.event.*;
public class ClickableRandomStrings extends RandomStrings
implements MouseListener {
public void init() {
// When the applet is created, do the initialization
// of the superclass, RandomStrings. Then set this
// applet to listen for mouse events on the
// "drawingSurface". (The drawingSurface variable
// is defined in the RandomStrings class and
// represents a component that fills the entire applet.)
super.init();
drawingSurface.addMouseListener(this);
}
public void mousePressed(MouseEvent evt) {
// When user presses the mouse, tell the system to
// call the drawingSurface's paintComponent() method.
drawingSurface.repaint();
}
// The next four empty routines are required by the
// MouseListener interface.
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseReleased(MouseEvent evt) { }
} // end class ClickableRandomStrings
Often, when a mouse event occurs, you want to know the location of
the mouse cursor. This information is available from the parameter to
the event-handling method, evt.
This parameter is an object of type MouseEvent, and it
contains instance methods that return information about the event.
To find out the coordinates of
the mouse cursor, call evt.getX() and evt.getY(). These
methods return integers which give the x and y coordinates
where the mouse cursor was positioned. The coordinates are expressed
in the coordinate system of the component that generated the event,
where the top left corner of the component is (0,0).
The user can hold down certain modifier keys
while using the mouse. The possible modifier keys include: the Shift key,
the Control key, the ALT key (called the Option key on the Macintosh),
and the Meta key (called the Command or Apple key on the Macintosh and with no
equivalent in Windows). You might want to respond to a mouse event
differently when the user is holding down a modifier key. The boolean-valued
instance methods evt.isShiftDown(), evt.isControlDown(),
evt.isAltDown(), and evt.isMetaDown() can be called
to test whether the modifier keys are pressed.
You might also want to have different responses depending on whether
the user presses the left mouse button, the middle mouse button, or
the right mouse button. Now, not every mouse has
a middle button and a right button, so Java handles the information
in a peculiar way. It treats pressing the right button as equivalent
to holding down the Meta key while pressing the left mouse button. That is, if the right button is pressed,
then the instance method evt.isMetaDown() will return
true (even if the Meta key is not pressed). Similarly,
pressing the middle mouse button is equivalent to holding down the
ALT key. In practice, what this really means is that pressing
the right mouse button under Windows is equivalent to holding
down the Command key while pressing the mouse button on Macintosh.
A program tests for either of these by calling evt.isMetaDown().
As an example, consider the following applet. Click on the applet with the
left mouse button to place a red rectangle on the applet. Click with
the right mouse button (or hold down the Command key and click on a Macintosh)
to place a blue oval on the applet. Hold down the Shift key and click to
clear the applet.
This applet is a JApplet which uses a nested class named
Display to define its drawing surface. There are many
ways to write this applet, but I decided in this case to let
the drawing surface object listen for mouse events on itself.
The main applet class does nothing but set up the drawing surface.
In order to respond to mouse clicks, the Display class implements the MouseListener
interface, and the constructor for the display class includes the
command "addMouseListener(this)". Since this command is
in a method in the Display class, the addMouseListener()
method in the display object is being called, and "this" also refers to
the display object. That is, the display object will send any mouse events
that it generates to itself.
The source code for this applet is shown below. You can see how the
instance methods in the MouseEvent object are used.
You can also check for the Four Steps of Event
Handling ("import java.awt.event.*", "implements
MouseListener", "addMouseListener", and the
event-handling methods).
The Display class in this example violates the rule that
all drawing should be done in a paintComponent() method.
The rectangles and ovals are drawn directly in the mousePressed()
routine. To make this possible, I need to
obtain a graphics context by saying "g = getGraphics()".
(After using g for drawing, I call g.dispose() to inform
the operating system that I will no longer be using g for drawing. It is
a good idea to do this to free the system resources that are used by the
graphics context.) I do not advise doing this type of direct drawing if
it can be avoided, but you can see that it does work in this case.
By the way, this applet still has the problem that
it does not save information about what has been drawn on the applet.
So if the applet is covered up and uncovered, the contents of the
applet are erased.
Here is the source code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleStamper extends JApplet {
public void init() {
// This method is called by the system to initialize
// the applet. An object belonging to the nested class
// Display is created and installed as the content
// pane of the applet. This Display object does
// all the real work.
Display display = new Display();
setContentPane(display);
}
class Display extends JPanel implements MouseListener {
// A nested class to represent the drawing surface that
// fills the applet.
Display() {
// This constructor simply sets the background color
// of the panel to be black and sets the panel to
// listen for mouse events on itself.
setBackground(Color.black);
addMouseListener(this);
}
public void mousePressed(MouseEvent evt) {
// Since this panel has been set to listen for mouse
// events on itself, this method will be called when the
// user clicks the mouse on the panel. (Since the panel
// fills the whole applet, that means clicking anywhere
// on the applet.)
if ( evt.isShiftDown() ) {
// The user was holding down the Shift key. Just
// repaint the panel. Since this class does not
// define a paintComponent() method, the method
// from the superclass, JPanel, is called. That
// method simply fills the panel with its background
// color, which is black. This has the effect of
// erasing the contents of the applet.
repaint();
return;
}
int x = evt.getX(); // x-coordinate where user clicked.
int y = evt.getY(); // y-coordinate where user clicked.
Graphics g = getGraphics(); // Graphics context for drawing
// directly on this JPanel.
if ( evt.isMetaDown() ) {
// User right-clicked at the point (x,y).
// Draw a blue oval centered at the point (x,y).
// (A black outline around the oval will make it
// more distinct when ovals and rects overlap.)
g.setColor(Color.blue);
g.fillOval( x - 30, y - 15, 60, 30 );
g.setColor(Color.black);
g.drawOval( x - 30, y - 15, 60, 30 );
}
else {
// User left-clicked (or middle-clicked) at (x,y).
// Draw a red rectangle centered at (x,y).
g.setColor(Color.red);
g.fillRect( x - 30, y - 15, 60, 30 );
g.setColor(Color.black);
g.drawRect( x - 30, y - 15, 60, 30 );
}
g.dispose(); // We are finished with the graphics context,
// so dispose of it.
} // end mousePressed();
// The next four empty routines are required by the
// MouseListener interface.
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseReleased(MouseEvent evt) { }
} // end nested class Display
} // end class SimpleStamper
MouseMotionListeners and Dragging
Whenever the mouse is moved, it generates events. The operating system of
the computer detects these events and uses them to move the mouse cursor on
the screen. It is also possible for a program to listen for
these "mouse motion" events and respond to them. The most common
reason to do so is to implement dragging.
Dragging occurs when the user moves the mouse while holding
down a mouse button.
The methods for responding to mouse motion events are defined in
an interface named MouseMotionListener. This interface specifies
two event-handling methods:
public void mouseDragged(MouseEvent evt);
public void mouseMoved(MouseEvent evt);
The mouseDragged method is called if the mouse is moved while
a button on the mouse is pressed. If the mouse is moved while no mouse button
is down, then mouseMoved is called instead. The parameter, evt,
is an object of type MouseEvent.
It contains the x and y coordinates of the mouse's location.
As long as the user continues to move the mouse, one of these methods will be
called over and over. (So many events are generated that it would be
inefficient for a program to hear them all, if it doesn't want to do
anything in response. This is why the mouse motion event-handlers are
defined in a separate interface from the other mouse events: You can
listen for the mouse events defined in MouseListener without automatically hearing
all mouse motion events as well.)
If you want your program to respond to mouse motion events, you must
create an object that implements the MouseMotionListener interface,
and you must register that object to listen for events. The registration
is done by calling a component's addMouseMotionListener method.
The object will then listen for mouseDragged and mouseMoved
events associated with that component. In most cases, the listener object
will also implement the MouseListener interface so that it can respond
to the other mouse events as well. For example, if we want an applet to
listen for all mouse events associated with a drawingSurface object, then the definition
of the applet class might have the form:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Mouser extends JApplet
implements MouseListener, MouseMotionListener {
public void init() { // set up the applet
drasingSurface.addMouseListener(this);
drawingSurface.addMouseMotionListener(this);
. . . // other initializations
}
.
. // Define the seven MouseListener and
. // MouseMotionListener methods. Also, there
. // can be other variables and methods.
Here is a small sample applet that displays information about mouse
events. It is programmed to respond to any of the seven different kinds of
mouse events by displaying the coordinates of the mouse, the type of event,
and a list of the modifier keys that are down (Shift, Control, Meta, and Alt).
Experiment to see what happens when you use the mouse on the applet. The source
code for this applet can be found in SimpleTrackMouse.java.
I encourage you to read the source code. You should now be familiar with
all the techniques that it uses.
It is interesting to look at what a program needs to do in order to respond to dragging
operations. In general, the response involves three methods: mousePressed(),
mouseDragged(), and mouseReleased(). The dragging gesture starts when
the user presses a mouse button, it continues while the mouse is dragged,
and it ends when the user releases the button. This means that the programming for the response
to one dragging gesture must be spread out over the three methods! Furthermore, the
mouseDragged() method can be called many times as the mouse moves.
To keep track of what is going on between one method call and the next,
you need to set up some instance variables.
In many applications, for example, in order to process a mouseDragged
event, you need to remember the previous coordinates of the mouse. You can store
this information in two instance variables prevX and prevY of
type int. I also suggest having a boolean variable, dragging,
which is set to true while a dragging gesture is being processed. This
is necessary because not every mousePressed event is the beginning of a
dragging gesture. The mouseDragged and mouseReleased methods can use
the value of dragging to check whether a drag operation
is actually in progress. You might need other instance variables
as well, but in general outline, the code for handling dragging looks like this:
private int prevX, prevY; // Most recently processed mouse coords.
private boolean dragging; // Set to true when dragging is in process.
. . . // other instance variables for use in dragging
public void mousePressed(MouseEvent evt) {
if ( we-want-to-start-dragging ) {
dragging = true;
prevX = evt.getX(); // Remember starting position.
prevY = evt.getY();
}
.
. // Other processing.
.
}
public void mouseDragged(MouseEvent evt) {
if ( dragging == false ) // First, check if we are
return; // processing a dragging gesture.
int x = evt.getX(); // Current position of Mouse.
int y = evt.getY();
.
. // Process a mouse movement from (prevX, prevY) to (x,y).
.
prevX = x; // Remember the current position for the next call.
prevY = y;
}
public void mouseReleased(MouseEvent evt) {
if ( dragging == false ) // First, check if we are
return; // processing a dragging gesture.
dragging = false; // We are done dragging.
.
. // Other processing and clean-up.
.
}
As an example, let's look at a typical use of dragging: allowing the user
to sketch a curve by dragging the mouse. This example also shows many other
features of graphics and mouse processing. In the following applet, you
can draw a curve by dragging the mouse on the large white area. Select
a color for drawing by clicking on one of the colored rectangles on the
right. Note that the selected color is framed with a white border. Clear
your drawing by clicking in the square labeled "CLEAR".
(This applet still has the old problem that the drawing will disappear if
you cover the applet and uncover it.)
You'll find the complete source code for this applet in the file
SimplePaint.java.
I will discuss a few
aspects of it here, but I encourage you to read it carefully in its entirety.
There are lots of informative comments in the source code. (This is actually
an old-style non-Swing Applet which uses a paint() method to draw
on the applet instead of a paintComponet() method to draw on a
drawing surface.)
The applet class for this example is designed to work for any reasonable
applet size, that is, unless the applet is too small. This means that
coordinates are computed in terms of the actual width and height of the
applet. (The width and height are obtained by calling getSize().width
and getSize().height.) This makes things quite a bit harder than
they would be if we assumed some particular fixed size for the applet.
Let's look at some of these computations
in detail. For example, the command used to fill in the
large white drawing area is
g.fillRect(3, 3, width - 59, height - 6);
There is a 3-pixel border along each edge, so the height of the drawing area is 6 less than
the height of the applet. As for the width: The colored rectangles are
50 pixels wide. There is a 3-pixel border on each edge of the applet.
And there is a 3-pixel divider between the drawing area and the colored rectangles.
All that adds up to make 59 pixels that are not included in the width of the
drawing area, so the width of the drawing area is 59 less than the width of the applet.
The white square labeled "CLEAR" occupies a 50-by-50 pixel
region beneath the colored rectangles. Allowing for this square,
we can figure out how much vertical space is available for the seven colored
rectangles, and then divide that space by 7 to get the vertical space available
for each rectangle. This quantity is represented by a variable,
colorSpace. Out of this space, 3 pixels are used as spacing
between the rectangles, so the height of each rectangle is colorSpace - 3.
The top of the N-th rectangle is located (N*colorSpace + 3) pixels
down from the top of the applet, assuming that we start counting at zero. This is because
there are N rectangles above the N-th rectangle, each of
which uses colorSpace pixels. The extra 3 is for the border at the
top of the applet. After all that, we can write down
the command for drawing the N-th rectangle:
g.fillRect(width - 53, N*colorSpace + 3, 50, colorSpace - 3);
That was not easy! But it shows the kind of careful thinking and precision
graphics that are sometimes necessary to get good results.
The mouse in this applet is used to do three different things: Select a
color, clear the drawing, and draw a curve. Only the third of these involves
dragging, so not every mouse click will start a dragging operation. The
mousePressed routine has to look at the (x,y) coordinates
where the mouse was clicked and decide how to respond. If the user
clicked on the CLEAR rectangle, the drawing area is cleared by
calling repaint(). If the user clicked somewhere in the strip of
colored rectangles, the selected color is changed. This involves computing
which color the user clicked on, which is done by dividing the y
coordinate by colorSpace. Finally, if the user clicked on the
drawing area, a drag operation is initiated. A boolean variable, dragging,
is set to true so that the mouseDragged and mouseReleased
methods will know that a curve is being drawn. The code for this follows the
general form given above. The actual drawing of the curve is done in the mouseDragged
method, which draws a line from the previous location of the mouse to
its current location. Some effort is required to make sure that the line does
not extend beyond the white drawing area of the applet. This is not automatic,
since as far as the computer is concerned, the border and the color bar are part
of the drawing surface. If the user drags the mouse outside the drawing area
while drawing a line, the mouseDragged routine changes the x
and y coordinates to make them lie within the drawing area.
Anonymous Event Handlers and Adapter Classes
As I mentioned above, it is a fairly common practice to use anonymous nested
classes to define listener objects. As discussed in Section 5.6,
a special form of the new operator is used to create an object that belongs to
an anonymous class. For example, a mouse listener object can be created with an expression
of the form:
new MouseListener() {
public void mousePressed(MouseEvent evt) { . . . }
public void mouseReleased(MouseEvent evt) { . . . }
public void mouseClicked(MouseEvent evt) { . . . }
public void mouseEntered(MouseEvent evt) { . . . }
public void mouseExited(MouseEvent evt) { . . . }
}
This is all just one long expression that both defines an un-named class and
creates an object that belongs to that class. To use the object as a mouse listener,
it should be passed as the parameter to some component's addMouseListener()
method in a command of the form:
component.addMouseListener( new MouseListener() {
public void mousePressed(MouseEvent evt) { . . . }
public void mouseReleased(MouseEvent evt) { . . . }
public void mouseClicked(MouseEvent evt) { . . . }
public void mouseEntered(MouseEvent evt) { . . . }
public void mouseExited(MouseEvent evt) { . . . }
} );
Now, in a typical application, most of the method definitions in this class will
be empty. A class that implements an interface must provide definitions
for all the methods in that interface, even if the definitions are empty.
To avoid the tedium of writing empty method definitions in cases like
this, Java provides adapter classes. An adapter class
implements a listener interface by providing empty definitions for all the
methods in the interface. An adapter class is only useful as a basis for making subclasses.
In the subclass, you can define just those methods that you actually want to use.
For the remaining methods, the empty definitions that are provided by the adapter
class will be used. The adapter class for the MouseListener interface
is named MouseAdapter.
For example, if you want a mouse listener that only responds to mouse-pressed events,
you can use a command of the form:
component.addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent evt) { . . . }
} );
To see how this works in a real example, let's write another version of the
ClickableRandomStrings applet that uses an anonymous class based on
MouseAdapter to handle mouse events:
import java.awt.event.*;
public class ClickableRandomStrings2 extends RandomStrings {
public void init() {
// When the applet is created, do the initialization
// of the superclass, RandomStrings. Then add a
// mouse listener to listen for mouse events on the
// "drawingSurface". (drawingSurface is defined
// in the superclass, RandomStrings.)
super.init();
drawingSurface.addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
// When user presses the mouse, tell the system to
// call the drawingSurface's paintComponent() method.
drawingSurface.repaint();
}
} );
} // end init()
} // end class ClickableRandomStrings2