Java 使用swing GUI在下载文件时显示进度条
我目前有一个类,它应该在下载文件时向我显示一个简单的表单。它正在工作,但进度条没有更新,我只能在下载完成后才能看到它。有人能帮我吗Java 使用swing GUI在下载文件时显示进度条,java,swing,download,progress-bar,progress,Java,Swing,Download,Progress Bar,Progress,我目前有一个类,它应该在下载文件时向我显示一个简单的表单。它正在工作,但进度条没有更新,我只能在下载完成后才能看到它。有人能帮我吗 import java.awt.FlowLayout; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import javax.swing.JFrame; import static javax.swing.JFrame.EXIT_ON_CLOSE; import
import java.awt.FlowLayout;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JProgressBar;
public class Downloader {
public Downloader(String site, File file) {
JFrame frm = new JFrame();
JProgressBar current = new JProgressBar(0, 100);
current.setSize(50, 100);
current.setValue(0);
current.setStringPainted(true);
frm.add(current);
frm.setVisible(true);
frm.setLayout(new FlowLayout());
frm.setSize(50, 100);
frm.setDefaultCloseOperation(EXIT_ON_CLOSE);
try {
URL url = new URL(site);
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
int filesize = connection.getContentLength();
float totalDataRead = 0;
try (java.io.BufferedInputStream in = new java.io.BufferedInputStream(connection.getInputStream())) {
java.io.FileOutputStream fos = new java.io.FileOutputStream(file);
try (java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024)) {
byte[] data = new byte[1024];
int i;
while ((i = in.read(data, 0, 1024)) >= 0) {
totalDataRead = totalDataRead + i;
bout.write(data, 0, i);
float Percent = (totalDataRead * 100) / filesize;
current.setValue((int) Percent);
}
}
}
} catch (IOException e) {
javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, e.getMessage(), "Error",
javax.swing.JOptionPane.DEFAULT_OPTION);
}
}
}
您的问题是一个典型的Swing并发问题。解决方案一如既往——在后台线程中执行长时间运行的代码,比如SwingWorker e、 g
您的问题是一个典型的Swing并发问题。解决方案一如既往——在后台线程中执行长时间运行的代码,比如SwingWorker e、 g
不要阻止EDT事件调度线程-发生这种情况时GUI将“冻结”。而是为长时间运行的任务实现SwingWorker。有关更多详细信息,请参阅。这是另一个dup:和第三个:。是时候学习你的谷歌技能了;谢谢大家,现在开始工作了。我一直在寻找,但我发现没有任何东西适合我试图实现的目标。谢谢不要阻止EDT事件调度线程-发生这种情况时GUI将“冻结”。而是为长时间运行的任务实现SwingWorker。有关更多详细信息,请参阅。这是另一个dup:和第三个:。是时候学习你的谷歌技能了;谢谢大家,现在开始工作了。我一直在寻找,但我发现没有任何东西适合我试图实现的目标。谢谢谢谢你的帮助,不过它很管用,它在20%java.util.concurrent.ExecutionException:java.lang.IllegalArgumentException:java.util.concurrent.FutureTask.reportFutureTask.java:122在java.util.concurrent.FutureTask.getFutureTask.java:188在javax.swing.SwingWorker.getSwingWorker.java:602在Downloader$1.propertyChangeDownloader.java:49@woutwoot:发生错误时百分比的值是多少?调用setProgressint progress时,只能传入0到100之间的值。如果百分比太大,比如说101,考虑使用IF(如果百分比为100)。{percent=100,或类似的。我刚刚测试过,出于某种原因,它只适用于大于20MB的文件。错误发生在@worker.get;@woutwoot:worker.get方法将捕获在doInBackground运行期间抛出的异常。尝试隔离错误,如果仍然卡住,则用您和您的数据发布一个新问题。错误发生的原因是错误是int溢出。若要修复此问题,必须将totalDataRead和filesize更改为long,然后为%的结果添加强制转换。更改后,您应该能够下载高达2GB的文件。多亏了这一点,它可以正常工作,但在20%java.util.concurrent.ExecutionException:java.lang.IllegalArgumentException:java.util.concurrent.FutureTask.reportFutureTask.java的值应介于0到100之间:java.util.concurrent.FutureTask.getFutureTask.java:188位于javax.swing.SwingWorker.getSwingWorker.java:602位于Downloader$1.propertyChangeDownloader.java:49@woutwoot:发生错误时百分比的值是多少?调用setProgressint progre时SS只能传递0到100之间的值。如果百分比太大,比如说101,考虑使用IF块-如果百分比大于100。{percent=100,或类似的。我刚刚测试过,出于某种原因,它只适用于大于20MB的文件。错误发生在@worker.get;@woutwoot:worker.get方法将捕获在doInBackground运行期间抛出的异常。尝试隔离错误,如果仍然卡住,则用您和您的数据发布一个新问题。错误发生的原因是错误为int溢出。若要修复此问题,必须将totalDataRead和filesize更改为long,然后添加百分比结果的强制转换。更改后,您应该能够下载高达2GB的文件。
import java.awt.FlowLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JProgressBar;
public class Downloader {
public Downloader(String site, File file) {
JFrame frm = new JFrame();
final JProgressBar current = new JProgressBar(0, 100);
current.setSize(50, 100);
current.setValue(0);
current.setStringPainted(true);
frm.add(current);
frm.setVisible(true);
frm.setLayout(new FlowLayout());
frm.setSize(50, 100);
frm.setDefaultCloseOperation(EXIT_ON_CLOSE);
final Worker worker = new Worker(site, file);
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if ("progress".equals(pcEvt.getPropertyName())) {
current.setValue((Integer) pcEvt.getNewValue());
} else if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
try {
worker.get();
} catch (InterruptedException | ExecutionException e) {
// handle any errors here
e.printStackTrace();
}
}
}
});
worker.execute();
}
}
class Worker extends SwingWorker<Void, Void> {
private String site;
private File file;
public Worker(String site, File file) {
this.site = site;
this.file = file;
}
@Override
protected Void doInBackground() throws Exception {
URL url = new URL(site);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
int filesize = connection.getContentLength();
int totalDataRead = 0;
try (java.io.BufferedInputStream in = new java.io.BufferedInputStream(
connection.getInputStream())) {
java.io.FileOutputStream fos = new java.io.FileOutputStream(file);
try (java.io.BufferedOutputStream bout = new BufferedOutputStream(
fos, 1024)) {
byte[] data = new byte[1024];
int i;
while ((i = in.read(data, 0, 1024)) >= 0) {
totalDataRead = totalDataRead + i;
bout.write(data, 0, i);
int percent = (totalDataRead * 100) / filesize;
setProgress(percent);
}
}
}
return null;
}
}