0

The code below does exactly what I need expect one thing. I just need to make this download a few more different URLs (pictures) sadly I got no idea how to do it. If anyone could help me to solve this I would be so thankful.

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Progressbar {

  public static void main(String[] args) {

    final JProgressBar jProgressBar = new JProgressBar();
    jProgressBar.setMaximum(100000);
    JFrame frame = new JFrame();
    frame.setContentPane(jProgressBar);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setSize(300, 70);
    frame.setVisible(true);
    Runnable updatethread = new Runnable() {
      public void run() {
        try {
          URL url = new URL("http://www.drgarbage.com/img/howto/cfgf-tutorial/createcfg.png");
          HttpURLConnection httpConnection = (HttpURLConnection) (url.openConnection());                        
          long completeFileSize = httpConnection.getContentLength();
          java.io.BufferedInputStream in = new     java.io.BufferedInputStream(httpConnection.getInputStream());
          java.io.FileOutputStream fos = new java.io.FileOutputStream("picture.png");
          java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);                       
          byte[] data = new byte[1024];
          long downloadedFileSize = 0;
          int x = 0;
          while ((x = in.read(data, 0, 1024)) >= 0) { 
            downloadedFileSize += x;

            // calculate progress
            final int currentProgress = (int) ((((double)downloadedFileSize) / ((double)completeFileSize)) * 100000d);

            // update progress bar
            SwingUtilities.invokeLater(new Runnable() {

              @Override
              public void run() {
                ProgressBar.setValue(currentProgress);
              }
            });
            bout.write(data, 0, x);
          }
          bout.close();
          in.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
      }
    };
    new Thread(updatethread).

    start();
  }
}
Kenster
  • 23,465
  • 21
  • 80
  • 106
