4

About this question: Reading data from CSV file and displaying it in a JTable

I tried to adapt the program of this question to make it fit to my need but it is making mistakes. I want the program to display a file located in the root of my project (so I have to write File DataFile = new File("res.csv");) that's all. The problem is that it displays only 2 lines, when 4 lines are supposed to be displayed.

Here is the code :

import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.*;
import javax.swing.border.EmptyBorder;
import java.io.*;
import javax.swing.table.*;

public class T1Data extends JPanel {
    private final JTable table;

    public T1Data() {
        super(new BorderLayout(3, 3));

        this.table = new JTable(new MyModel());
        this.table.setPreferredScrollableViewportSize(new Dimension(700, 70));
        this.table.setFillsViewportHeight(true);

        JPanel ButtonOpen = new JPanel(new FlowLayout(FlowLayout.CENTER));
        add(ButtonOpen, BorderLayout.SOUTH);

        // Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        // Add the scroll pane to this panel.
        add(scrollPane, BorderLayout.CENTER);

        // add a nice border
        setBorder(new EmptyBorder(5, 5, 5, 5));

        CSVFile Rd = new CSVFile();
        MyModel NewModel = new MyModel();
        this.table.setModel(NewModel);
        File DataFile = new File("res.csv");
        ArrayList<String[]> Rs2 = Rd.ReadCSVfile(DataFile);

        NewModel.AddCSVData(Rs2);
        System.out.println("Rows: " + NewModel.getRowCount());
        System.out.println("Cols: " + NewModel.getColumnCount());

    }

    // Method for reading CSV file
    public class CSVFile {
        private ArrayList<String[]> Rs = new ArrayList<>();
        private String[] OneRow;

