Interactive graphics programs track the position of the mouse cursor in a panel and respond to events such as mouse button presses, cursor movement, and dragging (a combination of the two). For example, to draw an oval, the user might press the mouse button at the ovalÕs upper left corner, drag the cursor down to ovalÕs lower right corner, and release the mouse button.
When a mouse event occurs in a panel, the
corresponding handler method is triggered.
Default handler methods that do nothing are also defined in the GBPanel class but
if the programmer overrides the relevant method in her subclass, the
application can then respond to the event appropriately. Here is a summary of the mouse event
handler methods in BreezySwing.
Type of Event |
GBPanel Method |
What it
does |
Mouse
press |
mousePressed(x,
y) |
Triggered
when the left mouse button is pressed.
x and y hold the
mouse cursorÕs coordinates. |
Mouse
release |
mouseReleased(x,
y) |
Triggered
when the left mouse button is released.
x and y hold the
mouse cursorÕs coordinates. |
Mouse
move |
mouseMoved(x,
y) |
Triggered
when the mouse is moved. x and y hold the
mouse cursorÕs coordinates. |
Mouse
drag |
mouseDragged(x,
y) |
Triggered
when the mouse is moved with left mouse button pressed. x and y hold the
mouse cursorÕs coordinates. |
Mouse
click |
mouseClicked(x,
y) |
Triggered
when the left mouse button is clicked.
x and y hold the
mouse cursorÕs coordinates. |
To illustrate the use of these methods in interactive graphics, we now present two programs that allow the user to draw geometric shapes in a panel.
The
first program allows the user to draw filled oval shapes as described above
(press the mouse, drag it down and to the right, and release it). The main
window has a drawing area and a button that clears the drawings. The next
screen shots show the program in action:
|
For this program and for the next one,
you use code for a slightly different main window class, defined in DrawingDemo.java, than you did for
previous graphics examples. Here is
the code for the main window:
import javax.swing.*;
import BreezySwing.*;
import java.awt.Color;
public class DrawingDemo
extends GBFrame{
DrawingPanel1 panel = new DrawingPanel1(Color.pink);
public
DrawingDemo(){
addPanel(panel, 1,1,1,1);
addButton("Clear",
2,1,1,1);
}
public
void buttonClicked(JButton buttonObj){
panel.clear();
}
public
static void main (String[] args){
JFrame frm = new DrawingDemo();
frm.setSize (300, 300);
frm.setVisible (true);
}
}
Note that the panel object is now created before the constructor is defined, and that the actual class of the panel is explicitly named. This panel is then added to the window in the constructor. You do this so that the panel can be cleared in the buttonClicked method.
The panel class is defined in the file DrawingPanel1.java. As in an earlier example, the panel must maintain a list of things that are drawn. Since these things are ovals, you use the class java.awt.geom.Ellipse2D.Double (whew!) to represent them, and the interface java.awt.Shape as the element type of the list.
The
methods mousePressed and mouseReleased collaborate to handle the user's mouse activity in
the panel. The two methods share the instance variables mouseX and mouseY. These variables track the position of a mouse press. When the user
presses the mouse, the mousePressed method sets these variables to the current mouse
coordinates. This will be the upper left corner of the oval. The user then
drags the mouse to the oval's lower right corner and releases it. At that
point, the mouseReleased method verifies that the new mouse position is
below and to the right of the old one, computes the width and height of the
oval from the two pairs of coordinates, creates the oval, adds it to the list
of shapes, and repaints the panel.
Here
is the code for the new panel class:
import BreezySwing.*;
import java.awt.*;
import java.awt.geom.*;
public class DrawingPanel1 extends GBPanel{
private
java.util.List<Shape> shapes = new java.util.ArrayList<Shape>();
private
int mouseX = 0, mouseY = 0; //
Track the position of a mouse press
public
DrawingPanel1(Color color){
setBackground(color);
}
public
void paintComponent (Graphics g){
//
Clear the panel and redraw all the points
super.paintComponent(g);
g.setColor(Color.blue);
for (Shape s : shapes)
((Graphics2D)g).fill(s);
}
public
void mousePressed(int x, int y){
//
Remember the coordinates of the press event
mouseX = x;
mouseY = y;
}
public
void mouseReleased(int x, int y){
//
Add the oval to the list of shapes and refresh the panel
if (x <= mouseX || y <= mouseY)
return;
int width = x - mouseX;
int height = y - mouseY;
shapes.add(new Ellipse2D.Double(mouseX, mouseY, width, height));
repaint();
}
public
void clear(){
//
Clear the list of shapes and refresh the panel
shapes = new java.util.ArrayList<Shape>();
repaint();
}
}
Note that the panel class includes a clear method, which creates a new list and repaints the panel. Also note that the paintComponent method draws a filled oval by calling the Graphics2D method fill with a shape as an argument. This method works with class that implements the Shape interface, so you will not have to change the code for paintComponent when you want to use other types of shapes (as in the next example).
The
second program allows the user to do freehand drawing in a panel. Here is an
example drawing, which shows the authors' artistic talent:
|
This program is structured very like the first one, but it draws tiny line segments in response to mouse drag events. A drag event occurs when the user presses and moves the mouse without releasing it. Therefore, when the user presses the mouse, the mousePressed method saves the mouse coordinates, as before. But when the user drags the mouse, the current mouse coordinates will be different from the saved ones, so the mouseDragged method creates a line segment from the two pairs of coordinates. It then adds the new line segment to the list of shapes and repaints the panel. Last but not least, to prepare for the next drag event, this method resets the saved coordinates to the new coordinates. The mouseReleased method is no longer needed.
Here
is the code for the freehand drawing program, in the file DrawingPanel2.java:
import BreezySwing.*;
import java.awt.*;
import java.awt.geom.*;
public class DrawingPanel2 extends GBPanel{
private
java.util.List<Shape> shapes = new java.util.ArrayList<Shape>();
private
int mouseX = 0, mouseY = 0; //
Track the position of a mouse press
public
DrawingPanel2(Color color){
setBackground(color);
}
public
void paintComponent (Graphics g){
//
Clear the panel and redraw all the line segments
super.paintComponent(g);
g.setColor(Color.blue);
for (Shape s : shapes)
((Graphics2D)g).fill(s);
}
public
void mousePressed(int x, int y){
//
Remember the coordinates of the press event
mouseX = x;
mouseY = y;
}
public
void mouseDragged(int x, int y){
//
Add a line segment to the list, remember the new mouse position, and refresh
the panel
shapes.add(new Line2D.Double(mouseX, mouseY, x, y));
mouseX = x;
mouseY = y;
repaint();
}
public
void clear(){
//
Clear the list of shapes and refresh the panel
shapes = new java.util.ArrayList<Shape>();
repaint();
}
}
As you can see, the paintComponent and clear methods are exactly the same in both example programs. By now, you should be able to read the code and recognize the common design patterns employed. Think about how your would add menus to the main window to change the color and thickness of the drawing "pen," among other things.
Back to tutorial | Next topic: Organizing widgets with panels |