I am trying to write a program that will allow me to remove a shape if the right mouse click is inside the shape. My approach was to include a method to find the min and max X & Y coordinates of the shape and remove it if the mouse click if the X & Y coordinates of the click are between those coordinates. Right now, my code is just removing the last shape that I spawned in my array list of shapes.
public class RemoveCircle extends JPanel
{
private JFrame framey;
private JPanel panels1;
Circle c1 = new Circle(100,100);
private int x, y;
MouseClicks ms1;
ArrayList<Circle> circles = new ArrayList<Circle>();
private int clickcount;
public RemoveCircle()
{
framey = new JFrame("RemoveCircle");
framey.setSize(900,900);
ms1 = new MouseClicks();
//circles.add(new Circle(x,y));//This may be the original circle being added
this.setBackground(Color.BLACK);
this.setPreferredSize(new Dimension(900,900));
framey.add(this);
framey.pack();
framey.setVisible(true);
this.addMouseListener(ms1);
}
public class Circle
{
int x, y;
Color c1;
int minsx, maxsx, minsy, maxsy;
public Circle(int x, int y)
{
this.x = x; this.y = y;
c1 = getRandoColor();
}
public void draw(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(c1);
g2d.fillOval(x,y,50,50);
}
Random numGenerator = new Random();
private Color getRandoColor()
{
return new Color(numGenerator.nextInt(255), numGenerator.nextInt(255), numGenerator.nextInt(255));
}
public int getMinY(int y)
{minsy = y - 25; return minsy; }
public int getMaxY(int y)
{maxsy = y + 25; return maxsy; }
public int getMinX(int x)
{minsx = x - 25; return minsx; }
public int getMaxX(int x)
{maxsx = x + 25; return maxsx; }
}
#Override
protected void paintComponent(Graphics g)
{
//if (clickcount < 10)
{
super.paintComponent(g);
for (Circle cr : circles)
cr.draw(g);
}
}
public class MouseClicks implements MouseListener
{
int b, y, x ;
int circlecount;
public void mouseClicked(MouseEvent m)
{
int x = m.getX(), y = m.getY(); b = m.getButton();
this.x = x;
this.y = y;
if (b == 1 && circlecount < 10) //Left Click
{
circles.add(new Circle(x-25, y-25)); //x-40 and y - 75
RemoveCircle.this.repaint();
circlecount++;
}
if (b == 3) //Left Click
{ for (Circle c : circles)
{
if ((x >= c.getMinX(x) && x <= c.getMaxX(x)) && (y >= c.getMinY(y) && y <= c.getMaxY(y)))
{
circles.remove(c);
RemoveCircle.this.repaint();
circlecount--;
}
}
}
}
public void mouseExited(MouseEvent m) {}
public void mousePressed(MouseEvent m) {}
public void mouseEntered(MouseEvent m) {}
public void mouseReleased(MouseEvent m) {}
}
}
The easier approach would be to take advantage of the Shape interface. The shape could be a circle or rectangle etc. Then you can use the Shape.contains(...) method to determine if a mouse clicks is in the bounds of the shape.
So instead of create a Circle class you create a ShapeInfo class with two properties:
Shape
Color
Your store this object in your ArrayList and your painting logic now becomes something like:
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
for (ShapeInfo info : shapes)
{
g2d.setColor( info.getColor() );
g2d.draw( info.getShape() );
}
Then the code in your MouseListner will iterate through the same ArrayList and invoke the contains(...) method on each Shape. When you find a match you remove the entry from the ArrayList.
You can use the Ellipse2D.Double class for the circle shape. Check out the DrawOnComponent example found in Custom Painting Approaches for an example that draw rectangles using this basic approach.
Related
Hi guys so i have this game made where the user avoids aliens coming from the right side of the screen and then they go past the left side. I need the aliens to reappear from the right side once they leave the left side of the screen. How can i go about doing this?
Here is my existing code:
EDIT:
Added alien class underneath main class
PImage background;
int x=0; //global variable background location
Alien alien1;
Alien alien2;
Alien alien3;
Defender user1;
void setup(){
size(800,400);
background = loadImage("spaceBackground.jpg");
background.resize(width,height);
alien1 = new Alien(800,100,5);
alien2 = new Alien(800,200,5);
alien3 = new Alien(800,300,5);
user1 = new Defender(10,height/2);
}
void draw ()
{
drawBackground();
alien1.move();
alien1.render();
alien2.move();
alien2.render();
alien3.move();
alien3.render();
user1.render();
}
void drawBackground()
{
image(background, x, 0); //draw background twice adjacent
image(background, x+background.width, 0);
x -=4;
if(x == -background.width)
x=0; //wrap background
}
void keyPressed()
{
if(key == CODED) {
if (keyCode == UP) {
user1.y = user1.y - 5;
}
else if (keyCode == DOWN)
{
user1.y = user1.y + 5;
}
}
}
final color Alien1 = color(0,255,0);
final color Alien2 = color(50,100,0);
class Alien
{
int x,y;
int speedX, speedY;
Alien(int x, int y, int speedX)
{
this.x = x;
this.y = y;
this.speedX = speedX;
}
void move()
{
x=x-speedX;
float stepY = random(-5,5);
y = y + (int)stepY;
}
//draw an alien
void render()
{
fill(Alien1);
ellipse(x,y,30,30);
fill(Alien2);
ellipse(x,y,50,15);
}
}
If you upload your Alien class then we can give clearer directions but the idea is that your should add the following logic in your move() method.
void move()
{
x=x-speedX;
float stepY = random(-5,5);
y = y + (int)stepY;
if(this.x < 0) {
this.x = 800; // or width, startingPosition, ...
}
}
Edit: Alien class was added so adapted my solution to the code.
I'm writing a program that displays a circle every time you click the Jpanel. I have it all set up and I want to be able to use the drawCircle method I created in my circle class to draw the circles in the paintComponent method. I'm storing all of the circles created in a linked list. Then I interate through each Circle in the list and try to use the method in my Circle class called drawCircle().
For some reason, if I try to use c1.drawCircle() in a for loop in the My panel class it only draws the last circle that was created. But if I just use g.fillOval(with the correct parameters grabbing the values from the Circle class) in the for loop it works properly and displays all the circles. Why is it doing this and how do I go about using the method in the Circle class properly
I'm unsure what to try right now.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
public class MouseTest {
private int borderWidth = 20;
private JFrame frame;
private boolean tracking;
private boolean start;
private boolean clearBol;
private int xstart;
private int ystart;
private int xend;
private int yend;
private LinkedList<Circle> circles;
public MouseTest() {
tracking = false;
start = false;
circles = new LinkedList<Circle>();
frame = new JFrame();
frame.setBounds(250, 98, 600, 480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton clear = new JButton("Clear");
JToggleButton circleButton = new JToggleButton()("Circles");
JToggleButton drawButton = new JToggleButton("Draw");
ButtonGroup circleOrDraw = new ButtonGroup();
MyPanel pane = new MyPanel();
clear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
clearBol = true;
frame.repaint();
}
});
JPanel top = new JPanel();
top.setLayout(new FlowLayout());
top.add(clear);
circleOrDraw.add(circleButton);
circleOrDraw.add(drawButton);
top.add(circleOrDraw);
cp.add(top, BorderLayout.NORTH);
cp.add(pane, BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
start = false;
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) {
int tmp = xstart;
xstart = xend;
xend = tmp;
}
if (yend < ystart) {
int tmp = ystart;
ystart = yend;
yend = tmp;
}
start = true;
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
int x = e.getX();
int y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
frame.setVisible(true);
} // constructor
public static void main(String[] arg) {
MouseTest first = new MouseTest();
} // main
public void msg(String s) {
System.out.println(s);
}
public void trackMouse() {
tracking = !tracking;
} // trackMouse
public class Circle extends JPanel {
Graphics g;
int x;
int y;
int r;
Color color;
public Circle(Graphics g, int x, int y, int r) {
this.g = g;
this.x = x;
this.y = y;
this.r = r;
int red = (int) (256 * Math.random());
int green = (int) (256 * Math.random());
int blue = (int) (256 * Math.random());
this.color = new Color(red, green, blue);
}
public void drawCircle() {
int x2 = x - (r / 2);
int y2 = y - (this.r / 2);
g.setColor(color);
g.fillOval(x2, y2, this.r, this.r);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getR() {
return r;
}
}
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
if (start) {
circles.add(new Circle(g, xend, yend,
(int) ((250 * Math.random() + 4))));
//Area where I'm having issues
for (Circle c1 : circles) {
msg("" + c1.getX());
// this method that I created in the circle class will only draw the first circle
//c1.drawCircle();
int r = c1.getR();
int x = c1.getX();
int y = c1.getY();
g.setColor(c1.getColor());
g.fillOval((c1.getX() - (r / 2)), (c1.getY() - (r / 2)),
r, r); // this will display all the circles
}
int size = circles.size();
msg(size + " Size");
msg("" + circles.getLast().getX());
}
if (clearBol) {
super.paintComponent(g);
circles.clear();
clearBol= false;
}
Thank you!
Most of the structure of your class needs to be changed
Your MyPanel should have a better name to give its functionality, maybe something like DrawingPanel.
The DrawingPanel is then responsible for managing the Circles to be painted. So typically you would just use an ArrayList to hold the Circle information.
Then you would add a method to the class, like addCircle(...) to add the Circle information to the ArrayList and then invoke repaint().
Then in your paintComponent(...) method the first thing you do is invoke super.paintComponent(...) to clear the panel. Then you iterate through the ArrayList and paint all the Circles. There will be no need for the Boolean values to check the state of the class. The ArrayList will either have circles or it won't.
You would also need a method like clearCircles(). This would simply remove all the Circles from the ArrayList and invoke repaint() on itself.
Your Circle class should NOT extend JPanel. It should just be a class that contains the information need to paint the circle: x/y location, size of circle and color of circle.
Now your frame is responsible of displaying your DrawingPanel and the buttons.
When you click the "Clear" button you simply invoke the clearCircles() method of the DrawingPanel.
For your MouseListener you simply invoke the addCircle(...) method of your DrawingPanel once you have all the information needed to create a Circle instance.
For a complete working example that incorporates all these suggestions check out the DrawOnComponent example found in Custom Painting Approaches
As part of my assignment, I'm supposed to make a shape that moves when the keyboard is pressed, and also changes color as it moves. I'm trying to add duplicate shapes that move when selected by clicking on them. However, for some reason, I can't add more than one shape. Here's my code. WARNING: MySimplePanel is very long, but the comments explain what my code does.
import java.awt.Graphics2D;
public interface ActionShape {
/**
* Calls the draw method inherited from the shape
* #param g
*/
public void draw(Graphics2D g);
public boolean contains(double x, double y);
public double getWidth();
public double getHeight();
public void setFrame(double x, double y, double w, double h);
}
Driver.java
public class Driver {
public static void main(String args[]) {
MySimplePanel panel = new MySimplePanel(800, 800, Color.gray);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static float random(float lower, float upper) {
float rand = (float) Math.random();
float range = upper - lower;
rand = range * rand;
System.out.println((lower + rand));
return (lower + rand);
}
}
myShape.java
public class myShape extends Rectangle2D.Double implements ActionShape{
static final int size = 50;
Ellipse2D oval;
Ellipse2D oval2;
Ellipse2D oval3;
public int red=127;
public int green=127;
public int blue = 0;
public myShape(int x, int y) {
//sets position of square to center
super(x-size/2, y-size/2, size, size);
oval = new Ellipse2D.Double(x-size/2, y - size, size, size);
oval2 = new Ellipse2D.Double(x-size/2, y + size/25, size, size);
oval3 = new Ellipse2D.Double(x - size, y-size/2, size, size);
}
/**
* Move all the shapes comprising this one
* #return
*/
#Override
public void draw(Graphics2D g) {
// TODO Auto-generated method stub
g.setColor(Color.black);
g.draw(this); //draw outline
g.draw(oval);
g.draw(oval2);
g.draw(oval3);
g.setColor(new Color(red,green,blue));//set color of all shapes
g.fill(this); //draw inside
g.fill(oval);
g.fill(oval2);
g.fill(oval3);
}
public void setFrame(double x, double y, double w, double h) {
super.setFrame(x, y, w, h);
oval.setFrame(x, y-size/2, w, h);
oval2.setFrame(x, y+size/2, w, h);
oval3.setFrame(x-size/2, y, w, h);
}
public boolean contains(double x, double y) {
if(super.contains(x, y) || oval.contains(x, y)|| oval2.contains(x, y)|| oval3.contains(x, y)) {
return true;
}else {
return false;
}
}
}
MySimplepanel
public class MySimplePanel extends JPanel implements MouseInputListener, KeyListener{
public static final int MOVE_PER_ARROW_KEY = 5; //variable that determines how many spaces the shape will move.
private int width;
private int height;
private boolean isPressed = false;
private boolean rightPressed = false;
private boolean otherPressed = false;
public myShape shape;
public int maxRed = 255;
public int maxGreen = 255;
public int maxBlue = 255;
public myShape selShape=null;
public int nextShape=0;
//An array of different shapes that all share an interface. This will be used when the right mouse button is pressed
public myShape[] shapes;
/**
* Construct a panel with specified width, height, and background color
* #param width
* #param height
* #param bgColor
*/
public MySimplePanel(int width, int height, Color bgColor) {
this.setPreferredSize(new Dimension(width, height));
this.setBackground(bgColor);
//Start to listen to mouse and keyboard input on this panel
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this); //detect keyboard input
this.setFocusable(true); //allows you to select this window (required to be able to type in it, just like Processing)
this.setFocusTraversalKeysEnabled(false); //disables shift and tab
setup();
}
private void setup() {
//sets up the starting coordinates for each shape the shape is going to be on the panel.
//I still need to align the center of the panel with the shape's center.
shape = new myShape(400,400);
shapes = new myShape[100];
//array of shapes
shapes[nextShape] = new myShape(200,200);
repaint();
}
/**
* This method is called whenever you call repaint();
*/
protected void paintComponent(Graphics graphicHelper) {
super.paintComponent(graphicHelper); //basically background() in Processing, erases everything
Graphics2D g = (Graphics2D) graphicHelper; //used for drawing in 2D mode
//width and height of the panel
width= getWidth();
height = getHeight();
//draws the shape.
shape.draw(g);
for(int i=0;i<nextShape;i++) {
shapes[i].draw(g);
g.setColor(Color.red);
g.draw(shapes[i]);
}
//for the very first shape that is drawn
if(isPressed==true) {
shape.draw(g);
g.setColor(Color.red);
g.draw(shape);
System.out.println("Shape pressed");
}
//for the very other shape that is drawn by right-clicking
if(otherPressed==true) {
for(int i=0;i<nextShape;i++) {
selShape.draw(g);
g.setColor(Color.red);
g.draw(selShape);
System.out.println("Other Shape pressed");
}
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
if(arg0.getButton() == MouseEvent.BUTTON1) {
if(shape.contains(arg0.getX(), arg0.getY())) {
selShape=shape;
isPressed=true;
repaint();
}
}
if(arg0.getButton() == MouseEvent.BUTTON1) {
for(int i=0; i<nextShape; i++) {
if(shapes[i]!=null) {
if(shapes[i].contains(arg0.getX(), arg0.getY())) {
selShape=shapes[i];
otherPressed=true;
repaint();
}
}
}
}
if(arg0.getButton() == MouseEvent.BUTTON3) {
rightPressed=true;
if(rightPressed==true) {
selShape=shapes[nextShape];
nextShape++;
repaint();
}
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
#Override
public void mouseDragged(MouseEvent arg0) {
}
#Override
public void mouseMoved(MouseEvent arg0) {
}
#Override
public void keyPressed(KeyEvent arg0) {
/**
* Scales the values of red and green based on the width and height respectively.
* red = 0 when the shape is all the way on the left, red = 255 when the shape is all the way on the right
* green = 0 when the shape is all the way up, green = 255 when the shape is all the way down
*/
selShape.red=(int) ((maxRed)*selShape.x/width);
selShape.green=(int) ((maxGreen)*selShape.y/height);
/**
* These two if statements are meant to keep the shape from moving off screen.
*/
if(selShape.x>width||selShape.x<(width=0)) {
selShape.x=width;
}
if(selShape.y>height||selShape.y<(height=0)) {
selShape.y=height;
}
/**
* Moves the shape in different directions depending on the key pressed. It also changes the values of red and green
*/
if(arg0.getKeyCode() == KeyEvent.VK_DOWN) {
selShape.setFrame(selShape.x, selShape.y + MOVE_PER_ARROW_KEY,
selShape.width, selShape.height);
selShape.green--;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_UP) {
selShape.setFrame(selShape.x, selShape.y - MOVE_PER_ARROW_KEY,
selShape.width, selShape.height);
selShape.green++;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_LEFT) {
selShape.setFrame(selShape.x - MOVE_PER_ARROW_KEY, selShape.y,
selShape.width, selShape.height);
selShape.red--;
repaint();
}else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
selShape.setFrame(selShape.x + MOVE_PER_ARROW_KEY, selShape.y,
selShape.width, selShape.height);
selShape.red++;
repaint();
}
/**
* If the shape reaches a certain spot, it will keep changing color randomly until it leaves that area.
*
* Still trying to get the shape's center to hit that spot.
*
*/
if(selShape.getCenterX()>=50 && selShape.getCenterX()<=150 && selShape.getCenterY()>=50 && selShape.getCenterY()<=150) {
selShape.red=(int)(Math.random()*maxRed)+1;
selShape.green=(int)(Math.random()*maxGreen)+1;
selShape.blue=(int)(Math.random()*maxBlue)+1;
System.out.println("x: "+selShape.x);
System.out.println("y: "+selShape.y);
}
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
myShape.java
public class myShape extends Rectangle2D.Double implements ActionShape {
static final int size = 50;
Ellipse2D oval;
Ellipse2D oval2;
Ellipse2D oval3;
public int red = 127;
public int green = 127;
public int blue = 0;
public myShape(int x, int y) {
// sets position of square to center
super(x - size / 2, y - size / 2, size, size);
oval = new Ellipse2D.Double(x - size / 2, y - size, size, size);
oval2 = new Ellipse2D.Double(x - size / 2, y + size / 25, size, size);
oval3 = new Ellipse2D.Double(x - size, y - size / 2, size, size);
}
/**
* Move all the shapes comprising this one
*
* #return
*/
#Override
public void draw(Graphics2D g) {
// TODO Auto-generated method stub
g.setColor(Color.black);
g.draw(this); // draw outline
g.draw(oval);
g.draw(oval2);
g.draw(oval3);
g.setColor(new Color(red, green, blue));// set color of all shapes
g.fill(this); // draw inside
g.fill(oval);
g.fill(oval2);
g.fill(oval3);
}
public void setFrame(double x, double y, double w, double h) {
super.setFrame(x, y, w, h);
oval.setFrame(x, y - size / 2, w, h);
oval2.setFrame(x, y + size / 2, w, h);
oval3.setFrame(x - size / 2, y, w, h);
}
public boolean contains(double x, double y) {
if (super.contains(x, y) || oval.contains(x, y) || oval2.contains(x, y) || oval3.contains(x, y)) {
return true;
} else {
return false;
}
}
I have an application where you place tiles. You can place tiles over tiles and I don't want that. I know that I need something like if the tile rectangle contains the mouse then don't place a tile over it. But this doesn't work. Look at this code:
for (int i = 0; i < b.toArray().length; i++) {
b.get(i).tick();
if (b.get(i).r.contains(Comp.mx, Comp.my)) {
canPlaceATile = false;
// System.out.println("yes");
}
else {
canPlaceATile = true;
//System.out.println("no");
}
if (b.get(i).remove) {
b.remove(i);
i--;
}
}
This is how I check if the mouse is inside the area of one of the tiles.
Block class:
public abstract class block {
public int x,id;
public int y;
protected Image img;
public boolean remove;
public int rotate;
public Rectangle r;
protected int bx, by;
public block() {
}
public abstract void tick();
public abstract void render(Graphics g);
public void createCollisionRect() {
r.setBounds(x - (int) play.camx, y - (int) play.camy, 20, 20);
}
}
an example of a tile:
public class wall extends block {
public wall(int x, int y, int rot) {
this.x = x;
this.y = y;
this.rotate = rot;
r = new Rectangle(x - (int) play.camx, y - (int) play.camy, 20, 20);
id = 0;
}
public void tick() {
createCollisionRect();
if (Comp.mr && r.contains(new Point((Comp.mx), (Comp.my)))) {
remove = true;
}
}
public void render(Graphics g) {
ImageIcon i62 = new ImageIcon("res/tiles/wall.png");
img = i62.getImage();
g.drawImage(img, x - (int) play.camx, y - (int) play.camy, null);
g.setColor(Color.red);
// g.drawRect(x -(int)play.camx, y - play.camy, 20,20);
}
}
I want to check if any of the rectangles contains the mouse and set canPlaceATile to false if the mouse is inside one of the rectangles. The code above doesn't work because when I print the console and I have my mouse over one of the tiles it says:
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
no
yes
and this is when my mouse is on the rectangle without moving it at all. How can I fix this so that I cannot place tiles on top of tiles. Her is where I place tiles:
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
Comp.ml = true;
if (manager.isplay && play.dragging == false) {
if (play.canPlaceATile) {
if (play.selectedID == 0) {
play.b.add(new wall((Comp.mx / 20) * 20, (Comp.my / 20) * 20, play.selectedRot));
}
}
}
}
}
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);
}
}
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:
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.
Use a BufferedImage.