0

I have a problem in retaining/keeping the values saved in a table of my GUI. My objective is to keep the values where it is stored in the table, exit my GUI, and open it again then I expect to see the same values stored in the table. My issue here is that whenever I close, and open again the GUI, it refreshes the values and makes it blank again.

I save my values by writing and reading a CSV file.

In writing the CSV file, it depends on what values the user inputs on the text fields of my GUI then it creates a CSV file on a specific location in my drive C.

In reading the CSV file, it reads the contents/values of the CSV file that was written then uses those values to store in a 2D array in order for it to be displayed into my table. But the problem is that I cannot retain those values in the table and also the table displays null values, just right next to the displayed data(I tried to do the != null but still it displays consecutive nulls just right after the inputted values)

GUI: GUI

CSV file: CSV file

Here is my source code:

public void writeCustomerCSV(){  // everything in this snippet code works fine(it creates a CSV file which stores the inputs of the user)
   try{
       BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\RALPH\\Documents\\Database Java CSV\\customers.csv"));
       StringBuilder sb = new StringBuilder();
        
       int y;
       for(int x = 0; x < itemTo2D.length; x++){
           for(y = 0; y < itemTo2D[0].length; y++){
               if(itemTo2D[x] != null){
                   sb.append(itemTo2D[x][y]);
                   sb.append(",");
               }
           }
            
           sb.append("-");  //separation for rows
           sb.append(",");  // separation for columns
            
       }
        
       bw.write(sb.toString());
       bw.close();
        
   }  catch (Exception ex){
        
     }
   
  }

public void readCustomerCSV(){  // reads the contents of the CSV file     *having issues in retaining the values
    int read2DStringIndex = 0;
    int newVarIndexer = 0;
    String[] fromfile = {};   // 1d string for getting the columns(7 columns) of the CSV file

 

    try{
         BufferedReader br = new  BufferedReader(new FileReader("C:\\Users\\RALPH\\Documents\\Database Java CSV\\customers.csv"));
         String line;
         
         while ((line = br.readLine()) != null){
             fromfile = line.split(",");  //separates the columns by a comma
         }
        
        
        
    } catch (Exception ex){
        
    }
    
    for(int g = 0; g < fromfile.length; g++){  
         if(fromfile[g].equals("-")){   //if there is a presence of a dash, it increments the read2DStringINdex (row index) of the 2D array     
             read2DStringIndex++;
              newVarIndexer = 0;

         }
         else{
             
             cust[read2DStringIndex][newVarIndexer] = fromfile[g];    //cust is the 2D array(declared universal) which is going to display the values to the table
            newVarIndexer++;
              
                   
              
              
         }
    }
    
 
       for(int h = 0; h < cust.length; h++){  //prints cust (2D array) , just to check what data is being stored
        for(int p = 0; p < cust[0].length; p++){
            System.out.println(cust[h][p] + ",");
        }
    }
     

    DefaultTableModel tblmodelll = (DefaultTableModel) mainTable.getModel();  // table

    setrowcount = 0;    
    for(int r = 0; r < cust.length; r++){
        if(setrowcount == 0){
            tblmodelll.setRowCount(0);
        }
        if(cust[r][0] != null){
            tblmodelll.addRow(cust[r]);  //displays the cust(2D array) data to table 
        }
        
      setrowcount++; 
     
      
   }
    
   

}

Am I missing something to add on my codes or is the logic of the code not right? You responses would indeed help in resolving this issue. Thank you very much!!!

Ralph Henry
  • 122
  • 1
  • 13
  • Two issues stand out - a) what if the user enters _A,B_ as a value OR _A-B_, and b) CSV are normally row by row by line so you read/write all the columns for row 0 as one line, then again for row 1, then row 2.... (note: except for values that are multi-line...) – Mr R Mar 29 '21 at 08:17
  • 1
    Perhaps a read of a previous answer to this sort of question - https://stackoverflow.com/a/14226913 - will provide some other ideas. – Mr R Mar 29 '21 at 08:20
  • You could use gson to save and load the entire thing or implement your loading logic using JsonReader and JsonWriter yourself – IntoVoid Mar 29 '21 at 08:22
  • Does the code where you modify the model do something sane with static input (i.e. don't read the file just call it with some static arrays to see it behaves correctly / split the problem into 2, checking your CSV read/write roundtrip and checking the GUI filling). – Mr R Mar 29 '21 at 08:24
  • what is the datatype of itemTo2D – IntoVoid Mar 29 '21 at 08:24
  • @MrR The CSV that is being written on my code is only one line.(Which means that the contents are being inputted/appended in only one line(one row only) where that line is separated by commas, and then dashes(the dashes represents the separation of the "rows" of the 1D array(fromfile). What my program usually does is to write the inputted values, store it on the CSV file as the 1D array values, then I managed to transfer those 1D values into a 2D array(cust) which this 2D array will serve as the array to display in the table. – Ralph Henry Mar 29 '21 at 12:04
  • 1
    @IntoVoid oh ok, I'll see what I can do with JsonReader and JsonWriter. Also the itemTo2D is a 2D String array. – Ralph Henry Mar 29 '21 at 12:06
  • @MrR Also, the code doesn't utilize with any static inputs, it more likely depends on the user inputs – Ralph Henry Mar 29 '21 at 12:08
  • @RalphHenry - can you add some sample data to the post? – Mr R Mar 29 '21 at 12:10
  • @MrR ok I added the sample data(specifically pics) – Ralph Henry Mar 29 '21 at 12:19
  • @RalphHenry ok that helped .. if you have a null, you still need to indicate there was a column value (just not set) - but the code skips the column meaning columns can't line up on reload ... - to fix move the `append(",")` outside the null protection. AND unless you are preventing the use of , or - the code will break as soon as someone use that value ... That's why XML enquotes use of `&` with `&` , etc. – Mr R Mar 29 '21 at 12:28
  • @MrR Oh, specifically I'll just the indicate there was a column value, so in which part would I indicate it? Also I'm a bit confused on the XML enquotes that you have mentioned, do I need to use the &?? – Ralph Henry Mar 29 '21 at 12:35
  • @RalphHenry sorry the XML thing was an analogy - they use particular keys that would be ambiuous used in attribute values or elemenet values - and their solution is to quote the value (use a different value to represent the original). See answer https://stackoverflow.com/a/66854364/15310387 below for fix to the write method. – Mr R Mar 29 '21 at 12:42

2 Answers2

1

You could read and write your table like this (if it is a string table. I'm using the JsonWriter and JsonReader of the Gson library here. But other JsonReader and JsonWriter should also work. I guess):

public static void write(Writer w, String[][] table) throws IOException {
    JsonWriter writer = null;
    try {
        writer = new JsonWriter(w);
        writer.setIndent("    ");
        writer.setSerializeNulls(true);

        int height = table.length;
        int width = height > 0 ? table[0].length : 0;

        writer.beginObject();
        writer.name("len");
        writer.value((long) width * (long) height);
        writer.name("sub");
        writer.value(width);

        writer.name("entries");
        writer.beginArray();

        int y, x;
        for (y = 0; y < height; y++) {
            for (x = 0; x < width; x++) {
                String entry = table[y][x];
                if (entry == null) writer.nullValue();
                else writer.value(entry);
            }
        }
        writer.endArray();

        writer.endObject();
        writer.flush();
    } finally {
        if (writer != null) writer.close();
    }
}

public static String[][] read(Reader r) throws IOException {
    JsonReader reader = null;
    long len = 0, sub = 0;
    String[][] table = null;
    try {
        reader = new JsonReader(r);

        reader.beginObject();
        read:
        do {
            while (reader.peek() != JsonToken.NAME) {
                if (!reader.hasNext()) break read;
            }

            String name = reader.nextName();
            if ("len".equals(name)) len = reader.nextLong();
            else if ("sub".equals(name)) sub = reader.nextLong();
            else if ("entries".equals(name)) {
                reader.beginArray();
                table = new String[(int) (len / sub)][(int) sub];
                long i;
                int y, x;
                String entry;
                for (i = 0L; i < len && reader.hasNext(); i++) {
                    y = (int) (i / sub); x = (int) (i % sub);
                    if (reader.peek() != JsonToken.STRING) {
                        entry = null;
                        reader.skipValue();
                    } else entry = reader.nextString();
                    table[y][x] = entry;
                }
                reader.endArray();
            }
        } while (true);
        reader.endObject();
    } finally {
        if (reader != null) reader.close();
    }
    return table;
}
IntoVoid
  • 914
  • 4
  • 7
1

The write method is broken - it produces variable length output ..

       for(int x = 0; x < itemTo2D.length; x++){
           for(y = 0; y < itemTo2D[0].length; y++){
               if(itemTo2D[x] != null){
                   sb.append(itemTo2D[x][y]);
                   sb.append(",");
               }
           }

A small change fixes that -

       for(int x = 0; x < itemTo2D.length; x++){
           for(y = 0; y < itemTo2D[0].length; y++){
               if(itemTo2D[x] != null){
                   sb.append(itemTo2D[x][y]);
               }
               sb.append(",");
           }

Additionally the readCSV has problems if for whatever reason the file has multiple lines in it -

     while ((line = br.readLine()) != null){
         fromfile = line.split(",");  //separates the columns by a com
     }

That will set fromfile over and over ..

It is probably easier to do 2 splits - one on the row separator ("-") and then for each row via (",") to get columns .. effectively it can be 2 for loops like the write...

Mr R
  • 754
  • 7
  • 19
  • Ok nice!!! Thank you very much for this!! I'll see what I can do with these adjustments and more likely give updates about its functionality. Again, thank you @MrR. – Ralph Henry Mar 29 '21 at 14:58