如何从线程更新 Java GUI?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13543345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to update java GUI from Thread?
提问by Alyafey
private void StartActionPerformed(java.awt.event.ActionEvent evt) {
Queue queue=new Queue();
int target=Integer.parseInt(Target.getText());
String path=Path.getText();
final Producer p=new Producer(queue, target);
Consumer c=new Consumer(queue);
p.start();
c.start();
while(p.finish !=true)
{
Runnable r = new Runnable() {
public void run() {
ProgressPrecent.setValue(Producer.ProgressPercent);
}
};
if(EventQueue.isDispatchThread()) {
r.run();
}
else {
EventQueue.invokeLater(r);
}
}
}
I have two classes that have a shared Queue. one of them is Producer that produces till a target other one consume those elements. all of two extends Thread. I want to display the progress percent to the user, but it freeze my GUI so what should I do?
我有两个具有共享队列的类。其中之一是生产者,直到另一个目标消耗这些元素。两个都扩展了线程。我想向用户显示进度百分比,但它冻结了我的 GUI,我该怎么办?
回答by morja
I think you will have to put the whole while loop into a thread. Otherwise the loop will block your ActionEvent and thus freezes the UI.
我认为您必须将整个 while 循环放入一个线程中。否则循环将阻止您的 ActionEvent 并因此冻结 UI。
Something like:
就像是:
new Thread(){
public void run(){
while(!p.finish){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
ProgressPrecent.setValue(Producer.ProgressPercent);
}
});
try{
Thread.sleep(100);
}catch(...){}
}
}
}.start();
回答by mKorbel
Worker Threads
by default never to invokedEventDispatchThread
, you have issue withConcurency in Swing
all updates to Swing GUI must be done on EDT
Runnable
could be proper way butProgressPrecent.setValue(Producer.ProgressPercent);
must be wrapped ininvokeLater
Worker Threads
默认情况下从不调用EventDispatchThread
,您有问题Concurency in Swing
Swing GUI 的所有更新都必须在 EDT 上完成
Runnable
可能是正确的方式,但ProgressPrecent.setValue(Producer.ProgressPercent);
必须包裹在invokeLater
code
代码
SwingUtilities.invokeLater(new Runnable(){
public void run(){
ProgressPrecent.setValue(Producer.ProgressPercent);
}
});
- remove testing for EDT,
- 删除 EDT 测试,
code lines
代码行
if(EventQueue.isDispatchThread()) {
r.run();
}
Workers Thread
by defaut never ever to invoke EDT, then doesn't matter if is started from EDT, nor tested for isDispatchThread()
doesn't make me some sence
Workers Thread
默认情况下永远不会调用 EDT,那么是否从 EDT 启动也没有关系,也没有经过测试对isDispatchThread()
我没有意义
never ever, don't to use
Thread.sleep(int
) insideSwing Listeners
, because caused freeze Swing GUI tooI think you can to use SwingWorker for this jobtoo
永远不要
Thread.sleep(int
在里面使用)Swing Listeners
,因为也会导致 Swing GUI 冻结我想你可以使用的SwingWorker这个工作太