【问题标题】:How to update JTable frequently using Threads in JAVA?如何在 JAVA 中使用线程频繁更新 JTable?
【发布时间】:2017-02-25 00:21:23
【问题描述】:

我有一个显示来自 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);
}

}

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

我想要上面链接中显示的相同输出。请通过那个。一个经常更新的表。

例如,如果我从数据库中获取数据并将其存储在 JTable 并说显示它。现在如果数据库值发生变化 连续然后我的桌子也应该显示变化 不断给用户。这样用户就会知道数据在哪里 变化。

【问题讨论】:

标签: java multithreading swing


【解决方案1】:

我认为我的矢量正在更新

忘记向量。 Vector仅用于将数据加载到JTableTableModel中。加载数据后,您可以通过TableModel 访问表中的数据。

不要更新你的向量。

而是更新TableModel中的数据:

table.getModel.setValueAt(...);

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

不要遍历向量。您将再次使用以下方法遍历 TableModel

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

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

另外,不要:

  1. 使用魔法值。人们不知道那些字符串是什么意思。 API 将包含一个变量,您可以将其用作约束。
  2. 使用这种形式的 add(...) 方法。阅读 API,您会发现您应该使用更新形式的方法。

所以代码应该是:

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

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

//c.add(head, BorderLayout.PAGE_START);
//c.add(table, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane( table );
c.add(scrollPane, BorderLayout.CENTER)

【讨论】:

    【解决方案2】:

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

    model.fireTableDataChanged();
    

    【讨论】:

    • 即使我添加了同样的事情发生。没有变化。表中的输出必须像股市图表一样定期更改
    【解决方案3】:

    你可以插入:

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

    while 块之后

    [EDIT] 并用 equals 而不是 == 测试字符串相等性

    【讨论】:

    • 兄弟也一样。输出没有任何变化。它需要像机场的航班状态板一样进行更改。
    • 哼,你有没有试过用 '.equals()' 替换你的测试?
    【解决方案4】:

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

    您可以使用“SwingUtilities.invokeAndWait(Runnable)”来强制 GUI 线程正在执行给定的 Runnable 并等待它的执行。或者,如果您不需要等待,您也可以使用 "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);    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多