见代码
package ex4;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
public class Second extends MouseAdapter{
private JFrame jf,jf2;
private JPanel jp;
private JProgressBar jpro;
private JTextField jtf1, jtf2;
private JButton jb,jb1,jb2;
double len=0;
double percent=0;
//界面实现
public Second() {
jf=new JFrame("文件复制");
jf.setBounds(300, 200, 400, 130);
jtf1=new JTextField(25);//源文件地址
jtf2=new JTextField(25);//目标文件地址
jb1=new JButton("选择文件");jb1.addMouseListener(this);
jb2=new JButton("选择地址");jb2.addMouseListener(this);
jb=new JButton("开始复制");jb.addMouseListener(this);
jp=new JPanel();
jp.add(jtf1);
jp.add(jb1);
jp.add(jtf2);
jp.add(jb2);
jf.getContentPane().add(jp,"Center");
jf.getContentPane().add(jb,"South");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
//设置进度条
jf2=new JFrame("复制进度");
jpro=new JProgressBar(JProgressBar.HORIZONTAL);
jpro.setValue(0);
jpro.setStringPainted(true);//显示进度条上的字符可见
jpro.setPreferredSize(new Dimension(350,20));
jpro.setBackground(Color.white);
jpro.setForeground(Color.green);
jf2.add(jpro);
jf2.setSize(400, 60);
jf2.setLocationRelativeTo(null);
jf2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Second();
}
double bytesum=0;
public void copyfile(File from,File to) throws Exception{//文件、文件夹的复制
int byteread=0;
byte[] b=new byte[1024*1024*15];
FileInputStream in;
FileOutputStream out;
if(from.isDirectory()) {
String filepath = from.getAbsolutePath();
filepath=filepath.replaceAll("\\\\", "/");
String toFilepath = to.getAbsolutePath();
toFilepath=toFilepath.replaceAll("\\\\", "/");
int lastIndexOf = filepath.lastIndexOf("/");
toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());
File copy=new File(toFilepath);
if (!copy.exists()) {
copy.mkdirs();
}
for (File f : from.listFiles()) {
copyfile(f, copy);
}
}
else {
String filepath = from.getAbsolutePath();
filepath=filepath.replaceAll("\\\\", "/");
String toFilepath = to.getAbsolutePath();
toFilepath=toFilepath.replaceAll("\\\\", "/");
int lastIndexOf = filepath.lastIndexOf("/");
toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());
//写文件
File newFile = new File(toFilepath);
in = new FileInputStream(from);
out = new FileOutputStream(newFile);
while ((byteread = in.read(b)) != -1) {
out.write(b, 0, byteread);
bytesum+=byteread;
percent=bytesum/len;
jpro.setValue((int)(percent*100));//***
//System.out.println(percent+"-----"+jpro.getValue());//输出调试,查看进度条的值
}
}
}
String src;//获取文本框中源文件地址
String des;//目标地址
//点击鼠标做出响应
public void mouseClicked(MouseEvent e){
if(e.getSource()==jb1) {
JFileChooser jfc=new JFileChooser();
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
jfc.showDialog(new JLabel(),"选择");
File file=jfc.getSelectedFile();
if(file!=null)
src=file.getAbsolutePath();
jtf1.setText(src);
}
else if(e.getSource()==jb2) {
JFileChooser jfc=new JFileChooser();
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
jfc.showDialog(new JLabel(),"选择");
File file=jfc.getSelectedFile();
if(file!=null)
des=file.getAbsolutePath();
jtf2.setText(des);
}
else if(e.getSource()==jb) {
jf2.setVisible(true);//显示进度条
if(jtf1!=null&&jtf2!=null) {
try{
len=getFileLength(src);//源文件的总字节数
File from=new File(src);
File to=new File(des);
new Thread(new Runnable() {//新建一个线程,防止awt事件被阻塞
public void run() {
try {
copyfile(from,to);
}
catch(Exception err) {
err.printStackTrace();
}
}
}).start();
}
catch(Exception ex2) {
ex2.printStackTrace();
}
}
}
}
//获得要复制的文件的总字节数
private long getFileLength(String path1) {
long len=0;
File file=new File(path1);
if(file.isFile())
return file.length();
File[] files=file.listFiles();
for(File f:files)
len+=getFileLength(f.getAbsolutePath());
return len;
}
}
遇到的问题
一、数据处理问题
jpro.setValue((int)(percent*100));//***
开始写成了
jpro.setValue((int)percent*100);导致进度条的值一直为0,我真是sx
二、线程阻塞问题
第一个问题解决后,发现进度条不能还是不能实时显示,即只显示最开始的0和最后的100%
百度的结果如下:
当应用程序在事件线程中执行长时间的操作时,会阻塞正常的AWT事件处理,因此阻止了重绘操作的发生。
因此新建了一个线程来实现文件赋值和进度条显示,问题解决。