用于多文件下载的java progressbar
我必须为一个项目做一个p2p程序。一切正常。我已经设置好,客户端可以一次下载多个文件(下载使用线程)。我现在的问题是如何才能真正获得下载的总体进度。我试过这样做,但没用用于多文件下载的java progressbar,java,swing,timer,progress-bar,Java,Swing,Timer,Progress Bar,我必须为一个项目做一个p2p程序。一切正常。我已经设置好,客户端可以一次下载多个文件(下载使用线程)。我现在的问题是如何才能真正获得下载的总体进度。我试过这样做,但没用 try { int bytesRead; InputStream in = mySocket.getInputStream(); DataInputStream clientData = new DataInputStream(in)
try {
int bytesRead;
InputStream in = mySocket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
OutputStream output = new FileOutputStream(("./download/" + filename));
byte[] buffer = new byte[1024];
int currentProgress = 0;
while (filesize > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, filesize))) != -1) {
output.write(buffer, 0, bytesRead);
filesize -= bytesRead;
currentProgress = (int) ((((double)filesize) / ((double)size)) * 100d);
currentProgress = ((100-currentProgress)/ViewClient.countFiles);
System.out.println(currentProgress);
}
output.close();
in.close();
System.out.println("File "+filename+" received from client.");
} catch (IOException ex) {
ex.printStackTrace();
}
使用此选项,每个值(0,1,2,3)将打印100次,然后我的进度条有时会上升到2'000'000,具体取决于文件。我如何获得下载的全部内容?
提前感谢您从概念上讲,您有
n个
任务,每个任务将产生0-100%的进度
为了简单起见,我将使用0-1作为进度值
您计算每个任务的进度并求和,然后将其除以任务数,这将为您提供介于0-1
之间的总体进度,例如
int taskCount = 10;
List<Double> taskProgress = new ArrayList<>(taskCount);
for (int index = 0; index < taskCount; index++) {
taskProgress.add(0.0);
}
double overallProgress = 0;
int round = 0;
do {
round++;
double sum = 0;
for (int index = 0; index < taskCount; index++) {
double progress = taskProgress.get(index);
progress += Math.random() * 0.1;
progress = Math.min(progress, 1.0);
sum += progress;
taskProgress.set(index, progress);
}
overallProgress = sum / (double)taskCount;
System.out.println("[" + round + "] " + NumberFormat.getPercentInstance().format(overallProgress) + "; " + NumberFormat.getNumberInstance().format(overallProgress));
} while (overallProgress < 1.0);
使用基于Swing的示例更新
因此,这基本上是使用一个SwingWorker
来执行后台任务,这基本上是将一个进度值增加一个随机量(然后暂停一个随机时间量)。worker通过其发布
/过程
方法提供进度更改通知,该方法向相关方提供通知,但在事件调度线程的上下文中这样做
该示例使用了一个简单的接口
,该接口被传递给SwingWorker
,以允许其向另一方提供有关进度状态更改的通知。然后,用户界面在映射中维护每个工人的进度信息,该映射用于计算总和以及由此产生的总进度。本质上与上面的概念相同,只是在一个更动态的示例中
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingWorker;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课进阶测验{
公共静态void main(字符串[]args){
新进展测试();
}
公开考试{
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展JPanel实现ProgressMonitor{
私人地图工作程序;
私有int任务计数;
私人双重进步;
公共测试窗格(){
workerProgress=新HashMap(25);
任务数=10;
对于(int-index=0;index<10;index++){
DownloadWorker=新的DownloadWorker(索引,this);
workerProgress.put(工人,0d);
worker.execute();
}
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
@凌驾
受保护组件(图形g){
超级组件(g);
Graphics2D g2d=(Graphics2D)g.create();
int width=(int)Math.round(getWidth()*进度);
setColor(UIManager.getColor(“ProgressBar.selectionBackground”);
g2d.fillRect(0,0,width,getHeight());
g2d.dispose();
}
@凌驾
public void progresswasdupdated(下载工作进程,双进程){
工人进程。放置(工人,进程);
双和=0;
对于(Map.Entry:workerProgress.entrySet()){
sum+=entry.getValue();
}
此.progress=sum/(double)taskCount;
重新油漆();
}
}
公共接口进程监视器{
public void progresswasdupdated(下载worker,加倍进度);
}
私有随机rnd=新随机();
公共类DownloadWorker扩展SwingWorker{
私有整数索引;
私有进程监视器进程监视器;
公共下载工作者(int索引,ProgressMonitor){
this.progressMonitor=progressMonitor;
这个指数=指数;
}
@凌驾
受保护的Void doInBackground()引发异常{
双进度=0;
做{
progress+=Math.random()*0.1;
进度=数学最小值(进度,1.0);
出版(进度);
线程睡眠(rnd.nextInt(490)+10);
}而(进展<1.0);
出版(1.0);
System.out.println(索引+“已结束”);
返回null;
}
public int getIndex(){
收益指数;
}
@凌驾
受保护的无效进程(列表块){
progressMonitor.ProgresswasUpdate(这是chunks.get(chunks.size()-1));
}
}
}
在本例中,为每个worker提供了一个int
索引,这可用于提供一些额外的调试,以便您可以查看每个worker是如何更新的您是否尝试过使用JProgressBar?这样想,你有n
下载次数,每个wi
[1] 5%; 0.049
[2] 9%; 0.09
[3] 14%; 0.144
[4] 18%; 0.179
[5] 23%; 0.23
[6] 28%; 0.276
[7] 32%; 0.321
[8] 37%; 0.366
[9] 40%; 0.403
[10] 45%; 0.451
[11] 51%; 0.505
[12] 55%; 0.552
[13] 60%; 0.601
[14] 64%; 0.642
[15] 69%; 0.695
[16] 76%; 0.761
[17] 80%; 0.803
[18] 84%; 0.845
[19] 87%; 0.869
[20] 90%; 0.902
[21] 92%; 0.925
[22] 95%; 0.946
[23] 96%; 0.962
[24] 97%; 0.971
[25] 98%; 0.976
[26] 99%; 0.986
[27] 99%; 0.989
[28] 99%; 0.993
[29] 100%; 1
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ProgressTest {
public static void main(String[] args) {
new ProgressTest();
}
public ProgressTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements ProgressMonitor{
private Map<DownloadWorker, Double> workerProgress;
private int taskCount;
private double progress;
public TestPane() {
workerProgress = new HashMap<>(25);
taskCount = 10;
for (int index = 0; index < 10; index++) {
DownloadWorker worker = new DownloadWorker(index, this);
workerProgress.put(worker, 0d);
worker.execute();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = (int)Math.round(getWidth() * progress);
g2d.setColor(UIManager.getColor("ProgressBar.selectionBackground"));
g2d.fillRect(0, 0, width, getHeight());
g2d.dispose();
}
@Override
public void progressWasUpdated(DownloadWorker worker, double progress) {
workerProgress.put(worker, progress);
double sum = 0;
for (Map.Entry<DownloadWorker, Double> entry : workerProgress.entrySet()) {
sum += entry.getValue();
}
this.progress = sum / (double)taskCount;
repaint();
}
}
public interface ProgressMonitor {
public void progressWasUpdated(DownloadWorker worker, double progress);
}
private Random rnd = new Random();
public class DownloadWorker extends SwingWorker<Void, Double> {
private int index;
private ProgressMonitor progressMonitor;
public DownloadWorker(int index, ProgressMonitor progressMonitor) {
this.progressMonitor = progressMonitor;
this.index = index;
}
@Override
protected Void doInBackground() throws Exception {
double progress = 0;
do {
progress += Math.random() * 0.1;
progress = Math.min(progress, 1.0);
publish(progress);
Thread.sleep(rnd.nextInt(490) + 10);
} while (progress < 1.0);
publish(1.0);
System.out.println(index + " has ended");
return null;
}
public int getIndex() {
return index;
}
@Override
protected void process(List<Double> chunks) {
progressMonitor.progressWasUpdated(this, chunks.get(chunks.size() - 1));
}
}
}