繁体   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