2

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||||
Community
  • 1
  • 1
Fahmi Ramadhan
  • 287
  • 2
  • 4
  • 11

2 Answers2

3

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, 
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Since you post a comment, I try to implement `String#split()` but my bad.. I got stuck in split value, I just use `"|"` without `"\\|"`. Now it's solved, thanks Mr. Hovercraft. – Fahmi Ramadhan Aug 10 '12 at 03:49
  • if the null value is on the back, how to get it? when I try to read data like this `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|||| ` Using split, it display until 5th column – Fahmi Ramadhan Aug 10 '12 at 06:26
  • try use `split(String regex,int limit)` http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String, int)? – Ghost_000_cs Aug 10 '12 at 08:19
  • +1 for advice to dig to the core of the problem (and actually doing it :-) Though surprised that the tokenizer can't handle it .. should it? – kleopatra Aug 10 '12 at 08:23
  • @Ghost_000_cs if the number of column dinamically change, how could I get the `limit` value? – Fahmi Ramadhan Aug 10 '12 at 08:46
  • @FahmiRamadhan maybe you can edit your question to show us how you want to dynamically change the number of column? since you are using JTable, I am guessing the column should be fixed, isn't it? Or you can try to set a variable and do some checkings (or get the JTable column size) to determine what should be the `limit` value? – Ghost_000_cs Aug 10 '12 at 08:54
  • Thx @Ghost_000_cs , I've edited my question. In the real case I want to load .txt to MySQL, but I want to let the user view what is the content of the txt through JTable, but I got stuck in this :) – Fahmi Ramadhan Aug 10 '12 at 16:15
  • @FahmiRamadhan have you tried using `getColumnCount()` to set the `limit`? – Ghost_000_cs Aug 11 '12 at 02:54
  • @Ghost_000_cs number of column in `JTable` is determined by .txt so I can't set the limit for reading .txt from `getColumnCount()` – Fahmi Ramadhan Aug 11 '12 at 03:08
  • @FahmiRamadhan what i will do is either set the `limit` when reading .txt and set the `JTable` column number, or have first line of the text file indicating how many column it will have for the data. I think there should be a workaround for your problem, all you have to do is trial and error. – Ghost_000_cs Aug 12 '12 at 02:51
  • @Ghost_000_cs finally I found it, I managed it by reading every `char` from the first line, if `char=='|'` then it add counter to limit number. thx for all reply – Fahmi Ramadhan Aug 13 '12 at 01:47
-1

The size of your column may be 0px. To see your column, why not writing a space character ' ' in your column ?

air-dex
  • 4,130
  • 2
  • 25
  • 25
  • yeah when I change the sample data, it works. But it's quite impossible if user must change the data first before load. Anyway thx for the reply – Fahmi Ramadhan Aug 10 '12 at 03:10
  • 1
    the minimum size for Column is 10 in pixels – mKorbel Aug 10 '12 at 08:07
  • might be, but isn't in a default setup: if it exists, it will show up the same width as all others. Hacks like writing dummy data just because one can't find the real issue is ... evil ;-) – kleopatra Aug 10 '12 at 08:21