2013-04-24 122 views
5

我正嘗試使用由單元格組成的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個沒有標識符的隨機單元格,因此我無法直接訪問它們。

有人可以給我這方面的建議嗎?我是否需要檢修我的代碼以及創建單元格的方式?我是非常愚蠢的,錯過了一個明顯的訪問方式嗎? 謝謝

回答

2

您可以使用適配器模式,如下所示。這樣,您可以將偵聽器單獨添加到每個網格單元,但仍然可以處理來自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); 
    } 
} 
+0

這是一段非常有用的代碼 - 謝謝!我可以問一個後續問題 - 我實際上從Grid創建兩個子類:OwnGrid和EnemyGrid。它們最初都覆蓋了Grid類中包含的MouseListener方法。 用你提出的新結構,我怎麼能在網格子類中重寫這些方法? – 2013-04-24 13:23:21

+0

@AndrewMartin我不知道我是否理解正確,但如果你想在兩個子類中處理不同的事件,你可以重寫'mouseClicked(MouseEvent e,Cell cell)' – 2013-04-24 13:28:23

+0

'我怎麼能重寫這些方法Grid子類不是不容易的工作(因爲沒有任何問題是可能的),你可以丟失在JCOmponents層次結構中,其中一個缺點來自繼承,[使用合成代替](http://www.javaworld.com/ jw-11-1998/jw-11-techniques.html) – mKorbel 2013-04-24 13:33:42

2
+0

感謝您的回答,並對其他帖子發表評論。我對構圖不是很熟悉。我已經擺脫了子類的「擴展」部分,而是創建完成「私人網格網格=新的網格()」 - 我現在怎麼連接到mouseListeners等? – 2013-04-24 13:37:26

+0

[see another JButton and ActionListener](http://stackoverflow.com/a/9007348/714968),再次將JButton更改爲JPanel和ActionListener爲MouseListener,作爲一般和工作代碼示例 – mKorbel 2013-04-24 13:41:36

+0

我建議使用putClientProperty基於網格的遊戲例如益智,數獨,...。 – mKorbel 2013-04-24 13:46:13

1

最明顯的辦法是將你的MouseListenerCell類本身。

我想到的第二個選項是使用java.awt.Container.getComponentAt(int, int)

+0

或SwingUtilities – mKorbel 2013-04-24 16:34:19

相關問題