2014-10-30 1 views
2

다른 위치로 복사 할 파일 목록이 있으며 JProgressBar를 사용하여 전송 진행 상황을 모니터링하고 싶습니다.JProgressBar에서 사용할 파일 크기를 정확히 합산합니다.

JProgressBar 생성자는 경계에 대해서만 int를 취하며 File.length는 long을 반환합니다. 나는 long으로 int 형을 캐스팅 할 수 있고 정확성을 잃을 수 있다는 것을 알고 있지만 이것을 수행하는 올바른 방법입니까?

구문 또는 코딩 문제가 아니기 때문에 코드를 포함하지 않았습니다. 진행률 막대에서 int를 long으로 캐스팅하는 것이 정확하고 정확할 지 모르겠습니다.

+0

'double bytes = file.length(); 이중 킬로바이트 = (바이트/1024); 더블 메가 바이트 = (킬로바이트/1024); 이중 기가 바이트 = (메가 바이트/1024); 더블 테라 바이트 = (기가 바이트/1024);'크기를 바이트로 변환 한 다음 합계를 시도 할 수 있습니다. –

+3

long이 가장 큰 int의 크기를 초과하지 않으면 어떤 정확도를 잃지 않을 것입니다.이 상황에서는 의심 스럽습니다 . –

+0

@HovercraftFullOfEels 그 생각조차하지 못했습니다. 고맙습니다. –

답변

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에 정밀 주조 손실되지 않습니다 진행률 막대 값을 설정하십시오.

관련 문제