下载文件,同时还更新JProgressBar

我已经尝试了不同方法的音调来使其工作,但它们要么不使用进度条,要么不按照我希望的方式工作。

我已经创建了一个带有进度条的新窗口,需要创建一个允许我下载文件同时更新JProgressBar 。 有一个Apache Commons方法非常容易用于下载文件,但它似乎与JProgressBar不兼容。

我在另一个线程中运行它时遇到了麻烦, SwingUtilities.invokeLater似乎没有更新到进度条,但它确实运行,因为我可以将它打印到控制台。 我甚至尝试过progressBar.repaint()方法。

所以我想要的是一种方法,可以下载文件,同时还更新JProgressBar以反映下载的状态。

提前致谢! 基尔

基于这篇文章,我建议你写一个Download class ,它可以轻松更新进度条。

这是Download类:

 import java.io.*; import java.net.*; import java.util.*; // This class downloads a file from a URL. class Download extends Observable implements Runnable { // Max size of download buffer. private static final int MAX_BUFFER_SIZE = 1024; // These are the status names. public static final String STATUSES[] = {"Downloading", "Paused", "Complete", "Cancelled", "Error"}; // These are the status codes. public static final int DOWNLOADING = 0; public static final int PAUSED = 1; public static final int COMPLETE = 2; public static final int CANCELLED = 3; public static final int ERROR = 4; private URL url; // download URL private int size; // size of download in bytes private int downloaded; // number of bytes downloaded private int status; // current status of download // Constructor for Download. public Download(URL url) { this.url = url; size = -1; downloaded = 0; status = DOWNLOADING; // Begin the download. download(); } // Get this download's URL. public String getUrl() { return url.toString(); } // Get this download's size. public int getSize() { return size; } // Get this download's progress. public float getProgress() { return ((float) downloaded / size) * 100; } // Get this download's status. public int getStatus() { return status; } // Pause this download. public void pause() { status = PAUSED; stateChanged(); } // Resume this download. public void resume() { status = DOWNLOADING; stateChanged(); download(); } // Cancel this download. public void cancel() { status = CANCELLED; stateChanged(); } // Mark this download as having an error. private void error() { status = ERROR; stateChanged(); } // Start or resume downloading. private void download() { Thread thread = new Thread(this); thread.start(); } // Get file name portion of URL. private String getFileName(URL url) { String fileName = url.getFile(); return fileName.substring(fileName.lastIndexOf('/') + 1); } // Download file. public void run() { RandomAccessFile file = null; InputStream stream = null; try { // Open connection to URL. HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // Specify what portion of file to download. connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); // Connect to server. connection.connect(); // Make sure response code is in the 200 range. if (connection.getResponseCode() / 100 != 2) { error(); } // Check for valid content length. int contentLength = connection.getContentLength(); if (contentLength < 1) { error(); } /* Set the size for this download if it hasn't been already set. */ if (size == -1) { size = contentLength; stateChanged(); } // Open file and seek to the end of it. file = new RandomAccessFile(getFileName(url), "rw"); file.seek(downloaded); stream = connection.getInputStream(); while (status == DOWNLOADING) { /* Size buffer according to how much of the file is left to download. */ byte buffer[]; if (size - downloaded > MAX_BUFFER_SIZE) { buffer = new byte[MAX_BUFFER_SIZE]; } else { buffer = new byte[size - downloaded]; } // Read from server into buffer. int read = stream.read(buffer); if (read == -1) break; // Write buffer to file. file.write(buffer, 0, read); downloaded += read; stateChanged(); } /* Change status to complete if this point was reached because downloading has finished. */ if (status == DOWNLOADING) { status = COMPLETE; stateChanged(); } } catch (Exception e) { error(); } finally { // Close file. if (file != null) { try { file.close(); } catch (Exception e) {} } // Close connection to server. if (stream != null) { try { stream.close(); } catch (Exception e) {} } } } // Notify observers that this download's status has changed. private void stateChanged() { setChanged(); notifyObservers(); } } 

如您所见,这个Download类有一些特定的字段,如sizedownloaded

在其他一些方法中你可以写:

 JProgressBar j = new JProgressBar(0,download.getSize()); 

在此之后你可以启动一个新的Thread ,它会以一定的间隔更新你的进度条,就像每10毫秒一样

 j.setValue(download.getDownloaded()); 

希望这可以帮到你。

在新的线程中下载文件工作正常:

 import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JProgressBar; /** * * @author adyliu(imxylz@gmail.com) * @since 2012-12-28 */ public class JProgressBarDemo { public static void main(String[] args) { final JProgressBar pbFile = new JProgressBar(); pbFile.setValue(0); pbFile.setMaximum(100); pbFile.setStringPainted(true); pbFile.setBorder(BorderFactory.createTitledBorder("Download file")); JFrame theFrame = new JFrame("ProgressBar Demo"); theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container contentPane = theFrame.getContentPane(); contentPane.add(pbFile, BorderLayout.SOUTH); final JButton btnDownload = new JButton("Download"); contentPane.add(btnDownload); final AtomicBoolean running = new AtomicBoolean(false); btnDownload.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { running.set(!running.get()); btnDownload.setText(running.get() ? "Pause" : "Continue"); if (running.get()) { new Thread() { public void run() { //download file in a thread int v = 0; while (running.get() && v < pbFile.getMaximum()) { pbFile.setValue(++v); LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(200)); } } }.start(); } } }); theFrame.setSize(300, 150); theFrame.setLocationRelativeTo(null); theFrame.setVisible(true); } }