线程完成后调用函数

Call a function after a Thread is completed

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

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

这是使用我的 ls 函数 return 当前 workingDir 中的所有文件。 addToPanel 将处理 lsEntries 以在面板上输出按钮。这非常适合删除文件。但是,我希望在上传完成后调用相同的更新功能。由于上传以 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 中的“确定”后,上传开始。这是 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 是一个 class 在 Jsch 中处理数据传输。 我尝试使用 Thread.join() 和 CountDownLatch。两者都阻止了我的 JProgressBar 更新。是否有不同的解决方案?

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

  • done() 方法在 Swing 事件线程 的工作线程中调用 方法。
  • 或者给SwingWorker增加一个PropertyChangeListener,监听"state"属性,当新值SwingWorker.StateValue.DONE时做出反应。

请注意,您还可以将 PropertyChangeListener 添加到工作线程并监听其进度 属性。在 worker 中更新您的数据时,通过调用 setProgress(int value) 并使用 0 到 100 之间的值来更新此 属性。然后在侦听器中,使用此值更新您的 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();
    }   
}