使用mouseClicked在JPanel中着色 - 错误

时间:2015-09-07 19:23:05

标签: java swing jpanel coordinate

美好的一天,

我可能对我的问题的标题有点模糊,但我希望这可以解释。这个场景非常基础 - 我有一个JFrame,我有一个JPlanes数组。我的想法是,当我点击其中一个时,点击后应该变成黑色。这是代码:

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();
    }
}

实际问题是此代码不能执行我上面解释的操作。单击时,它会在JPlane的一个黑色中显示颜色,但在从网格的上角开始的 9x9区域内。我对此没有解释。问题似乎在以下两行:

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

我的一个猜测是我在坐标系中有某种偏移,但这并不能解释为什么无论我按哪个JPanel,彩色的JPanels只在9x9的上部区域。

有没有人知道如何解决我上面描述的问题?如果我的解释中有些不清楚,请询问。先感谢您。

以下是工作代码的屏幕截图:

Screenshot of working code

2 个答案:

答案 0 :(得分:3)

您可以使用event.getSource()检测点击的面板,例如关注示例代码

public void mouseClicked(MouseEvent e) {

        JPanel panel = (JPanel)e.getSource();// 
        panel.setBackground(Color.black); 

}

问题是你不能直接使用xy作为数组元素的索引。因为面板也有宽度和边框。如果你使用x y,你必须制作一些数学逻辑。例如,你点击网格中第一个jpanel的中间位置,让我们假设x和y坐标大约是10px,但在你的代码中你调用了[10][10] Janel,但实际上你应该调用[0][0]。 同样@ Cr0w3表示你将列表器添加到所有panels.so如果你点击第一个网格单元格的中间或最后一个网格单元格,则x,y没有区别。

但是如果您使用数学逻辑来检测单击元素,则需要考虑框架/主面板宽度(在升高时也必须更新)和边框厚度。

你真的想用 10000面板吗?你可能需要使用一个面板并覆盖绘制组件方法.10000面板对这种事情没有效果。如果你调整大小或快速点击面板,你会发现它需要花费很多时间。因此您可能需要在jpanel上绘制图形。请参阅此example

答案 1 :(得分:1)

我认为你不应该将监听器添加到面板本身,而是添加到框架。

因为X和Y坐标可能与面板尺寸有关(例如,面板的上角返回1/1,因此即使单击面板,也可以在[1] [1]处将颜色应用于面板在[50] [50]。

如果您使用该帧进行收听,您将获得50/50作为坐标。

不幸的是我无法发表评论,因为我的声誉很低,但我希望我能帮上一点。

如果要向面板添加侦听器,请不要使用坐标,只需将颜色应用于单击的面板而不听取坐标。在这种情况下,使用e.getSource()可以帮助你。