从文本文件读取时多线程进度条不更新

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

我的问题是它只在进度条中显示两个输出,如果未启动则为 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                   
}

所以,你有两个基本问题,首先,你从来没有调用 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 已经有 "progress" 支持,您可以使用 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 属性 更改时更新进度