【问题标题】:Colouring in a JPanel using mouseClicked - Error使用 mouseClicked 在 JPanel 中着色 - 错误
【发布时间】:2015-12-03 09:04:55
【问题描述】:

早安,

我可能对我的问题的标题有点含糊,但我希望这能解释清楚。该场景非常基本 - 我有一个 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,彩色的 JPanel 都只位于上部 9x9 区域。

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

这是工作代码的截图:

【问题讨论】:

  • Mouse#getX 和 Mouse#getY 返回鼠标事件相对于产生事件的组件的像素位置。

标签: java swing jpanel coordinate


【解决方案1】:

您可以使用event.getSource() 检测被点击的面板,就像下面的示例代码一样

public void mouseClicked(MouseEvent e) {

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

}

问题是你不能直接使用x,y 作为数组元素的索引。因为面板也有宽度和边框。如果你选择 x y,你必须做一些数学逻辑。例如,您单击网格中第一个 jpanel 的中间,因此假设 x 和 y 坐标约为 10px,但在您的代码中您调用 [10][10] Janel 但实际上您应该调用 [0][0]。 也正如@Cr0w3 所说,您将侦听器添加到所有面板。因此,如果您单击第一个网格单元格或最后一个网格单元格的中间,则 x,y 没有区别。

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

您是否真的想使用 10000 个面板来执行此操作?您可能需要使用一个面板并覆盖绘制组件方法。10000 个面板对这种事情无效。如果您调整大小或快速单击面板,您会发现这需要很长时间。所以您可能需要在 jpanel 上绘制图形。请参阅 example

【讨论】:

    【解决方案2】:

    我认为您不应该将侦听器添加到面板本身,而应添加到框架中。

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

    如果您在该点使用框架进行收听,您将收到 50/50 作为坐标。

    很遗憾我不能发表评论,因为我的声誉很低,但我希望我能帮上一点忙。

    如果您想向面板添加侦听器,请不要使用坐标,只需将颜色应用于单击的面板而不听坐标。在这种情况下,使用 e.getSource() 应该会对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2014-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多