Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程运行时重新绘制swing组件_Java_Multithreading_Swing - Fatal编程技术网

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

Java 线程运行时重新绘制swing组件,java,multithreading,swing,Java,Multithreading,Swing,我有一个线程,当我按下开始按钮时开始。我想做的是重新绘制标签,使其包含线程更改的信息。我面临的唯一问题是,只有在线程运行完成之后,jLabels才会重新绘制。有人能给我一些建议,让我在线程运行时重新绘制它吗?谢谢 以下是我的代码片段: Store m = new Store(); //Store extends Thread private void startActionPerformed(java.awt.event.ActionEvent evt) { .... /

我有一个线程,当我按下开始按钮时开始。我想做的是重新绘制标签,使其包含线程更改的信息。我面临的唯一问题是,只有在线程运行完成之后,jLabels才会重新绘制。有人能给我一些建议,让我在线程运行时重新绘制它吗?谢谢

以下是我的代码片段:

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
    }
}  
startActionPerformed()方法不应在EventDispatchThread(EDT)上运行,该线程应用于所有Swing修改操作。如果您阻止EDT,您的UI将不会重新绘制,它将冻结

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

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

这可以通过调用以下命令来实现:

    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            queue0.setText("<text>");
        }
    });
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
queue0.setText(“”);
}
});

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

问题是,实际的绘制也在EDT的事件循环期间完成;您的
while()
循环基本上阻止了EDT继续进行。
一种可能的解决方法是使用一个额外的线程来负责更新标签。

不要在EDT上运行while循环,而是让线程触发重绘事件,如果线程调用
noOfClients.setText(无论什么)
,则应该已经发生了重绘事件。不要阻止Swing线程。仅在操作方法完成后才调用重新绘制<代码>重新绘制()不执行重新绘制,但只通知swing以后必须重新绘制组件。有关更多信息,请阅读SwingUtilities.invokeAndWait()
m.start()中的setText()中的WrapstartActionPerformed
调用code>。换句话说,他在
startActionPerformed
中启动线程,因此
startActionPerformed
在EDT中运行。