Draw varying size rectangle with different orientation using rectangle 2D


I want to draw a rectangle in a java application. I have used rectangle2d to draw a rectangle. I need the rectangle to vary size based on mouse drag. i.e. The size of the rectangle varies as I drag the mouse. I am currently able to draw only one type of the rectangle, i.e. When i drag the mouse towards down right of the screen. But i am unable to draw the other rectangles.for example. when the mouse is dragged top right of the screen. I am using a method called setRect that takes upper left x and y coordinates of the rectangle. But since when I drag the mouse top left, my upper left and upper right change and my rectangle distorts.

I have tried my best to explain this in words. If you have any doubts on the question, open up MS paint application or any ther drawing application, select a rectangle and move the mouse in all directions and see the 4 different orientations of rectangle when the mouse is dragged up left, up right, down left and down right. Out of these I am able to draw only one when up left coordinates remain the same. is there any function that I can use to draw the rest of the three rectangle orientations


Answers:


Assuming you are using two sets of Points gained from the mousePressed and the mouseDragged MouseEvent, Here something to consider.

Break it down into smaller pieces. Look at it in terms of quadrants (The O in the center being the initial Point gathered from the mousePressed

           Quadrants
+--------------+---------------+
|              |               |
|              |               |
|      I       |       II      |
|              |               |
|              |               |
+--------------O---------------+
|              |               |
|              |               |
|     IV       |      III      |
|              |               |
|              |               |
+--------------+---------------+

When you drag the mouse, the second Point obtained from the mouseDragged will be either in quadrant I, II, III, or IV.

So again I'll say.. Break it down into smaller pieces.

How would you draw the rectangle if the the second point is in quadrant I?

  • Point 2 would then become the initial point to draw from. So you would have to switch the drawing points using

    // original
    setRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
    
    // change to
    setRect(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y);
    

    You can use logic to check which quadrant point is in, such as

    public boolean isPointTwoInQuadOne(Point p1, Point p2) {
        return p1.x >= p2.x && p1.y >= p2.y;
    }
    

Hope that helps you out, or at least helps you see the problem from a different perspective :)


Here's a running example. I figured out the quadrant I for you, and you seem to already know the quadrant III, so I'll leave it to you, to figure II and IV ;-)

enter image description here

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RectangleDrawWithDrag extends JPanel{
    private static final int D_W = 500;
    private static final int D_H = 500;

    private Point p1;
    private Point p2;
    private Rectangle2D rectangle;

    public RectangleDrawWithDrag() {
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent e) {
                p1 = e.getPoint();
                rectangle = new Rectangle2D.Double(p1.x, p1.y, p1.x - p1.x, p1.y - p1.y);
            }
        });
        addMouseMotionListener(new MouseMotionAdapter(){
            public void mouseDragged(MouseEvent e) {
                p2 = e.getPoint();
                if (isPointTwoInQuadOne(p1, p2)) {
                    rectangle.setRect(p2.x, p2.y, p1.x - p2.x, p1.y - p2.y);
                } else {
                    rectangle.setRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
                }

                repaint();
            }
        });
    }

    public boolean isPointTwoInQuadOne(Point p1, Point p2) {
        return p1.x >= p2.x && p1.y >= p2.y;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        if (rectangle != null) {
            g2.fill(rectangle);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new RectangleDrawWithDrag());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}