2014-09-29 173 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)方法。