簡體   English   中英

當GUI不更新信息時,通過SWING和多線程處理GUI

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM