准确汇总文件大小以在 JProgressBar 中使用
Posted
技术标签:
【中文标题】准确汇总文件大小以在 JProgressBar 中使用【英文标题】:Accurately summing file sizes to use in a JProgressBar 【发布时间】:2014-10-30 13:47:14 【问题描述】:我有一个要复制到另一个位置的文件列表,我想使用 JProgressBar 来监控传输进度。
JProgressBar 构造函数只接受一个 int 作为边界,而 File.length 返回一个 long。我知道我可以将 long 转换为 int 并失去一些准确性,但这是正确的方法吗?
我没有包含任何代码,因为这实际上不是语法或编码问题,我只是不确定将 long 转换为 int 以用于进度条对于我的目的是否正确或准确。
【问题讨论】:
double bytes = file.length(); double kilobytes = (bytes / 1024); double megabytes = (kilobytes / 1024); double gigabytes = (megabytes / 1024); double terabytes = (gigabytes / 1024);
你可以将大小转换成字节然后尝试求和
除非您的 long 超出最大 int 的大小,否则您不会失去任何准确性,这在这种情况下是值得怀疑的。
@HovercraftFullOfEels 我什至没有想到这一点。谢谢
一个 int 最多只能存储 4Gb - 这些天几乎没有很多数据。
@BarrySW19 你是说只要我的文件小于 4Gb 我就可以了吗?
【参考方案1】:
我并没有真正看到关于进度条边界的问题,因为实际进度是从 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
以设置进度条值。
【讨论】:
以上是关于准确汇总文件大小以在 JProgressBar 中使用的主要内容,如果未能解决你的问题,请参考以下文章
JTable的TableColumn添加多个JProgressBar