-1

I'm trying to resize a Rectangle2D using the mouse dragging method. In addition I want to recenter it in the middle of the JPanel. I think the code and formulas are correct but it doesen't work properly because it resizes the rectangle excessively and it not suitably following the cursor.

Here I'll post the relevant codes.

Constructor:

public Canvas(double width, double height) {
    this.width = width;
    this.height = height;

    rect = new Rectangle2D.Double(this.x, this.y, this.width, this.height);
    vertex = new Rectangle2D[4];

    this.addMouseMotionListener(this);
    this.addMouseListener(this);
}

vertex is an array of Rectangle2D that are drawn to the vertices of the rectangle only if the mouse is inside

paintComponent:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    //RETTANGOLO
    Graphics2D g2 = (Graphics2D)g;
    Stroke oldStroke = g2.getStroke();
    g2.setStroke(new BasicStroke(SPESSORE));
    g2.draw(rect);
    g2.setStroke(oldStroke);
    g2.setColor(Color.BLACK);

    setAtCenter();

    //VERTICI
    vertex[0] = new Rectangle2D.Double(this.x, this.y, SIZEV, SIZEV);
    vertex[1] = new Rectangle2D.Double(this.x + this.width - SIZEV, 
                                        this.y, SIZEV, SIZEV);
    vertex[2] = new Rectangle2D.Double(this.x, this.y + this.height - SIZEV, 
                                        SIZEV, SIZEV);
    vertex[3] = new Rectangle2D.Double(this.x + this.width - SIZEV, 
                                        this.y + this.height - SIZEV, 
                                        SIZEV, SIZEV);
    if (dentro) {
        for (int i = 0; i < 4; i++) {
            g2.draw(vertex[i]);
        }
    } 
}

private void setAtCenter() {
    this.x = ((this.getWidth()/2) - (this.width/2));
    this.y = ((this.getHeight()/2) - (this.height/2));
    rect.setRect(x, y, this.width, this.height);
}

mouseMoved:

@Override
public void mouseMoved(MouseEvent e) {
    dentro = false;
    inVertex = -1;
    if (rect.contains(e.getPoint())) {
        dentro = true;
    }
    for (int i = 0; i < 4; i++) {
        if (vertex[i].contains(e.getPoint())) {
            inVertex = i;
            break;
        }
    }
}

mousePressed:

@Override
public void mousePressed(MouseEvent e) {
    if (inVertex >= 0) {
        this.startX = e.getX();
        this.startY = e.getY();
    }
}

mouseDragged:

@Override
public void mouseDragged(MouseEvent e) {
    double dX;
    double dY;
    if (inVertex >= 0) {
        this.endX = e.getX();
        this.endY = e.getY();
        dX = startX - endX;
        dY = startY - endY;
        this.width += dX;
        this.height += dY;
        this.repaint();
    }
}

I hope I've posted all the necessary informations and someone finally help me to solve this problem that for too long afflicts me.

EDIT: I've solved the problem by tracking the position of the vertices by setting the width and height accordingly. I simplified the code allowing the resize only from the origin vertex. Thanks for support.

Thanks to everyone!

Shafa95
  • 201
  • 2
  • 14

1 Answers1

1

mouseDragged() will be called repeatedly. In your current implementation, each time mouseDragged() is called, you are adding the entire distance again and again, instead of just adding the what changed since the last mouseDragged() call.

    this.width += dX;
    this.height += dY;

A quick fix would be to store the current position in startX and startY each time mouseDragged() is called.

@Override
public void mouseDragged(MouseEvent e) {
    double dX;
    double dY;
    if (inVertex >= 0) {
        this.endX = e.getX();
        this.endY = e.getY();
        dX = startX - endX;
        dY = startY - endY;
        this.width += dX;
        this.height += dY;

        this.startX = this.endX;
        this.startY = this.endY;

        this.repaint();
    }
}

But this adding up the incremental changes in size is a strange approach. You would probably be better off just keeping track of which vertex is grabbed, then update its position. Then draw your shape based on the positions of the vertices, without keeping track of size changes -- that is, the size of the rectangle is implicit based on the position of your vertices.

martinez314
  • 12,162
  • 5
  • 36
  • 63
  • I tried your solution and now resize is slowed compared to the cursor position. So I'll try to follow your advice and keep track of every vertex position and redrawing the Rectangle each time based on the vertices position. But I hope it will work with my `setAtCenter()` method – Shafa95 Jun 02 '16 at 18:14
  • I've solved the problem by tracking the position of the vertices by setting the width and height accordingly. I simplified the code allowing the resize only from the origin vertex. Thanks for support. – Shafa95 Jun 03 '16 at 21:17