Многопоточный индикатор выполнения не обновляется при чтении из текстового файла

Моя проблема в том, что он показывает только два вывода на индикаторе выполнения: 0%, если он не запущен, и 100% сразу, когда программа закончила сканирование файла. Я хочу, чтобы он показывал процесс при сканировании файла не на 100% мгновенно (он не обновляет индикатор выполнения). Любая помощь была бы отличной. Спасибо! :) Вот полный код:

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                   
}

person Mr.X    schedule 15.02.2016    source источник
comment
Вы никогда не вызываете publish, поэтому process никогда не вызывается. Кроме того, вы нарушаете однопоточные правила Swing, обновляя индикатор выполнения в doInBackground.   -  person MadProgrammer    schedule 15.02.2016
comment
Кстати, допустим, вы прочитали 10 символов, 10 * 100 = 1000!   -  person MadProgrammer    schedule 15.02.2016
comment
Для примера пример, пример   -  person MadProgrammer    schedule 15.02.2016


Ответы (1)


Итак, у вас есть две основные проблемы: во-первых, вы никогда не вызываете publish, поэтому process никогда не будет вызываться, а во-вторых, ваши вычисления прогресса неверны...

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));

Таким образом, если вы прочитаете 10 символов, значение вашего прогресса будет 100 * 10, что равно 1000!

SwingWorker уже имеет поддержку "прогресс", которую вы можете использовать PropertyChangeListener, чтобы получать уведомления при его изменении, для пример

Итак, ваш код должен выглядеть как...

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

Затем вы прикрепите PropertyChangeListener к экземпляру SwingWorker и обновите ход выполнения при изменении свойства progress.

person MadProgrammer    schedule 15.02.2016
comment
Спасибо, что указали на это, (100 * 10) LOL. Я не заметил этого из-за всех этих проектов и прочего, многозадачность во всей красе. Но все равно спасибо :) Теперь работает - person Mr.X; 17.02.2016