JProgressbar Update solution
Hi,
here is the code to update progressbar while reading a file,i would certainly appreciate if anyone could give a feedback or provide a better solution than this.
import java.awt.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
publicclass ProgressDemoextends JFrameimplements ActionListener
{
JButton button;
JProgressBar pb;
JTextArea tf;
FileInputStream fis=null;
public ProgressDemo()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container pane=getContentPane();
pane.setLayout(new BorderLayout());
tf=new JTextArea(20,20);
JScrollPane sp=new JScrollPane(tf);
button=new JButton("Open");
button.addActionListener(this);
pb=new JProgressBar();
pb.setStringPainted(true);
setProgressMin();
setProgressMax();
JPanel panel=new JPanel();
panel.add(pb);
panel.add(button);
pane.add(sp,BorderLayout.CENTER);
pane.add(panel,BorderLayout.SOUTH);
show();
}
publicvoid actionPerformed(ActionEvent ae)
{
if(ae.getSource()==button)
{
try
{
setFileProgress();
}
catch(Exception e){}
}
}
publicvoid setProgressMax()
{
new Thread(new Runnable(){
publicvoid run()
{
try{
FileInputStream fis=new FileInputStream("test.txt");
int fileSize=fis.available();
pb.setMaximum(fileSize);
fis.close();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}).start();
}
publicvoid setProgressMin()
{
new Thread(new Runnable(){
publicvoid run()
{
try
{
pb.setMinimum(0);
}
catch(Exception e)
{ e.printStackTrace();
}
}
}).start();
}
publicvoid setFileProgress()
{
new Thread(new Runnable(){
publicvoid run()
{
try{
FileInputStream fis=new FileInputStream("test.txt");
byte[] buf =newbyte[1024*10];
int len;
while ((len = fis.read(buf))!=-1)
{
tf.append(new String(buf,0,len)+"\n");
showFileProgress(len);
}
fis.close();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}).start();
}
publicvoid showFileProgress(finalint length)
{
new Thread(new Runnable(){
publicvoid run()
{
try{
pb.setValue(pb.getValue()+length);
}
catch(Exception e)
{ e.printStackTrace();
}
}
}).start();
}
publicstaticvoid main(String[] args)
{
new ProgressDemo();
}
}
Best Regards,
Zmonc
[6700 byte] By [
zmonca] at [2007-10-2 8:20:06]

You should read API doc for SwingUtilities.invokeLater() and invokeAndWait() methods, and,
other documentations linked from there.
Rule of thumb is: Long and time-consuming task that is launched from withing GUI event handler
should be run as a separate thread. And, GUI update required in the thread should be registered
with GUI event queue by calling invokeXxxx() method.
See this code:
import java.awt.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;
public class ProgressDemo extends JFrame implements ActionListener{
JButton button;
JProgressBar pb;
JTextArea ta;
int flen, count;
File infile;
Thread fread;
String line, charset;
byte[] ba;
public ProgressDemo(String fnam){
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container pane = getContentPane();
charset = "UTF-8";
ta = new JTextArea(20, 20);
JScrollPane sp = new JScrollPane(ta);
button = new JButton("Open");
button.addActionListener(this);
infile = new File(fnam);
flen = (int)(infile.length());
// line count or percentage might be more appropriate for a huge file
pb = new JProgressBar(0, flen);
pb.setStringPainted(true);
JPanel panel = new JPanel();
panel.add(pb);
panel.add(button);
pane.add(sp,BorderLayout.CENTER);
pane.add(panel,BorderLayout.SOUTH);
pack();
setVisible(true);
fread = new Thread(){
public void run(){
try{
BufferedReader br = new BufferedReader(new FileReader(infile));
while ((line = br.readLine()) != null){
if (line.length() == 0){
++count; // assume UNIX text file
}
else{
ba = line.getBytes(charset);
count += (ba.length + 1);
}
// This type of GUI update should sync with actual progress of I/O.
// For that, we use invokeAndWait() instead of invokeLater()
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
ta.append(line + "\n");
pb.setValue(count);
}
});
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
pb.setValue(flen); // just in case ...
}
});
}
catch (Exception e){
e.printStackTrace();
}
}
}; // end thread def
} // constructor
public void actionPerformed(ActionEvent ae){
fread.start();
button.setEnabled(false);
}
public static void main(String[] args) {
String filename = "OldTestament.txt";
if (args.length > 0){
filename = args[0];
}
new ProgressDemo(filename);
}
}
hiwaa at 2007-7-16 22:19:07 >
