我有100个粒子在Timer
和ActionListener
的帮助下全部移动。我通过在x,y
中保存坐标StringBuilder
来跟踪粒子的移动。完成此过程后,我尝试将结果打印到CSV文件中,输出看起来像这样;
time1, x1, y1, x2, y2, ... , xn, yn
time2, x1, y1, x2, y2, ... , xn, yn
,在粒子移动100次后计时器停止的那一刻,我在ActionListener
中使用了一个计数器来完成这项工作。问题是,我的CSV文件输出看起来乱七八糟,应该只有100行。
我尝试过使用\n
,\r\n
,%n
之类的不同&#34;换行符和#34;但它们都没有给我100行。< / p>
我想使用StringBuilder
而不仅仅使用+
的原因是因为我希望代码能够为尽可能多的粒子工作。如果您有任何其他建议,我很乐意接受它们。
Controller
:
import javax.swing.event.*;
import java.awt.event.*;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import javax.swing.*;
public class Controller extends JPanel implements ActionListener{
Model model;
View view;
private Timer timer;
private int delta = 100;
private StringBuilder csv = new StringBuilder();
private int counter = 0;
private int time = 2000;
public Controller(Model m, View v) {
model = m;
view = v;
timer = new Timer(delta, this);
timer.setInitialDelay(time);
timer.start();
}
public void actionPerformed(ActionEvent arg0) {
counter++;
csv.append(time);
csv.append(",");
csv.append(model.getPos());
csv.append("\n");
model.updatePos();
view.repaint();
time += delta * 0.001;
if (counter>100) {
timer.stop();
PrintWriter pw;
try {
pw = new PrintWriter("data.csv");
pw.println(csv);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
Model
:
import java.util.ArrayList;
public class Model {
public int numberofparticles;
public ArrayList<Particle> particlelist;
public StringBuilder position = new StringBuilder();
Model() {
particlelist = new ArrayList<Particle>();
numberofparticles = 100;
for (int i = 0; i < numberofparticles; i++) {
particlelist.add(new Particle());
}
}
public void updatePos() {
for (int i = 0; i < numberofparticles; i++) {
particlelist.get(i).x += 2*Math.cos(Math.random()*2*Math.PI);
particlelist.get(i).y += 2*Math.sin(Math.random()*2*Math.PI);
}
}
public StringBuilder getPos() {
for (int i=0; i < numberofparticles; i++) {
//position.setLength(0);
position.append(particlelist.get(i).x);
position.append(",");
position.append(particlelist.get(i).y);
position.append(",");
}
return position;
}
public class Particle {
private double x;
private double y;
public Particle(double setX,double setY) {
x = setX;
y = setY;
}
Particle() {
this(500+250*2*Math.cos(Math.random()*2*Math.PI),
300+150*2*Math.sin(Math.random()*2*Math.PI));
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
}
View
:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class View extends JPanel{
Model model;
View(Model m){
model = m;
this.setPreferredSize(new Dimension(1010,610));
}
public void paint(Graphics g) {
g.setColor(Color.DARK_GRAY);
for (int i=0; i < model.numberofparticles; i++) {
g.fillOval((int)(model.particlelist.get(i).getX()), (int) (model.particlelist.get(i).getY()), 3, 3);
}
}
}
MyFrame
:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
public class MyFrame extends JFrame{
Model model;
View view;
MyFrame() {
Model model = new Model();
View view = new View(model);
Controller control = new Controller(model, view);
this.setBackground(Color.ORANGE);
this.add(BorderLayout.NORTH, control);
this.add(view);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main( String[] args ) {
new MyFrame();
}
}
编辑: 上面的代码现已完成,可以复制粘贴以重新创建错误。
在Model
中,我注释了一行会在每次运行后重置StringBuilder
,但如果我使用此行,那么输出到CSV的数据就变为空。我不明白为什么。
答案 0 :(得分:1)
如果不进行测试,我认为错误是StringBuilder position
是模型中的一个字段。在您的代码中,每次调用getPos()
都会向同一个字符串构建器添加更多内容。相反,getPos()
应首先创建一个新的字符串构建器,并在向其添加坐标时将其保留在本地。
%n
中的StringBuilder.append()
也永远不会给你换行。 '\n'
,"\r\n"
或System.getProperty("line.separator")
应该有效,最后一个是最正确的。
顺便说一下,模型的字段应该是public
吗?我认为您可以安全地声明它们private
以获得更好的封装。