Printwriter使用StringBuilder到CSV文件的多行

时间:2018-01-26 10:17:20

标签: java timer actionlistener printwriter

我有100个粒子在TimerActionListener的帮助下全部移动。我通过在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的数据就变为空。我不明白为什么。

1 个答案:

答案 0 :(得分:1)

如果不进行测试,我认为错误是StringBuilder position是模型中的一个字段。在您的代码中,每次调用getPos()都会向同一个字符串构建器添加更多内容。相反,getPos()应首先创建一个新的字符串构建器,并在向其添加坐标时将其保留在本地。

%n中的StringBuilder.append()也永远不会给你换行。 '\n'"\r\n"System.getProperty("line.separator")应该有效,最后一个是最正确的。

顺便说一下,模型的字段应该是public吗?我认为您可以安全地声明它们private以获得更好的封装。