【问题标题】:How to use Java progress bar while read a text file?阅读文本文件时如何使用Java进度条?
【发布时间】:2014-06-03 17:48:55
【问题描述】:

我是 java swing 新手,我想阅读文本文件。在读取该文件时,我想在 java 进度条中显示已读取行的百分比。欢迎任何示例代码。我试过了,但我不知道我的逻辑是否正确。我怎样才能做到这一点。

import java.io.*;
import javax.swing.*;
import javax.swing.UIManager.*;
import javax.swing.border.EtchedBorder;
public class UploadFile 
{  
JFrame frame;
JProgressBar progressBar_1;
public static void main(String args[])throws IOException
{  
    UploadFile obj=new UploadFile();
    obj.redfile();
}  
public UploadFile()
{
    frame = new JFrame();
    frame.setBounds(100, 100, 400, 200);
    frame.getContentPane().setLayout(null);
    progressBar_1 = new JProgressBar();
    progressBar_1.setBounds(102, 40, 150, 16);
    frame.getContentPane().add(progressBar_1);
    progressBar_1.setStringPainted(true);
    frame.setVisible(true);
}
public void redfile()
{
    try{
    String s="";
    File f1=new File("sample.txt");
    FileReader fr=new FileReader(f1);
    BufferedReader br=new BufferedReader(fr);
    Task t=new Task();
    t.start();
    while((s=br.readLine())!=null){
                                                                                           try{Thread.sleep(200);}catch(Exception e){
        }
        System.out.println("-->"+s);
    }
    }catch(Exception e){
    }
}
private class Task extends Thread
{
    public void run()
    {
        for(int j=0;j<=100; j+=5)
        {
            progressBar_1.setValue(j);
        }
        try {
           Thread.sleep(100);
        } catch (InterruptedException e) {}
    }
}

    }

【问题讨论】:

  • 嗯,不应该在任务中完成文件的读取和进度棒的更新在 EDT 的上下文中完成吗?尝试查找 SwingWorker...
  • 使用SwingWorker。您的代码破坏了 Swing 的线程模型并且过于复杂。此外,您没有关闭您的Reader,所以这是内存泄漏。最后,您实际上并没有在阅读文件时更新进度条 - 无论文件大小如何,您只需每 100 毫秒更新一次。
  • 考虑为此使用 ProgressMonitorInputStream。
  • +1 对@qqilihq 对ProgressMonitorInputStreamprogress monitors 的建议。我还建议查看JTextComponent.read(Reader,Object)
  • @BoristheSpider 感谢这个想法。

标签: java multithreading swing io jprogressbar


【解决方案1】:

您不需要任何线程来更新进度条状态。您知道文件中存在的字节总数。只需根据读取的字节数计算完成的百分比。

public void redfile() {
    try {
        ...

        long totalLength = f1.length();
        double lengthPerPercent = 100.0 / totalLength;
        long readLength = 0;
        System.out.println(totalLength);
        while ((s = br.readLine()) != null) {
            readLength += s.length();
            progressBar_1.setValue((int) Math.round(lengthPerPercent * readLength));
            ...
        }
        progressBar_1.setValue(100);
        fr.close();

    } catch (Exception e) {
         ...
    }
}

【讨论】:

  • 这将阻止 EDT。在 EDT 上执行长时间运行的任务是个坏主意,因为它会冻结用户界面。需要另一个线程,只需要一个线程来完成工作,而不是更新进度。
  • 请注意 BufferedReader.readLine() 返回一个字符串 not including 任何行终止字符。所以readLength变量和进度条会撒谎,并且差异会随着时间的推移而累积,尤其是对于包含很多行的大文件。
  • @Uniqus 感谢您的指正。我们可以修复它吗?我们可以在每次迭代中添加换行符使用的字节数来修复它。它会纠正它吗?我完全同意 Boris 使用另一个线程来更新进度条作为一个好的解决方案。
  • @Braj 好吧,不同的操作系统和不同的文件编辑工具有不同的行尾。甚至可以有混合行结尾的文件。因此无法判断它是被readLine() 剥离的“\n”还是“\r\n”。我仍在寻找一个优雅的解决方案。
  • @Uniqus 您可以尝试System.getProperty("line.separator") 来获取Java doc 中提到的操作系统特定的行分隔符
猜你喜欢
  • 1970-01-01
  • 2015-11-11
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多