Search code examples
javaswingjpanelcoordinate

Colouring in a JPanel using mouseClicked - Error


Good day,

I might've been a bit vague with the title of my question, but I hope this will explain. The scenario is quite basic - I have a JFrame, in which I have an array of JPlanes. The idea is that when I click on one of them, upon clicking in should become black. Here is the code:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.*;
import javax.swing.border.Border;

public class PixelArt {

    JFrame frame;
    Border blackline;
    JPanel squares[][] = new JPanel[100][100];
    int x;
    int y;

    public PixelArt() {

        frame = new JFrame("Pixel Art");
        frame.setSize(1000, 1000);
        frame.setLayout(new GridLayout(100, 100));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                x = i;
                y = j;
                squares[i][j] = new JPanel();
                squares[i][j].setBorder(BorderFactory.createDashedBorder(null));
                squares[i][j].addMouseListener(new MouseAdapter() {

                    public void mouseClicked(MouseEvent e) {

                        x = e.getX();
                        y = e.getY();
                        squares[x][y].setBackground(Color.black); 

                    }
                });

                frame.add(squares[i][j]);
            }
        }

        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new PixelArt();
    }
}

The actual problem is that this code does not do what I explained above. It does color in one of the JPlane's black when clicked, but within a 9x9 area starting from the upper corner of the grid. I do not have an explanation for this. The problem seems to be in the following 2 lines:

    x = e.getX();
    y = e.getY();

One of my guesses is that I have some kind of an offset in the coordinate system, but then this does not explain why regardless on which JPanel I press, the JPanels colored are only in the upper 9x9 area.

Does anyone have a clue how I could fix the problem I described above? If something is unclear in my explanation, please ask. Thank you in advance.

Here is a screenshot of the working code:

Screenshot of working code


Solution

  • you can detect clicked panel using event.getSource() like follow example code

    public void mouseClicked(MouseEvent e) {
    
            JPanel panel = (JPanel)e.getSource();// 
            panel.setBackground(Color.black); 
    
    }
    

    the problem is you can't use x,y directly as indexes to array element. because panels has a width and borders too.if you go with x y you have to make some mathematics logic. for example you click middle of your first jpanel in the grid so let's assume x and y coordinate is about 10px but in your code you call [10][10] Janel but actually you should call [0][0]. also as @Cr0w3 says you add listners to all panels.so if you clicked middle of first grid cell or last grid cell there is no difference in x,y.

    but if you make a mathematical logic to detect clicked element you need to take in to account your frame/main panel width(also have to update when risize) and border thickness.

    also do you really want to do this using 10000 panels ? you may need use a one panel and override paint component method.10000 panels isn't effective for this kind of thing.if you resize or click quickly on panels you will see it take a lot of time. so you may need to draw graphics on a jpanel .see this example