package tk.amberide.ide.swing.tree.filesystem;
import java.io.File;
import java.util.ArrayList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class FileTreeModel implements TreeModel {
private FileTreeNode root = null;
private ArrayList listeners = null;
public FileTreeModel() {
this.root = new FileTreeNode(null);
}
public FileTreeModel(File root) {
setRoot(root);
}
public void setRoot(File root) {
if (!root.isDirectory()) {
throw new IllegalArgumentException("root must be a directory");
}
this.root = addNodes(null, root);
}
protected FileTreeNode addNodes(FileTreeNode curTop, File dir) {
String curPath = dir.getPath();
FileTreeNode curDir = new FileTreeNode(dir);
if (curTop != null) { // should only be null at root
curTop.add(curDir);
}
File f;
ArrayList<File> files = new ArrayList<File>();
// Make two passes, one for Dirs and one for Files. This is #1.
String[] tmp = dir.list();
if (tmp != null) {
_outer:
for (int i = 0; i < tmp.length; i++) {
String thisObject = tmp[i];
String newPath;
if (curPath.equals(".")) {
newPath = thisObject;
} else {
newPath = curPath + File.separator + thisObject;
}
f = new File(newPath);
if (f.isDirectory()) {
addNodes(curDir, f);
} else {
files.add(f);
}
}
}
// Pass two: for files.
for (int fnum = 0; fnum < files.size(); fnum++) {
curDir.add(new FileTreeNode(files.get(fnum)));
}
return curDir;
}
public Object getChild(Object parent, int index) {
FileTreeNode ftn = (FileTreeNode) parent;
return ftn.getChildAt(index);
}
public int getChildCount(Object parent) {
FileTreeNode ftn = (FileTreeNode) parent;
return ftn.getChildCount();
}
public int getIndexOfChild(Object parent, Object child) {
FileTreeNode ftn = (FileTreeNode) parent;
return ftn.getIndex((TreeNode) child);
}
public FileTreeNode getRoot() {
return this.root;
}
public boolean isLeaf(Object node) {
FileTreeNode ftn = (FileTreeNode) node;
if (ftn == this.root) {
return false;
}
if (ftn.getFile().isDirectory()) {
return false;
}
return true;
}
public void reload(TreePath tp) {
FileTreeNode node = (FileTreeNode) tp.getLastPathComponent();
node.removeAllChildren();
if (this.listeners != null) {
for (int i = 0; i < this.listeners.size(); i++) {
TreeModelListener listener = (TreeModelListener) this.listeners.get(i);
listener.treeStructureChanged(new TreeModelEvent(this, tp));
}
}
}
public void addTreeModelListener(TreeModelListener l) {
if (this.listeners == null) {
this.listeners = new ArrayList();
}
this.listeners.add(l);
}
public void removeTreeModelListener(TreeModelListener l) {
if (this.listeners != null) {
this.listeners.remove(l);
}
}
public void valueForPathChanged(TreePath path, Object newValue) {
}
public class FileTreeNode extends DefaultMutableTreeNode {
File file;
boolean root = false;
public FileTreeNode(File content) {
this.file = content;
userObject = this;
}
public File getFile() {
return file;
}
public String toString() {
return file != null ? file.toString() : "null";
}
}
}