我正在尝试在此问题的投票答案中找到的代码:Download file using java apache commons?
这是一个下载应用程序,看一看,(我对JFrames和ActionEvents不是很熟悉)
Download.java
package main;
public class Download extends JFrame implements Runnable{
public static int total;
public static int done;
private static class ProgressListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
done = (int)((DownloadCountingOutputStream) e.getSource()).getByteCount();
jbar.repaint();
DownloadCountingOutputStream.parent.draw((int)((DownloadCountingOutputStream) e.getSource()).getByteCount());//redraw
DownloadCountingOutputStream.parent.repaint();
}
}
public static JProgressBar jbar = new JProgressBar();
public void draw(int downloaded){System.out.println("downloaded: "+downloaded+ " Total: "+total);
if (downloaded== 0){
Container cont = new Container();
setDefaultCloseOperation(3);
setSize(600, 450);
setResizable(false);
setVisible(true);
cont.add(jbar);
jbar.setBounds(40, 50, 500, 50);
jbar.setMaximum(total);//The total value of bytes to download
//jbar.setValue(50);
add(cont);
jbar.setVisible(true);
}
jbar.setValue(downloaded);
//This should update the value of the progress Bar
}
public void run() {
URL dl = null;
File fl = null;
OutputStream os = null;
InputStream is = null;
ProgressListener progressListener = new ProgressListener();
draw(done);
try {
fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/afile.rar");
dl = new URL("https://dl.dropbox.com/u/48076798/afile.rar");
os = new FileOutputStream(fl);
is = dl.openStream();
total = Integer.parseInt(dl.openConnection().getHeaderField("Content-Length"));
String total = dl.openConnection().getHeaderField("Content-Length");
DownloadCountingOutputStream dcount = new DownloadCountingOutputStream(os);
dcount.setListener(progressListener);
dcount.setParent(this);
IOUtils.copy(is, dcount);
} catch (Exception e) {
System.out.println(e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
DownloadCountingOutputStream.java
package main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.io.output.CountingOutputStream;
public class DownloadCountingOutputStream extends CountingOutputStream {
private ActionListener listener = null;
public static Download parent;
public DownloadCountingOutputStream(OutputStream out) {
super(out);
}
public void setListener(ActionListener listener) {
this.listener = listener;
}
public void setParent(Download o){
parent = o;
}
@Override
protected void afterWrite(int n) throws IOException {
super.afterWrite(n);
if (listener != null) {
listener.actionPerformed(new ActionEvent(this, 0, null));
}
}
}
答案 0 :(得分:3)
从您提供的代码示例中很难说明......
此问题的主要原因是尝试在阻止事件调度线程(EDT)的同时更新UI。
重要的是不要在EDT中进行任何长时间运行或阻止操作,因为这样可以防止重绘请求被执行。
有关详细信息,请阅读Concurrency in Swing
以下示例演示如何使用SwingWorker
提供与UI重新同步的进度更新
public class TestProgress {
public static void main(String[] args) {
new TestProgress();
}
public TestProgress() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
ProgressPane progressPane = new ProgressPane();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(progressPane);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
progressPane.doWork();
}
});
}
public class ProgressPane extends JPanel {
private JProgressBar progressBar;
public ProgressPane() {
setLayout(new GridBagLayout());
progressBar = new JProgressBar();
add(progressBar);
}
public void doWork() {
Worker worker = new Worker();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
});
worker.execute();
}
}
public class Worker extends SwingWorker<Object, Object> {
@Override
protected Object doInBackground() throws Exception {
for (int index = 0; index < 1000; index++) {
int progress = Math.round(((float) index / 1000f) * 100f);
setProgress(progress);
Thread.sleep(10);
}
return null;
}
}
}