package Editor.Utils;
import java.io.File;
import java.util.Date;
/**
* FileSystemModel is a TreeTableModel representing a hierarchical file
* system. Nodes in the FileSystemModel are FileNodes which, when they
* are directory nodes, cache their children to avoid repeatedly querying
* the real file system.
*
* @version %I% %G%
*
* @author Philip Milne
* @author Scott Violet
*/
public class FileSystemModel extends AbstractTreeTableModel
implements TreeTableModel {
// Names of the columns.
static protected String[] cNames = {"Name", "Size"};//, "Type", "Modified"};
// Types of the columns.
static protected Class[] cTypes = {TreeTableModel.class, Integer.class, String.class, Date.class};
// The the returned file length for directories.
public static final Integer ZERO = new Integer(0);
public FileSystemModel() {
super(new FileNode(new File(File.separator)));
}
//
// Some convenience methods.
//
protected File getFile(Object node) {
FileNode fileNode = ((FileNode)node);
return fileNode.getFile();
}
protected Object[] getChildren(Object node) {
FileNode fileNode = ((FileNode)node);
return fileNode.getChildren();
}
//
// The TreeModel interface
//
public int getChildCount(Object node) {
Object[] children = getChildren(node);
return (children == null) ? 0 : children.length;
}
public Object getChild(Object node, int i) {
return getChildren(node)[i];
}
// The superclass's implementation would work, but this is more efficient.
public boolean isLeaf(Object node)
{
return getFile(node).isFile();
}
//
// The TreeTableNode interface.
//
public int getColumnCount() {
return cNames.length;
}
public String getColumnName(int column) {
return cNames[column];
}
public Class getColumnClass(int column) {
return cTypes[column];
}
public Object getValueAt(Object node, int column) {
File file = getFile(node);
try {
switch(column) {
case 0:
return file.getName();
case 1:
return file.isFile() ? new Integer((int)file.length()) : ZERO;
case 2:
return file.isFile() ? "File" : "Directory";
case 3:
return new Date(file.lastModified());
}
}
catch (SecurityException se) { }
return null;
}
}
/* A FileNode is a derivative of the File class - though we delegate to
* the File object rather than subclassing it. It is used to maintain a
* cache of a directory's children and therefore avoid repeated access
* to the underlying file system during rendering.
*/
class FileNode {
File file;
Object[] children;
public FileNode(File file) {
this.file = file;
}
// Used to sort the file names.
static private MergeSort fileMS = new MergeSort() {
public int compareElementsAt(int a, int b) {
return 0;//((String)toSort[a]).compareTo((String)toSort[b]);
}
};
/**
* Returns the the string to be used to display this leaf in the JTree.
*/
public String toString() {
return file.getName();
}
public File getFile() {
return file;
}
/**
* Loads the children, caching the results in the children ivar.
*/
protected Object[] getChildren() {
if (children != null) {
return children;
}
try {
String[] files = file.list();
if(files != null) {
fileMS.sort(files);
children = new FileNode[files.length];
String path = file.getPath();
for(int i = 0; i < files.length; i++) {
File childFile = new File(path, files[i]);
children[i] = new FileNode(childFile);
}
}
} catch (SecurityException se) {}
return children;
}
}