Java swing, need to draw rectangles using the mouse without losing previous rectangles with overlap

StackOverflow https://stackoverflow.com/questions/22161927

  •  19-10-2022
  •  | 
  •  

Question

in this class that i have extending JLabel I need to be able to use the mouse to left click, then drag down and/or right to create a rectangle and be able to repeat that process to draw multiple rectangles without losing any of the previous ones and drawing boxes for overlap as well as being able to find the rectangle made by the union of all rectangles like this

my current code was adapted as much as i could from the java demo on Performing Custom Painting the program seems to be behaving in odd ways because of how the repaint method is used to update the JLabel but i have no idea how to fix it

JLabel class

import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class JLabelx extends JLabel {
    private int squareX = 0;
    private int squareY = 0;
    private int squareW = 0;
    private int squareH = 0;

public JLabelx() {

    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            squareX = e.getX();
            squareY = e.getY();
            //set coordinates of next rectangle 
        }
    });

    addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent e) {

            newDraw(e.getX(),e.getY());
            //find length and width of next rectangle
        }
    });

    }
protected void newDraw(int x, int y) {
    int OFFSET = 1;
    if ((squareX!=x) || (squareY!=y)) {
    //  repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
        squareW=x-squareX;
        squareH=y-squareY;
        repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
    } 
}
protected void paintComponent(Graphics g) {
    super.paintComponents(g);       

    g.setColor(Color.GREEN);
    g.fillRect(squareX,squareY,squareW,squareH);
    g.setColor(Color.BLACK);
    g.drawRect(squareX,squareY,squareW,squareH);

    }
}

I have also been given a Rectangle class that looks similar to java.awt.Rectangle which has methods that find the rectangles made by overlaps and the rectangles made by the union of all rectangles, but I don't know how to create rectangle objects with mouse movements and then paint them in this JLabel

public class Rectangle {
private int x,y,width,height;

public Rectangle(int x,int y,int width,int height)
{
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

public Rectangle(Rectangle a)
{
    this.x = a.x;
    this.y = a.y;
    this.width = a.width;
    this.height = a.height;
}

public String toString()
{
    return "Start: ("+x+","+y+"), Width: "+width+", Height: "+height+"\n";
}

public int getX()
{
    return x;
}

public int getY()
{
    return y;
}

public int getWidth()
{
    return width;
}

public int getHeight()
{
    return height;
}

public void setX(int x)
{
    this.x = x;
}

public void setY(int y)
{
    this.y = y;
}

public void setWidth(int width)
{
    this.width = width;
}

public void setHeight(int height)
{
    this.height = height;
}

public int area()
{
    return width*height;
}

public boolean overlaps(Rectangle a)
{
    if ((x>a.x+a.width) || (a.x>x+width) || (y>a.y+a.height) || (a.y>y+height))
    {
        return false;
    }
    return true;
}

public Rectangle intersect(Rectangle a)
{
    if (!overlaps(a))
        return null;

    int left,right,top,bottom;

    if (x<a.x)
        left = a.x;
    else
        left = x;

    if (y<a.y)
        bottom = a.y;
    else
        bottom = y;

    if ((x+width)<(a.x+a.width))
        right = x+width;
    else
        right = a.x+a.width;

    if ((y+height)<(a.y+a.height))
        top = y+height;
    else
        top = a.y+a.height;

    return new Rectangle(left,bottom,right-left,top-bottom);
}

public Rectangle union(Rectangle a)
{
    int left,right,top,bottom;

    if (x<a.x)
        left = x;
    else
        left = a.x;

    if (y<a.y)
        bottom = y;
    else
        bottom = a.y;

    if ((x+width)<(a.x+a.width))
        right = a.x+a.width;
    else
        right = x+width;

    if ((y+height)<(a.y+a.height))
        top = a.y+a.height;
    else
        top = y+height;

    return new Rectangle(left,bottom,right-left,top-bottom);
    }


 }
Was it helpful?

Solution

Not sure why you are extending a JLabel to do custom painting. The tutorial showed you how to use a JPanel.

For the two common ways to do incremental paint, check out Custom Painting Approaches:

  1. Use a List to keep track of the Rectangles (this is probably what you want since you want to be able to test for intersections.
  2. Use a BufferedImage.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top