Search code examples
javaswingjlabelpaintcomponentmouselistener

Painted rectangles not showing up


I've been trying for quite a while to get this to work and done a lot of research but I can't work out why it's not happening: My end goal is get a grid of x by y green squares, and when you click on a square it changes colour. (this is part of a bigger project)

Now I am aware that this is probably a very inefficient way of doing so, but I've tried different ways and nothing seems to work.

In my Grid class I have this:

    squares = new Square[width][height];
 for (int i = 0; i < width; i++){
    for (int j = 0; j < height; j++){
        squares[i][j] = new Square(i,j);
        frame.getContentPane().add(squares[i][j]);
    }
}

And this is my Square class:

public class Square extends JLabel implements MouseListener{

private int x,y,width,height, mouseX,mouseY;
private Color colour = Color.GREEN;


public Square(int width, int height){
this.x = width*45;
this.y = height*45;
addMouseListener(this);
this.setBounds(x, y, 45, 45);
}

public void paintComponent(Graphics g){
   Graphics2D g2 = (Graphics2D) g;
   g2.setColor(colour);
   g2.fillRect(x, y, 45, 45);
}

@Override
public void mouseClicked(MouseEvent e) {
    mouseX = e.getX();
    mouseY = e.getY();
    if(mouseX > x && mouseX < x+45 && mouseY > y && mouseY < y+45){
    if(colour.equals(Color.GREEN)){
        colour = Color.RED;
    } else{
        colour = Color.GREEN;
    }
    repaint();
    }
}

}

However when I run the code, all I see is the first square and the last square; how come?

If you have any tips of how I could have done this far more efficiently, please do tell and criticize this code.


Solution

  • To solve your problem. You need to change your code in some places.

    1) You don't need to pass x, y co-ordinates with Square() constructor. Declare empty constructor like this:

     public Square() {
            addMouseListener(this);
            this.setBounds(x, y, 45, 45);
     }
    

    2) Set GridLayout to your JFrame.

      frame.setLayout(new GridLayout(width, height));
    

    3) Call empty constructor on your loop.

     Square[][] squares = new Square[width][height];
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                squares[i][j] = new Square();
                frame.add(squares[i][j]);
            }
        }