JSON save/load

edited June 2018 in Questions about Code

hello! im trying to write a kind of user interface to manage JSON files. What i want is user can store data in JSON files. when mousePressed save a new JSON FILE. here`s my code with a null pointer exception:

 JSONObject json;
File saving;
File loading;

void setup() {
  json = new JSONObject();

}

void draw(){

}

void mousePressed() {
  selectInput("Select a file to process:", "fileSelected");
  saveJSONObject(json, saving.getAbsolutePath());
}




void fileSelected(File selection) {
  saving = selection;
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
  } else { 
    println("User selected " + selection.getAbsolutePath());
  }
}

Answers

  • Which line Shows error?

  • Ah 16

    In draw loop until saving is != null

    Only then we can save

    The command fileSelected doesn’t stop/ pause for the user hence 16 is reached immediately without saving is set.

    It’s a little confusing. But it’s a 2nd thread that does the file dialogue while the sketch runs on and on

  • void mousePressed() {
      selectOutput("Select a file to process:", "fileSelected");
      if(saving  != null)  saveJSONObject(json, saving.getAbsolutePath());
    }
    

    it works, but i need to click twice (one for choose the place, and one for save the file) why that?

  • This belongs into draw()

    if(saving != null)

    saveJSONObject(json, saving.getAbsolutePath());

  • Hmmm actually it belongs to the callback function if mousePressed() is the trigger to save the data:

    void fileSelected(File selection) {
      saving = selection;
      if (selection == null) {
        println("Window was closed or the user hit cancel.");
      } else { 
        println("User selected " + selection.getAbsolutePath());
    
        ... LOAD/prepare/verify your json data here
    
        saveJSONObject(json, saving.getAbsolutePath());
      }
    }
    

    Kf

  • Good idea

    There is also a new forum

  • full new version with load and save:

    see comments below:

    Chrisir ;-)

    // Escape is de-activated. 
    // using selectInput and selectOutput here. 
    // using also setting path dataPath() and file ending "json".
    // fileNameForScreen shows the current file name throughout.
    // Uses a JSONArray within a JSONObject.
    
    JSONObject json;   // WITHIN this object is an array named animals, see json.setJSONArray("animals", values);
    
    // fileNameForScreen shows the current file name throughout
    String fileNameForScreen = "Not a file";
    
    void setup() {
      size(660, 660);
      background(110);
    
      json = new JSONObject();
    
      // TWO possible test arrays 
      String[] species = { "Capra hircus", "Panthera pardus", "Equus zebra" };
      String[] names   = { "Goat", "Leopard", "Zebra" };
      // String[] species = { "Cw", "Pp", "Ez" };
      // String[] names   = { "G", "Leo", "Z" };
      //
    
      // build values (JSONArray) 
      JSONArray values = new JSONArray();
    
      for (int i = 0; i < species.length; i++) {
    
        JSONObject animal = new JSONObject();
    
        animal.setInt("id", i);
        animal.setString("species", species[i]);
        animal.setString("name", names[i]);
    
        values.setJSONObject(i, animal);
      }//for 
    
      // add values (JSONArray) to json 
      // comment this out to generate an error 
      json.setJSONArray("animals", values);
    
      // generate another error for testing outputJSONArray:
      //json = null;
    }
    
    void draw() {
      background(110);
    
      // show Menu
      noFill();
      stroke(0); 
      rect(width-49, 27, 
        45, 80-27);
      fill(0); 
      text("Load\n\n" + "Save", 
        width-44, 44);
    
      // show file name 
      fill(255); // white 
      text(fileNameForScreen, 
        min(width-44, width - textWidth(fileNameForScreen) - 11), 15);
    
      // show array 
      outputJSONArray(json, "animals");
    }
    
    // --------------------------------------------------------------------------
    
    void keyPressed() {
      // De-activate Escape key 
      if (key==ESC) {
        key=0; // kill Escape
      }
    }
    
    void mousePressed() {
      // println (mouseY);
      // right screen border?
      if (mouseX>width-50) {
        checkMouseOnMenu();
      }
    }
    
    void checkMouseOnMenu() {
    
      // using selectInput and selectOutput here. 
      // also setting path and file ending json. 
    
      if (mouseY>20&&mouseY<47) { 
        //Load
        String fileString = dataPath("") + "\\" +"*.json" ;
        println(fileString);
        File toLoad = new File( fileString ) ;
        selectInput("Load a file:", "fileSelectedForLoad", toLoad);
      } else if (mouseY>48&&mouseY<77) {
        //Save
        String fileString = dataPath("") + "\\*.json" ;
        println(fileString);
        File toSave = new File( fileString ) ;
        selectOutput("Save to a file:", "fileSelectedForSave", toSave);
      } else {
        // ignore
      }
    }
    
    // ---------------------------------------------------------------------------------
    
    void fileSelectedForLoad(File selection) {
      File loading;
      loading = selection;
      if (selection == null) {
        println("Window was closed or the user hit cancel.");
      } else { 
        println("User loaded " + selection.getAbsolutePath());
        if (loading  != null) { 
          json =  loadJSONObject(loading.getAbsolutePath());
          fileNameForScreen=loading.getName();//https://docs.oracle.com/javase/7/docs/api/java/io/File.html
        }
      }//else 
      //
    }
    
    void fileSelectedForSave(File selection) {
      File saving;
      saving = selection;
      if (selection == null) {
        println("Window was closed or the user hit cancel.");
      } else {
        String saveString = saving.getAbsolutePath();
        saveString=saveString.trim();
        // ending json ok? 
        if (saveString.indexOf(".json") < 0) {
          saveString+=".json"; // very rough approach...
          saving = new File(saveString);
        }
        println("User saved to " + selection.getAbsolutePath());
        if (saving != null) { 
          saveJSONObject(json, saving.getAbsolutePath());
          fileNameForScreen=saving.getName();//https://docs.oracle.com/javase/7/docs/api/java/io/File.html
        }
      }//else 
      //
    }
    
    // ---------------------------------------------------------------------------------
    
    void outputJSONArray(JSONObject json, String nameOfJSONArray) {
    
      // output of an JSONArray named "nameOfJSONArray" in an an JSONObject json.
      // The function is not generic since column names "species" etc. must be correct as below. 
    
      // error check I. 
      if (json==null) { 
        fill(255, 33, 0); // red 
        text( "No json object", 30, 30+2);
        return;
      }//if 
    
      JSONArray valuesLoaded =  json.getJSONArray(nameOfJSONArray);
    
      // error check II. 
      if (valuesLoaded==null) { 
        String error = "No json array named "
          + nameOfJSONArray
          + " in json object.";
        fill(255, 33, 0); // red       
        text(error, 30, 30+2);
        return;
      }//if
    
      fill(40, 255, 17); // black 
    
      for (int i = 0; i < valuesLoaded.size(); i++) {
    
        JSONObject animal = valuesLoaded.getJSONObject(i); 
    
        int id = animal.getInt("id");
        String species = animal.getString("species");
        String name = animal.getString("name");
    
        // println(id + ", " + species + ", " + name);
        text(id + ", " + species + ", " + name, 40, 50+35*i); // small table
      }//for 
      //
    }//func 
    // 
    
  • edited June 2018

    If we got the keys & values as separate arrays, we can create a StringDict passing both arrays as its arguments; and then create our JSONObject passing that StringDict as its argument. Much shorter & cleaner! \m/

    String[] species = { "Capra hircus", "Panthera pardus", "Equus zebra" };
    String[] names   = { "Goat", "Leopard", "Zebra" };
    
    StringDict animals = new StringDict(species, names);
    
    JSONObject jsonObj = new JSONObject(animals);
    println(jsonObj);
    
    exit();
    

    {
      "Capra hircus": "Goat",
      "Equus zebra": "Zebra",
      "Panthera pardus": "Leopard"
    }
    
  • edited June 2018

    thanks guys. im understanding a little bit better all of json world. now my problem is how to store the type of an Object for later restore this data. I`ve a system with an array. using polymorphism two Obj(sphere, can) extends main Obj. How can indicate what type of object are in JSON to later restore?

      void setData() {
        JSONObject system = new JSONObject();
        JSONArray o = new JSONArray();
        for (int i = 0; i < s.o.size(); i++) {
          Obj obj = s.o.get(i);
          JSONObject objeto = new JSONObject();
          objeto.setFloat("posX", obj.x);
          objeto.setFloat("posY", obj.y);
          objeto.setFloat("posZ", obj.z);
          o.setJSONObject(i, objeto);
        }
        system.setJSONArray("Objetos", o);
        json.setJSONObject("system", system);
      }
    
      void loadData(String path) {
        json = loadJSONObject(path);
        JSONObject system = json.getJSONObject("system");
        JSONArray Objetos = system.getJSONArray("Objetos");
        for (int i = 0; i < Objetos.size(); i++) {
          JSONObject objeto = Objetos.getJSONObject(i);
          float x = objeto.getFloat("posX");
          float y = objeto.getFloat("posY");
          float z = objeto.getFloat("posZ");
    
          s.o.add(new Obj_Sphere(x, y, z));
          //s.o.add(new Obj_Can(x, y, z));
        }
      }
    
    
    class System {
    
      ArrayList<Obj>o;
    
      System() {
        o = new ArrayList<Obj>();
      }
    
      void addObj(int choice) {
    
        if (choice == 0) o.add(new Obj_Sphere(random(-width/2, width/2), random(-height/2, height/2), 0));
        if (choice == 1) o.add(new Obj_Can(random(-width/2, width/2), random(-height/2, height/2), 0));
    
        println(o.getClass());
      }
    
      void update() {
        for (Obj obj : o) {
          obj.display();
        }
      }
    }
    
  • edited June 2018

    Just invent a further field like xPos , name it typeOfObject and store "can" or "sphere" in it

  •      String type1= objeto.getString("typeOfObject");
    
         if(type1.equals("sphere"))
            s.o.add(new Obj_Sphere(x, y, z));
         else if (type1.equals("can"))
            s.o.add(new Obj_Can(x, y, z));
         else
            println ("unknown type: "+type1);
    
Sign In or Register to comment.