I have a 2d-array of Rectangle-objects which make up a grid in JPanel. I want to make a method which will take x and y coordinates of a MouseEvent as parameters and return the indices of the corresponding Rectangle in that array. Let's say every Rectangle in that array has the area of 30x30 pixels and we have a point at x = 36, y = 15. The result in this case should be indexX = 1 and indexY = 0. All I need is a formula which would calculate it.
Edit: I made a simplified version of my problem:
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);
}
}
All I need is the formula for mousePositionToRectangleIndex()
CodePudding user response:
You can simply check which rectangle has been pressed in your mouse listener to find out your i and j. For example:
- give the grid JPanel a preferred size, not a size:
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());
}
- give it a MouseListener that checks if a rectangle contains the click point:
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);
}
}
}
}
}
- Don't set the JFrame's size (you're forgetting the menu bar takes space, but rather pack it:
frame.add(grid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setSize(300, 300);
frame.pack();
frame.setVisible(true);
For example:
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);
}
}
But having said that, the whole thing can be done with a JLabel grid, and perhaps a little more cleanly too. Here I increment the color of the clicked cell:
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]));
}
}
}