package gui.tree;
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.dnd.Autoscroll;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
public class FileTree extends JTree implements Autoscroll {
public static final Insets defaultScrollInsets = new Insets(8, 8, 8, 8);
protected Insets scrollInsets = defaultScrollInsets;
public FileTree(String path) throws FileNotFoundException, SecurityException {
super((TreeModel) null);
putClientProperty("JTree.lineStyle", "Angled");
DefaultMutableFileTreeNode rootNode = new DefaultMutableFileTreeNode(null, path);
boolean addedNodes = rootNode.populateDirectories(true);
setModel(new DefaultTreeModel(rootNode));
addTreeExpansionListener(new TreeExpansionHandler());
}
public String getPathName(TreePath path) {
Object o = path.getLastPathComponent();
if (o instanceof DefaultMutableFileTreeNode) {
return ((DefaultMutableFileTreeNode) o).fullName;
}
return null;
}
public DefaultMutableFileTreeNode addNode(DefaultMutableFileTreeNode parent, String name) {
int index = parent.addNode(name);
if (index != -1) {
((DefaultTreeModel) getModel()).nodesWereInserted(
parent, new int[]{index});
return (DefaultMutableFileTreeNode) parent.getChildAt(index);
}
return null;
}
public void setScrollInsets(Insets insets) {
this.scrollInsets = insets;
}
public Insets getScrollInsets() {
return scrollInsets;
}
public Insets getAutoscrollInsets() {
Rectangle r = getVisibleRect();
Dimension size = getSize();
Insets i = new Insets(r.y + scrollInsets.top, r.x + scrollInsets.left,
size.height - r.y - r.height + scrollInsets.bottom,
size.width - r.x - r.width + scrollInsets.right);
return i;
}
public void autoscroll(Point location) {
JScrollPane scroller =
(JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
if (scroller != null) {
JScrollBar hBar = scroller.getHorizontalScrollBar();
JScrollBar vBar = scroller.getVerticalScrollBar();
Rectangle r = getVisibleRect();
if (location.x <= r.x + scrollInsets.left) {
hBar.setValue(hBar.getValue() - hBar.getUnitIncrement(-1));
}
if (location.y <= r.y + scrollInsets.top) {
vBar.setValue(vBar.getValue() - vBar.getUnitIncrement(-1));
}
if (location.x >= r.x + r.width - scrollInsets.right) {
hBar.setValue(hBar.getValue() + hBar.getUnitIncrement(1));
}
if (location.y >= r.y + r.height - scrollInsets.bottom) {
vBar.setValue(vBar.getValue() + vBar.getUnitIncrement(1));
}
}
}
public static class DefaultMutableFileTreeNode extends DefaultMutableTreeNode {
public DefaultMutableFileTreeNode(String parent, String name) throws SecurityException,
FileNotFoundException {
this.name = name;
fullName = parent == null ? name : parent + File.separator + name;
File f = new File(fullName);
if (f.exists() == false) {
throw new FileNotFoundException("File " + fullName + " does not exist");
}
isDir = f.isDirectory();
if (isDir == false && f.isFile() == false) {
isDir = true;
}
}
public boolean isLeaf() {
return !isDir;
}
public boolean getAllowsChildren() {
return isDir;
}
public boolean isDir() {
return isDir;
}
public String getFullName() {
return fullName;
}
public String toString() {
return name;
}
boolean populateDirectories(boolean descend) {
boolean addedNodes = false;
if (populated == false) {
File f;
try {
f = new File(fullName);
} catch (SecurityException e) {
populated = true;
return false;
}
if (interim == true) {
removeAllChildren();
interim = false;
}
String fileNames[] = f.list();
ArrayList al = new ArrayList();
for (int i = 0; i < fileNames.length; i++) {
String fileName = fileNames[i];
File d = new File(fullName, fileName);
try {
DefaultMutableFileTreeNode node =
new DefaultMutableFileTreeNode(fullName, fileName);
al.add(node);
if (descend && d.isDirectory()) {
node.populateDirectories(false);
}
addedNodes = true;
if (descend == false) {
break;
}
} catch (Throwable t) {
}
}
if (addedNodes == true) {
Object[] nodes = al.toArray();
Arrays.sort(nodes, new Comparator() {
public boolean equals(Object o) {
return false;
}
public int compare(Object o1, Object o2) {
DefaultMutableFileTreeNode node1 = (DefaultMutableFileTreeNode) o1;
DefaultMutableFileTreeNode node2 = (DefaultMutableFileTreeNode) o2;
if (node1.isDir != node2.isDir) {
return node1.isDir ? -1 : +1;
}
return node1.fullName.compareTo(node2.fullName);
}
});
for (int j = 0; j < nodes.length; j++) {
this.add((DefaultMutableFileTreeNode) nodes[j]);
}
}
if (descend == true || addedNodes == false) {
populated = true;
} else {
interim = true;
}
}
return addedNodes;
}
public int addNode(String name) {
if (populated == true) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
DefaultMutableFileTreeNode node = (DefaultMutableFileTreeNode) getChildAt(i);
if (node.name.equals(name)) {
if (node.isDir()) {
node.interim = true;
node.populated = false;
}
return -1;
}
}
try {
DefaultMutableFileTreeNode node = new DefaultMutableFileTreeNode(fullName, name);
add(node);
return childCount;
} catch (Exception e) {
}
}
return -1;
}
protected String name; protected String fullName; protected boolean populated; protected boolean interim; protected boolean isDir; }
protected class TreeExpansionHandler implements TreeExpansionListener {
public void treeExpanded(TreeExpansionEvent evt) {
TreePath path = evt.getPath(); JTree tree = (JTree) evt.getSource();
DefaultMutableFileTreeNode node = (DefaultMutableFileTreeNode) path.getLastPathComponent();
if (node.populateDirectories(true)) {
((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);
}
}
public void treeCollapsed(TreeExpansionEvent evt) {
}
}
}