简体   繁体   中英

Printwriter multiple lines with StringBuilder to CSV-file

I have 100 particles that all move with the help of Timer and ActionListener . I'm tracking the movement of my particles by saving the coordinates x,y in a StringBuilder . When the process is done I'm trying to print the results into a CSV-file, with an output that looks like this;

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. The problem is, my output in my CSV-file looks all messed up with more than 600 rows, it should only have 100 rows.

I've tried using different "newline"-commands like \\n , \\r\\n , %n , but none of them gives me 100 lines.

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. If you have any other suggestions, I would gladly take them.

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

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. I have no idea why.

Without testing I believe that the error is that StringBuilder position is a field in the model. In your code each call to getPos() adds more to the same string builder. Instead getPos() should first create a new string builder and keep it locally while adding the coordinates to it.

Also %n in StringBuilder.append() will never give you a newline. Either '\\n' , "\\r\\n" or System.getProperty("line.separator") should work, the last being the most correct.

As an aside, should the fields of the model be public ? I think you can safely declare them private for better encapsulation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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