0

I have some code to specifically download one thing and then more code to download an array of items specified, however for some reason the progress bar does not show up unless I call the first method first and then the second one. However, the gui itself does appear. This shouldn't happen because the code is almost identical except for a few things. Here is the code to the first one:

public void downloadMod(final String url, final String location) {

    Thread download = new Thread() {

        public void run() {

            try {

                URL website = new URL(url);
                HttpURLConnection connection = (HttpURLConnection)website.openConnection();

                int size = connection.getContentLength();
                float totalDataRead = 0;

                BufferedInputStream input = new BufferedInputStream(connection.getInputStream());
                FileOutputStream fileOutput = new FileOutputStream(location);
                BufferedOutputStream output = new BufferedOutputStream(fileOutput, 1024);

                byte[] data = new byte[1024];
                int i = 0;

                while((i = input.read(data, 0, 1024)) >= 0) {

                    totalDataRead = totalDataRead + i;
                    output.write(data, 0, i);
                    float percentf = (totalDataRead * 100) /size;
                    int percent = (int)percentf;
                    progressBar.setValue(percent);

                }

                output.close();
                input.close();

                Zip.unZip(location);

                //new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/pack.json").delete();
                new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/version").delete();

                new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/minecraft/pack.json").renameTo(new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/pack.json"));
                new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/minecraft/version").renameTo(new File(Start.POWER_LAUNCHER_LOCATION + "modpacks/" + ModPack.getMod(LauncherGUI.selectedMod) + "/version"));

                dispose();

                new Launch().launch(ModPack.getMod(LauncherGUI.selectedMod));

            }
            catch(Exception e) {

                JOptionPane.showMessageDialog(null, "Error Downloading!");

                new File(location).delete();

                dispose();

            }

        }

    };

    download.start();

}

The second one does almost the exact same thing except with multiple files:

public void downloadCrap(final String[] urls, final String[] locations) {

   Thread download = new Thread() {

        public void run() {

            for (int j = 0; j < urls.length; j++) {

                try {

                    URL website = new URL(urls[j]);
                    HttpURLConnection connection = (HttpURLConnection) website.openConnection();

                    int size = connection.getContentLength();
                    float totalDataRead = 0;

                    BufferedInputStream input = new BufferedInputStream(connection.getInputStream());
                    FileOutputStream fileOutput = new FileOutputStream(locations[j]);
                    BufferedOutputStream output = new BufferedOutputStream(fileOutput, 1024);

                    byte[] data = new byte[1024];
                    int i = 0;

                    while ((i = input.read(data, 0, 1024)) >= 0) {

                        totalDataRead = totalDataRead + i;
                        output.write(data, 0, i);
                        float percentf = (totalDataRead * 100) / size;
                        int percent = (int) percentf;
                        progressBar.setValue(percent);

                    }

                    output.close();
                    input.close();

                }
                catch (Exception e) {

                    new File(locations[j]).delete();

                }

            }

        }

    };

    download.start();

    try {

        download.join();

    }
    catch(Exception e) {

        e.printStackTrace();

    }

    dispose();

}

I have no idea what I'm doing wrong and help would be appreciated!

  • You are calling your progressbar's `setValue` from inside another thread. Since the main thread and your other thread are running concurrently you do not know if maybe your thread is doing all its work and then the main thread can update the progressbar. Thus, the behaviour can be hard to predict. Check out http://stackoverflow.com/questions/10342309/jprogressbar-painting-issue for threads and jprogressbar. – Pphoenix Jul 08 '14 at 14:31
  • EDIT: Posted a link to the wrong SO question: http://stackoverflow.com/questions/3174613/update-jprogressbar should be the correct one. – Pphoenix Jul 08 '14 at 14:38
  • the progress bar does not even show up though and it works just fine in the first method every time – user1978403 Jul 08 '14 at 14:50
  • I think it is just a lucky shot that it works the first time. Using a SwingWorker will make the code behave in a more expected way. – Pphoenix Jul 08 '14 at 15:07

2 Answers2

0

You should use a SwingWorker. Check the oracle tutorial for JProgressBar.

http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html

Stelium
  • 1,207
  • 1
  • 12
  • 23
0

You can't update UI-Components from another thread. All UI operation should be done inside the EDT (Event Dispatcher Thread). You can try to perform the update with usage of SwingUtilities class like this:

SwingUtilities.invokeLater(new Runnable()
{
   @Override
   public void run()
   {
      progressBar.setValue(percent);
   }
 });

This runnable will be executed inside of EDT

spx01
  • 359
  • 4
  • 6