简体   繁体   English

下载文件时更新JProgressBar

[英]Update a JProgressBar while Downloading a File

I am trying to create a installer, that is downloading some files for my program. 我正在尝试创建一个安装程序,该程序正在为我的程序下载一些文件。 While a file is downloading I want my JProgressBar to be updated, but somehow the program is freezing when I use my code. 在下载文件时,我希望更新我的JProgressBar,但是以某种方式,当我使用代码时,程序冻结了。

My download void 我的下载无效

    public static boolean download() {
    URL url = null;
    try {
         url = new URL("http://(domainnameremoved).de/download/1408/");
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    final Download download = new Download(url);
    Start.progressBar.setMinimum(0);
    Start.progressBar.setMaximum(download.getSize());

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            while(!(download.getStatus() == 2)||!(download.getStatus() == 3)||!(download.getStatus() == 4)) {
                Start.progressBar.setValue(download.getDownloaded());
            }
            }

    });

    if(download.getStatus() == 2) {
        return true;
    } else {
        return false;
    }


}

My download class (not from me, I found it on the internet) 我的下载课程(不是从我这里下载的,我是在互联网上找到的)

public class Download extends Observable implements Runnable {

// Max size of download buffer.
private static final int MAX_BUFFER_SIZE = 1024;

// These are the status names.
public static final String STATUSES[] = {"Downloading",
"Paused", "Complete", "Cancelled", "Error"};

// These are the status codes.
public static final int DOWNLOADING = 0;
public static final int PAUSED = 1;
public static final int COMPLETE = 2;
public static final int CANCELLED = 3;
public static final int ERROR = 4;

private URL url; // download URL
private int size; // size of download in bytes
private int downloaded; // number of bytes downloaded
private int status; // current status of download

// Constructor for Download.
public Download(URL url) {
    this.url = url;
    size = -1;
    downloaded = 0;
    status = DOWNLOADING;

    // Begin the download.
    download();
}

// Get this download's URL.
public String getUrl() {
    return url.toString();
}

public int getDownloaded() {
    return this.downloaded;
}

// Get this download's size.
public int getSize() {
    return size;
}

// Get this download's progress.
public float getProgress() {
    return ((float) downloaded / size) * 100;
}

// Get this download's status.
public int getStatus() {
    return status;
}

// Pause this download.
public void pause() {
    status = PAUSED;
    stateChanged();
}

// Resume this download.
public void resume() {
    status = DOWNLOADING;
    stateChanged();
    download();
}

// Cancel this download.
public void cancel() {
    status = CANCELLED;
    stateChanged();
}

// Mark this download as having an error.
private void error() {
    status = ERROR;
    stateChanged();
}

// Start or resume downloading.
private void download() {
    Thread thread = new Thread(this);
    thread.start();
}

// Get file name portion of URL.
private String getFileName(URL url) {
    String fileName = url.getFile();
    return fileName.substring(fileName.lastIndexOf('/') + 1);
}

// Download file.
public void run() {
    RandomAccessFile file = null;
    InputStream stream = null;

    try {
        // Open connection to URL.
        HttpURLConnection connection =
                (HttpURLConnection) url.openConnection();

        // Specify what portion of file to download.
        connection.setRequestProperty("Range",
                "bytes=" + downloaded + "-");

        // Connect to server.
        connection.connect();

        // Make sure response code is in the 200 range.
        if (connection.getResponseCode() / 100 != 2) {
            error();
        }

        // Check for valid content length.
        int contentLength = connection.getContentLength();
        if (contentLength < 1) {
            error();
        }

  /* Set the size for this download if it
     hasn't been already set. */
        if (size == -1) {
            size = contentLength;
            stateChanged();
        }

        // Open file and seek to the end of it.
        file = new RandomAccessFile(getFileName(url), "rw");
        file.seek(downloaded);

        stream = connection.getInputStream();
        while (status == DOWNLOADING) {
    /* Size buffer according to how much of the
       file is left to download. */
            byte buffer[];
            if (size - downloaded > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[size - downloaded];
            }

            // Read from server into buffer.
            int read = stream.read(buffer);
            if (read == -1)
                break;

            // Write buffer to file.
            file.write(buffer, 0, read);
            downloaded += read;
            stateChanged();
        }

  /* Change status to complete if this point was
     reached because downloading has finished. */
        if (status == DOWNLOADING) {
            status = COMPLETE;
            stateChanged();
        }
    } catch (Exception e) {
        error();
    } finally {
        // Close file.
        if (file != null) {
            try {
                file.close();
            } catch (Exception e) {}
        }

        // Close connection to server.
        if (stream != null) {
            try {
                stream.close();
            } catch (Exception e) {}
        }
    }
}

// Notify observers that this download's status has changed.
private void stateChanged() {
    setChanged();
    notifyObservers();
}
}

Do you know why my program is just freezing and why my ProgressBar doesn't update? 您知道为什么我的程序只是冻结,为什么ProgressBar没有更新吗?

There could be issue if you use some custom Look&Feel which is not thread safe. 如果您使用一些线程安全的自定义外观,可能会出现问题。 If you use default Look&Feel this could't happen. 如果使用默认的外观,则不会发生。 Possible issue in your case it that when a some URL socket is open that blocks main thread. 在您的情况下,可能的问题是,当某些URL套接字打开时会阻塞主线程。 You invoks SwingUtilities.invokeLater... to update progressbar, this SwingUtils.invokLater() will wait until that web socket is closed. 您调用SwingUtilities.invokeLater ...更新进度条,此SwingUtils.invokLater()将等待直到该Web套接字关闭。 You could use simple: 您可以使用简单的方法:

      new Thread(new Runnable(){ public void run(){ do here what you want in your case...}}).start(); 

or you colud use more complicated SwingWorker object. 或者您使用更复杂的SwingWorker对象。 Also you may use Thread.sleep() method with value of ~1 to 5ms into both run() methods into Download class and download method to optimize processor stress. 同样,您也可以将Thread.sleep()方法的值在1到5毫秒之间,分别用于run()方法和Download类以及download方法,以优化处理器压力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM