2015-09-03 69 views
0

我正在嘗試創建一個安裝程序,即正在爲我的程序下載一些文件。當一個文件正在下載時,我想讓我的JProgressBar被更新,但是當我使用我的代碼時程序凍結了。下載文件時更新JProgressBar

我的下載無效

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; 
    } 


} 

我的下載類(不是從我這裏,我發現它在互聯網上)

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(); 
} 
} 

你知道爲什麼我的程序只是凍結,爲什麼我的ProgressBar不更新?

+1

看看[併發中的擺動](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)和[工作線程和SwingWorker](http://docs.oracle.com/ JavaSE的/教程/ uiswing /併發/ worker.html)。 'invokeLater'沒有做你認爲的那樣 – MadProgrammer

+0

並且看看[這個例子](http://stackoverflow.com/questions/12020949/jprogressbar-isnt-progressing/12021971#12021971)的一些想法 – MadProgrammer

回答

0

如果您使用一些自定義外觀可能會有問題&感覺不是線程安全的。如果您使用默認外觀&感覺這種事情不會發生。 可能的問題在於,當某個URL套接字打開時會阻塞主線程。你調用SwingUtilities.invokeLater ...來更新進度條,這個SwingUtils.invokLater()將一直等到該web套接字關閉。你可以使用簡單的:

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

或者你colud使用更復雜的SwingWorker對象。也可以使用Thread.sleep()方法,將值爲〜1至5ms的Thread.sleep()方法應用到兩個run()方法中,並將其轉換爲Download類和Download方法以優化處理器壓力。