kuki
  • 65
  • 1
  • 9
  • sorry I didn't got your problem. Can you explain it more detailed and probably show an example? ... – Felix Jul 16 '15 at 12:10
  • @Felix , I mean I just want to download the same way , but insted of one url (picture) I need 3 url's . – kuki Jul 16 '15 at 12:14
  • just use a String in your URL url = new Url(myString); and set that String accordingly?? oO – 12dollar Jul 16 '15 at 12:15
  • @12dollar , yeah but progress bar will just show a download process of first item downloaded , not all of them – kuki Jul 16 '15 at 12:17
  • possible duplicate of [download files in a single progress bar](http://stackoverflow.com/questions/14107183/download-files-in-a-single-progress-bar) – godfatherofpolka Jul 16 '15 at 12:30
  • See http://stackoverflow.com/questions/14107183/download-files-in-a-single-progress-bar and http://stackoverflow.com/questions/17262945/tracking-progress-of-multiple-image-downloads-with-swingworker-and-jprogressbar for related questions. – godfatherofpolka Jul 16 '15 at 12:31

1 Answers1

1

Here's a quick solution based on https://docs.oracle.com/javase/tutorial/uiswing/examples/components/ProgressBarDemoProject/src/components/ProgressBarDemo.java

The progress calculation uses a bit of cheating in that it assumes that all files are roughly the same size. It would be more proper to prefetch all file sizes and then do calculations on the proper total.

Edit: I've added an additional progress bar indicating current file download based on the solution given in https://stackoverflow.com/a/8917565/3469592. I'm not sure, whether this is good practice. Criticism and suggestions for improvement are welcome.

Warning: The code is artificially slowed down to make it easier to watch. Remove the Thread.sleep(200) part if you actually want to use this!

/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

import java.io.FileNotFoundException;
import java.io.IOException;


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;

public class ProgressBarDemo extends JPanel
                             implements ActionListener, 
                                        PropertyChangeListener {

  private JProgressBar overallProgressBar;
  private JProgressBar currentProgressBar;
  private JButton startButton;
  private JTextArea taskOutput;
  private Task task;

  class Task extends SwingWorker<Void, Integer> {

    private final JProgressBar currentProgressBar;

    private Task(JProgressBar progressBar) {
      currentProgressBar = progressBar;
    }

    private void download(String urlString, int fileNumber, int total) {
      java.io.InputStream in = null;
      java.io.OutputStream out = null;

      try {
        taskOutput.append("Downloading file " + fileNumber + "...");

        java.net.URL url = new java.net.URL(urlString);

        java.net.HttpURLConnection httpConnection = (java.net.HttpURLConnection) (url.openConnection());

        long completeFileSize = httpConnection.getContentLength();
        in = httpConnection.getInputStream();
        out = new java.io.FileOutputStream("picture"+fileNumber+".png");

        final byte[] data = new byte[1024];
        long downloadedFileSize = 0;
        int count;
        while ((count = in.read(data, 0, 1024)) != -1) { 
          // --------------------------
          // TODO: Make downloads slower so you can watch things better, do not use in production code!
          try {
            Thread.sleep(200);
          } catch (InterruptedException ignore) {}
          // --------------------------

          downloadedFileSize += count;

          /* calculate progress (cheap variant, we assume that files are roughly the same size), another, more proper, way would be to prefetch all file sizes and give actual progress */
          final int currentProgress = (int) (((double)downloadedFileSize) / ((double)completeFileSize) * 100d );
          final int scaledCurrentProgress = currentProgress / total;
          final int overallProgress = (int) (((double)fileNumber/(double)total) * 100d);
          /* notifications of progress */
          setProgress(Math.min(scaledCurrentProgress + overallProgress,100));
          publish(Math.min(currentProgress,100));
          /* save downloaded data */        
          out.write(data, 0, count);
        } 

        taskOutput.append("done!\n");           
      } catch (FileNotFoundException e) {
        taskOutput.append("File not found: " + e);
      } catch (IOException e) {
        taskOutput.append("IO exception: " + e);
      } catch (Exception e) {
        taskOutput.append("Something went wrong: " + e);
      } finally {
        try {
          if (in != null) {
            in.close();
          }
          if (out != null) {
            out.close();
          }
        } catch (IOException e) {
          taskOutput.append("IO exception: " + e);
        }
      }
    }

    /*
     * Main task. Executed in background thread.
     */
    @Override
    public Void doInBackground() {
      // TODO: Probably this data would be given to the class in the constructor
      java.util.List<String> urlStrings = java.util.Arrays.asList(
                                            "http://imgs.xkcd.com/comics/tamagotchi_hive.png ", 
                                            "http://imgs.xkcd.com/comics/solar_system_questions.png ",
                                            "http://imgs.xkcd.com/comics/90s_kid.png",
                                            "http://imgs.xkcd.com/comics/xkcd_phone_3.png",
                                            "http://imgs.xkcd.com/comics/episode_vii.png");

      setProgress(0);

      int numberOfURLs = urlStrings.size();

      for (int i = 0; i < numberOfURLs; i++) {
        download(urlStrings.get(i), i, numberOfURLs);
      }

      return null;
    }

    /*
     * Handle data from publish(), i.e., current file progress
     */
    @Override
    protected void process(java.util.List<Integer> progressList) {
      final int progress = progressList.get(progressList.size() - 1);
      currentProgressBar.setValue(progress);
    }

    /*
     * Executed in event dispatching thread
     */
    @Override
    public void done() {
      setCursor(null); //turn off the wait cursor
      taskOutput.append("All files downloaded!\n");
    }
  } // end of class Task

  public ProgressBarDemo() {
    super(new BorderLayout());

    //Create the demo's UI.
    startButton = new JButton("Start");
    startButton.setActionCommand("start");
    startButton.addActionListener(this);

    overallProgressBar = new JProgressBar(0, 100);
    overallProgressBar.setValue(0);
    overallProgressBar.setStringPainted(true);

    currentProgressBar = new JProgressBar(0, 100);
    currentProgressBar.setValue(0);
    currentProgressBar.setStringPainted(true);

    taskOutput = new JTextArea(5, 20);
    taskOutput.setMargin(new Insets(5,5,5,5));
    taskOutput.setEditable(false);

    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(3,2));
    panel.add(new JLabel("Current File"));
    panel.add(currentProgressBar);
    panel.add(new JLabel("Overall Progress"));
    panel.add(overallProgressBar);
    panel.add(startButton);

    add(panel, BorderLayout.PAGE_START);
    add(new JScrollPane(taskOutput), BorderLayout.CENTER);
    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
  }

  /**
   * Invoked when the user presses the start button.
   */
  public void actionPerformed(ActionEvent evt) {
    startButton.setEnabled(false);
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    //Instances of javax.swing.SwingWorker are not reusuable, so
    //we create new instances as needed.
    task = new Task(currentProgressBar);
    task.addPropertyChangeListener(this);
    task.execute();
  }

  /**
   * Invoked when task's progress property changes.
   */
  public void propertyChange(PropertyChangeEvent evt) {
    if ("progress" == evt.getPropertyName()) {
      int progress = (Integer) evt.getNewValue();
      overallProgressBar.setValue(progress);
    } 
  }

  /**
   * Create the GUI and show it. As with all GUI code, this must run
   * on the event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("ProgressBarDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    JComponent newContentPane = new ProgressBarDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);

    //Display the window.
    frame.pack();
    frame.setVisible(true);
  }

  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}
Community
  • 1
  • 1
godfatherofpolka
  • 1,645
  • 1
  • 11
  • 24