1

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

vs97
  • 5,765
  • 3
  • 28
  • 41
  • `Mouse#getX` and `Mouse#getY` return the pixel position of the mouse event relative to the component which generated the event. – MadProgrammer Sep 08 '15 at 00:04

2 Answers2

4

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

Community
  • 1
  • 1
Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60
1

I think you should not add the listener to the panels themselves, but to the frame.

Because the X and Y coordinates might be relative to the panel size (e.g., upper corner of the panel returns 1/1, thus you apply the color to the panel at [1][1] even though you click the panel at [50][50].

If you use the frame for listening at the point you will receive 50/50 as coordinates.

Unfortunately I cannot comment, because of my low reputation but I hope I could help a little.

If you want to add a listener to the panel do not use the coordinates and just apply color to the clicked panel without listening to the coordinates. Using e.getSource() should help you in that case.

Cr0w3
  • 120
  • 10