import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileFilter;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
public class DirectoryTree extends JTree
{
private static final long serialVersionUID = -9076626433161848703L;
public DirectoryTree()
{
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Computer");
DefaultMutableTreeNode node;
for (File f : File.listRoots())
{
node = new DefaultMutableTreeNode(new FileNode(f));
node.add(new DefaultMutableTreeNode(Boolean.TRUE));
root.add(node);
}
setModel(new DefaultTreeModel(root));
setCellRenderer(new DirTreeRenderer());
addTreeExpansionListener(new DirExpansionListener());
getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
setShowsRootHandles(true);
setEditable(false);
}
private DefaultMutableTreeNode getTreeNode(TreePath path)
{
return (DefaultMutableTreeNode) (path.getLastPathComponent());
}
private FileNode getFileNode(DefaultMutableTreeNode node)
{
if (node == null)
return null;
Object obj = node.getUserObject();
if (obj instanceof FileNode)
return (FileNode) obj;
return null;
}
private class DirTreeRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer
{
private static final long serialVersionUID = 1L;
public DirTreeRenderer()
{
super();
setOpaque(false);
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
boolean leaf, int row, boolean hasFocus)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object obj = node.getUserObject();
if(obj instanceof Boolean)
{
return super.getTreeCellRendererComponent(tree, "Lese Verzeichnis...", sel, expanded, leaf,
row, hasFocus);
}
super.getTreeCellRendererComponent(tree, obj.toString(), sel, expanded, leaf, row, hasFocus);
if(obj instanceof FileNode)
{
setIcon(FileSystemView.getFileSystemView().getSystemIcon(((FileNode)obj).getFile()));
}
return this;
}
}
private class DirExpansionListener implements TreeExpansionListener
{
public void treeExpanded(TreeExpansionEvent event)
{
final DefaultMutableTreeNode node = getTreeNode(event.getPath());
final FileNode fileNode = getFileNode(node);
Thread runner = new Thread()
{
public void run()
{
if (fileNode != null && fileNode.expand(node))
{
Runnable runnable = new Runnable()
{
public void run()
{
((DefaultTreeModel)getModel()).reload(node);
}
};
SwingUtilities.invokeLater(runnable);
}
}
};
runner.start();
}
public void treeCollapsed(TreeExpansionEvent event)
{
}
}
private class FileNode implements Comparable<FileNode>
{
private File file;
public FileNode(File file)
{
this.file = file;
}
public boolean expand(DefaultMutableTreeNode parent)
{
DefaultMutableTreeNode top = (DefaultMutableTreeNode) parent.getFirstChild();
if (top == null || !(top.getUserObject() instanceof Boolean))
{
return false;
}
parent.removeAllChildren();
File[] dirs = listDirectories();
List<FileNode> nodeList = new ArrayList<FileNode>(dirs.length);
for (File f : dirs)
{
nodeList.add(new FileNode(f));
}
Collections.sort(nodeList);
for(FileNode fileNode : nodeList)
{
DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileNode);
parent.add(node);
if (fileNode.hasSubDirs())
node.add(new DefaultMutableTreeNode(Boolean.TRUE));
}
return true;
}
public File getFile()
{
return file;
}
public File[] listDirectories()
{
File dirs[] = file.listFiles(new FileFilter() {
public boolean accept(File file)
{
return file.canRead() && file.isDirectory() && !file.isHidden();
}
});
return dirs != null ? dirs : new File[0];
}
public boolean hasSubDirs()
{
return listDirectories().length > 0;
}
public int compareTo(FileNode node)
{
return Collator.getInstance(Locale.GERMANY).compare(file.getName(), node.getFile().getName());
}
public String toString()
{
return file.getName().length() > 0 ? file.getName() : file.getPath();
}
}
public static void main(String[] args) throws Exception
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
final JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{
frame.setVisible(false);
System.exit(0);
}
});
frame.add(new JScrollPane(new DirectoryTree()));
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}