在线程运行时重新绘制swing组件

时间:2016-04-05 12:31:35

标签: java multithreading swing

当我按下开始按钮时,我有一个线程。我想要做的是重新绘制标签,使它们包含我的线程所做的更改的信息。我面临的唯一问题是,只有在线程完成运行后,jLabel才会重新绘制。有人可以给我任何关于如何在线程运行时重新绘制它的消息吗?感谢。

以下是我的代码片段:

Store m = new Store(); //Store extends Thread
private void startActionPerformed(java.awt.event.ActionEvent evt) {    
    ....
    //I get the simulation time of the store from a textbox
    //the thread runs for this number of seconds
    //when it is done, the store is closed(the open variable is set to false)
    ....

    m.start();

    while (m.isOpen()) {
        queue0.setText(String.valueOf(m.clientiCasai(0)));
        //here I will have more queues
        ....
        noOfClients.repaint(); //this is the label that should show the number of clients in queue 0
    }
}  

2 个答案:

答案 0 :(得分:1)

你的 startActionPerformed()方法不应该在EventDispatchThread(EDT)上运行,它是将用于所有Swing Modification操作的Thread。如果您阻止EDT,您的UI将不会重新绘制,它将冻结

您的 noOfClients.repaint()调用应该在EDT上完成,但是您的调用将新值设置为 queue0 标签应该在EDT上。

为简化起见。如果您在EDT上调用 queue0.setText(),则会为您完成重新绘制,因此您可以将其删除。

这可以通过致电:

来实现
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            queue0.setText("<text>");
        }
    });

要解决您的问题,您可以将对方法 startActionPerformed()的实例的引用传递给您的Store,并在需要时从那里调用它,或者您可以启动另一个监视Store进度的Thread并将其传播到Swing EDT。

答案 1 :(得分:1)

问题是实际的绘画也是在EDT的事件循环中完成的;你的while()循环基本上阻止了EDT的进行。 一种可能的解决方法是使用额外的线程来处理更新标签。