2012-12-28 5 views
4

다른 방법으로 톤을 시도했지만 진행률 표시 줄과 함께 작동하지 않거나 내가 원하는 방식으로 작동하지 않습니다.JProgressBar도 업데이트하면서 파일을 다운로드하십시오.

이미 진행률 표시 줄이있는 새 창을 만들었으며 JProgressBar을 업데이트하면서 파일을 다운로드 할 수있는 방법을 만들어야합니다. 파일을 다운로드하는 데 매우 쉽게 사용할 수있는 Apache Commons 메서드가 있지만 JProgressBar과 호환되지 않는 것 같습니다.

SwingUtilities.invokeLater은 진행률 표시 줄에 업데이트되지 않는 것 같지만 다른 스레드에서 실행하면 문제가 발생하지만 콘솔로 인쇄 할 때 실행할 수 있습니다. 나는 심지어 progressBar.repaint() 방법을 시도했다.

그럼 내가 파일을 다운로드 할 수있는 방법은 JProgressBar을 다운로드 상태를 반영하여 업데이트하는 것입니다.

미리 감사드립니다. Keir

답변

12

this 문서를 기반으로 진행률 표시 줄을 쉽게 업데이트 할 수있는 Download class을 작성하시는 것이 좋습니다. 당신이 볼 수 있듯이,이 Download 클래스는 sizedownloaded 같은 일부 특정 분야를 가지고

import java.io.*; 
import java.net.*; 
import java.util.*; 

// This class downloads a file from a URL. 
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(); 
} 

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

:

Download 클래스입니다.

다른 방법에서는 쓸 수있다 : 당신이 매 10ms마다 같은 일정한 간격으로 진행 표시 줄을 업데이트 않는 새로운 Thread을, 시작할 수 이후

JProgressBar j = new JProgressBar(0,download.getSize()); 

j.setValue(download.getDownloaded()); 

희망이 도움이 될 수 있습니다. 새 스레드에서 파일을 다운로드

4

잘 작동 :

import java.awt.BorderLayout; 
import java.awt.Container; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.atomic.AtomicBoolean; 
import java.util.concurrent.locks.LockSupport; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JProgressBar; 

/** 
* 
* @author adyliu([email protected]) 
* @since 2012-12-28 
*/ 
public class JProgressBarDemo { 

    public static void main(String[] args) { 
     final JProgressBar pbFile = new JProgressBar(); 
     pbFile.setValue(0); 
     pbFile.setMaximum(100); 
     pbFile.setStringPainted(true); 
     pbFile.setBorder(BorderFactory.createTitledBorder("Download file")); 

     JFrame theFrame = new JFrame("ProgressBar Demo"); 
     theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     Container contentPane = theFrame.getContentPane(); 
     contentPane.add(pbFile, BorderLayout.SOUTH); 
     final JButton btnDownload = new JButton("Download"); 
     contentPane.add(btnDownload); 
     final AtomicBoolean running = new AtomicBoolean(false); 
     btnDownload.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       running.set(!running.get()); 
       btnDownload.setText(running.get() ? "Pause" : "Continue"); 
       if (running.get()) { 
        new Thread() { 
         public void run() { 
          //download file in a thread 
          int v = 0; 
          while (running.get() && v < pbFile.getMaximum()) { 
           pbFile.setValue(++v); 
           LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(200)); 
          } 
         } 
        }.start(); 
       } 
      } 
     }); 
     theFrame.setSize(300, 150); 
     theFrame.setLocationRelativeTo(null); 
     theFrame.setVisible(true); 
    } 

} 
관련 문제