Handling Mouse Events
Everything so far has drawn a fixed picture. Mouse events let an applet react to what the user actually does with the pointer - clicks, presses, releases, and movement - which is what turns a static drawing into something interactive.
MouseListener and MouseMotionListener
AWT splits mouse input into two listener interfaces:
| Interface | Methods |
|---|---|
MouseListener | mouseClicked, mousePressed, mouseReleased, mouseEntered, mouseExited |
MouseMotionListener | mouseDragged, mouseMoved |
Register a listener with addMouseListener() or addMouseMotionListener(), typically in init().
Adapter Classes: Skip the Methods You Don't Need
Implementing MouseListener directly means writing all five methods, even empty ones you
don't care about. MouseAdapter and MouseMotionAdapter are abstract classes that
already implement every method with an empty body, so you can extend one (usually as an anonymous inner
class) and override only what you actually need:
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
// handle it
}
});
MouseEvent: Where Did It Happen
Every listener method receives a MouseEvent, which carries the pointer's position at the
time of the event via e.getX() / e.getY(), or bundled as a single
java.awt.Point via e.getPoint().
Extending PaintApplet: A Freehand Drawing Pad
To let the user draw with the mouse, track every point the pointer passes over while a button is held
down (that's exactly what mouseDragged reports), store each point in a list, and draw a
small filled circle at every stored point during paint():
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
public class PaintApplet extends Applet {
private Color currentColor = Color.BLUE;
private Font titleFont = new Font("Arial", Font.BOLD, 18);
private List<Point> drawnPoints = new ArrayList<>();
public void init() {
setBackground(Color.WHITE);
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
drawnPoints.add(e.getPoint());
repaint();
}
});
}
public void paint(Graphics g) {
g.setFont(titleFont);
g.setColor(Color.BLACK);
g.drawString("Welcome to PaintApplet!", 20, 30);
g.drawRect(10, 10, getWidth() - 20, getHeight() - 20);
g.setColor(currentColor);
drawShapes(g);
g.setColor(currentColor);
for (Point p : drawnPoints) {
g.fillOval(p.x, p.y, 4, 4);
}
}
private void drawShapes(Graphics g) {
g.drawLine(20, 50, 120, 50);
g.drawRect(20, 60, 60, 40);
g.fillOval(100, 60, 40, 40);
int[] xPoints = {200, 230, 260};
int[] yPoints = {100, 60, 100};
g.drawPolygon(xPoints, yPoints, 3);
}
public void cycleColor() {
if (currentColor == Color.BLUE) currentColor = Color.RED;
else if (currentColor == Color.RED) currentColor = Color.GREEN;
else currentColor = Color.BLUE;
repaint();
}
}
Why an Adapter Here, and Why a List
The code above extends MouseMotionAdapter instead of implementing
MouseMotionListener directly because it only cares about mouseDragged. Implementing
the interface would also force writing an empty mouseMoved(MouseEvent e) {} just to satisfy
the compiler - the adapter already supplies that no-op for free.
Notice that dragged points are stored in drawnPoints and re-drawn in full on every
call to paint(), rather than drawing each point once, the moment it arrives, directly from
inside mouseDragged. That's deliberate: paint() can be invoked again at any time
for reasons outside your control - resizing the window, another window overlapping and uncovering the
applet, switching tabs and back. Each of those calls repaints the entire surface from scratch.
If earlier strokes weren't stored anywhere, they'd simply vanish the next time anything triggered a
repaint. Keeping every point in a list and replaying all of them each time is what makes the drawing
durable.