2015-09-03 5 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

Посмотрите на [Concurrency in Swing] (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

Может возникнуть проблема, если вы используете какой-либо пользовательский вид & Чувство, которое не является потокобезопасным. Если вы используете default Look & Почувствуйте, что этого не может быть. Возможная проблема в вашем случае, когда открыт какой-либо URL-адрес, который блокирует основной поток. Вы вызываете SwingUtilities.invokeLater ... чтобы обновить progressbar, этот SwingUtils.invokLater() будет ждать, пока этот веб-сокет не будет закрыт. Вы можете использовать простую:

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

или вы используете более сложный объект SwingWorker. Также вы можете использовать метод Thread.sleep() со значением от 1 до 5 мс в обоих методах run() в класс загрузки и метод загрузки для оптимизации нагрузки процессора.

Смежные вопросы