简体   繁体   English

在网格中单击 position。 Java Swing

[英]Get click position in grid. Java Swing

I got this code witch creates a clickable grid that shows the mouse position, altough i am not able to get the position in the grid in where the mouse is clicked, trying to be both X and Y position.我得到了这个代码,它创建了一个可点击的网格,显示了鼠标 position,尽管我无法在单击鼠标的网格中找到 position,试图同时成为 X 和 Y Z4757FE07FD492A38BE0EA6A760EZ。 Any ideas?有任何想法吗?

This how the grid looks这是网格的外观

Code:代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

public class TestGrid02 {


public TestGrid02() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class TestPane extends JPanel {
    private static final int ROWS = 20;
    private static final int COLUMNS = 20;
    private static GridBagConstraints gbc;

    public TestPane() {
        setLayout(new GridBagLayout());

        gbc = new GridBagConstraints();
        for (int row = 0; row < ROWS; row++) {
            for (int col = 0; col < COLUMNS; col++) {
                gbc.gridx = col;
                gbc.gridy = row;
                CellPane cellPane = new CellPane();
                Border border = null;
                if (row < ROWS-1) {
                    if (col < COLUMNS-1) {
                        border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
                    } else {
                        border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
                    }
                } else {
                    border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
                }
                cellPane.setBorder(border);
                add(cellPane, gbc);
            }
        }
    }
}

public class CellPane extends JPanel {

    private Color defaultBackground;

    public CellPane() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                defaultBackground = getBackground();
                setBackground(Color.RED);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setBackground(defaultBackground);
            }
            @Override
            public void mouseClicked(MouseEvent e){
                //Here is where it is supposed to be
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(30, 30);
    }
}

} In the CellPane class, witch is intended to be the one that listens to the mouse it is supposed to be the function that i need, at the mouseClicked listener, however i have tried with e.getX() or e.getLocationOnScreen() and these values were changing everytime i click in the same grid.在 CellPane class 中,女巫是用来听鼠标的,它应该是我需要的 function,在 mouseClicked 监听器中,但是我尝试过使用 e.getX() 或 e.getLocationOnScreen()每次我在同一个网格中单击时,这些值都会发生变化。

Well, that looks familiar嗯,看起来很眼熟

So, the basic idea would be to pass in the cell it's coordinates (ie, row/column) value via the constructor, for example...因此,基本思想是通过构造函数将其坐标(即行/列)值传递给单元格,例如...

public class CellPane extends JPanel {

    private Color defaultBackground;
    
    private Point cellCoordinate;

    public CellPane(Point cellCoordinate) {
        this.cellCoordinate = cellCoordinate;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                defaultBackground = getBackground();
                setBackground(Color.RED);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setBackground(defaultBackground);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                //Here is where it is supposed to be
                System.out.println("Did click cell @ " + getCellCoordinate().x + "x" + getCellCoordinate().y);
            }
        });
    }

    public Point getCellCoordinate() {
        return cellCoordinate;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(30, 30);
    }
}

The cell itself doesn't really care, not does it have any reasonable information available to it to determine how it's been laid out, so your best bet is to "tell" it the information you want it to represent.单元格本身并不真正关心,它没有任何合理的信息可用于确定其布局方式,因此您最好的选择是“告诉”它您希望它代表的信息。

For me, I'd just pass in the GridBagLayout row/col information, for example...对我来说,我只需传入GridBagLayout行/列信息,例如......

gbc.gridx = col;
gbc.gridy = row;
CellPane cellPane = new CellPane(new Point(col, row));

This way you remove all concept (and the issues associated with it) of how the cell is laid out通过这种方式,您可以删除单元格布局方式的所有概念(以及与之相关的问题)

This approach (using buttons and action listeners) is better IMO.这种方法(使用按钮和动作监听器)是更好的 IMO。 It uses the getButtonRowCol method to return a string indicating the button's location in an array (the buttonArray ).它使用getButtonRowCol方法返回一个字符串,该字符串指示按钮在数组中的位置( buttonArray )。

在此处输入图像描述

Use b.setBorderPainted(false);使用b.setBorderPainted(false); (uncomment that code line) to get rid of the borders around each button. (取消注释该代码行)以消除每个按钮周围的边框。 Look to the values passed to the constructor of the GridLayout to remove the space between buttons.查看传递给GridLayout的构造函数的值以删除按钮之间的空间。

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

public class GameGridLayout {

    int size = 40;
    int iconSize = 10;
    JButton[][] buttonArray = new JButton[size][size];
    ActionListener actionListener;
    JLabel output = new JLabel("Click somewhere on the GUI");

    GameGridLayout() {
        JPanel gui = new JPanel(new BorderLayout(2,2));
        gui.setBorder(new EmptyBorder(4,4,4,4));
        gui.add(output,BorderLayout.PAGE_END);
        JPanel gameContainer = new JPanel(new GridLayout(0,size,2,2));
        gui.add(gameContainer);
        actionListener = e -> output.setText(getButtonRowCol((JButton)e.getSource()));
        for (int ii=0; ii<size*size; ii++) {
            JButton b = getButton();
            gameContainer.add(b);
            buttonArray[ii%size][ii/size] = b;
        }
        JFrame f = new JFrame("GameGridLayout");
        f.add(gui);
        f.pack();
        f.setMinimumSize(f.getSize());
        f.setLocationByPlatform(true);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }

    private String getButtonRowCol(JButton button) {
        StringBuilder sb = new StringBuilder();
        for (int xx=0; xx<size; xx++) {
            for (int yy=0; yy<size; yy++) {
                if (button.equals(buttonArray[xx][yy])) {
                    sb.append("User selected button at: ");
                    sb.append(xx+1);
                    sb.append(",");
                    sb.append(yy+1);
                    break;
                }
            }
        }
        return sb.toString();
    }

    private JButton getButton() {
        JButton b = new JButton();
        b.setIcon(new ImageIcon(
                new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_ARGB)));
        b.setRolloverIcon(new ImageIcon(
                new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_RGB)));
        b.setMargin(new Insets(0,0,0,0));
        //b.setBorderPainted(false);
        b.setContentAreaFilled(false);
        b.addActionListener(actionListener);
        return b;
    }

    public static void main(String[] args) {
        Runnable r = () -> new GameGridLayout();
        SwingUtilities.invokeLater(r);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM