如何使用MouseListener在网格中查找特定单元格
我正尝试使用由单元格组成的10 x 10网格创建Java游戏。 网格看起来链接才可这样的:如何使用MouseListener在网格中查找特定单元格
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.
Cell类看起来是这样的:
public class Cell extends JPanel {
public static final int CELL_SIZE = 1;
private int xPos;
private int yPos;
public Cell (int x, int y) {
xPos = x;
yPos = y;
setOpaque(true);
setBorder(BorderFactory.createBevelBorder(CELL_SIZE));
setBackground(new Color(105, 120, 105));
setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
}
// Getter methods for x and y.
我的问题是,我现在想实现在网格类的MouseListeners。我已经意识到,虽然我可以返回网格的X和Y坐标,但我似乎无法操纵单元格本身。 我假设这是因为当我在网格中创建它们时,我创建了100个没有标识符的随机单元格,因此我无法直接访问它们。
有人可以给我这方面的建议吗?我是否需要检修我的代码以及创建单元格的方式?我是非常愚蠢的,错过了一个明显的访问方式吗? 谢谢
您可以使用适配器模式,如下所示。这样,您可以将侦听器单独添加到每个网格单元,但仍然可以处理来自Grid
的事件。
请注意,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
}
子类可以覆盖此为:
public class EnemyGrid extends Grid {
public void click(MouseEvent e, Cell cell) {
cell.setBackground(Color.red);
}
}
可以将多个这种方法中,与其他附加参数
例如约How to determine clicked JButton in a grid ,的逻辑相同和
Mouse(Xxx)Listener
覆盖
getPreferredSize(new Dimension(x, y))
for JPanel而不是setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
感谢您的回答,并对其他帖子发表评论。我对构图不是很熟悉。我已经摆脱了子类的“扩展”部分,而是创建完成“私人网格网格=新的网格()” - 我现在怎么连接到mouseListeners等? – 2013-04-24 13:37:26
[see another JButton and ActionListener](http://stackoverflow.com/a/9007348/714968),再次将JButton更改为JPanel和ActionListener为MouseListener,作为一般和工作代码示例 – mKorbel 2013-04-24 13:41:36
我建议使用putClientProperty基于网格的游戏例如益智,数独,...。 – mKorbel 2013-04-24 13:46:13
最明显的办法是将你的MouseListener
上Cell
类本身。
我想到的第二个选项是使用java.awt.Container.getComponentAt(int, int)
。
或SwingUtilities – mKorbel 2013-04-24 16:34:19
这是一段非常有用的代码 - 谢谢!我可以问一个后续问题 - 我实际上从Grid创建两个子类:OwnGrid和EnemyGrid。它们最初都覆盖了Grid类中包含的MouseListener方法。 用你提出的新结构,我怎么能在网格子类中重写这些方法? – 2013-04-24 13:23:21
@AndrewMartin我不知道我是否理解正确,但如果你想在两个子类中处理不同的事件,你可以重写'mouseClicked(MouseEvent e,Cell cell)' – 2013-04-24 13:28:23
'我怎么能重写这些方法Grid子类不是不容易的工作(因为没有任何问题是可能的),你可以丢失在JCOmponents层次结构中,其中一个缺点来自继承,[使用合成代替](http://www.javaworld.com/ jw-11-1998/jw-11-techniques.html) – mKorbel 2013-04-24 13:33:42