使用 mouseClicked 在 JPanel 中着色 - 错误
Colouring in a JPanel using mouseClicked - Error
美好的一天,
我的问题标题可能有点含糊,但我希望这能解释清楚。这个场景非常基本——我有一个 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 区域。
有谁知道如何解决我上面描述的问题?如果我的解释不清楚,请询问。先感谢您。
这是工作代码的屏幕截图:
我认为您不应该将侦听器添加到面板本身,而应该添加到框架。
因为 X 和 Y 坐标可能与面板大小有关(例如,面板的上角 returns 1/1,因此您将颜色应用于 [1][1] 处的面板即使您单击 [50][50].
处的面板
如果您在该点使用框架收听,您将收到 50/50 作为坐标。
遗憾的是我不能发表评论,因为我的声誉很低,但我希望我能提供一点帮助。
如果要向面板添加监听器,请不要使用坐标,只需将颜色应用于单击的面板而不监听坐标。在这种情况下,使用 e.getSource() 应该会有所帮助。
您可以使用 event.getSource()
检测点击的面板,就像遵循示例代码
public void mouseClicked(MouseEvent e) {
JPanel panel = (JPanel)e.getSource();//
panel.setBackground(Color.black);
}
问题是您不能直接使用 x
、y
作为数组元素的索引。因为面板有一个宽度和边框 too.if 你要用 x y 你必须做一些数学逻辑。例如,您单击网格中第一个 jpanel 的中间,因此我们假设 x 和 y 坐标约为 10px,但在您的代码中您调用 [10][10]
Janel,但实际上您应该调用 [0][0]
。
也正如 @Cr0w3 所说,如果您单击第一个网格单元格或最后一个网格单元格的中间,则将监听器添加到所有 panels.so,则 x、y 没有区别。
但如果您制定数学逻辑来检测点击的元素,则需要考虑您的 frame/main 面板宽度(在调整大小时也必须更新)和边框厚度。
您是否真的想使用 10000 个面板来做到这一点?您可能需要使用一个面板并覆盖绘制组件方法。10000 个面板对这种类型无效thing.if 如果您在面板上快速调整大小或单击,您会发现这会花费很多时间。所以您可能需要在 jpanel 上绘制图形。请参阅此 example
美好的一天,
我的问题标题可能有点含糊,但我希望这能解释清楚。这个场景非常基本——我有一个 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 区域。
有谁知道如何解决我上面描述的问题?如果我的解释不清楚,请询问。先感谢您。
这是工作代码的屏幕截图:
我认为您不应该将侦听器添加到面板本身,而应该添加到框架。
因为 X 和 Y 坐标可能与面板大小有关(例如,面板的上角 returns 1/1,因此您将颜色应用于 [1][1] 处的面板即使您单击 [50][50].
处的面板如果您在该点使用框架收听,您将收到 50/50 作为坐标。
遗憾的是我不能发表评论,因为我的声誉很低,但我希望我能提供一点帮助。
如果要向面板添加监听器,请不要使用坐标,只需将颜色应用于单击的面板而不监听坐标。在这种情况下,使用 e.getSource() 应该会有所帮助。
您可以使用 event.getSource()
检测点击的面板,就像遵循示例代码
public void mouseClicked(MouseEvent e) {
JPanel panel = (JPanel)e.getSource();//
panel.setBackground(Color.black);
}
问题是您不能直接使用 x
、y
作为数组元素的索引。因为面板有一个宽度和边框 too.if 你要用 x y 你必须做一些数学逻辑。例如,您单击网格中第一个 jpanel 的中间,因此我们假设 x 和 y 坐标约为 10px,但在您的代码中您调用 [10][10]
Janel,但实际上您应该调用 [0][0]
。
也正如 @Cr0w3 所说,如果您单击第一个网格单元格或最后一个网格单元格的中间,则将监听器添加到所有 panels.so,则 x、y 没有区别。
但如果您制定数学逻辑来检测点击的元素,则需要考虑您的 frame/main 面板宽度(在调整大小时也必须更新)和边框厚度。
您是否真的想使用 10000 个面板来做到这一点?您可能需要使用一个面板并覆盖绘制组件方法。10000 个面板对这种类型无效thing.if 如果您在面板上快速调整大小或单击,您会发现这会花费很多时间。所以您可能需要在 jpanel 上绘制图形。请参阅此 example