如何在JAVA中使用Threads频繁更新JTable?

时间:2017-02-24 10:52:05

标签: java multithreading swing

我有一个显示来自Vector的信息的JTable。现在我必须定期更新表的最后一列。为此我采用了一个调度程序线程并在我的主程序的构造函数中实现它。代码运行正常,但表没有更新。它显示我输入的数据。 请帮忙。

我的主要计划:

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);
}

}

我尝试更新&#34;模型&#34;我每次更新时的表格。我也试过使用SwingUtilities线程。但没有,相同的输出没有改变。我认为我的矢量正在更新,但我的表格没有更新。您可以通过查看此链接获得一个清晰的想法:Christmas Tree in Jtable

我想要上面链接中显示的相同输出。请仔细阅读。经常更新的表。

  

例如,如果我从数据库中获取数据并将其存储在数据库中   JTable并说显示它。现在数据库值是否改变   然后我的桌子也应该显示那个变化   持续给用户。因此用户将知道数据的位置   变化

4 个答案:

答案 0 :(得分:3)

更改数据后,您需要通知表模型数据已更改,您可以使用数据更改事件 更新objdata1.status

tqdm.tqdm

答案 1 :(得分:3)

  

我认为我的矢量正在更新

忘掉Vector。 Vector仅用于将数据加载到TableModel的{​​{1}}。加载数据后,您可以通过JTable

访问表格的数据

请勿更新您的Vector。

而是更新TableModel

中的数据
TableModel

然后表格将自动重新绘制。

不要遍历Vector。您将再次使用:

遍历table.getModel.setValueAt(...);
TableModel

另外,请勿:

  1. 使用魔法值。人们不知道那些String是什么意思。 API将有一个可用作约束的变量。
  2. 使用add(...)方法的那种形式。阅读API,你会发现你应该使用更新的方法形式。
  3. 所以代码应该是:

    String value = table.getValueAt(...).toString();
    
    if (value.equals(...))
        // do something
    

    使用JTable时,通常会将表格添加到滚动窗格,而不是自己管理标题和表格。所以你可以使用:

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

答案 2 :(得分:2)

我很确定您的问题是GUI更改总是由AWT线程完成,而不是由任何其他创建的线程完成(并且您的代码中还有一些其他较小的陷阱)

你可以使用&#34; SwingUtilities.invokeAndWait(Runnable)&#34;强制执行GUI线程正在执行给定的Runnable并等待它的执行。或者,如果您不需要等待,您也可以使用&#34; SwingUtilities.invokeLater(Runnable)。哪一个更好取决于您的要求!

在您的示例中,它看起来像:

        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);    

答案 3 :(得分:2)

您可以插入:

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

在while块之后

[EDIT]并使用equals而不是==

测试字符串相等性