2014-09-29 200 views
1

該程序應該在繪製的網格上運行元胞自動機模擬(想想康威的生命遊戲),並有一個開始/暫停按鈕,以啓動/暫停模擬,運行間隔1秒。據我所知,除了繪製網格(處理,GUI的其餘部分)之外,其他所有內容都可以正常工作。Java Swing:發佈繪製柵格

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ConcurrentModificationException; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 


public class CA_DriverV2 extends JFrame{ 

    private static final Color white = Color.WHITE, black = Color.BLACK; 

    private Board board; 
    private JButton start_pause; 

    public CA_DriverV2(){ 

     board = new Board(); 
     board.setBackground(white); 

     start_pause = new JButton("Start"); 
     start_pause.addActionListener(board); 

     this.add(board, BorderLayout.NORTH); 
     this.add(start_pause, BorderLayout.SOUTH); 
     this.setLocationRelativeTo(null); 
     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     this.setSize(300, 300); 
     this.setVisible(true); 

    } 

    public static void main(String args[]){ 
     new CA_DriverV2(); 
    } 

    private class Board extends JPanel implements ActionListener{ 

     private final Dimension DEFAULT_SIZE = new Dimension(5, 5); 
     private final int DEFAULT_CELL = 10, DEFAULT_INTERVAL = 1000, DEFAULT_RATIO = 60; 

     private Dimension board_size; 
     private int cell_size, interval, fill_ratio; 
     private boolean run; 
     private Timer timer; 

     private Color[][] grid; 

     public Board(){ 
      board_size = DEFAULT_SIZE; 
      cell_size = DEFAULT_CELL; 
      interval = DEFAULT_INTERVAL; 
      fill_ratio = DEFAULT_RATIO; 
      run = false; 

      //Initialize grid with random values 
       //NOTE: Add JOptionPane for option to define fill rate and board size? 
       //ALT: Have a resize(int h, int w) method to resize grid when needed. 
       //ALT: Have refill(int r) method to restart with different fill ratio. 
      grid = new Color[board_size.height][board_size.width]; 
      for (int h = 0; h < board_size.height; h++) 
       for (int w = 0; w < board_size.width; w++){ 
        int r = (int)(Math.random() * 100); 
        if (r >= fill_ratio) 
         grid[h][w] = black; 
        else grid[h][w] = white; 
       } 

      timer = new Timer(interval, this); 
     } 

     @Override 
     public Dimension getPreferredSize(){ 
      return new Dimension(board_size.height, board_size.width); 
     } 

     @Override 
     public void paintComponent(Graphics g){ 
      for (int h = 0; h < board_size.height; h++) 
       for (int w = 0; w < board_size.width; w++){ 
        try{ 
         if (grid[h][w] == black) 
          g.setColor(black); 
         else g.setColor(white); 
         g.fillRect(h * cell_size, w * cell_size, cell_size, cell_size); 
        } catch (ConcurrentModificationException cme){} 
       } 
     } 

     public void actionPerformed(ActionEvent e) { 

      //Timer tick processing 
      if (e.getSource().equals(timer)){ 
       repaint(); 
       Color[][] newGrid = new Color[board_size.height][board_size.width]; 
       for (int h = 1; h < board_size.height; h++) 
        for (int w = 1; w < board_size.height; w++) { 
         int surrounding = 0; 
         //Count black neighbors 
         for (int i = -1; i <= 1; i++) 
          for (int j = -1; j <= 1; j++){ 
           if(i != 0 && j != 0){ 
            try{ 
             if(grid[h + i][w + j] == black) 
              surrounding++; 
            } catch(ArrayIndexOutOfBoundsException ae){} 
           } 
          } 



         //Generate next iteration 
         if (surrounding > 5 || surrounding < 2) 
          newGrid[h][w] = black; 
         else newGrid[h][w] = white; 
        } 
       for (int h = 1; h < board_size.height; h++){ 
        for (int w = 1; w < board_size.height; w++){ 
         grid[h][w] = newGrid[h][w]; 
         System.out.print(grid[h][w] + " "); 
        } 
        System.out.println(); 
       } 
       System.out.println(); 
      } 

      //Start-Pause button processing 
      else if(e.getSource().equals(start_pause)){ 
       if(run){ 
        timer.stop(); 
        start_pause.setText("Pause"); 
       } 
       else { 
        timer.restart(); 
        start_pause.setText("Start"); 
       } 
       run = !run; 

      } 
     } 
    } 
} 

它打印在最高層,它看起來像由按鈕條子覆蓋在初始網格的條子的東西,剩下的是默認的灰色。

+0

'catch(ArrayIndexOutOfBoundsException ae){}' - 請不要這樣做。認真。 – 2014-09-29 16:53:24

回答

2

您的Board Board變量添加BorderLayout.NORTH而不是BorderLayout.CENTER,因此它只填充前5個像素。

而且按照我的意見,你不應該有這樣的代碼在你的程序:

catch(ArrayIndexOutOfBoundsException ae){} 

不僅要你不要忽略異常,但你不應該連追這種類型的例外。取而代之的是創建一個小小的循環,以便他們可以處理邊緣。

另外,不要忘記在你的類的覆蓋中調用super.paintComponent(g)方法。