2016-05-17 21 views
1

異なる速度で移動する2つのボールがフレームの中央に移動してから開始位置に戻ろうとするシンプルなシミュレーションをコーディングしました。最後に指定されたtotalTimeでシミュレーションを終了し、このデータを記録します。ループ内で複数のシミュレーションを実行するJava Swing

私の質問は、ループスルーして複数のシミュレーションを自動的に実行できますか?現在、私のtotalTimeが起動しているとき、アニメーションはフリーズしますが、ウィンドウは閉じません。理想的には、私は古いウィンドウを閉じて、新しいボールが新しいスピードでポップアップするのを見たいと思う。

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      double rSpeed = 0; 
      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
      frame.setSize(500, 500); 
      Rectangle r = frame.getBounds(); 
      frame.add(new MoveAgents(r.getWidth(), rSpeed)); 
     }    
    }); 
} 

public MoveAgents(double w, double rFrameSpeed) { 
    //initialize my 2 balls and their speeds and starting locations 

    Timer timer = new Timer(15, null); 
    timer.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      totalTime++; 

      if (totalTime == 1000) { 
       timer.stop(); 

       try { 
        generateCsvFile(OUTPUT_FILE); 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      } 
      //otherwise, do things 
    } 
} 

答えて

2

それはをループすることが可能になると、自動的に複数のシミュレーションを実行します。

だから私のコードは次のようになりますか?

はい。シミュレーションが終了したら、を表示して、を置き換えてください。その代わり、

  • Timerに呼び出しstop()

  • generateCsvFile()を呼び出して結果を保存します。

  • シミュレーションのモデルを初めて実行したときと同じように初期化します。

  • Timerrestart()を呼び出します。以下の例で

、モデルは、シミュレーションは、単にレンダリングし1000にインクリメントれ、data命名intあります。シミュレーションを繰り返す回数のcountは、パラメータとしてSimulationコンストラクタに渡されます。 frame.setSize()の代わりに、図面パネルのgetPreferredSize()を、hereのように上書きします。おかげで素晴らしい

image

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

/** 
* @see https://stackoverflow.com/a/37293513/230513 
*/ 
public class SimTest { 

    private void display() { 
     JFrame f = new JFrame("SimTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new Simulation(8)); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    private static class Simulation extends JPanel { 

     private final Font font = this.getFont().deriveFont(36f); 
     private int count; 
     private int data; 
     Timer t = new Timer(100, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       repaint(); 
       if ((data += 100) == 1000) { 
        t.stop(); 
        System.out.println("Saving results…");//generateCsvFile(); 
        if (--count == 0) { 
         System.out.println("Fin!"); 
         System.exit(0); 
        } else { 
         init(); 
         t.restart(); 
        } 
       } 
      } 
     }); 

     public Simulation(int count) { 
      this.count = count; 
      init(); 
      t.start(); 
     } 

     private void init() { 
      data = 0; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setFont(font); 
      g.drawString(String.valueOf(data), 8, g.getFontMetrics().getHeight()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(256, 128); 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new SimTest()::display); 
    } 
} 
+0

ああ!これは私の主な方法でループを実行しようとしたときに遭遇したすべての問題よりも無限に優れています。 – Kevin

+0

@Kevin: 'javax.swing.Timer'を外部で制御できるループを提供すると考えると、[EDT](http://docs.oracle.com/javase/tutorial /uiswing/concurrency/initial.html)。 – trashgod

関連する問題