2014-10-30 55 views
2

我有一份要拷貝到另一個位置的文件列表,我想使用JProgressBar來監視傳輸的進度。準確地總結文件大小以便在JProgressBar中使用

JProgressBar構造函數只接受一個int的邊界,而File.length返回一個long。我知道我可以將長整型轉換爲整數並且失去一些準確性,但是這是做到這一點的正確方法嗎?

我不包括任何代碼,因爲它不是一個真正的語法或編碼的問題,我只是不知道,如果一個遠投,爲在進度條中使用int是正確的還是我的目的不夠準確。

+0

'double bytes = file.length(); double kilobytes =(bytes/1024); double megabytes =(kilobytes/1024); double gigabytes =(兆字節/ 1024); double terabytes =(gigabytes/1024);'你可以將大小轉換爲字節,然後嘗試求和 – 2014-10-30 13:49:03

+3

除非你的長度超過最大整數的大小,否則你不會失去任何精度,在這種情況下值得懷疑。 – 2014-10-30 13:49:16

+0

@HovercraftFullOfEels我甚至沒有想到這一點。謝謝 – 2014-10-30 13:53:44

回答

2

我真的沒有看到有關進度條邊界的問題,只是因爲實際進度是從0到100的百分比值。您應該始終能夠計算處理的字節與總字節數之間的比例,這就是實際進展。

我認爲正確的問題會是這樣的:我如何正確地更新我的進度條的進度根據文件的長度和總字節傳輸?

考慮這個例子:

import java.awt.event.ActionEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.File; 
import java.util.List; 
import javax.swing.AbstractAction; 
import javax.swing.Action; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

public class Demo { 

    private void createAndShowGUI() { 

     final JProgressBar progressBar = new JProgressBar(); 
     progressBar.setStringPainted(true); 
     progressBar.setString(""); 

     final SwingWorker<Void,String> worker = new SwingWorker<Void, String>() { 
      @Override 
      protected Void doInBackground() throws Exception { 

       long totalSize = 0l; 

       File[] files = new File(System.getProperty("user.dir")).listFiles(); 
       for (File file : files) { 
        totalSize += file.length(); 
       } 

       long transferred = 0l; 

       for (File file : files) {      
        Thread.sleep(250); // Just for animation purpose 
        transferred += file.length(); 
        int progress = (int) (transferred * 100l/totalSize); 
        setProgress(progress); 

        String text = String.format("%1s%%: %2s/%3s bytes", progress, transferred, totalSize); 
        publish(text); 
       } 

       return null; 
      } 

      @Override 
      protected void process(List<String> chunks) { 
       progressBar.setString(chunks.get(chunks.size() - 1)); 
      } 
     }; 

     worker.addPropertyChangeListener(new PropertyChangeListener() { 
      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 
       if ("progress".equals(evt.getPropertyName())) { 
        progressBar.setValue((Integer)evt.getNewValue()); 
       } 
      } 
     }); 

     Action startAction = new AbstractAction("Start") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       worker.execute(); 
       setEnabled(false); 
      } 
     }; 

     JPanel content = new JPanel(); 
     content.add(progressBar); 
     content.add(new JButton(startAction)); 

     JFrame frame = new JFrame("Demo"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.add(content); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Demo().createAndShowGUI(); 
      } 
     }); 
    }  
} 

因爲transferred * 100l/totalSize將始終爲0和100之間的值,你可能會失去一個小數點準確性,但你絕對不會爲了失去精密鑄造它int到設置進度條值。