I'm working on these online Stanford lessons on Java, and we just made the leap to events, and I'm having difficulty wrapping my head around it. I'm playing around with a program that is in the "Art and Science of Java" book. This program will move a rectangle and oval around on the canvas if you click on them.
I modified the run method to try and get the listener to only work on the rectangle, but I was surprised to see even with my changes, both objects are being listened to...why?
Original run method:
public void run() {
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
开发者_开发知识库GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
addMouseListeners();
}
My changed program (with the MouseListener in the private createRectangle method):
import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;
/** This class displays a mouse-draggable rectangle and oval */
public class DragObjects extends GraphicsProgram {
public void run() {
createRectangle();
createOval();
}
private void createOval(){
GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
}
private void createRectangle(){
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
addMouseListeners();
}
/** Called on mouse press to record the coordinates of the click */
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
/** Called on mouse drag to reposition the object */
public void mouseDragged(MouseEvent e) {
if (gobj != null) {
gobj.move(e.getX() - lastX, e.getY() - lastY);
lastX = e.getX();
lastY = e.getY();
}
}
/** Called on mouse click to move this object to the front */
public void mouseClicked(MouseEvent e) {
if (gobj != null) gobj.sendToFront();
}
/* Instance variables */
private GObject gobj; /* The object being dragged */
private double lastX; /* The last mouse X position */
private double lastY; /* The last mouse Y position */
}
It would be helpful if you would point out that the method addMouseListeners()
is in the superclass, GraphicsProgram
. What it does is adds the listener to the canvas, not just to the individual shape. From there, you'll need to somehow determine whether the mouseclick occurred in the rectangle or in the oval.
Or there might be a way to add the listener just to a single shape. Check the Javadoc for the GRect
and GOval
classes. I'm assuming those are also in one of the acm.* packages, which means they're not built in to the Java language. (This is why I recommend using an IDE like Eclipse that can automatically import each class automatically, instead of importing an entire package.)
It might also be helpful to post a link to the online lessons you're following.
I haven't looked at the source other than what you have posted. But you will need to other modify gOval and gRect or a superclass to accept a mouseListener, or in your listener do something like the following.
in the MouseClicked, MouseMoved, etc. methods. Get the point of the event, and then go through your Objects and query them to see if the point exists withing their bounds.
You would need a list of objects to loop through and then call something like gRect.containsPoint(myPoint) in this method check to see if the point exists in the shape. You will still have issues where shapes overlap, so you will need some concept of a z-axis or depth to determine which shape is on top.
You need to post the source for the addMouseListeners.
If you take a look at this post over here you might get some ideas on how listeners can work (if you post the addMouseListener source we can help with your specific question of course!)
精彩评论