Search code examples
javaswingfile-iojtableabstracttablemodel

How to display empty column when load txt to JTable?


I need to load .txt to JTable with delimiter, I found a good sample here

This is the sample data :

 102|Beth Reiser||New York|(212)5558725
 111|Dylan Ricci||Syracuse|(315)5554486
 116|Brian Gugliuzza||Mamaroneck|(914)5553817
 120|Gertrude Stein||Elmsford|(914)5553476
 131|Daljit Sinnot||Bohemia|(516)5559811

This is my modified code :

package Model;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;

public class DataFileTableModel extends AbstractTableModel {

    protected Vector data;
    protected Vector columnNames ;
    protected String datafile;

    public DataFileTableModel(String f, String delimiter){
        datafile = f;
        initVectors(delimiter);
    }

    public void initVectors(String delimiter) {

        String aLine ;
        data = new Vector();
        columnNames = new Vector();
        int lineNum=0;

        try {
            FileInputStream fin =  new FileInputStream(datafile);
            BufferedReader br = new BufferedReader(new InputStreamReader(fin));
            // extract column names
            StringTokenizer st1 =
                    new StringTokenizer(br.readLine(), delimiter);
            while(st1.hasMoreTokens())
                columnNames.addElement(st1.nextToken());
            // extract data
            while ((aLine = br.readLine()) != null && lineNum<20) {
                StringTokenizer st2 =
                        new StringTokenizer(aLine, delimiter);
                lineNum++;
                while(st2.hasMoreTokens())
                    data.addElement(st2.nextToken());
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int getRowCount() {
        return data.size() / getColumnCount();
    }

    public int getColumnCount(){
        return columnNames.size();
    }

    public String getColumnName(int columnIndex) {
        String colName = "";

        if (columnIndex <= getColumnCount())
            colName = (String)columnNames.elementAt(columnIndex);

        return colName;
    }

    public Class getColumnClass(int columnIndex){
        return String.class;
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return (String)data.elementAt( (rowIndex * getColumnCount()) + columnIndex);
    }

    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        return;
    }
}

According to data, it will display 5 column, but it just display 4 column, column 3 were skipped because of empty. I want to display all column to JTable, how could I achieve this? According to @hovercraft-full-of-eels it's successfully display when the empty column is in the middle of the table, but it cannot handle the empty column in the back side. How to get this?

Data sample for empty column in the back side:

102|Beth Reiser||New York|(212)5558725||||
111|Dylan Ricci||Syracuse|(315)5554486||||
116|Brian Gugliuzza||Mamaroneck|(914)5553817||||

Solution

  • It's all due to your using a StringTokenizer: Your tokenizer is skipping the empty column pure and simple. First you should simplify your problem -- test the StringTokenizer's parsing of the text file without any Swing code, and then try to fix it before adding any Swing code or making your JTable.

    Check out the results of testing your data using a StringTokenizer vs. splitting on \\|:

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class DataFileFoo {
       private static final String DATA_FILE_PATH = "datafile.txt";
       private static final String DELIMITER = "|";
       private static final String SPLIT_REGEX = "\\|";
    
       public static void main(String[] args) {
          System.out.println("usingStringTokenizer()");
          usingStringTokenizer();
    
          System.out.println();
          System.out.println("usingStringSplit();");
          usingStringSplit();
       }
    
       public static void usingStringTokenizer() {
          File datafile = new File(DATA_FILE_PATH);
          try {
             FileInputStream fin = new FileInputStream(datafile);
             BufferedReader br = new BufferedReader(new InputStreamReader(fin));
             // extract column names
             String aLine = "";
             while ((aLine = br.readLine()) != null) {
                StringTokenizer st2 = new StringTokenizer(aLine, DELIMITER);
                while (st2.hasMoreTokens()) {
                   System.out.print(st2.nextToken() + ", ");
                }
                System.out.println();
    
             }
             br.close();
          } catch (Exception e) {
             e.printStackTrace();
          }
       }
    
       public static void usingStringSplit() {
          File datafile = new File(DATA_FILE_PATH);
          try {
             FileInputStream fin = new FileInputStream(datafile);
             BufferedReader br = new BufferedReader(new InputStreamReader(fin));
             // extract column names
             String aLine = "";
             while ((aLine = br.readLine()) != null) {
                String[] tokens = aLine.split(SPLIT_REGEX);
                for (String token : tokens) {
                   System.out.print(token + ", ");
                }
                System.out.println();
    
             }
             br.close();
          } catch (Exception e) {
             e.printStackTrace();
          }
       }
    }
    

    Using your data file,

     102|Beth Reiser||New York|(212)5558725
     111|Dylan Ricci||Syracuse|(315)5554486
     116|Brian Gugliuzza||Mamaroneck|(914)5553817
     120|Gertrude Stein||Elmsford|(914)5553476
     131|Daljit Sinnot||Bohemia|(516)5559811
    

    This returns:

    usingStringTokenizer()
     102, Beth Reiser, New York, (212)5558725, 
     111, Dylan Ricci, Syracuse, (315)5554486, 
     116, Brian Gugliuzza, Mamaroneck, (914)5553817, 
     120, Gertrude Stein, Elmsford, (914)5553476, 
     131, Daljit Sinnot, Bohemia, (516)5559811, 
    
    usingStringSplit();
     102, Beth Reiser, , New York, (212)5558725, 
     111, Dylan Ricci, , Syracuse, (315)5554486, 
     116, Brian Gugliuzza, , Mamaroneck, (914)5553817, 
     120, Gertrude Stein, , Elmsford, (914)5553476, 
     131, Daljit Sinnot, , Bohemia, (516)5559811,