使用swing和awt我创建了一个网格。用户可以单击网格中的任何空单元格,将其标记为红色单元格。网格由20 x 20个单元组成,每个单元32个像素。
当用户单击一个单元格时,我会得到鼠标单击的x和y坐标,并执行以下计算以找出哪个单元格是选定的:
int mouseX = e.getX();
int mouseY = e.getY();
int row = mouseY / Model.NODE_SIZE;
int col = mouseX / Model.NODE_SIZE;
问题是,当我在单元格边缘(右边框或下边框)附近单击时,行和列会变得不准确(错误),从而导致标记下一个单元格(右侧单元格或底部单元格),而不是标记我正在单击的正确单元格。
越接近网格的右/下边界,精度就越差。
我是这样画网格的:
public class MainPanel extends JPanel {
// reference to the model
private Model model;
public MainPanel() {
setPreferredSize(new Dimension(660, 660));
// retrieve the model
model = Controller.getController().getModel();
// draw
repaint();
// listen to mouse clicks
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int mouseX = e.getX();
int mouseY = e.getY();
System.out.println("mouseX: " + mouseX + " mouseY: " + mouseY);
// get the row and column clicked
int row = mouseY / Model.NODE_SIZE;
int col = mouseX / Model.NODE_SIZE;
if(row > Model.BOARD_SIZE - 1 || col > Model.BOARD_SIZE - 1) { // avoid out of bounds
return;
}
System.out.println("row: " + row + " col: " + col);
Controller.getController().getModel().setTarget(col, row);
repaint();
}
});
}
/**
* Custom painting codes on this JPanel
* Called by repaint()
*/
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // fills background
setBackground(Color.WHITE); // sets background color
// draw the tiles
Node[][] nodes = model.getBoard();
for(int i = 0; i < Model.BOARD_SIZE; i++) {
for(int j = 0; j < Model.BOARD_SIZE; j++) {
if(nodes[i][j].getNodeType() == NodeType.OBSTACLE) {
g.setColor(Color.BLACK);
g.fillRect(i + Model.NODE_SIZE * i, j + Model.NODE_SIZE * j, Model.NODE_SIZE, Model.NODE_SIZE);
}
else if(nodes[i][j].getNodeType() == NodeType.SOURCE) {
g.setColor(Color.GREEN);
g.fillRect(i + Model.NODE_SIZE * i, j + Model.NODE_SIZE * j, Model.NODE_SIZE, Model.NODE_SIZE);
}
else if(nodes[i][j].getNodeType() == NodeType.TARGET) {
g.setColor(Color.RED);
g.fillRect(i + Model.NODE_SIZE * i, j + Model.NODE_SIZE * j, Model.NODE_SIZE, Model.NODE_SIZE);
}
else {
g.setColor(Color.BLACK);
g.drawRect(i + Model.NODE_SIZE * i, j + Model.NODE_SIZE * j, Model.NODE_SIZE, Model.NODE_SIZE);
}
}
}
}
}
链接到runnable:
https://www.dropbox.com/s/bqoimipp7i1f39s/gridexample.jar?dl=0
2条答案
按热度按时间zed5wv101#
你的油漆代码是错的,基本上。。。
是将每个单元格的大小增加一个已绘制行/单元格的系数,例如。。。
绿线是用
g.drawRect(0, 0, BOARD_SIZE * NODE_SIZE, BOARD_SIZE * NODE_SIZE);
,它应该是网格的可见区域,但您正在绘制超出它的区域。相反,如果我用。。。
它变得更加准确了。。
另一个想法是
Rectangle
要定义网格的每个单元格,可以使用Rectangle#contains
测试鼠标是否在任何给定的单元格范围内…作为一个想法kulphzqa2#
查看此代码:
结合本规范:
是可疑的,你在屏幕上画的矩形大小为
i + Model.NODE_SIZE * i
-所以屏幕上矩形的大小在前面的每个矩形中偏移1。这个偏移会使你所选矩形的潜在“检测”变得更糟,你点击屏幕右下角的距离越远。我怀疑如果你把密码改成
它将按预期工作。