2014-01-28 75 views
0

嗨我已經實現了一個模擬的MVC和我使用JPanel來繪製每個模擬週期,當我遍歷代理的集合並更新他們在二維數組中的位置。然而重繪方法對我來說工作不正常,當我單擊開始按鈕一次時,JPanel應該自動保持刷新。但是,如果我不斷點擊開始按鈕,然後重新刷新JPanel與代理更新的位置,我做錯了什麼?重繪只有當我點擊按鈕

GUI Class: 
    public class MainGUI implements Runnable { 

     public static void main(String[] args) { 
      EventQueue.invokeLater(new MainGUI()); 
     } 

     @Override 
     public void run() { 
      JFrame f = new JFrame(); 
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      f.add(new MainPanel()); 
      f.pack(); 
      f.setLocationRelativeTo(null); 
      f.setSize(400, 400); 
      f.setVisible(true); 
      f.repaint(); 
     } 

     class MainPanel extends JPanel { 

      public MainPanel() { 
       super(new BorderLayout()); 

       Simulator model = new Simulator(); 
       GridView view1 = new GridView(model); 
       Controller control = new Controller(model, view1); 
       JLabel label = new JLabel("Welcome to the ABM Simulation"); 


       this.add(label, BorderLayout.NORTH); 
       this.add(view1, BorderLayout.CENTER); 
       this.add(control, BorderLayout.SOUTH); 
      } 
     } 


    } 

    View Class: 

     public class GridView extends JPanel { 

      private Simulator sim; 
      private int rows; 
      private int cols; 
      private Agent[][] current2DArray; 

      public GridView(Simulator sim) { 
       this.sim = sim; 
       this.rows = sim.getGrid().getRow(); 
       this.cols = sim.getGrid().getColumn(); 
       this.current2DArray = sim.getGrid().getGrid(); 

       JPanel canvas = new JPanel(); 
       canvas.setLayout(null); 
       canvas.setPreferredSize(new Dimension(rows, cols)); 
      } 

      public void paintComponent(Graphics g) { 
       super.paintComponent(g); 
       setBackground(Color.GRAY); 

       for(Agent agent : sim.getAgents()) { 
        g.setColor(agent.getColor()); 
        g.fill3DRect(agent.getLocation().getRow(), agent.getLocation().getCol(), 5, 5, true); 
       repaint(); 
       } 
      } 

     public void drawAgents(Graphics g) { 
      g.setColor(Color.GRAY); 
      g.fillRect(0,0,rows,cols); 
      for(int row = 0; row < current2DArray.length; row++) { 
       for(int col = 0; col < current2DArray[row].length; col++) { 
        if(current2DArray[row][col] instanceof Cop) { 
         if(current2DArray[row][col].getState() == 1) { 
          g.setColor(Color.RED); 
          g.fill3DRect(row, col, 5, 5, true); 
         } 
         else if(current2DArray[row][col].getState() == 2) { 
          //no nothing 
         } 

        } 
        else if(current2DArray[row][col] instanceof Citizen) { 
         if(current2DArray[row][col].getState() == 3) { 
          g.setColor(Color.BLACK); 
          g.fill3DRect(row, col, 5, 5, true); 
         } 
         else if(current2DArray[row][col].getState() == 4) { 
          //no nothing 
         } 
        } 
        else if(current2DArray[row][col] == null) { 
         //if empty do nothing 
        } 
       } 
      } 
     } 
    } 

public class Controller extends JPanel { 
    private Simulator sim; 
    private GridView view; 
    private JButton start = new JButton("Start"); 

    public Controller(Simulator sim, GridView view) { 
     this.sim = sim; 
     this.view = view; 
     this.add(start); 
     start.addActionListener(new ButtonHandler()); 
    } 

    private class ButtonHandler implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      String cmd = e.getActionCommand(); { 
       if("Start".equals(cmd)) { 
        sim.resumeSimulation(); 
       } 
      } 
     } 

    } 
} 
+0

您在GridView構造函數中的代碼中似乎有3條冗餘行。您創建一個'JPanel畫布',但從不將其分配給任何東西。 –

回答

0

在每個模擬週期後,在您的JPanel上調用repaint()以重新繪製它。按下按鈕無意中觸發了這一點。

因此,在模擬可以訪問的地方創建一個參考,然後調用repaint()方法,即myGridView.repaint()

+0

完成一個模擬週期後,爲什麼向面板發送信號以重繪repaint()? – user3112844

+0

panel.repaint()當然! –

0

如果你想要一個固定的幀速率,那麼你可以設置一個Timer來強制你的面板重畫。

擺動物體通常盡其所能,除非他們的組件或您通過其他方式告知,並期望合作從而導致心痛。