0

I have a JTable that displays information from a Vector.Now I have to update the last column of the table periodically. For this I took a scheduler-thread and implemented it in the constructor of my main program. The code runs fine but the Table is not updating.It is showing the data which I entered starting. Please help.

My Main Program:

public class JTableList extends JFrame 
{
    public static  ObjectData objdata1;
    static int i=0;
    public JTableList()
    {
       VectorList.objectDataRetrive();  //vectorList is a class that first stores data into a vector of type ObjectData class.
//objectDataRetrive just stores data into vector that is in ObjectData class
      final DefaultTableModel model = new DefaultTableModel();
      model.setColumnIdentifiers(VectorList.coloumn_name);  //adding column names

     for(int i=0;i<VectorList.size;i++)//adding row names 
     {
        objdata1 = VectorList.vect.get(i);  //VectorList returns ObjectData class object in which the data is stored already.
        model.insertRow(i, new Object[] { objdata1.id , objdata1.name,objdata1.acc_no,objdata1.exchange_name,objdata1.status });
     }

     ScheduledExecutorService execService =  Executors.newScheduledThreadPool(5);
        execService.scheduleAtFixedRate(()->{
            //only frequently change last column "status"
            while(i<VectorList.size) //loop until size of the vector.Here it is 5
            {
                objdata1 = VectorList.vect.get(i);
                if(objdata1.status == "Verified"){
                    objdata1.status = "Done";
                    i++;
                    break; 
                    }

                if(objdata1.status == "NA"){
                    objdata1.status = "Waiting";
                    i++;
                    break;
                }

                if(objdata1.status == "Pending"){
                    objdata1.status = "Verified";
                    i++;
                    break;
                }
                if(objdata1.status == "Done"){
                    objdata1.status = "Verified";
                    i++;
                    break;
                }
                if(objdata1.status == "Waiting"){
                    objdata1.status = "NA";
                    i++;
                    break;
                }


            }
            if(i==VectorList.size-1)
                i=0;


        }, 0, 3000L, TimeUnit.MILLISECONDS);    



      JTable table = new JTable(model);
      JTableHeader head = table.getTableHeader();

      Container c = getContentPane();
      c.setLayout(new BorderLayout());
      c.add("North", head);
      c.add("Center",table);



}

public static void main(String[] argv) 
{
     JTableList jtable = new JTableList();
    // JTableList.startThread();
     jtable.setSize(500,400);
     jtable.setVisible(true);
     jtable.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

I have tried updating the "model" of the table everytime I update. I tried using SwingUtilities thread also.But none, same output without changing. I think my vector is getting updated but my table is not getting updated.You can get a clear idea by seeing this link : Christmas Tree in Jtable

I want the same output that was shown in the above link. Please go through that. A table that frequently updates.

For example if I am taking data from a database and storing it in a JTable and say displaying it.Now if the database value changes continuously then my table should also DISPLAY that changes continuously to the user.So that the user will know where the data is changing.

Hema Chandra
  • 363
  • 2
  • 4
  • 16
  • Possible duplicate of [How to fill data in a JTable with database?](http://stackoverflow.com/questions/2192764/how-to-fill-data-in-a-jtable-with-database) – Catalina Island Feb 24 '17 at 11:14

4 Answers4

1

After changing the data you need to notify the table model that data changed, you can use the data changed event after updating objdata1.status

model.fireTableDataChanged();
Elgayed
  • 1,129
  • 9
  • 16
  • Even if I add the line same thing happening.No change. The ouput in the table has to be changed periodically like Stock Market graph – Hema Chandra Feb 24 '17 at 11:19
1

I think my vector is getting updated

Forget about the Vector. The Vector is only used to load data into the TableModel of the JTable. Once the data is loaded you access the data of the table via the TableModel.

Don't update your Vector.

Instead you update the data in the TableModel:

table.getModel.setValueAt(...);

The table will then repaint itself automatically.

Don't iterate through the Vector. Again you would iterate through the TableModel using:

String value = table.getValueAt(...).toString();

if (value.equals(...))
    // do something

Also, don't:

  1. use magic values. People don't know what those String mean. The API will have a variable that you can use as the constraint.
  2. use that form of the add(...) method. Read the API and you will see you should be using the newer form of the method.

So the code should be:

  //c.add("North", head);
  //c.add("Center",table);
  c.add(head, BorderLayout.PAGE_START);
  c.add(table, BorderLayout.CENTER);

When using a JTable you would typically add the table to a scrollpane instead of managing the header and table by yourself. So you can use:

//c.add(head, BorderLayout.PAGE_START);
//c.add(table, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane( table );
c.add(scrollPane, BorderLayout.CENTER)
camickr
  • 321,443
  • 19
  • 166
  • 288
0

I am quite sure your problem is that GUI Changes are always done by the AWT Thread, not by any other created Thread (and you also have a few other smaller pitfalls in your code)

You can use "SwingUtilities.invokeAndWait(Runnable)" to enforce the GUI Thread is executing a given Runnable and wait for the execution of it. Or if you doesn't need to wait you could also use "SwingUtilities.invokeLater(Runnable) instead. Which one is better depends on your requirements!

In your example it would look like:

        ScheduledExecutorService execService =  Executors.newScheduledThreadPool(5);
        execService.scheduleAtFixedRate(()->{
            //only frequently change last column "status"
            while(i<VectorList.size) //loop until size of the vector.Here it is 5
            {
                 SwingUtilities.invokeAndWait(new Runnable() {
                     @Override
                     public void run() {
                          objdata1 = VectorList.vect.get(i);
                          if(objdata1.status.equals("Verified")){
                              objdata1.status = "Done";
                              model.fireTableDataChanged();
                              i++;
                              break; 
                         }
                     }
            //...

                }
            }
            if(i==VectorList.size-1)
                i=0;
        }, 0, 3000L, TimeUnit.MILLISECONDS);    
nikmaster
  • 421
  • 1
  • 6
  • 19
0

You could insert :

final int finalI = i;
SwingUtilities.invokeLater(new Runnable() {
  public void run () {
    model.fireTableCellUpdated(finalI, 4);
  }
}

after the while block

[EDIT] and test for String equality with equals instead of ==

Laurent G
  • 397
  • 8
  • 16