java 进度条 不更新_java进度条不动怎么解决?
在編寫完進度條后,我們有時候會遇到它完全不動的情況,小伙伴們知道是什么原因嗎?下面聽小編為你們講解講解。
進度條不動可能是因為這個原因,“當應用程序在事件線程中執行長時間的操作時,會阻塞正常的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进度条不动怎么解决?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十天学会单片机(1)单片机的认识、各进制
- 下一篇: linux 串口驱动