3

I am new to java swing, I want to read the text file. while reading that file i want to display the percentage of readed lines in java progress bar. Any sample code is welcome. i tried but i don't know whether my logic is correct or not. How can i acheive this.

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) {}
    }
}

    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
PS Kumar
  • 2,096
  • 6
  • 30
  • 45
  • Well, shouldn't the reading of the file by done within the Task and the updating of the progress bat be done within the context of the EDT? Try looking up SwingWorker... – MadProgrammer Apr 19 '14 at 07:44
  • 4
    Use a `SwingWorker`. Your code is breaking Swing's threading model and is overly complicated. Further you don't close your `Reader` so this is a memory leak. Finally, you don't actually update the progress bar as you read the file - you just update every 100ms regardless of file size. – Boris the Spider Apr 19 '14 at 07:54
  • 3
    Consider using a ProgressMonitorInputStream for this. – qqilihq Apr 19 '14 at 09:13
  • 2
    +1 to the suggestion of @qqilihq for `ProgressMonitorInputStream` and [progress monitors](http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html#monitors). I also recommend looking at [`JTextComponent.read(Reader,Object)`](http://docs.oracle.com/javase/8/docs/api/javax/swing/text/JTextComponent.html#read-java.io.Reader-java.lang.Object-). – Andrew Thompson Apr 19 '14 at 09:27

1 Answers1

4

You don't need any Thread to update the progress bar status. You know the total no of bytes present in the file. Just calculate the percent done on the basis of bytes read.

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) {
         ...
    }
}
Braj
  • 46,415
  • 5
  • 60
  • 76
  • 7
    This will block the EDT. It's a bad idea to carry out long running tasks on the EDT as it will freeze the user interface. Another thread is required, just one to do the work not one to update progress. – Boris the Spider Apr 20 '14 at 08:59
  • 1
    Notice that `BufferedReader.readLine()` returns a string [not including](https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()) any line-termination characters. So `readLength` variable and the progress bar will lie, and the difference will accumulate with time, especially for large files containing lots of lines. – Uniqus Jul 07 '16 at 19:37
  • @Uniqus Thanks for correction. Can we fix it? We can add no of bytes used by new line character in each iteration to fix it. Will it correct it? I completely agree with Boris to use another thread for updating progress bar as a good solution. – Braj Jul 11 '16 at 05:25
  • @Braj Well, there are different line endings specific to different operating systems and different file editing tools. There can even be files with mixed line endings. So there is no way to tell whether it was "\n" or "\r\n" stripped by `readLine()`. I am still looking for an elegant solution. – Uniqus Jul 15 '16 at 13:00
  • @Uniqus you can try `System.getProperty("line.separator")` to get the OS specific line seperator as mentioned in [Java doc](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html) – Braj Jul 16 '16 at 05:53
  • @Braj Thanks for the advice. I know about this property. But still there is absolutely no guarantee that the file being processed was created and edited on the current operating system by an editor which follows the system's line ending convention. – Uniqus Jul 18 '16 at 18:49