FileTree.java
package ac.essex.ooechs.imaging.commons.util.panels;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.*;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Vector;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Arrays;
/**
* <p/>
* Adapted from code at:
* http://www.java2s.com/Code/Java/Swing-JFC/FileSystemTree.htm
* </p>
*
* @author Olly Oechsle, University of Essex, Date: 18-Feb-2008
* @version 1.0
*/
public abstract class FileTree extends JTree {
private File root;
private String[] children;
public FileTree() {
this(new File(System.getProperty("user.dir")), null);
}
public FileTree(File directory, FilenameFilter filter) {
super();
setModel(new FileSystemModel(directory, filter));
setEditable(true);
addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent event) {
File file = (File) getLastSelectedPathComponent();
onSelectFile(file);
}
});
}
public File getRoot() {
return root;
}
public String[] getChildren() {
return children;
}
/**
* Called when a file is selected in the tree
*/
public abstract void onSelectFile(File f);
class FileSystemModel implements TreeModel {
Comparator<String> byDirThenAlpha = new DirAlphaComparator();
private File root;
private FilenameFilter filter;
private Vector<TreeModelListener> listeners = new Vector<TreeModelListener>();
public FileSystemModel(File rootDirectory, FilenameFilter filter) {
this.root = rootDirectory;
this.filter = filter;
}
public Object getRoot() {
return root;
}
public Object getChild(Object parent, int index) {
File directory = (File) parent;
children = directory.list(filter);
Arrays.sort(children, byDirThenAlpha);
return new TreeFile(directory, children[index]);
}
public int getChildCount(Object parent) {
File file = (File) parent;
if (file.isDirectory()) {
String[] fileList = file.list(filter);
if (fileList != null)
return fileList.length;
}
return 0;
}
public boolean isLeaf(Object node) {
File file = (File) node;
return file.isFile();
}
public int getIndexOfChild(Object parent, Object child) {
File directory = (File) parent;
File file = (File) child;
children = directory.list(filter);
Arrays.sort(children, byDirThenAlpha);
for (int i = 0; i < children.length; i++) {
if (file.getName().equals(children[i])) {
return i;
}
}
return -1;
}
public void valueForPathChanged(TreePath path, Object value) {
File oldFile = (File) path.getLastPathComponent();
String fileParentPath = oldFile.getParent();
String newFileName = (String) value;
File targetFile = new File(fileParentPath, newFileName);
oldFile.renameTo(targetFile);
File parent = new File(fileParentPath);
int[] changedChildrenIndices = {getIndexOfChild(parent, targetFile)};
Object[] changedChildren = {targetFile};
fireTreeNodesChanged(path.getParentPath(), changedChildrenIndices, changedChildren);
}
private void fireTreeNodesChanged(TreePath parentPath, int[] indices, Object[] children) {
TreeModelEvent event = new TreeModelEvent(this, parentPath, indices, children);
Iterator iterator = listeners.iterator();
TreeModelListener listener;
while (iterator.hasNext()) {
listener = (TreeModelListener) iterator.next();
listener.treeNodesChanged(event);
}
}
public void addTreeModelListener(TreeModelListener listener) {
listeners.add(listener);
}
public void removeTreeModelListener(TreeModelListener listener) {
listeners.remove(listener);
}
private class TreeFile extends File {
public TreeFile(File parent, String child) {
super(parent, child);
}
public String toString() {
return getName();
}
}
}
class DirAlphaComparator implements Comparator<String> {
// Comparator interface requires defining compare method.
public int compare(String filea, String fileb) {
return filea.compareToIgnoreCase(fileb);
}
}
}