0

I have a some class for downloading a big files from a web sites and displaying a process with jProgressBar. I am using a SwingWorker class and the method doInBackground. It works fine, but when size of downloaded file > 20mb, i am getting a java.lang.IllegalArgumentException: the value should be from 0 to 100. What am i doing wrong? Please, help me! My piece of code:

   @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;
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373

1 Answers1

2

Having played around with your calculations, this...

int percent = (totalDataRead * 100) / filesize;

Just looks wrong to me (it might just be my pathetic math brain), but out of 40mb at around 20.48mb (or 51%), it reverts to a negative number (-51%)

How ever, if I use

int percent = Math.round(((float)count / (float)range) * 100f);

It works just fine.

Also, I'd consider making filesize and totalDataRead long instead of int, but that's just me.

And a runnable example which I used to test it with...

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        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 {

        private JProgressBar pb;

        public TestPane() {
            pb = new JProgressBar();
            setLayout(new GridBagLayout());
            add(pb);

            SwingWorker worker = new SwingWorker() {
                @Override
                protected Object doInBackground() throws Exception {
                    int range = 40 * (1024 * 1024);
                    for (int count = 0; count < range; count += 1024) {
                        int percent = Math.round(((float)count / (float)range) * 100f);
                        setProgress(percent);
                        Thread.sleep(1);
                    }
                    return null;
                }
            };
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (null != evt.getPropertyName()) {
                        switch (evt.getPropertyName()) {
                            case "progress":
                                pb.setValue(worker.getProgress());
                                break;
                        }
                    }
                }
            });
            worker.execute();
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366