简体   繁体   English

Printwriter用StringBuilder将多行转换为CSV文件

[英]Printwriter multiple lines with StringBuilder to CSV-file

I have 100 particles that all move with the help of Timer and ActionListener . 我有100个粒子,它们都在TimerActionListener的帮助下移动。 I'm tracking the movement of my particles by saving the coordinates x,y in a StringBuilder . 我通过将坐标x,yStringBuilder跟踪粒子的运动。 When the process is done I'm trying to print the results into a CSV-file, with an output that looks like this; 完成该过程后,我尝试将结果打印到CSV文件中,其输出如下所示;

time1, x1, y1, x2, y2, ... , xn, yn time2, x1, y1, x2, y2, ... , xn, yn , At the moment the timer stops after the particles have moved 100 times, I use a counter in my ActionListener to get this done. time1, x1, y1, x2, y2, ... , xn, yn time2, x1, y1, x2, y2, ... , xn, yn ,在粒子移动了100次后计时器停止使用我的ActionListener的计数器来完成此操作。 The problem is, my output in my CSV-file looks all messed up with more than 600 rows, it should only have 100 rows. 问题是,我的CSV文件中的输出看起来都被600多行弄乱了,它应该只有100行。

I've tried using different "newline"-commands like \\n , \\r\\n , %n , but none of them gives me 100 lines. 我尝试使用\\n\\r\\n%n类的不同“换行”命令,但是它们都不给我100行。

The reason I want to use a StringBuilder and not just use + is because I want the code to work for as many particles as possible. 我想要使​​用StringBuilder而不是仅使用+的原因是因为我希望代码能够处理尽可能多的粒子。 If you have any other suggestions, I would gladly take them. 如果您还有其他建议,我很乐意接受。

Controller : 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 : 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 : 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 : 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();
    }
}

Edit: The code above is now complete and can be copy pasted to recreate the error. 编辑:上面的代码现已完成,可以复制粘贴以重新创建错误。

In Model , I've commented out a line which would reset the StringBuilder after every run, but if I use this line then the data output to the CSV just becomes nothing. Model ,我注释掉了一行,它将在每次运行后重置StringBuilder ,但是如果我使用此行,那么输出到CSV的数据将什么都没有。 I have no idea why. 我不知道为什么。

Without testing I believe that the error is that StringBuilder position is a field in the model. 未经测试,我相信错误是StringBuilder position是模型中的一个字段。 In your code each call to getPos() adds more to the same string builder. 在您的代码中,每次调用getPos()向同一字符串生成器添加更多getPos() Instead getPos() should first create a new string builder and keep it locally while adding the coordinates to it. 相反, getPos()应该首先创建一个新的字符串生成器,并在向其中添加坐标时将其保留在本地。

Also %n in StringBuilder.append() will never give you a newline. 同样, StringBuilder.append() %n永远不会给您换行符。 Either '\\n' , "\\r\\n" or System.getProperty("line.separator") should work, the last being the most correct. '\\n'"\\r\\n"System.getProperty("line.separator")应该都可以工作,最后一个最正确。

As an aside, should the fields of the model be public ? 顺便说一句,模型的领域应该public吗? I think you can safely declare them private for better encapsulation. 我认为您可以安全地将它们声明为private以实现更好的封装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM