Java 如何使用MouseStener在网格中查找特定单元格

Java 如何使用MouseStener在网格中查找特定单元格,java,swing,jpanel,grid-layout,mouselistener,Java,Swing,Jpanel,Grid Layout,Mouselistener,我正在尝试创建一个由单元格组成的10 x 10网格的Java游戏。 网格如下所示: public class Grid extends JPanel implements MouseListener { public static final int GRID_SIZE = 10; public Grid() { setPreferredSize(new Dimension(300, 300)); setLayout(new GridLayout

我正在尝试创建一个由单元格组成的10 x 10网格的Java游戏。 网格如下所示:

public class Grid extends JPanel implements MouseListener {
    public static final int GRID_SIZE = 10;

    public Grid() {
        setPreferredSize(new Dimension(300, 300));
        setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));

        for (int x = 0; x < GRID_SIZE; x++)
            for (int y = 0; y < GRID_SIZE; y++)
                add(new Cell(x, y));
        addMouseListener(this);
    }

// All Mouse Listener methods are in here.
我的问题是,我现在正试图在Grid类中实现MouseListener。我意识到,虽然我可以返回网格的X和Y坐标,但我似乎无法操纵单元格本身。 我假设这是因为当我在网格中创建它们时,我创建了100个没有标识符的随机单元,所以我无法直接访问它们

有人能给我一些建议吗?我是否需要修改我的代码和创建单元格的方式?我是不是太愚蠢了,错过了一个明显的途径去接近他们?
谢谢,您可以使用适配器模式,如下所示。这样,您可以将侦听器单独添加到每个网格单元,但仍然可以处理
网格中的事件

请注意,
Grid
不再实现
MouseListener
,现在由单元格处理

public class Grid extends JPanel {
    public static final int GRID_SIZE = 10;

    public Grid() {
        setPreferredSize(new Dimension(300, 300));
        setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));

        for (int x = 0; x < GRID_SIZE; x++) {
            for (int y = 0; y < GRID_SIZE; y++) {
                final Cell cell = new Cell(x, y);
                add(cell);
                cell.addMouseListener(new MouseListener() {
                    public void mouseClicked(MouseEvent e) {
                        click(e, cell);
                    }
                    // other mouse listener functions
                });
            }
        }        
    }

    public void click(MouseEvent e, Cell cell) {
        // handle the event, for instance
        cell.setBackground(Color.blue);
    }

    // handlers for the other mouse events
}
  • 使用

  • 您可以使用其他附加参数将此方法设置为多个

  • 例如,对于
    JPanel
    鼠标(Xxx)侦听器

  • 替代
    setPreferredSize(新维度(单元格大小,单元格大小))


最明显的方法是在
单元格
类本身上移动您的
鼠标侦听器


我能想到的第二个选择是使用
java.awt.Container.getComponentAt(int,int)

这是一段非常有用的代码-谢谢!我可以问一个后续问题吗?我实际上在网格外创建了两个子类:OwnGrid和EnemyGrid。它们最初都覆盖了Grid类中包含的MouseListener方法。使用您提出的新结构,我如何在网格子类中重写这些方法?@AndrewMartin我不确定我是否正确理解这一点,但如果您想在两个子类中以不同的方式处理事件,您可以重写
mouseClicked(MouseEvent e,Cell-Cell)
我如何在网格子类中重写这些方法这不是一件容易的工作(因为这是可能的,没有任何问题),你可能会迷失在JCOmponents层次结构中,缺点之一来自继承,我的意思是:假设我遵循你的方法,让mouseClicked方法将背景设置为黄色。在子类中,我创建了一个名为public void mouseClicked的方法,该方法接受相同的参数-MouseEvent和Cell。但是,在这种方法中,我尝试将背景颜色更改为红色。不幸的是,什么也没有发生。我能做些什么来解决这个问题?@AndrewMartin我对这个方法的名字有点不走运。我将其重命名为
单击
,完全没有覆盖的问题。谢谢你的回答和你在另一篇文章中的评论。我对作文不是很熟悉。我已经去掉了子类的“extends”部分,而是创建了done“private Grid Grid=new Grid()”-现在我如何将其连接到mouseListeners等,再次将JButton更改为JPanel,ActionListener更改为MouseListener,作为通用和工作代码示例,我建议将putClientProperty用于基于网格的游戏,例如益智游戏、数独游戏等。我现在正试着仔细阅读。我以前几乎从未使用过这些构造!
public class Grid extends JPanel {
    public static final int GRID_SIZE = 10;

    public Grid() {
        setPreferredSize(new Dimension(300, 300));
        setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));

        for (int x = 0; x < GRID_SIZE; x++) {
            for (int y = 0; y < GRID_SIZE; y++) {
                final Cell cell = new Cell(x, y);
                add(cell);
                cell.addMouseListener(new MouseListener() {
                    public void mouseClicked(MouseEvent e) {
                        click(e, cell);
                    }
                    // other mouse listener functions
                });
            }
        }        
    }

    public void click(MouseEvent e, Cell cell) {
        // handle the event, for instance
        cell.setBackground(Color.blue);
    }

    // handlers for the other mouse events
}
public class EnemyGrid extends Grid {
    public void click(MouseEvent e, Cell cell) {
        cell.setBackground(Color.red);
    }
}