线程完成后调用函数

时间:2017-12-03 13:12:52

标签: java multithreading sftp jprogressbar

我正在使用Jsch编写Sftp客户端程序。我正在使用JProgressBars来显示上传和下载的进度。我的GUI包含根据我的工作目录中的文件的按钮。当我删除文件时,我更新了我的gui以向用户提供反馈:

void update() {
    panel.removeAll();
    addToPanel(ls(channelsftp, sftpWorkingDir));
    validate();
}

这是使用我的ls-function返回当前workingDir中的所有文件。 addToPanel将处理lsEntries以在面板上输出Buttons。这非常适合删除文件。但是,我想在上传完成后调用相同的更新函数。由于上传以JProgressBar的形式向我提供图形反馈,因此其功能被移至线程:

final JFileChooser uploadChooser = new JFileChooser();
    ulo.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            int returnVal = uploadChooser.showOpenDialog(Navigator.this);
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                String pathToUpload = uploadChooser.getSelectedFile().getAbsolutePath();
                Runnable uploadIt = new UploadUtil(pathToUpload, chacha);
                new Thread(uploadIt).start();
            }   
        }
    });

因此,在用户点击此JFileChooser中的OK后,上传开始。这是UploadUtil:

public class UploadUtil implements Runnable{

    String paTU;
    ChannelSftp csftp;

    public UploadUtil(String pathToUl, ChannelSftp chaSftp) {
        paTU = pathToUl;
        csftp = chaSftp;
    }

    @Override
    public void run() {
        try {
            csftp.put(paTU, LoginAndFunctions.sftpWorkingDir, new SystemOutProgressMonitor());
        } catch (SftpException e) {
            Error errorUploading = new Error(e.toString()+"\nUploadpipe closed unexpectedly");
            errorUploading.setVisible(true);
        }
    }
}

SystemOutProgressMonitor是一个在Jsch中处理datatransfer的类。 我尝试使用Thread.join()和CountDownLatch。两者都阻止我的JProgressBar更新。它有不同的解决方案吗?

1 个答案:

答案 0 :(得分:1)

解决方案是使用回调方法或机制。由于这是一个Swing问题,使用SwingWorker,而不是线程中的Runnable,它为您提供两个潜在方式

  • 完成其工作后,在{Swing事件线程上的工作人员内调用done()方法。
  • 或者将一个PropertyChangeListener添加到SwingWorker,听取"状态"属性,并在新值为SwingWorker.StateValue.DONE时作出反应。

请注意,您还可以将PropertyChangeListener添加到工作线程并侦听其progress属性。在工作人员更新数据时,通过使用0到100之间的值调用setProgress(int value)来更新此属性。然后在侦听器中,使用此值更新JProgressBar。

例如(请注意,代码尚未测试,如果有错误,请对不起):

public class UploadUtil extends SwingWorker<Void, Void> {

    String paTU;
    ChannelSftp csftp;

    public UploadUtil(String pathToUl, ChannelSftp chaSftp) {
        paTU = pathToUl;
        csftp = chaSftp;
    }

    @Override
    public void doInBackground() throws Exception {
        try {
            csftp.put(paTU, LoginAndFunctions.sftpWorkingDir, new SystemOutProgressMonitor());
        } catch (SftpException e) {
            Error errorUploading = new Error(e.toString()+"\nUploadpipe closed unexpectedly");
            errorUploading.setVisible(true);
        }
    }
}

你的工人的倾听者:

class UploadUtilListener implements PropertyChangeListener {
    public void propertyChanged(PropertyChangeEvent e) {
        if (e.getNewValue() == SwingWorker.StateValue.DONE) {
            // do your code here that you want called when worker done
        }
    }
}

然后使用它:

public void actionPerformed(ActionEvent arg0) {
    int returnVal = uploadChooser.showOpenDialog(Navigator.this);
    if(returnVal == JFileChooser.APPROVE_OPTION) {
        String pathToUpload = uploadChooser.getSelectedFile().getAbsolutePath();
        UploadUtil uploadIt = new UploadUtil(pathToUpload, chacha);
        uploadIt.addPropertyChangeListener(new UploadUtilListener());
        uploadIt.execute();
    }   
}