Drag/Moving a shape around jPanel - java

Yesterday I ask a question about how to draw a bounding box to hold a shape inside and how to drag and drop that selected shape.
The first question is solved. But I'm having some trouble to move the shape. Is there any especific transformations to move a shape around the jPanel?
I have this code:
public boolean drag(MouseEvent e) {
if(points.isEmpty()) //if point's vector is empty
return false;
if(!selected)
return false;
int x = e.getX(), y = e.getX();
if (!dragging)
lastMovePoint.setLocation(x, y);
dragging = true;
int deslocX = 0;
int deslocY = 0;
int oldX = -1;
int oldY = -1;
int size = points.size();
for(int i = 0; i < size; i++) {
oldX = lastMovePoint.x;
oldY = lastMovePoint.y;
deslocX = x - oldX;
deslocY = y - oldY;
points.set(i, new Point(points.get(i).x + deslocX, points.get(i).y + deslocY));
//set the vector of points so that when there is a repaint() it repaints the shape with the new
//coordinates
}
lastMovePoint.setLocation(x, y); //set the location of the old point
return true;
}
This method is called by the listener mouseDragged and return true in case of sucess. What I'm trying to do is to add the difference between the previous point of dragg and the actual.
When I run this code I have a problem:
The shape only goes to right/left, up and down is not working...
.

Yes, in order to drag components you also need to know the starting location so you can calculate the distance the mouse has moved.
Here is some code that shows this general behaviour for moving a window.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class MoveWindow extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
private static void createAndShowGUI()
{
JWindow window = new JWindow();
window.setSize(300, 300);
window.setLocationRelativeTo( null );
window.setVisible(true);
MouseInputAdapter listener = new MoveWindow();
window.addMouseListener( listener );
window.addMouseMotionListener( listener );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
I'll let you implement it for your purposes.

int x = e.getX(), y = e.getX();
This should probably be changed to
int x = e.getX(), y = e.getY();
That's why it only works in the x direction, you aren't actually taking into account the Y direction

Related

How do I paint multiple objetcs that move at different speeds in Java?

I am working on homework for class, and its late because I can't seem to understand the material despite all the research that I am doing. I am a beginner and do not know much in the way of java. Also, this is my first post so please be forgiving when you are reading this.
I am building on source code from my textbook, which I updated recently for past homework, but now I am trying to generate a class that draws multiple squares and moves those objects independently and at different speeds. They will all need to rebound off the walls as well. I followed the instructions and created two arrays that will hold the random x and y values between 1 and 10. However, I struggle with arrays and I am sure that I am not doing it correctly. So, I would love some feedback to see if I have it set up correctly.
I have a the jpanel pulling up and drawing, and as long as there is 1 square it is working fine bouncing off the walls, but things change when I draw more than one. The do not move independently and they also share the same speed. Some even disappear from time to time. This has really thrown me off. I appreciate any help!
In short, I am trying to paint new squares that all travel in different directions and at different speeds. Per the instructions we are suppose create and use a two arrays that handle the x and y values.
Here is what I have so far:
public class DotsPanel extends JPanel
{
private int delay = 15;
private final int SIZE = 7, IMAGE_SIZE = 3; // radius of each dot
private Timer timer;
private int x, y, i;
private ArrayList<Point> pointList;
static int [] xarray = new int [1000];
static int [] yarray = new int [1000];
Random rand = new Random();
//-----------------------------------------------------------------
// Constructor: Sets up this panel to listen for mouse events.
//-----------------------------------------------------------------
public DotsPanel()
{
pointList = new ArrayList<Point>();
int [] xarray = new int [1000];
int [] yarray = new int [1000];
timer = new Timer(delay, new ReboundListener());
addMouseListener (new DotsListener());
addMouseMotionListener (new DotsListener());
setBackground(Color.gray);
setPreferredSize(new Dimension(700, 500));
for(int i = 0; i < xarray.length; i++)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
timer.start();
}
//-----------------------------------------------------------------
// Draws all of the dots stored in the list.
//-----------------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.setColor(Color.BLUE);
for (Point spot : pointList)
{
page.fillRect(spot.x-SIZE, spot.y-SIZE, 25, 25);
page.drawString("Count: " + pointList.size(), 5, 15);
}
}
//*****************************************************************
// Represents the listener for mouse events.
//*****************************************************************
private class DotsListener implements MouseListener, MouseMotionListener
{
//--------------------------------------------------------------
// Adds the current point to the list of points and redraws
// the panel whenever the mouse button is pressed.
//--------------------------------------------------------------
public void mousePressed(MouseEvent event)
{
pointList.add(event.getPoint());
repaint();
}
public void mouseDragged(MouseEvent event)
{
// initially I had two xarray and yarray in here just like in
// mouseClicked
// but it did not change anything when removed
}
//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseClicked(MouseEvent event)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseMoved(MouseEvent e) {}
}
private class ReboundListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed(ActionEvent event)
{
for (Point spot : pointList)
{
spot.x += xarray[i];
spot.y += yarray[i];
if (spot.x <= 0 || spot.x >= 700)
xarray[i] = xarray[i] * -1;
if (spot.y <= 0 || spot.y >= 500)
yarray[i] = yarray[i] * -1;
repaint();
}
}
}
}
However, I struggle with arrays and I am sure that I am not doing it correctly.
I wouldn't use Arrays.
Instead, have a Ball object manage its own state. Then you can have different color, speed, size etc for each Ball. Then when the Timer fires you just calculate the new position and repaint the Ball.
Here is an example to get you started:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class BallAnimation4
{
private static void createAndShowUI()
{
BallPanel panel = new BallPanel();
JFrame frame = new JFrame("BallAnimation4");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setSize(800, 600);
frame.setLocationRelativeTo( null );
//frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible( true );
panel.addBalls(5);
panel.startAnimation();
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
class BallPanel extends JPanel implements ActionListener
{
private ArrayList<Ball> balls = new ArrayList<Ball>();
public BallPanel()
{
setLayout( null );
setBackground( Color.BLACK );
}
public void addBalls(int ballCount)
{
Random random = new Random();
for (int i = 0; i < ballCount; i++)
{
Ball ball = new Ball();
ball.setRandomColor(true);
ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
ball.setMoveRate(32, 32, 1, 1, true);
// ball.setMoveRate(16, 16, 1, 1, true);
ball.setSize(32, 32);
balls.add( ball );
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Ball ball: balls)
{
ball.draw(g);
}
}
public void startAnimation()
{
Timer timer = new Timer(75, this);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
move();
repaint();
}
private void move()
{
for (Ball ball : balls)
{
ball.move(this);
}
}
class Ball
{
public Color color = Color.BLACK;
public int x = 0;
public int y = 0;
public int width = 1;
public int height = 1;
private int moveX = 1;
private int moveY = 1;
private int directionX = 1;
private int directionY = 1;
private int xScale = moveX;
private int yScale = moveY;
private boolean randomMove = false;
private boolean randomColor = false;
private Random myRand = null;
public Ball()
{
myRand = new Random();
setRandomColor(randomColor);
}
public void move(JPanel parent)
{
int iRight = parent.getSize().width;
int iBottom = parent.getSize().height;
x += 5 + (xScale * directionX);
y += 5 + (yScale * directionY);
if (x <= 0)
{
x = 0;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (x >= iRight - width)
{
x = iRight - width;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (y <= 0)
{
y = 0;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
if (y >= iBottom - height)
{
y = iBottom - height;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
}
public void draw(Graphics g)
{
g.setColor(color);
g.fillOval(x, y, width, height);
}
public void setColor(Color c)
{
color = c;
}
public void setLocation(int x, int y)
{
this.x = x;
this.y = y;
}
public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
{
this.moveX = xMove;
this.moveY = yMove;
directionX = xDir;
directionY = yDir;
randomMove = randMove;
}
public void setRandomColor(boolean randomColor)
{
this.randomColor = randomColor;
switch (myRand.nextInt(3))
{
case 0: color = Color.BLUE;
break;
case 1: color = Color.GREEN;
break;
case 2: color = Color.RED;
break;
default: color = Color.BLACK;
break;
}
}
public void setSize(int width, int height)
{
this.width = width;
this.height = height;
}
}
}
Since your Arrays only contain the Point you want to paint you don't have any information about the speed each point should be moved at. The best you could do is create a random amount each point should be moved each time its location is changed. This would give erratic movement as each time you move a point the distance would be random.
If you want more constant speed then you would need to create a second Array to contain the distance each point should move every time.
This starts to get messy creating a new Array every time you want a new property to be unique for the object you want to paint. That is why the approach to create a custom Object with multiple properties is easier to manage.

JPanel subclass "jumps around" when dragged

I'm currently coding on a small "Paint"-program of mine; so far, you can draw on it with a pen, zoom in up to 100x, and choose a color. Next thing I wanted to add was (or is) the possibility to drag the JPanel subclass, on which the image chosen to edit is drawn, around. Basically, by holding down the right mouse button, you change the location of the JPanel subclass, which is located on a JInternalFrame. I've got a code sample that should be working fine on its own; at least it does for me. To replicate the issue, just launch the DragPanelTest class and drag your mouse while over the component with the red border - the panel isn't dragged smoothly, but instead jumps back and forth all the time.
code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class DragPanelTest extends JPanel implements MouseMotionListener, MouseListener {
Point oldDragPt;
boolean dragEnabled;
int newX;
int newY;
public static void main(String[] args) {
System.out.println("Launching Test.java ...");
JFrame frame = new JFrame("Title");
JInternalFrame intFrame = new JInternalFrame("title", true, true, true, true);
JDesktopPane deskPane = new JDesktopPane();
DragPanelTest dragPanel = new DragPanelTest();
frame.setSize(300, 300);;
frame.setLayout(null);
frame.setVisible(true);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - frame.getWidth()) / 2;
int y = (d.height - frame.getHeight()) / 2;
frame.setLocation(x, y);
deskPane.setBounds(50, 50, 200, 200);
deskPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
frame.add(deskPane);
deskPane.add(intFrame);
intFrame.setSize(150, 150);
intFrame.add(dragPanel);
intFrame.setVisible(true);
}
public DragPanelTest() {
this.setSize(100,100);
this.setBorder(BorderFactory.createLineBorder(Color.RED));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
if (e.isMetaDown()) {
dragEnabled = true;
oldDragPt = new Point((int) this.getMousePosition().getX(), (int) this.getMousePosition().getY());
}
repaint();
}
public void mouseReleased(MouseEvent e) {
dragEnabled = false;
oldDragPt = null;
}
public void mouseDragged(MouseEvent e) {
if (e.isMetaDown() && this.getMousePosition() != null) {
if (oldDragPt != null) {
if (dragEnabled) {
int mouseX = (int) this.getMousePosition().getX();
int mouseY = (int) this.getMousePosition().getY();
int x = this.getX();
int y = this.getY();
int diffX = (mouseX - (int) oldDragPt.getX());
int diffY = (mouseY - (int) oldDragPt.getY());
newX = getX() + diffX;
newY = getY() + diffY;
this.setLocation(newX, newY);
this.repaint();
oldDragPt = new Point(mouseX, mouseY);
}
} else {
oldDragPt = new Point((int) this.getMousePosition().getX(), (int) this.getMousePosition().getY());
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
Note that I left out some System.out.println() or #Override commands to shorten the code a bit.
Anyhow, if anyone knows what I'm doing wrong / what to improve, I'd be very thankful!
the panel isn't dragged smoothly, but instead jumps back and forth all the time.
When you have jumping its because the relative movements between the mouse and the component and the parent panel is off. Your code is too complicated to point out the exact line causing the problem.
The basic code for dragging a component around a panel is:
public class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
For more advanced code with more feature you can also check out the Component Mover class found in Moving Windows.
I had a similar problem with moving the viewport for a scrollpane. I think that the when a component is re-positioned, the value of the saved point is relative to the original location and is incorrect relative to the new location. My solution, which seems illogical to me, made the drag operation flow smoothly. What I did is to add the point delta back into the saved location.
This is the basic code to drag the viewport:
Point priorPanPoint;
public void mouseDragged(MouseEvent e) {
Point newPt = subtractPoints(priorPanPoint, e.getPoint());
priorPanPoint = addPoints(e.getPoint(), newPt);
newPt = addPoints(getVisibleRect().getLocation(), newPt);
viewport.setViewPosition(newPt);
}
public void mousePressed(MouseEvent e) {
priorPanPoint = e.getPoint();
}
private Point addPoints(Point p1, Point p2) {
return new Point(p1.x + p2.x, p1.y + p2.y); }
private Point subtractPoints(Point p1, Point p2) {
return new Point(p1.x - p2.x, p1.y - p2.y);
}

Java MouseMotionListener and restricting drawn shapes movement

Working on an applet that draws 2 eyes and uses MouseMotionListener to move the they eyes. Also when the mouse exits the content pane, the eyes look straight. The one thing
I'm struggling with is I can't figure out how to restrict the pupils movements to stay within the eye. Any suggestions you guys have would be great.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WatchMe extends JApplet
{
private int leftMouseX = 130;
private int leftMouseY = 155;
private int rightMouseX = 305;
private int rightMouseY = 155;
private boolean mouseEntered;
//init method
public void init()
{
//set background to green
getContentPane().setBackground(Color.green);
//add mouse listener
addMouseListener(new MyMouseListener());
//add a motion listener
addMouseMotionListener(new MyMouseMotionListener());
}
public void paint(Graphics g)
{
//call superclass paint method
super.paint(g);
//draw left eye
g.setColor(Color.yellow);
g.fillOval(75, 100, 150, 150);
//draw left pupil
g.setColor(Color.black);
g.fillOval(leftMouseX, leftMouseY, 40, 40);
//draw right eye
g.setColor(Color.yellow);
g.fillOval(250, 100, 150, 150);
//draw right pupil
g.setColor(Color.black);
g.fillOval(rightMouseX, rightMouseY, 40, 40);
//checks to see if the mouse is in the pane, if not
//sets the x,y coordinates to look straight
if (! mouseEntered)
{
leftMouseX = 130;
leftMouseY = 155;
rightMouseX = 305;
rightMouseY = 155;
repaint();
}
}
private class MyMouseListener implements MouseListener
{
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
mouseEntered = true;
repaint();
}
public void mouseExited(MouseEvent e)
{
mouseEntered = false;
repaint();
}
}
private class MyMouseMotionListener implements MouseMotionListener
{
public void mouseDragged(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
}
}
As a start I would recommend putting your eye dimensions in variables as shown below. This way you reduce the chance of errors when entering the same numbers more than once, and if you later decide to change the eye size or position, you only have to change it once.
public static final int LEFT_X = 75;
public static final int LEFT_Y = 100;
public static final int EYE_SIZE = 150;
We also need the left pupil to be independent of the mouse (so it doesn't follow the mouse out of the eye) so we'll do this:
private leftPupilX = 130;
private leftPupilY = 155;
Next you need to determine whether or not the mouse is currently in the left eye. This is what will restrict the pupil to the bounds of the eye. I've done this in a method for convenience.
public void setLeftEye() {
//Set the X Coord for the pupil
//Mouse is to the left of the eye
if(leftMouseX < LEFT_X) {
leftPupilX = LEFT_X;
//Mouse is to the right of the eye
} else if(leftMouseX > LEFT_X + EYE_SIZE) {
leftPupilX = LEFT_X + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilX = leftMouseX;
}
//Set the Y Coord for the pupil
//Mouse is above the eye
if(leftMouseY < LEFT_Y) {
leftPupilY = LEFT_X;
//Mouse is below the eye
} else if(leftMouseY > LEFT_Y + EYE_SIZE) {
leftPupilY = LEFT_Y + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilY = leftMouseY;
}
}
Finally you'll need to update the code that draws the left pupil to reflect the variable change, and actually call our new method.
//draw left pupil
setLeftEye();
g.setColor(Color.black);
g.fillOval(leftPupilX, leftPupilY, 40, 40);
These changes should make the left eye track your mouse the way you described. You'll need to do something similar for the right eye, since it has different coordinates. If you have any problems, let me know and I will try to help. :)

How can i draw a line between two points created as a result of a mouse click

I am trying to write a program to connect two dots with a line between them. First of all, I would like to say, I know drawline() function but I am not allowed to use it (this is H.W assignment). So my problem is that,I managed to write code to connect two dots but for some reason whenever I run my program the (0,0) pixel is always turned-on and on my first mouse click the line draws from (0,0) to the first click coordinates. can some one help me figure out how can I run the application without the (o,o) pixel turned-on??.
Another thing I want to do its to seperate each one of the lines (two clicks = line, another two clicks = another seperate line) and thats also something I am struggling to implement.
hope my explanation is good enough, Any help would be great!
this is my code:
package com.mycompany;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class MousePanel extends JPanel implements MouseListener,ActionListener{
private int x,y,x2,y2,a=1;
public MousePanel(){
super();
addMouseListener(this);
}
public void paint(Graphics g){
int w = x2 - x ;
int h = y2 - y ;
int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0 ;
if (w<0) dx1 = -1 ; else if (w>0) dx1 = 1 ;
if (h<0) dy1 = -1 ; else if (h>0) dy1 = 1 ;
if (w<0) dx2 = -1 ; else if (w>0) dx2 = 1 ;
int longest = Math.abs(w) ;
int shortest = Math.abs(h) ;
if (!(longest>shortest)) {
longest = Math.abs(h) ;
shortest = Math.abs(w) ;
if (h<0) dy2 = -1 ; else if (h>0) dy2 = 1 ;
dx2 = 0 ;
}
int numerator = longest >> 1 ;
for (int i=0;i<=longest;i++) {
g.fillRect(x,y,1,1);
numerator += shortest ;
if (!(numerator<longest)) {
numerator -= longest ;
x += dx1 ;
y += dy1 ;
} else {
x += dx2 ;
y += dy2 ;
}
}
}
public void mouseClicked(MouseEvent mouse){
x=x2;
y=y2;
x2 = mouse.getX();
y2 = mouse.getY();
repaint();
}
public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mousePressed(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }
public static void main(String arg[]){
JFrame frame = new JFrame("MousePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640,640);
MousePanel panel = new MousePanel();
frame.setContentPane(panel);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
If your intention is just to draw a line then you may simply use drawLine() method instead of sequencing rectangular dots into a line.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class MousePanel extends JPanel implements MouseListener,ActionListener{
private int x,y,x2,y2,a=1;
private int count=0;
public MousePanel(){
super();
addMouseListener(this);
}
public void paint(Graphics g){
if(count==2){
g.drawLine(x, y, x2, y2);
count=0;
x=0;
y=0;
x2=0;
y2=0;
}
}
public void mouseClicked(MouseEvent mouse){
count++;
if(count==1){
x=mouse.getX();
y=mouse.getY();
}
if(count==2){
x2 = mouse.getX();
y2 = mouse.getY();
}
repaint();
}
public void mouseEntered(MouseEvent mouse){ }
public void mouseExited(MouseEvent mouse){ }
public void mousePressed(MouseEvent mouse){ }
public void mouseReleased(MouseEvent mouse){ }
public static void main(String arg[]){
JFrame frame = new JFrame("MousePanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640,640);
MousePanel panel = new MousePanel();
frame.setContentPane(panel);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
However, there is nothing wrong in your code too. But you need to add counter to store the point values as shown in above code.
Just replace mouseClicked() method. As you have already defined a variable a use it to figure out the button click count.
public void mouseClicked(MouseEvent mouse) {
if (a == 1) {
a = 0;
x = x2 = mouse.getX();
y = y2 = mouse.getY();
} else {
a = 1;
x = x2;
y = y2;
x2 = mouse.getX();
y2 = mouse.getY();
repaint();
}
}
Try to use a counter in your code to check "number of clicks".
1st click means initial point and 2nd click means end point.
If clicks%2!=0 then set your initial coordinates according to that point else get second coordinates and draw line.
I guess this would be enough for you to continue.
Its your assignment so try to figure it out :)

I'm not able to make this program draw figures towards left & up. It only draws to right and down

I'm having problem drawing rectangle to the left and upwards. They draw perfect to right and downwards.
An answer would be highly appreciated.
import acm.program.*;
import acm.graphics.*;
import java.awt.event.*;
public class Ch10_Ex04_Mouse_Dragged_Rectangle extends GraphicsProgram
{
public void init()
{
addMouseListeners();
}
public void mousePressed (MouseEvent e)
{
X = e.getX();
Y = e.getY();
rect = new GRect (e.getX(), e.getY(), 0, 0);
add (rect);
}
public void mouseDragged (MouseEvent e)
{
// if (e.getX() < X)
// rect.setBounds(X, Y, -e.getX() + X, e.getY() - Y);
rect.setBounds(X, Y, e.getX()-X, e.getY()-Y);
}
int X, Y;
private GRect rect;
}
I am making some assumptions here, but I think this is the mouseDragged function you are looking for (I did not validate this for syntax errors). This should draw the rectangle in all four possible drag directions (1) right/down, (2) right/up, (3) left/down, (4) left/up:
public void mouseDragged (MouseEvent e)
{
// Determine x-val and length
int xPos = X;
int xLen = Math.abs(X - e.getX());
if (e.getX() < X) {
xPos = e.getX();
}
// Determine y-val and length
int yPos = Y;
int yLen = Math.abs(Y - e.getY());
if (e.getY() < Y) {
yPos = e.getY();
}
// Set bounds on rectangle
rect.setBounds(xPos, yPos, xLen, yLen);
}

Categories