Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing progress bar for download process

I am using Java function to download file from internet.

public void getLatestRelease()
{
    try
    {
        // Function called
        long startTime = System.currentTimeMillis();

        // Open connection
        System.out.println("Connecting...");
        URL url = new URL(latestReleaseUrl);
        url.openConnection();

        // Download routine
        InputStream reader = url.openStream();
        FileOutputStream writer = new FileOutputStream("release.zip");

        byte[] buffer = new byte[153600];
        int totalBytesRead = 0;
        int bytesRead = 0;

        while ((bytesRead = reader.read(buffer)) > 0)
        {
            writer.write(buffer, 0, bytesRead);
            buffer = new byte[153600];
            totalBytesRead += bytesRead;
        }

        // Download finished
        long endTime = System.currentTimeMillis();

        // Output download information
        System.out.println("Done.");
        System.out.println((new Integer(totalBytesRead).toString()) + " bytes read.");
        System.out.println("It took " + (new Long(endTime - startTime).toString()) + " milliseconds.");

        // Close input and output streams
        writer.close();
        reader.close();
    }

    // Here I catch MalformedURLException and IOException :)
}

And I have JProgressBar component in my JPanel, which is supposed to visualize download progress:

private static void createProgressBar(JPanel panel)
{
    JProgressBar progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    panel.add(progressBar, BorderLayout.SOUTH);
}

I'd like to separate "back-end" functions from "front-end" views, presented to users, by analogy with MVC in web applications.

So, function getLatestRelease() lies in the package framework in class MyFramework.

Everything, connected with Swing interface generation, including event listeners, is in the package frontend.

In the main Controller class I create an instance of MyFramework and an instance of ApplicationFrontend, which is the main class of frontend package.

The questions is how to update progressBar value, depending on download progress?

like image 437
Edward Ruchevits Avatar asked Aug 13 '12 16:08

Edward Ruchevits


People also ask

Which Swing classes can be used with progress bar in Java?

To create a progress bar in swing you use the JProgressbar class. With JProgressBar you can either create vertical or horizontal progress bar.


1 Answers

when you want to do MVC in swing, the SwingWorker class comes to mind.
SwingWorker comes with a property called "progress", that you can listen to using a PropertyChangeListener.

Progress events can be fired from the swingworker using its setProgress(int 0-100) method. So here it is for loading the file in the background with a notion of progress (note that you will need to have an idea of the size of the file to be able to compute a progress percentage).

Showing the progress can be done using two options : a JProgressBar for complete control, or a ProgressMonitor to show an almost self-managed popup with a progress bar in it. See the tutorial to see the differences.

Solution 1

As they say, if you go for a ProgressMonitor and your background task is reading from an InputStream, you can use the ProgressMonitorInputStream class to do the reading and displaying progress without bothering with calling setProgress or listening to the "progress" property.

Solution 2

If you want to do it manually, create your SwingWorker loading task that calls setProgress as it goes, instanciate a ProgressMonitor (or a JProgressBar) as needed, register a PropertyChangeListener on your SwingWorker that checks for "progress" changes and updates the monitor/bar accordingly.

Note: It is important to go through a PropertyChangeListener because it decouples the model (the task) from the view (the swing progress component) and abide by the EDT usage rules.

like image 112
Simon Baslé Avatar answered Nov 02 '22 18:11

Simon Baslé