[英]Handling GUI with SWING with multithreading when the GUI does not update informations
因此,我有一个桌面应用程序使用了本教程 (但略作修改)启发的MVC模式设计。 该应用程序需要做的是将文件列表从目录复制到另一个目录。 我想做的基本上是在复制每个文件之后更新我的GUI。
首先,让我向您展示代码。 在我的模型中,我有这个伪方法(不是真正的方法,但是背后的逻辑是相同的):
public void dummyMethod(Integer k) throws InterruptedException{
for(int i=0;i<10;i++){
System.out.println(i);
Thread.sleep(1000);
this.firePropertyChange(DefaultController.BACKUP_DUMMY, i-1, i);
}
}
在我看来,我有:
@Override
public void modelPropertyChange(PropertyChangeEvent evt) {
// .......
else if( evt.getPropertyName().equals( DefaultController.BACKUP_DUMMY ) ){
System.out.println("WHAT?");
this.dummy.setText(evt.getNewValue().toString());
}
}
正如您所能想象的那样? 每次打印都会被打印,但是直到循环完成才更新GUI。 当您使用SWING及其EDT时,这是经典的问题,我已经在oracle网站上阅读了本文/教程,但我认为我不需要使用SwingWorker。 我只需要在GUI上更新单个组件即可。
但是GUI直到循环完成才更新。
这表明您的所有代码都在EDT上运行,因此,在整个循环完成之前,GUI无法重绘自身。
但我认为我不需要使用SwingWorker。
为什么不呢,那可能是最简单的解决方案。 您的主循环在单独的线程上运行,然后在处理每个文件时“发布”结果。
或使用Gursel建议的方法。 长时间运行的代码在单独的线程中执行,并且仅在EDT上触发属性更改事件,这意味着GUI可以在EDT上重新绘制自身。
不要将事件分发线程用于长时间运行的操作。 您应该启动另一个线程以进行长期运行,例如文件复制。 如果需要从辅助线程更新gui,则应使用SwingUtilities.invokeLater或SwingUtilities.invokeAndWait方法。
举个例子 ;
final JLabel label = new JLabel();
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actioPerformed(ActionEvent ev) {
Thread workerThread = new Thread() {
public void run() {
//do long running job then update ui
SwingUtilities.invokeLater(new Runnable() {
public void run(){
label.setText("Operation has finished");
}
});
}
}.start();
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.