java进度条不动怎么解决?

TheDisguiser 2020-09-15 15:06:12 java常见问答 8965

在编写完进度条后,我们有时候会遇到它完全不动的情况,小伙伴们知道是什么原因吗?下面听小编为你们讲解讲解。

进度条不动可能是因为这个原因,“当应用程序在事件线程中执行长时间的操作时,会阻塞正常的AWT事件处理,因此阻止了重绘操作的发生”,即API本身就是线程不安全的。造成这个错误的原因,就是在run方法内直接写:

progressBar.setValue(jd);

最终修改示例:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
public class Exp10_3 extends JFrame implements Runnable
{
    boolean b = false; // 线程执行的标志
    int jd = 0; // 当前进度
    long sum = 0; // 当前共复制的长度
    JButton button1 = new JButton("被复制");
    JTextField beCyFile = new JTextField(30);
    JButton button2 = new JButton("复制到");
    JTextField CyToDir = new JTextField(30);
    JButton Start = new JButton("开始复制");
    JLabel label = new JLabel("进度");
    JProgressBar progressBar = new JProgressBar();
    void initUI()
    {
        JPanel top1 = new JPanel();
        JPanel top2 = new JPanel();
        JPanel end = new JPanel();
        top1.add(button1);
        top1.add(beCyFile);
        top2.add(button2);
        top2.add(CyToDir);
        setLayout(new GridLayout(4, 1));
        add(top1);
        add(top2);
        add(Start);
        progressBar.setStringPainted(true); // 设置进度条上字符串可显示
        progressBar.setBackground(Color.GREEN); // 设置进度条颜色
        end.add(label);
        end.add(progressBar);
        add(end);
        button1.addActionListener(new ActionListener()
        {
            // 将选择文件的绝对路径显示到被复制后的文本框内
            @Override
            public void actionPerformed(ActionEvent e)
            {
                JFileChooser fc = new JFileChooser();
                fc.setFileHidingEnabled(false); // 显示隐藏文件
                fc.setMultiSelectionEnabled(false); // 允许多选
                fc.setDialogTitle("请选择要复制的文件");
                if (fc.showOpenDialog(Exp10_3.this) == JFileChooser.APPROVE_OPTION)
                {
                    beCyFile.setText(fc.getSelectedFile()
                        .getAbsolutePath());
                    CyToDir.setText(fc.getSelectedFile()
                        .getParent()); // 获取file文件的父目录(强大的API) 自我设定:默认复制到同一目录
                }
            }
        });
        button2.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                JFileChooser fc = new JFileChooser();
                fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 仅仅能选择目录
                fc.setDialogTitle("请选择要复制到的路径");
                if (fc.showOpenDialog(Exp10_3.this) == JFileChooser.APPROVE_OPTION)
                {
                    CyToDir.setText(fc.getSelectedFile()
                        .getAbsolutePath());
                }
            }
        });
        Start.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                jd = 0;
                b = true;
                try
                {
                    String file1Path = beCyFile.getText();
                    File file1 = new File(beCyFile.getText()); // 被复制的文件
                    String file2Path = CyToDir.getText() + "\\copy" + file1.getName(); // 复制完后新文件路径名
                    File file2 = new File(file2Path); // 新建复制文件
                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file1Path));
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file2Path));
                    byte[] be = new byte[1024 * 1024]; // 之前定义为b和boolean重复了 屏蔽了全局标志b
                    int len = bis.read(be);
                    long sum = 0;
                    long file1len = file1.length();
                    while (-1 != len)
                    {
                        bos.write(be, 0, len); // 一次读一个字节数组 换行也会读 不用自动换行了
                        bos.flush();
                        sum += len;
                        jd = (int)(sum * 1.0 / file1len * 100); // 之前没有乘1.0 且多写了一个(int) 导致jd一直是0 最后一次突变100
                        len = bis.read(be);
                    }
                    最后再绘一次
                    Dimension d = progressBar.getSize();
                    Rectangle rect = new Rectangle(0, 0, d.width, d.height);
                    progressBar.setValue(jd);
                    progressBar.paintImmediately(rect);
                    b = false;
                    System.out.println("b=" + b);
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        });
        Thread t = new Thread(this);
        t.start();
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args)
    {
        Exp10_3 t = new Exp10_3();
        t.initUI();
    }
    @Override
    public void run()
    {
        while (true)
        {
            if (b)
            {
                //progressBar.setValue(jd);//之前run内就这一行,进度条一直不刷新
                Dimension d = progressBar.getSize();
                Rectangle rect = new Rectangle(0, 0, d.width, d.height);
                progressBar.setValue(jd);
                progressBar.paintImmediately(rect);
                if (jd == 100)
                {
                    b = false;
                    //System.out.println("run内b=" + b);// 不能写return 此进程不能结束 一直开着
                }
            }
            //System.out.println("我没有结束");//删了此行进度条就又不刷新了
            //第一次改进  上面一行换成下面5行  即输出操作改成停顿1ms
            try
            {
                Thread.sleep(1);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

以上就是本篇文章的所有内容,对于一些java常见问题及解决方法还有不懂的话就来我们网站看看吧。

推荐阅读:

java进度条怎么实现?

java进度条窗口具体如何制作?

java进度条时间显示怎么实现?