실제 진행률은 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
에 정밀 주조 손실되지 않습니다 진행률 막대 값을 설정하십시오.
'double bytes = file.length(); 이중 킬로바이트 = (바이트/1024); 더블 메가 바이트 = (킬로바이트/1024); 이중 기가 바이트 = (메가 바이트/1024); 더블 테라 바이트 = (기가 바이트/1024);'크기를 바이트로 변환 한 다음 합계를 시도 할 수 있습니다. –
long이 가장 큰 int의 크기를 초과하지 않으면 어떤 정확도를 잃지 않을 것입니다.이 상황에서는 의심 스럽습니다 . –
@HovercraftFullOfEels 그 생각조차하지 못했습니다. 고맙습니다. –