当我按下开始按钮时,我有一个线程。我想要做的是重新绘制标签,使它们包含我的线程所做的更改的信息。我面临的唯一问题是,只有在线程完成运行后,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
}
}
答案 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的进行。
一种可能的解决方法是使用额外的线程来处理更新标签。