2013-05-15 2 views
0

때때로 mousePressed 이벤트가 실행되지만 다른 경우에는 실행되지 않습니다. 그것은 또한 당신이 그것을 누르는 시간에 의존하는 것처럼 보입니다. 나는 항상 일하도록 어떻게해야합니까?Game Of Life 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

mousePressed()에 System.out에 문을 추가하고 당신이 그것을 항상 호출되는 것을 볼 수 있습니다 :

나는 그래서 여기에 전체 클래스의 코드의 일부에 결함이있는 확실하지 않다

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

주요 문제는 if (isActive) {및 Timer.isRunning을 테스트하여 같은 순간에 여러 인스턴스를 피할 수 있습니다. – mKorbel

0

whiskeyspider가 말한 것 이외에, 셀이 실행되는 동안 셀을 클릭하면 다음 세대까지 셀 표시등이 보이지 않을 것입니다. 그리고 그 위치가 살아있는 것으로 간주되는 경우에만 처리 ​​후 다음 세대.

관련 문제