NullPointerException when trying to write a csv using Intelij as an ide

I made this in Intelij, with processing, trying to write a csv. But this code gives me an error 'Exception in thread "Animation Thread" java.lang.NullPointerException' when I write the csv with saveTable, why?

When I print out the table I get 'processing.data.Table@66ede931', giving me proof that the table is really there!, so the bug must be the in the path?

import processing.core.PApplet;
import processing.data.Table;
import processing.data.TableRow;    

public class WriteCsv {

    static PApplet parent;

    public WriteCsv(PApplet p) {
        parent = p;
    }

    Table table;

    public void createNewCsv() {

       table.addColumn("M_Phase");//342
       table.setInt(1, "M_Phase", 0);//342

       parent.println("table : " + table  ); // prints out 'processing.data.Table@66ede931', so table is not a null!!
       parent.saveTable( table, "data/info.csv" );
}
}

Any ideas what can cause the this error?

Answers

  • edited October 2016 Answer ✓

    Got no InteliJ but made a PDE sketch example using a separate ".java" tab.
    Which is hopefully pretty close to other IDEs' behavior. :\">

    "Save_Load_Table.pde":

    /**
     * Save&Load Table from Top Class (v1.1.4)
     * GoToLoop (2016-Oct-02)
     *
     * forum.Processing.org/two/discussion/18374/
     * nullpointerexception-when-trying-to-write-a-csv-
     * using-intelij-as-an-ide#Item_1
     */
    
    void setup() {
      println(new WriteCSV(this, "M_Phase")
        .addCSVRow(342)
        .addCSVRow(-5)
        .saveCSVTable("info.csv")
        .loadCSVTable("info.csv")
        .addCSVRow(MAX_INT));
      exit();
    }
    

    "WriteCSV.java":

    import processing.core.PApplet;
    import processing.data.Table;
    import processing.data.TableRow;
    
    public class WriteCSV {
      protected final PApplet p;
      protected Table t;
    
      public WriteCSV(PApplet sketch, String colName) {
        p = sketch;
        (t = new Table()).addColumn(colName, Table.INT);
      }
    
      public Table getTable() {
        return t;
      }
    
      public WriteCSV addCSVRow(int v) {
        t.addRow().setInt(0, v);
        PApplet.println("#Value:", v, " \t #Rows:", t.getRowCount());
        return this;
      }
    
      public WriteCSV saveCSVTable(String filename) {
        final String path = p.dataPath(filename);
        p.saveTable(t, path);
        PApplet.println("Table w/ #rows", t.getRowCount(), 
          "saved:  \"" + path + '"');
        return this;
      }
    
      public WriteCSV loadCSVTable(String filename) {
        String path = p.dataPath(filename);
        t = p.loadTable(path, "header");
        PApplet.println("Table w/ #rows", t.getRowCount(), 
          "loaded: \"" + path + '"');
        return this;
      }
    
      @Override public String toString() {
        StringBuilder sb = new StringBuilder(t.getColumnTitle(0)).append(':');
        int row = 0;
        for (TableRow tr : t.rows())
          sb.append('\n').append(row++).append(": ").append(tr.getInt(0));
        return sb.toString();
      }
    }
    
  • Wow, that totally worked! I was really surprised that the solution is so much different compared with the example at the processing site! Its a lot more code to chew trough and to understand, but it perfectly works! Many many thanx You really made my day!!

  • Answer ✓

    All you were missing was a call to initiate Table.

    Your line 13 just defines the table to be of type Table, but it doesn't instantiate it.

    Table table = new Table();
    
  • @GoToLoop How would you modify your code so to append to a file? Is it possible to use your sample or would I need to write appending operations using explicit java code aka. writing my own code?

    On another note, I notice the following code which I do not recognize:

    public WriteCSV loadCSVTable(String filename) {...}
    

    You are returning your own class where the method was defined. I can see some functionality in this structure (I have seen it when using ControlP5 objects). Is this something that you find in java coding (I haven't seen it in C/C++). Would that fall under OOP design?

    Lastly, in your code line 41 when using the StringBuilder object, don'y you need to define the column ID when implementing the object, beside the column name? When you do the for loop in line 43/44, you are building "rowNumber:columnValue" pairs.

    Kf

  • edited October 2016

    How would you modify your code so to append to a file?

    It's completely relying on Processing functions: loadTable() & saveTable().

    Just call loadCSVTable() method, do your appending stuff w/ addCSVRow() or something else, then call saveCSVTable().

    You are returning your own class where the method was defined.

    Yea! More precisely, it's returning the same current instance. That's what this keyword means.

    Is this something that you find in Java coding?

    Well, it's completely language agnostic. Any OOP language can return this or self in order to provide method chaining. :ar!

    Would that fall under OOP design?

    Dunno. It's just a fun pattern. Any method which would be void can instead return this. :D

    BtW, Processing's PVector class got fully chainable at version 3.
    Same for Processing's JS respin: p5.js. :P

  • edited October 2016

    Lastly, in your code at line 41, when using the StringBuilder object, don't you need to define the column's ID when implementing the object, besides the column's name?

    I don't get what you mean. Class StringBuilder belongs to Java's API and got nothing to do w/ Processing: http://docs.Oracle.com/javase/8/docs/api/java/lang/StringBuilder.html

    When you do the for loop in line 43/44, you are building "rowNumber: columnValue" pairs.

    Method toString() is just for displaying purposes. This particular example only got 1 column. So it's always index 0 for it. Then I build the StringBuilder row by row. :-B

  • "Fully chainable" is interesting concept indeed. Thxs!

    Kf

  • edited October 2016

    Of course, the once non-void methods aren't chainable. :-@
    Although any other returning object can start another type of chain. :P

Sign In or Register to comment.