我从ftp下载文件
现在需要显示进度条 由于是一个线程 进度条每次都没有同步显示 直接白板 现在需要多线程实现 求教
就是因为进度条在等待 等文件全部现在完后 才显示最后一条信息的进度。。 应该是每下载一个文件就需要该进度条更新一次
因为ftp上有很多文件 每次遍历文件的时候才下载 不可能每次都new一个新的线程 求教如何做到在一个for循环内一边下载 一边更新进度条显示进度 求高手指教
现在需要显示进度条 由于是一个线程 进度条每次都没有同步显示 直接白板 现在需要多线程实现 求教
就是因为进度条在等待 等文件全部现在完后 才显示最后一条信息的进度。。 应该是每下载一个文件就需要该进度条更新一次
因为ftp上有很多文件 每次遍历文件的时候才下载 不可能每次都new一个新的线程 求教如何做到在一个for循环内一边下载 一边更新进度条显示进度 求高手指教
你需要确保的第一件事: ftp文件下载这件事,不是在UI线程(EDT)中进行的更新 ProgressBar 的问题,很简单,写一个 adapter,使其能从任何线程调用,其功能就是更新 ProgressBar 的显示。对用户代码(即对你ftp文件下载的代码)的接口可以写成这样:
public interface ProgressMonitor {
public void updateMessage(String message); public void updateProgress(int current, int total);
}
为了使用方便,也可以加两条显示用的:public void show();public void dispose();
void download(String filepath, ProgressViewer viewer) { viewer.updateMessage("Downloading " + filepath + " ... "); int total = getFileSize(filepath);
int progress = 0;
// 在过程中可以调用:
progress += bufferSize;
viewer.updateProgress(progress, total);
}
用了工具类 如下
private static final long serialVersionUID = 1L; public int total = 0; public int current = 0; private JPanel jContentPane = null; private JLabel jlb = null; private JProgressBar jpg1 = null; private JProgressBar jpg2 = null; /**
* @param owner
*/
public Monitor() {
initialize();
} public void setText(String text) {
jlb.setText(text);
} /**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(300, 200);
this.setResizable(false);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setTitle("Transms3 AutoUpdater Version 0.1");
this.setContentPane(getJContentPane());
this.setLocationRelativeTo(null);
this.setAlwaysOnTop(true);
this.setVisible(true);
}
public static void main(String args[])
{
Monitor m = new Monitor();
} /**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jlb = new JLabel();
jlb.setHorizontalAlignment(SwingConstants.CENTER);
jlb.setForeground(Color.blue);
jlb.setHorizontalTextPosition(SwingConstants.CENTER);
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(3);
jContentPane = new JPanel();
jContentPane.setLayout(gridLayout);
jContentPane.add(jlb, null);
jContentPane.add(getJpg1(), null);
jContentPane.add(getJpg2(), null);
}
return jContentPane;
} /**
* This method initializes jpg1
*
* @return javax.swing.JProgressBar
*/
protected JProgressBar getJpg1() {
if (jpg1 == null) {
jpg1 = new JProgressBar();
jpg1.setStringPainted(true);
jpg1.setString("总更新文件进度");
}
return jpg1;
} /**
* This method initializes jpg2
*
* @return javax.swing.JProgressBar
*/
protected JProgressBar getJpg2() {
if (jpg2 == null) {
jpg2 = new JProgressBar();
jpg2.setStringPainted(true);
jpg2.setString("当前更新文件进度");
}
return jpg2;
}
但是我用该类的时候没有实时更新进度条 所以我想是不是线程问题引起的? 求指教!
monitor.total += remotefiles.get(key).size;
} monitor.getJpg1().setMaximum(monitor.total);
monitor.setText("开始下载文件" + "...");
monitor.getJpg1().setString("下载文件:第" + i + "个/共" + remotefiles.size() + "个");
listener.setFile(remotefiles.get(filename));
String localfilepath = formatPath4File(nextFilePath
+ File.separator + filename);
client.download(filename, new File("D://DZXJ_PIC//"+localfilepath), listener);
ProgressViewe 写错了 ,应该是 ProgressMonitor
实现可以这样写(没有测试):import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
/**
*
* @date 31/10/2012
*/
public class ProgressAdapter implements ProgressMonitor {
private JDialog dialog;
private JProgressBar bar;
private JLabel label;
public ProgressAdapter(String title, Component parent) {
assert SwingUtilities.isEventDispatchThread();
dialog = new JDialog();
dialog.setModal(true);
dialog.setTitle(title);
dialog.setLocationRelativeTo(parent);
bar = new JProgressBar();
label = new JLabel();
dialog.getContentPane().setLayout(new GridLayout(2, 1));
dialog.getContentPane().add(bar);
dialog.add(label);
dialog.getContentPane().setPreferredSize(new Dimension(600, 100));
}
public void show() {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
dialog.setVisible(true);
}
});
}
public void dispose() {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
dialog.dispose();
}
});
}
@Override
public void updateProgress(final int current, final int total) {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
bar.setMinimum(total);
bar.setValue(current);
}
});
} @Override
public void updateMessage(final String message) {
SwingUtilities.invokeLater(new Runnable() { @Override
public void run() {
label.setText(message);
}
});
}
}
bar.setMinimum(total);
改成bar.setMaximum(total);
那你不能直接开始下载,要确保下载的工作在另一个线程里进行:
public void actionPerformed(ActionEvent e) {
// 开始下载文件
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// 下载文件
return null;
}
}.execute();
}
是在现在的时候 还是?
actionPerfromed 这个方法,是在UI线程中被调用的,UI线程的名字叫EDT,是一个单线程,这个线程负责所有的UI控件绘制工作,也就是说,如果你的文件下载工作占用了这个线程,那你整个的图形界面是不可能有任何更新的,就像死机一样。建议你去读一下 SwingWorker 的用法。
上班时上不了qq,下班用站内短信发给你qq号