2015-09-03 26 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方法以优化处理器压力。