        public ArrayList<String[]> ReadCSVfile(File DataFile) {
            try {
                BufferedReader brd = new BufferedReader(
                        new FileReader(DataFile));

                while (brd.readLine() != null) {
                    String st = brd.readLine();
                    OneRow = st.split(",|\\s|;");
                    Rs.add(OneRow);
                    System.out.println(Arrays.toString(OneRow));
                } // end of while
            } // end of try
            catch (Exception e) {
                String errmsg = e.getMessage();
                System.out.println("File not found:" + errmsg);
            } // end of Catch
            return Rs;
        }// end of ReadFile method
    }// end of CSVFile class

    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("T1Data");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane.
        T1Data newContentPane = new T1Data();
        frame.setContentPane(newContentPane);

        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    class MyModel extends AbstractTableModel {
        private String[] columnNames = { "1", "2", "3", "4", "5", "6", "7", "8" };
        private ArrayList<String[]> Data = new ArrayList<>();

        public void AddCSVData(ArrayList<String[]> DataIn) {
            this.Data = DataIn;
            this.fireTableDataChanged();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;// length;
        }

        @Override
        public int getRowCount() {
            return Data.size();
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            return Data.get(row)[col];

        }
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Content of CSV file: with "." that seems to bother :

Valeur par défaut,07/04/2014,0.5,1,0,0,0
Valeur par défaut,07/04/2014,0.5,1,0,0,0
Valeur par défaut,07/04/2014,0.5,1,0,0,0
Valeur par défaut,07/04/2014,0.5,1,0,0,0
Valeur par défaut,07/04/2014,0.5,1,0,0,0
Community
  • 1
  • 1
user3460225
  • 69
  • 1
  • 1
  • 7

2 Answers2

3

You have done readLine twice. Once in the while condition and next inside it. You are losing the line read in the while condition.

Updated: Changed the code to the following and it gives the expected output:

package stackoverflow;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;

public class T1Data extends JPanel {
    private final JTable table;

    public T1Data() {
        super(new BorderLayout(3, 3));
        this.table = new JTable(new MyModel());
        this.table.setPreferredScrollableViewportSize(new Dimension(700, 70));
        this.table.setFillsViewportHeight(true);
        JPanel ButtonOpen = new JPanel(new FlowLayout(FlowLayout.CENTER));
        add(ButtonOpen, BorderLayout.SOUTH);
        // Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        // Add the scroll pane to this panel.
        add(scrollPane, BorderLayout.CENTER);
        // add a nice border
        setBorder(new EmptyBorder(5, 5, 5, 5));
        CSVFile Rd = new CSVFile();
        MyModel NewModel = new MyModel();
        this.table.setModel(NewModel);
        File DataFile = new File("res.csv");
        ArrayList<String[]> Rs2 = Rd.ReadCSVfile(DataFile);
        NewModel.AddCSVData(Rs2);
        System.out.println("Rows: " + NewModel.getRowCount());
        System.out.println("Cols: " + NewModel.getColumnCount());
    }

    // Method for reading CSV file
    public class CSVFile {
        private final ArrayList<String[]> Rs = new ArrayList<String[]>();
        private String[] OneRow;

        public ArrayList<String[]> ReadCSVfile(File DataFile) {
            try {
                BufferedReader brd = new BufferedReader(new FileReader(DataFile));
                while (brd.ready()) {
                    String st = brd.readLine();
                    OneRow = st.split(",|\\s|;");
                    Rs.add(OneRow);
                    System.out.println(Arrays.toString(OneRow));
                } // end of while
            } // end of try
            catch (Exception e) {
                String errmsg = e.getMessage();
                System.out.println("File not found:" + errmsg);
            } // end of Catch
            return Rs;
        }// end of ReadFile method
    }// end of CSVFile class

    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("T1Data");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Create and set up the content pane.
        T1Data newContentPane = new T1Data();
        frame.setContentPane(newContentPane);
        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    class MyModel extends AbstractTableModel {
        private final String[] columnNames = { "1", "2", "3", "4", "5", "6", "7", "8" };
        private ArrayList<String[]> Data = new ArrayList<String[]>();

        public void AddCSVData(ArrayList<String[]> DataIn) {
            this.Data = DataIn;
            this.fireTableDataChanged();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;// length;
        }

        @Override
        public int getRowCount() {
            return Data.size();
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            return Data.get(row)[col];
        }
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

Updated:

Output: enter image description here

Priyesh
  • 2,041
  • 1
  • 17
  • 25
  • I have corrected what you said but there is other errors as I said in another comment. Could you compile the code please and tell me what's wrong? – user3460225 Apr 06 '14 at 21:07
  • Even with this code it is doing the same. Displaying correctly in the system.out but blank in the JPanel. – user3460225 Apr 07 '14 at 15:04
  • I **do** see data in the JPanel when I run the code above. Screenshot attached. – Priyesh Apr 07 '14 at 15:37
  • Right, sorry I have understood the problem, it is because I have things like 1.5 (with a POINT) in some cells and it doesn't like it... If I do 1,5 obviously it read 1 and then 5 in two cells. But with the code I had before (with readLine twice) it read correctly the point. What is the problem? – user3460225 Apr 07 '14 at 16:56
  • Can you share the csv file? I can't replicate your problem. The code reads numbers with decimal points correctly. – Priyesh Apr 07 '14 at 17:06
  • How should I do to share the file? I don't know how to do that. – user3460225 Apr 07 '14 at 17:16
  • Add the content from the file to your question. – Priyesh Apr 07 '14 at 17:17
  • It is not so much interesting the content but it is added – user3460225 Apr 07 '14 at 17:21
  • And this file is generated by another java program that convert double into string (like 1.5), but what is interesting is that the first program read it but not the second one. And I see that it has to be with "." because when there is no "." it is working. – user3460225 Apr 07 '14 at 17:24
  • What is the expected output with the above input? Can you write what should go in each column of JPanel for the first row? – Priyesh Apr 08 '14 at 09:29
  • 1st column : Valeurpardéfaut (if the 3 words are together) 2nd one : 07/04/2014 3rd one : 0.5 4th : 1 5th : 0 6th : 0 7th: 0 - really if the 3 words are not together (I should get only one word really) it does 1:Valeur 2:par 3:defaut 4:07/04/2014 5:0.5 6:1 7:0 8:0 (that what I get with the first code) – user3460225 Apr 08 '14 at 09:44
  • I think that was the problem (that I had 3 words separated), I am trying when they are together and tell you if it ok. – user3460225 Apr 08 '14 at 10:14
  • You should split using st.split(",") then. The st.split(",|\\s|;") method splits the line if it encounters any of ',' ' ' or ';'. – Priyesh Apr 08 '14 at 12:06
0

Your problem is in the while loop inside the reader. You read a line, test if it is null, and since it isn't, you read and process the next line. Am I right in assuming you only see the second and fourth lines from your file? A better way to do it would be:

String st = brd.readLine();
while (st != null) {
    <do something>
    st = brd.readLine();
}

OR

while ((String st = brd.readLine()) != null) {
    <do stuff>
}

(Second variant is generally discouraged)

Also, the code above is full of malpractices (not closing resources, double model creation, inconsistent naming convention etc). I suggest you get someone to review it (or post to https://codereview.stackexchange.com/), unless you are aware of those and were just lazy to make a better example.

Community
  • 1
  • 1
Ordous
  • 3,844
  • 15
  • 25
  • No it just that I am relatively debutant and I took the code that was on the question thinking it was correctly edited. I'll do that. I understand what you mean by reading twice, thank you, I tried to correct it but for the display in the console it's OK but it is not displaying it in the `JPanel` as expected, it is generating mistakes. If i do several `brd.readLine()` before the loop it is working normally (but displaying only the last two lines). – user3460225 Apr 05 '14 at 19:23
  • So are you sating that the program prints 4 strings in system.out? Have you tried debugging it to see just what exactly it reads and passes to the table? – Ordous Apr 06 '14 at 12:07
  • Yes it prints the 4 lines of my csv in system.out. When i debugged it I cannot see anything it is displaying plenty of errors that I have seen lot of times before, and in the Jpanel appear but without anything inside. – user3460225 Apr 06 '14 at 12:57