java - 将 x、y 坐标映射到二维数组索引
问题描述
我需要将 Swing GUI 的 x、y 坐标映射到它所代表的特定行/列。根据我在每个“正方形”中单击的位置,它将切换显示在上方、下方、左侧或右侧的线条。例如,如果我的鼠标位于正方形的上半部分,它可以切换顶部、左侧或右侧的线来显示。下半部分也是如此,除了底线而不是顶部。要区分它是右行还是左行,取决于鼠标所在的正方形的垂直一半。
最重要的是,如果与顶部屏幕上的按钮进行交互,程序应该打印“Button clicked”。“按钮”被简单地绘制为一个矩形,并且没有使用 JButton 或任何东西,因为它必须使用简单的矩形和文本来创建。
我目前拥有的代码是这个,它绘制了必要的球以及它们之间的线。例如,如果在上图中显示的灰色网格的顶部单击鼠标,它将调用 r = 0 和 c = 0 的 drawHorizontalLine。对于它旁边的正方形,并且鼠标最靠近顶线,它将使用 r = 0 和 c = 1 调用。如果要绘制一条垂直线,例如最左上角,它将是 r = 0、c = 0 等等。R代表行,C代表列。
如果您需要任何进一步的信息,请在评论中告诉我。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SwingMain extends JPanel implements MouseListener {
final static int SEPARATION = 125;
final static int DIAMETER = 15;
final static int NBALLS = 5;
final static int WIDTH = (NBALLS) * (SEPARATION + DIAMETER) + (SEPARATION);
final static int HEIGHT = (NBALLS) * (SEPARATION + DIAMETER) + (SEPARATION);
final static int XSTART = SEPARATION;
final static int YSTART = SEPARATION;
JFrame frame = new JFrame();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new SwingMain().start());
}
public void start() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.add(this);
setBackground(Color.gray);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.white);
int y = YSTART;
for (int r = 0; r < NBALLS; r++) {
int x = XSTART;
for (int c = 0; c < NBALLS; c++) {
g2d.fillOval(x, y, DIAMETER, DIAMETER);
x += SEPARATION + DIAMETER;;
}
y += SEPARATION + DIAMETER;;
}
drawHorizontalLine(g2d, 0, 0);
drawButton(g2d);
}
public void drawHorizontalLine(Graphics2D g, int r, int c) {
int x1 = (SEPARATION) * (c + 1);
int x2 = x1 + SEPARATION;
int y1 = (SEPARATION) * (r + 1) + 2;
int y2 = SEPARATION * (r + 1) + 6;
drawRectangle(g, x1, y1, x2, y2, Color.WHITE);
}
public void drawRectangle(Graphics2D graphic, int x1, int y1, int x2, int y2, Color c) {
graphic.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
}
private void drawButton(Graphics2D g) {
int centerX = WIDTH / 2;
int x1 = centerX - 100;
int x2 = centerX + 100;
int y1 = 25;
int y2 = 75;
drawRectangle(g, x1, y1, x2, y2, Color.WHITE);
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.gray);
g.setFont(new Font("TimesRoman", Font.BOLD, 20));
int strWidth = fm.stringWidth("Completed.");
int strHeight = fm.getAscent();
g.drawString("Completed.",
(centerX - 20) - strWidth / 2,
45 + strHeight);
}
public void mousePressed(MouseEvent e) {
//If the area of the button is clicked
System.out.println("Button clicked.");
}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
解决方案
再一次,你只需要解决一个基本的数学问题。
根据我在每个“正方形”中单击的位置,它将切换显示在上方、下方、左侧或右侧的线...
好吧,我不太了解您的全部要求,但这并不重要。因为这又归结为一个数学公式。因此,您可以根据自己的要求实施公式。
也许下面的建议会让你朝着正确的方向开始。
也许你可以介绍一下“细胞”的概念。在您的示例中,您有 5 个球,因此每行/列上有 4 个方形单元格。
现在我们可以将“单元格大小(宽度/高度)定义为:
int cellSize = DIAMETER + SEPARATION;
现在在鼠标侦听器中,您需要确定:
- 你点击了哪个单元格
- 您单击了单元格的哪一侧(左侧或右侧)
因此,如果我们首先从列开始(行的逻辑将类似),您可能会执行以下操作:
int columnPoint = event.getX() - SEPARATION;
if (columnPoint < 0 ) // you clicked in the left margin
int columnCell = columnPoint / cellSize;
If (columnCell > NBALLS) // you clicked in the right margin
int cellPoint = columnPoint % cellSize);
if (cellPoint < cellSize / 2)
// you clicked on the left half
else
// you clicked on the right half
重复上面的基本逻辑来判断被点击的行以及是否点击了顶部/底部。
同样,没有任何代码经过测试。这是我试图解释的概念。
推荐阅读
- javascript - Javascript中使用键或循环访问对象属性的区别
- php - 如何使用 PHP 从两个不同的表中进行选择,从结果中生成变量并对它们进行数学运算
- angular - ng2-fancy-image-uploader 不能在 Angular 8 中工作
- database - 捕获导致 ORA-01438 的列:值大于此列允许的指定精度
- android - adb remount 总是需要 adb root
- c++ - 如何从 CPP 源代码行号中获取 LLVM 位代码行号?
- sql-order-by - 对结果集的行进行排序,但 Redshift 中的一行除外
- r - R函数对数据进行排序
- javascript - 我的解决方案有意义吗?使用 Promise、超时、try/catch
- angular - 如何根据文件类型显示图标并避免 ngIf 条件的数量?