0

I'm working on JTable that reads text from a .txt file. the txt file gets updated dynamically after 3 sec. Now when I run the application, everything is good except that the output of .txt files comes in JTable from the second line. The first line of txt file doesn't appear on my JTable. Can anyone help? Here's the code:

public class InterfaceFrame extends JFrame implements ActionListener{

public static void main(String[] args) throws
URISyntaxException,
IOException,
InterruptedException {
    panel.setSize(100,100);
      panel.add(table);
      model.fireTableStructureChanged();

        table.setModel(model);
        InsertFileToJtable model = new InsertFileToJtable();
      table.setPreferredScrollableViewportSize(new Dimension(500, 70));
      table.setFillsViewportHeight(true);

      RowSorter<TableModel> sorter =
              new TableRowSorter<TableModel>(model);
            table.setRowSorter(sorter);

        JScrollPane scrollpane = new JScrollPane(table);
        panel.add(scrollpane, BorderLayout.CENTER);

        JButton button = new JButton("Show View");
        panel.add( button, BorderLayout.SOUTH );


        tabbedPane.addTab("Process",null,scrollpane,"");
}

I might be doin something wrong in making the text file. Here's the code which generated the .txt file.:

import java.io.*;
import java.util.StringTokenizer;


public class GetProcessList
{

 private String GetProcessListData()
 {
 Process p;
 Runtime runTime;
 String process = null;
 try {
 System.out.println("Processes Reading is started...");

 //Get Runtime environment of System
 runTime = Runtime.getRuntime();

 //Execute command thru Runtime
 p=runTime.exec("ps -e");              //For Linux

 //Create Inputstream for Read Processes
 InputStream inputStream = p.getInputStream();
 InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
 BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

 //Read the processes from sysrtem and add & as delimeter for tokenize the output
 String line = bufferedReader.readLine();
 process = "&";
 while (line != null) {
 line = bufferedReader.readLine();
 process += line + "&";
 }

 //Close the Streams
 bufferedReader.close();
 inputStreamReader.close();
 inputStream.close();

 System.out.println("Processes are read.");
 } catch (IOException e) {
 System.out.println("Exception arise during the read Processes");
 e.printStackTrace();
}
    return process;
 }

 void showProcessData()
 {
 try {

 //Call the method For Read the process
 String proc = GetProcessListData();

 //Create Streams for write processes
 //Given the filepath which you need.Its store the file at where your java file.
 OutputStreamWriter outputStreamWriter =
 new OutputStreamWriter(new FileOutputStream("ProcessList.txt"));
 BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);

 //Tokenize the output for write the processes
 StringTokenizer st = new StringTokenizer(proc, "&");

 while (st.hasMoreTokens()) {
 bufferedWriter.write(st.nextToken());  //Write the data in file
 bufferedWriter.newLine();               //Allocate new line for next line
 }

 //Close the outputStreams
 bufferedWriter.close();
 outputStreamWriter.close();

 } catch (IOException ioe) {
 ioe.printStackTrace();
 }

 }
}

Heres the code that reads ProcessList.txt and gives output into JTable:

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

public class InsertFileToJtable extends AbstractTableModel{
Vector data;
Vector columns;
private String[] colNames = {"<html><b>PID</b></html>","<html><b>TTY</b</html>",<html>  <b>time</b></html>","<html><b>Process Name</b></html>",};


public InsertFileToJtable() {
String line;
data = new Vector();
columns = new Vector();
  try {
        FileInputStream fis = new FileInputStream("ProcessList.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
        StringTokenizer st1 = new StringTokenizer(br.readLine(), " ");
        while (st1.hasMoreTokens())
                columns.addElement(st1.nextToken());
        while ((line = br.readLine()) != null) {
                StringTokenizer st2 = new StringTokenizer(line, " ");
                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 columns.size();
}

public Object getValueAt(int rowIndex, int columnIndex) {
return (String) data.elementAt((rowIndex * getColumnCount())
                + columnIndex);
}
@Override
public String getColumnName(int column) {
return colNames[column];
}
@Override
public Class getColumnClass(int col){
return getValueAt(0,col).getClass();
}
}   
Ingila Ejaz
  • 399
  • 7
  • 25
  • 2
    uuuups, no issue on my side, post an [SSCCE](http://sscce.org/), short, runnable, compilable, with short hardcoded value from txtFile, otherwise everything here will be only shorts to the dark – mKorbel Nov 30 '12 at 11:07
  • 1
    By _first line_, do you mean the table's _header_? – trashgod Nov 30 '12 at 12:19
  • @trashgod right, sure, the correct question – mKorbel Nov 30 '12 at 12:42
  • @trashgod No no, What I mean is for example the test file is 123 4 Jan 2012 Alex 345 5 Jan 2012 Jack In this case only 345 5 Jan 2012 Jack gets printed inside Jtable, not the first line :( – Ingila Ejaz Nov 30 '12 at 13:13
  • @mKorbel See the answer to your question above :( – Ingila Ejaz Nov 30 '12 at 13:16
  • 2
    @IngilaEjaz: Sorry, I can't parse your comment. As mKorbel has requested, please edit your question to include an [sscce](http://sscce.org/) that shows the text file and how you read it. Use the `
    ` tag to preserve the text file's format.
    – trashgod Nov 30 '12 at 14:04
  • @trashgod I've made some changes to the question too :( – Ingila Ejaz Dec 01 '12 at 14:09

1 Answers1

2

I'd do this a little differently, avoiding an intermediate text file. Instead,

  • Use ProcessBuilder, which "can be invoked repeatedly from the same instance." You can read the output as shown here and parse it into a suitable data structure, e.g. List<List<String>>.

    ProcessBuilder pb = new ProcessBuilder("ps -ef");
    
  • Start a javax.swing.Timer having a three second period; invoke pb.start() in the timer's listener.

  • When parsing concludes, fireTableDataChanged() in your AbstractTableModel, shown here.

Presto, your table updates with the latest result every three seconds.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 2
    Examples using `List>` may be found [here](http://stackoverflow.com/a/2951908/230513) and [here](http://stackoverflow.com/a/6849654/230513). – trashgod Dec 01 '12 at 14:56