2013-05-15 62 views
0

有時會執行mousePressed事件,但在其他時間則不會。它似乎也取決於你按下它的時間。我如何得到它始終工作?生命遊戲Java MouseAdapter並不總是有效

我不知道這部分代碼是錯誤的,所以這裏的全班同學:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import java.util.Random; 

import javax.swing.JButton; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
public class Board extends JPanel implements ActionListener { 
    Timer timer = new Timer(500, this); 

    private boolean[][] board; 
    private boolean isActive = false; 
    private int height; 
    private int width; 
    private int multiplier = 20; 

    private JButton btnRun; 
    private JButton btnRand; 
    private JButton btnClear; 

    public Board() { 
     this(new boolean[20][20]); 
    } 

    public Board(final boolean[][] board) { 
     this.board = board; 
     height = board.length; 
     width = board[0].length; 
     setBackground(Color.black); 
     btnRun = new JButton("Run"); 
     add(btnRun); 
     btnRun.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       isActive = !isActive; 
       btnRun.setText(isActive ? "Pause" : "Run"); 
      } 
     }); 
     btnRand = new JButton("Random"); 
     add(btnRand); 
     btnRand.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       setBoard(randomBoard()); 
      } 
     }); 
     btnClear = new JButton("Clear"); 
     add(btnClear); 
     btnClear.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       setBoard(clearBoard()); 
      } 
     }); 
     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       getBoard()[e.getY()/multiplier][e.getX()/multiplier] = !getBoard()[e.getY()/multiplier][e.getX()/multiplier]; 
      } 
     }); 
     timer.start(); 
    } 

    public int getMultiplier() { 
     return multiplier; 
    } 

    public boolean[][] getBoard() { 
     return board; 
    } 

    public void setBoard(boolean[][] boardToSet) { 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       board[i][j] = boardToSet[i][j]; 
      } 
     } 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       g.setColor(board[i][j] ? Color.green : Color.gray); 
       g.fillRect(j * multiplier, i * multiplier, multiplier - 1, multiplier - 1); 
      } 
     } 
     if (isActive) { 
      timer.start(); 
     } 
     else { 
      timer.stop(); 
      repaint(); 
     } 
    } 

    public void actionPerformed(ActionEvent e) { 
     board = nextGeneration(); 
     repaint(); 
    } 

    public boolean[][] randomBoard() { 
     Random rand = new Random(); 
     boolean[][] randBoard = new boolean[height][width]; 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       randBoard[i][j] = rand.nextBoolean(); 
      } 
     } 
     return randBoard; 
    } 

    public boolean[][] clearBoard() { 
     boolean[][] emptyBoard = new boolean[height][width]; 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       emptyBoard[i][j] = false; 
      } 
     } 
     return emptyBoard; 
    } 

    public int countSurrounding(int a, int b) { 
     int count = 0; 
     int[][] surrounding = {{a - 1, b - 1}, 
           {a - 1, b }, 
           {a - 1, b + 1}, 
           {a , b - 1}, 
           {a , b + 1}, 
           {a + 1, b - 1}, 
           {a + 1, b }, 
           {a + 1, b + 1}}; 
     for (int[] i: surrounding) { 
      try { 
       if (board[i[0]][i[1]]) { 
        count++; 
       } 
      } 
      catch (ArrayIndexOutOfBoundsException e) {} 
     } 
     return count; 
    } 

    public boolean[][] nextGeneration() { 
     boolean[][] nextBoard = new boolean[height][width]; 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       nextBoard[i][j] = board[i][j]; 
      } 
     } 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       if (board[i][j] && !(countSurrounding(i, j) == 2 || countSurrounding(i, j) == 3)) { 
        nextBoard[i][j] = false; 
       } 
       else if (!board[i][j] && countSurrounding(i, j) == 3) { 
        nextBoard[i][j] = true; 
       } 
      } 
     } 
     return nextBoard; 
    } 
} 
+0

不需要粘貼代碼兩次.. –

+0

可以在'getBoard()[e.getY()/ multiplier] [e.getX()/ multiplier]' – NeplatnyUdaj

+0

相關:http:// stackoverflow。 com/questions/16552392/keep-a-mouselistener-always-running/16552941#16552941 – whiskeyspider

回答

2

添加的System.out語句mousePressed(),你會看到,它總是叫:

public void mousePressed(MouseEvent e) { 
     System.out.println("mousePressed"); 
     getBoard()[e.getY()/multiplier][e.getX()/multiplier] = !getBoard()[e.getY()/multiplier][e.getX()/multiplier]; 
     repaint(); 
    } 

與其他人在other very similar question中提出的一樣,問題源於您在繪畫方法中使用計時器。

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    for (int i = 0; i < height; i++) { 
     for (int j = 0; j < width; j++) { 
      g.setColor(board[i][j] ? Color.green : Color.gray); 
      g.fillRect(j * multiplier, i * multiplier, multiplier - 1, multiplier - 1); 
     } 
    } 
    //if (isActive) { // take this stuff out... 
    // timer.start(); 
    //} 
    //else { 
    // timer.stop(); 
    // repaint(); 
    //} 
} 

paintComponent()方法應該只用於繪製組件。不要用它來啓動/停止定時器,對repaint()進行額外的調用,或者調用任何其他類型的程序邏輯。重新考慮你的設計,特別是在paintComponent()

+0

主要問題可能是如果(isActive){並通過測試Timer.isRunning,以避免在同一時刻的多個實例 – mKorbel

0

除了whiskeypider所說的,如果在運行時點擊某個單元格,直到下一代纔會看到單元格亮起,並且只有當該位置被認爲處於活動狀態時,處理後纔會在下一代中亮起代。