するツールをSwingで作ってみました。
コピー中に進捗が分かるように、進捗バー(JProgressBar)をつけてみました。
また、ディレクトリをコピーする処理は別スレッドで処理するようにしました。
デザインは少しいけてませんが、それはまたということで。
・初期画面
・コピーボタン押下後
・コピー完了後
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import javax.swing.BoxLayout;
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.SwingWorker;
import javax.swing.Timer;
/**
* ディレクトリをコピー
* 処理中は進捗バーを表示
*/
public class DirCopy extends JFrame implements ActionListener {
JProgressBar progress = new JProgressBar();
JButton buttonFromCopy = null;
JButton buttonToCopy = null;
JButton buttonCopy = null;
int fileSize = 0;
float currentFileSizePercent = 0;
File fileFrom = null;
File fileTo = null;
boolean flg1 = false;
boolean flg2 = false;
Timer time = null;
public static void main(String[] args) {
DirCopy frame = new DirCopy();
frame.setBounds(20, 20, 300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
DirCopy() {
JLabel label = new JLabel("進捗バー");
label.setAlignmentX(0.5f);
progress.setPreferredSize(new Dimension(10, 100));
progress.setStringPainted(true);
buttonFromCopy = new JButton("コピー元");
buttonFromCopy.addActionListener(this);
buttonFromCopy.setActionCommand("FromCopy");
buttonFromCopy.setAlignmentY(0.5f);
buttonToCopy = new JButton("コピー先");
buttonToCopy.setActionCommand("ToCopy");
buttonToCopy.addActionListener(this);
buttonToCopy.setAlignmentY(0.5f);
buttonCopy = new JButton("コピー");
buttonCopy.setEnabled(false);
buttonCopy.setActionCommand("copy");
buttonCopy.addActionListener(this);
JButton buttonClose = new JButton("close");
buttonClose.setAlignmentX(0.5f);
buttonClose.setActionCommand("close");
buttonClose.addActionListener(this);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.LINE_AXIS));
panel3.setLayout(new BoxLayout(panel3, BoxLayout.Y_AXIS));
panel1.add(label);
panel1.add(progress);
panel2.add(buttonFromCopy);
panel2.add(buttonToCopy);
panel2.add(buttonCopy);
panel3.add(buttonClose);
getContentPane().add(panel1, BorderLayout.PAGE_START);
getContentPane().add(panel2, BorderLayout.CENTER);
getContentPane().add(panel3, BorderLayout.PAGE_END);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("time")) {
if (currentFileSizePercent < 100) {
progress.setValue((int)currentFileSizePercent);
progress.setString("処理中です");
} else {
progress.setValue((int)currentFileSizePercent);
progress.setString("完了");
time.stop();
}
}
// 閉じるボタン押下
if (e.getActionCommand().equals("close")) {
System.exit(0);
}
// コピー元ボタン押下
if (e.getActionCommand().equals("FromCopy")) {
JFileChooser fChooser = new JFileChooser();
//ディレクトリのみ選択可能
fChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int select = fChooser.showOpenDialog(this);
if(select == JFileChooser.APPROVE_OPTION) {
fileFrom = fChooser.getSelectedFile();
fileSize = (int) getFileSize(fileFrom);
flg1 = true;
// コピーボタンを活性化
if (flg2) buttonCopy.setEnabled(true);
}
}
// コピー先ボタン押下
if (e.getActionCommand().equals("ToCopy")) {
JFileChooser fChooser = new JFileChooser();
// ディレクトリのみ選択可能
fChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int select = fChooser.showOpenDialog(this);
if (select == JFileChooser.APPROVE_OPTION) {
fileTo = fChooser.getSelectedFile();
flg2 = true;
// コピーボタンを活性化
if (flg1) buttonCopy.setEnabled(true);
}
}
// コピーボタン押下
if(e.getActionCommand().equals("copy")) {
File dir = new File(fileTo.getPath() + "/" + fileFrom.getName());
if(dir.isDirectory() && dir.exists()) {
dirDelete(dir);
}
time = new Timer(1000, this);
time.setActionCommand("time");
time.start();
FileCopy fileCopy = new FileCopy();
// 別スレッドでファイルコピー
fileCopy.execute();
}
}
/**
* ディレクトリ以下のファイルサイズを取得
* @param dir ディレクトリ
* @return ファイルサイズ
*/
private long getFileSize(File dir) {
long size = 0;
File[] fileList = dir.listFiles();
if(fileList != null) {
for(File file : fileList) {
if(file.isFile()) {
size += file.length();
} else {
size += getFileSize(file);
}
}
}
return size;
}
/**
* @param dirFrom コピー元のディレクトリ
* @param dirTo コピー先のディレクトリ
*/
private void fileCopy(File dirFrom, File dirTo) {
File[] fromFile = dirFrom.listFiles();
dirTo = new File(dirTo.getPath() + "/" + dirFrom.getName());
dirTo.mkdir();
if(fromFile != null) {
for(File f : fromFile) {
// ファイルの場合
if (f.isFile()) {
copy(f, dirTo);
// ディレクトリの場合
} else {
fileCopy(f, dirTo);
}
}
}
}
/**
* ファイルをディレクトリにコピーする
* @param file コピーするファイル
* @param dir コピーするファイルの格納フォルダ
*/
private void copy(File file, File dir) {
File copyFile = new File(dir.getPath() + "/" + file.getName());
FileChannel channelFrom = null;
FileChannel channelTo = null;
try {
copyFile.createNewFile();
channelFrom = new FileInputStream(file).getChannel();
channelTo = new FileOutputStream(copyFile).getChannel();
//ファイルをコピー
channelFrom.transferTo(0, channelFrom.size(), channelTo);
float currentFileSize = getFileSize(new File(fileTo.getPath() + "/" + fileFrom.getName()));
//処理の進捗率をファイルサイズから求める
currentFileSizePercent = (float) (currentFileSize / fileSize) * 100;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (channelFrom != null) { channelFrom.close(); }
if (channelTo != null) { channelTo.close(); }
} catch (IOException e) { e.printStackTrace(); }
}
}
/**
* 指定したディレクトリを削除
* @param file 削除ディレクトリ
*/
private void dirDelete(File dir) {
for (File f : dir.listFiles()) {
if (f.isFile()) {
f.delete();
} else {
dirDelete(f);
f.delete();
}
}
dir.delete();
}
/**
* ディレクトリをコピー
*/
class FileCopy extends SwingWorker<Object, Object> {
@Override
public Object doInBackground() {
fileCopy(fileFrom, fileTo);
return null;
}
}
}


