线程完成后调用函数
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();
}
}
我正在使用 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();
}
}