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); 
    } 
}     
 
}