[英]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.