如何将屏幕上的点转换为二维数组中相应对象的索引
How to convert a point on screen into indices of the corresponding object in a 2d-array
我有一个二维矩形对象数组,它们在 JPanel 中构成一个网格。我想制作一个方法,它将 MouseEvent 的 x 和 y 坐标作为参数,return 该数组中相应 Rectangle 的索引。假设该数组中的每个矩形都有 30x30 像素的面积,我们在 x = 36,y = 15 处有一个点。在这种情况下,结果应该是 indexX = 1 和 indexY = 0。我只需要一个公式计算一下。
编辑:我做了一个简化版的问题:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class Grid extends JPanel {
private final Rectangle[][] grid = new Rectangle[10][10];
public Grid() {
this.setSize(300, 300);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle(i * getWidth() / 10, j * getHeight() / 10, 30, 30);
}
}
this.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
g.setColor(Color.BLUE);
g.fillRect((int) grid[i][j].getX(), (int) grid[i][j].getY(), (int) grid[i][j].getWidth(), (int) grid[i][j].getHeight());
}
}
}
public static Point mousePositionToRectangleIndex(int xPos, int yPos) {
//Problem:
//int indexX = formulaHere;
//int indexY = formulaHere;
// return new Point(indexX, indexY);
return null;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Grid grid = new Grid();
MouseMotionListener mml = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
mousePositionToRectangleIndex(e.getX(), e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
frame.addMouseMotionListener(mml);
frame.add(grid);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
我只需要 mousePositionToRectangleIndex() 的公式
您可以简单地检查鼠标侦听器中按下了哪个矩形以找出您的 i 和 j。例如:
- 为网格 JPanel 指定一个首选大小,而不是大小:
public Grid() {
// this.setSize(300, 300);
setPreferredSize(new Dimension(300, 300));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle((i * getPreferredSize().width) / 10, (j * getPreferredSize().height) / 10, 30, 30);
}
}
addMouseListener(new MyMouse());
}
- 给它一个 MouseListener 检查矩形是否包含点击点:
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j].contains(e.getPoint())) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
}
}
}
}
}
- 不要设置 JFrame 的大小(您忘记了菜单栏需要 space,而是将其打包:
frame.add(grid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(300, 300);
frame.pack();
frame.setVisible(true);
例如:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class Grid extends JPanel {
private final Rectangle[][] grid = new Rectangle[10][10];
public Grid() {
// this.setSize(300, 300);
setPreferredSize(new Dimension(300, 300));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle((i * getPreferredSize().width) / 10, (j * getPreferredSize().height) / 10, 30, 30);
}
}
addMouseListener(new MyMouse());
}
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j].contains(e.getPoint())) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
}
}
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
g2.setColor(Color.BLUE);
// g.fillRect((int) grid[i][j].getX(), (int) grid[i][j].getY(), (int) grid[i][j].getWidth(), (int) grid[i][j].getHeight());
g2.fill(grid[i][j]);
}
}
}
public static Point mousePositionToRectangleIndex(int xPos, int yPos) {
//Problem:
//int indexX = formulaHere;
//int indexY = formulaHere;
// return new Point(indexX, indexY);
return null;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Grid grid = new Grid();
MouseMotionListener mml = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
mousePositionToRectangleIndex(e.getX(), e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
// frame.addMouseMotionListener(mml);
frame.add(grid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(300, 300);
frame.pack();
frame.setVisible(true);
}
}
不过话说回来,整个事情都可以用 JLabel 网格来完成,而且也许还更干净一些。这里我增加了点击单元格的颜色:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Grid2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
GridPanel mainPanel = new GridPanel();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class GridPanel extends JPanel {
private static final int SIDES = 10;
private static final int MAX_COLORS = 6;
private static final Dimension LABEL_SIZE = new Dimension(30, 30);
private int[][] model = new int[SIDES][SIDES];
private JLabel[][] labelGrid = new JLabel[SIDES][SIDES];
private List<Color> colors = new ArrayList<>();
public GridPanel() {
for (int i = 0; i < MAX_COLORS; i++) {
float hue = ((float) i) / MAX_COLORS;
Color c = Color.getHSBColor(hue, 1f, 1f);
colors.add(c);
}
setLayout(new GridLayout(SIDES, SIDES));
for (int i = 0; i < labelGrid.length; i++) {
for (int j = 0; j < labelGrid[i].length; j++) {
model[i][j] = 0;
JLabel label = new JLabel();
label.setPreferredSize(LABEL_SIZE);
label.setOpaque(true);
label.setBackground(colors.get(0));
label.addMouseListener(new MyMouse(i, j));
labelGrid[i][j] = label;
add(label);
}
}
}
private class MyMouse extends MouseAdapter {
private int i;
private int j;
public MyMouse(int i, int j) {
this.i = i;
this.j = j;
}
@Override
public void mousePressed(MouseEvent e) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
model[i][j]++;
model[i][j] %= MAX_COLORS;
labelGrid[i][j].setBackground(colors.get(model[i][j]));
}
}
}
我有一个二维矩形对象数组,它们在 JPanel 中构成一个网格。我想制作一个方法,它将 MouseEvent 的 x 和 y 坐标作为参数,return 该数组中相应 Rectangle 的索引。假设该数组中的每个矩形都有 30x30 像素的面积,我们在 x = 36,y = 15 处有一个点。在这种情况下,结果应该是 indexX = 1 和 indexY = 0。我只需要一个公式计算一下。
编辑:我做了一个简化版的问题:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class Grid extends JPanel {
private final Rectangle[][] grid = new Rectangle[10][10];
public Grid() {
this.setSize(300, 300);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle(i * getWidth() / 10, j * getHeight() / 10, 30, 30);
}
}
this.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
g.setColor(Color.BLUE);
g.fillRect((int) grid[i][j].getX(), (int) grid[i][j].getY(), (int) grid[i][j].getWidth(), (int) grid[i][j].getHeight());
}
}
}
public static Point mousePositionToRectangleIndex(int xPos, int yPos) {
//Problem:
//int indexX = formulaHere;
//int indexY = formulaHere;
// return new Point(indexX, indexY);
return null;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Grid grid = new Grid();
MouseMotionListener mml = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
mousePositionToRectangleIndex(e.getX(), e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
frame.addMouseMotionListener(mml);
frame.add(grid);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
我只需要 mousePositionToRectangleIndex() 的公式
您可以简单地检查鼠标侦听器中按下了哪个矩形以找出您的 i 和 j。例如:
- 为网格 JPanel 指定一个首选大小,而不是大小:
public Grid() {
// this.setSize(300, 300);
setPreferredSize(new Dimension(300, 300));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle((i * getPreferredSize().width) / 10, (j * getPreferredSize().height) / 10, 30, 30);
}
}
addMouseListener(new MyMouse());
}
- 给它一个 MouseListener 检查矩形是否包含点击点:
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j].contains(e.getPoint())) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
}
}
}
}
}
- 不要设置 JFrame 的大小(您忘记了菜单栏需要 space,而是将其打包:
frame.add(grid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(300, 300);
frame.pack();
frame.setVisible(true);
例如:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class Grid extends JPanel {
private final Rectangle[][] grid = new Rectangle[10][10];
public Grid() {
// this.setSize(300, 300);
setPreferredSize(new Dimension(300, 300));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
grid[i][j] = new Rectangle((i * getPreferredSize().width) / 10, (j * getPreferredSize().height) / 10, 30, 30);
}
}
addMouseListener(new MyMouse());
}
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j].contains(e.getPoint())) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
}
}
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
g2.setColor(Color.BLUE);
// g.fillRect((int) grid[i][j].getX(), (int) grid[i][j].getY(), (int) grid[i][j].getWidth(), (int) grid[i][j].getHeight());
g2.fill(grid[i][j]);
}
}
}
public static Point mousePositionToRectangleIndex(int xPos, int yPos) {
//Problem:
//int indexX = formulaHere;
//int indexY = formulaHere;
// return new Point(indexX, indexY);
return null;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Grid grid = new Grid();
MouseMotionListener mml = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
mousePositionToRectangleIndex(e.getX(), e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
// frame.addMouseMotionListener(mml);
frame.add(grid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(300, 300);
frame.pack();
frame.setVisible(true);
}
}
不过话说回来,整个事情都可以用 JLabel 网格来完成,而且也许还更干净一些。这里我增加了点击单元格的颜色:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Grid2 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
GridPanel mainPanel = new GridPanel();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class GridPanel extends JPanel {
private static final int SIDES = 10;
private static final int MAX_COLORS = 6;
private static final Dimension LABEL_SIZE = new Dimension(30, 30);
private int[][] model = new int[SIDES][SIDES];
private JLabel[][] labelGrid = new JLabel[SIDES][SIDES];
private List<Color> colors = new ArrayList<>();
public GridPanel() {
for (int i = 0; i < MAX_COLORS; i++) {
float hue = ((float) i) / MAX_COLORS;
Color c = Color.getHSBColor(hue, 1f, 1f);
colors.add(c);
}
setLayout(new GridLayout(SIDES, SIDES));
for (int i = 0; i < labelGrid.length; i++) {
for (int j = 0; j < labelGrid[i].length; j++) {
model[i][j] = 0;
JLabel label = new JLabel();
label.setPreferredSize(LABEL_SIZE);
label.setOpaque(true);
label.setBackground(colors.get(0));
label.addMouseListener(new MyMouse(i, j));
labelGrid[i][j] = label;
add(label);
}
}
}
private class MyMouse extends MouseAdapter {
private int i;
private int j;
public MyMouse(int i, int j) {
this.i = i;
this.j = j;
}
@Override
public void mousePressed(MouseEvent e) {
System.out.printf("Point pressed, i, j: [%d, %d]%n", i, j);
model[i][j]++;
model[i][j] %= MAX_COLORS;
labelGrid[i][j].setBackground(colors.get(model[i][j]));
}
}
}