2013-04-24 87 views
5

Tôi đang cố gắng tạo một trò chơi Java với lưới 10 x 10 bao gồm các ô. Các Lưới trông liks này:Cách sử dụng MouseListener để tìm một ô cụ thể trong lưới

lớp
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. 

The Cell trông như thế này:

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. 

Vấn đề của tôi là bây giờ tôi đang cố gắng để thực hiện MouseListeners trong lớp Grid. Những gì tôi đã nhận ra là trong khi tôi có thể trả về các tọa độ X và Y của Grid, tôi dường như không thể thao túng các tế bào. Tôi giả định điều này là bởi vì khi tôi tạo chúng trong Grid, tôi đang tạo ra 100 ô ngẫu nhiên không có số nhận dạng và vì vậy tôi không có cách nào để truy cập trực tiếp chúng.

Ai đó có thể cho tôi lời khuyên về điều này không? Tôi có cần phải sửa chữa mã của tôi và cách tôi tạo ra các tế bào? Tôi đang ngu ngốc và thiếu một cách rõ ràng để truy cập chúng? Cảm ơn

Trả lời

2

Bạn có thể sử dụng mẫu bộ điều hợp, như được hiển thị bên dưới. Bằng cách đó, bạn có thể thêm người nghe vào từng ô lưới riêng lẻ, nhưng vẫn xử lý các sự kiện từ Grid.

Lưu ý rằng Grid không còn thực hiện MouseListener, điều này được xử lý bởi các ô ngay bây giờ.

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 
} 

Một lớp con có thể ghi đè này như:

public class EnemyGrid extends Grid { 
    public void click(MouseEvent e, Cell cell) { 
     cell.setBackground(Color.red); 
    } 
} 
+0

Đây là một đoạn mã thực sự hữu ích - cảm ơn bạn! Tôi có thể hỏi một câu hỏi tiếp theo - tôi thực sự tạo ra hai lớp con ra khỏi Grid: OwnGrid và EnemyGrid. Cả hai ban đầu đều overrode các phương pháp MouseListener đã được chứa trong lớp Grid. Với cấu trúc mới mà bạn đã đề xuất, làm thế nào tôi có thể ghi đè lên các phương thức này trong các lớp con Lưới? –

+0

@AndrewMartin Tôi không chắc liệu tôi có hiểu chính xác hay không, nhưng nếu bạn muốn xử lý sự kiện khác nhau trong cả hai lớp con, bạn chỉ có thể ghi đè 'mouseClicked (MouseEvent e, Cell cells)' –

+0

'cách tôi có thể ghi đè các phương thức này các lớp con lưới không phải là công việc không dễ dàng (vì có thể không có bất kỳ vấn đề nào), bạn có thể bị mất trong hệ thống phân cấp JCOmponents, một trong những bất lợi đến từ thừa kế, [sử dụng composition thay thế] (http://www.javaworld.com/ jw-11-1998/jw-11-technical.html) – mKorbel

2
+0

Cảm ơn câu trả lời của bạn và nhận xét của bạn về bài đăng khác. Tôi không thực sự quen thuộc với bố cục. Tôi đã thoát khỏi phần "mở rộng" của lớp con và thay vào đó đã tạo xong "lưới lưới riêng tư = lưới mới()" - làm cách nào tôi có thể kết nối nó với mouseListeners, v.v ...? –

+0

[xem một JButton và ActionListener] (http://stackoverflow.com/a/9007348/714968), một lần nữa thay đổi JButton thành JPanel và ActionListener thành chỉ MouseListener, như là ví dụ chung và mã làm việc – mKorbel

+0

Tôi khuyên bạn nên sử dụng putClientProperty cho trò chơi dựa trên lưới ví dụ câu đố, sudoku, .... – mKorbel

1

Cách rõ ràng nhất sẽ được di chuyển MouseListener của bạn trên lớp Cell riêng của mình.

Tùy chọn thứ hai tôi có thể nghĩ là sử dụng java.awt.Container.getComponentAt(int, int).

+0

hoặc SwingUtilities – mKorbel