在编写完进度条后,我们有时候会遇到它完全不动的情况,小伙伴们知道是什么原因吗?下面听小编为你们讲解讲解。
进度条不动可能是因为这个原因,“当应用程序在事件线程中执行长时间的操作时,会阻塞正常的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进度条不动怎么解决?分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/27494.html