Search code examples
javaswingfile-handlingswingworkerjprogressbar

Multi-threaded Progress Bar not updating while Reading from text file


My problem is that It only shows two output in the progress bar 0% if not started and 100% instantly when the program finished scanning the file. I want it to show the process while scanning the file not 100% instantly.(its not updating the progress bar) Any help would be great. Thanks! :) Here is the full code:

import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.FileReader;
import java.io.BufferedReader;
import javax.swing.JOptionPane;
import javax.swing.*;
import javax.swing.SwingWorker;
import javax.swing.SwingUtilities;
import java.util.List;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import
public class Log_in extends javax.swing.JFrame {

    /**
     * Creates new form Log_in
     */

    FileOutputStream fos;
    DataOutputStream dos;
    FileInputStream fis ;
    DataInputStream dis;
    private Timer time;
    private ActionListener ActionL;
    public static String r;
    public Log_in(){
        setContentPane(new JLabel(new ImageIcon("C:\\Users\\Gondar\\Music\\bg.jpg")));     
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextField1.setText("Student Name");
        jTextField1.setToolTipText("Enter your profile name.");

        jButton1.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jButton1.setText("Submit");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel1.setFont(new java.awt.Font("Rockwell", 0, 26)); // NOI18N
        jLabel1.setForeground(new java.awt.Color(255, 255, 255));
        jLabel1.setText("Curriculum Simulator with Recommendation System");

        jProgressBar1.setStringPainted(true);

        jLabel2.setForeground(new java.awt.Color(102, 255, 102));
        jLabel2.setText("Loading Profile....");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(0, 208, Short.MAX_VALUE)
                .addComponent(jLabel1)
                .addGap(203, 203, 203))
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(477, 477, 477)
                        .addComponent(jLabel2))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(465, 465, 465)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(420, 420, 420)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(83, 83, 83)
                .addComponent(jLabel1)
                .addGap(74, 74, 74)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(44, 44, 44)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 244, Short.MAX_VALUE)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>                        
SwingWorker sw= new SwingWorker<Boolean,Integer>() {
    protected Boolean doInBackground() throws Exception {
        try {
         double lengthPerPercent = 100.0;
         long readLength = 0;
         FileReader fr=new FileReader("mario.txt");
         BufferedReader br=new BufferedReader(fr);
         while((r = br.readLine())!= null){
         readLength += r.length();
        jProgressBar1.setValue((int)(lengthPerPercent * readLength));
        }
        fr.close();
        }catch(Exception err) {
            System.out.println(err);
        }
        return true;
    }
 protected void process(List<Integer> chunks) {
        for (Integer i : chunks)
            jProgressBar1.setValue(i);
    }
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTextField1.setText("Student Name");
        jTextField1.setToolTipText("Enter your profile name.");

        jButton1.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jButton1.setText("Submit");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel1.setFont(new java.awt.Font("Rockwell", 0, 26)); // NOI18N
        jLabel1.setForeground(new java.awt.Color(255, 255, 255));
        jLabel1.setText("Curriculum Simulator with Recommendation System");

        jProgressBar1.setStringPainted(true);

        jLabel2.setForeground(new java.awt.Color(102, 255, 102));
        jLabel2.setText("Loading Profile....");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(0, 208, Short.MAX_VALUE)
                .addComponent(jLabel1)
                .addGap(203, 203, 203))
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(477, 477, 477)
                        .addComponent(jLabel2))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(465, 465, 465)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(420, 420, 420)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 182, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(83, 83, 83)
                .addComponent(jLabel1)
                .addGap(74, 74, 74)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(44, 44, 44)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 244, Short.MAX_VALUE)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>                        
    protected void done() {
        try {
            if (jProgressBar1.getValue() == 100 )
                jProgressBar1.setValue(100); // 100% done
            else
                System.out.println("ProcessingFailed.");
        }
        catch (Exception ex) {
                System.out.println("Processing Failed.");
        }
    }
    };

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
   sw.execute();
        /*try {
         double lengthPerPercent = 100.0;
          long readLength = 0;
         FileReader fr=new FileReader("mario.txt");
         BufferedReader br=new BufferedReader(fr);
         while ((r = br.readLine()) != null) {
            readLength += r.length();
            jProgressBar1.setValue((int) Math.round(lengthPerPercent * readLength));
        }
        jProgressBar1.setValue(100);
        fr.close();
        if (jProgressBar1.getValue() == 100) {


        }
        }catch(Exception err) {
            JOptionPane.showMessageDialog(this, err);
        }

    }                                        

    /**
     * @param args the command line arguments
     */
}
    public static void main(String args[]) throws Exception{
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Log_in().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration                   
}

Solution

  • So, you have two basic problems, first, you never call publish, so process will never be called and secondly, you progress calculations are wrong...

    double lengthPerPercent = 100.0;
    long readLength = 0;
    FileReader fr=new FileReader("mario.txt");
    BufferedReader br=new BufferedReader(fr);
    while((r = br.readLine())!= null){
        readLength += r.length();
        jProgressBar1.setValue((int)(lengthPerPercent * readLength));
    

    So, if you read 10 characters, you progress value would be 100 * 10 which equals 1000!

    SwingWorker already has "progress" support, which you can use a PropertyChangeListener to be notified when it changes, for example

    So, your code should look for more like...

    File file = new File("mario.txt");
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String r = null;
        long fileLength = file.length();
        long readLength = 0;
        while ((r = br.readLine()) != null) {
            readLength += r.length();
            setProgress((int) (((float) readLength / (float) fileLength) * 100f);
        }
    }
    

    Then you would attach a PropertyChangeListener to the instance of SwingWorker and update the progress when the progress property changes