我正在使用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更新。它有不同的解决方案吗?
答案 0 :(得分:1)
解决方案是使用回调方法或机制。由于这是一个Swing问题,使用SwingWorker,而不是线程中的Runnable,它为您提供两个潜在方式
done()
方法。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();
}
}