I want to show the filesystem using a CheckBoxTree with digin behaviour.
The filesystem does not have to be editable.
I have code that works; it uses FileTreeNode which I extended from DefaultMutableTreeNode.
FileTreeNode creates FileTreeNode instances for its children, only when asked for a child through
method getChildAt(int index) .
It works, but is rather slow, when compared to a javax.swing.JTree .
With digin enabled, the CheckBoxTree creates way more FileTreeNode instances than
the JTree, when showing the same part of the filesystem.
Is there a way to make the creation of FileTreeNode instances more lazy ?
I have enclosed some files. Two of these files contain main(String[]) to run test programs:
FileTreeFrame.java: test program using JTree and FileTreeNode
CheckBoxFileTreeFrame.java: test program using CheckBoxTree and FileTreeNode
Anybody any idea to increase speed, be more lazy ?
- Code: Select all
import java.io.*;
import java.util.*;
import java.util.logging.*;
import javax.swing.tree.*;
@SuppressWarnings("serial")
public class FileTreeNode extends DefaultMutableTreeNode {
private static class FileComparator implements Comparator<File> {
public int compare(File o1, File o2) {
return o1.getName().compareTo(o2.getName());
}
}
private static Logger getLogger() {
return Logger.getLogger(FileTreeNode.class.getName());
}
private static final FileComparator fileComparator;
private static final DirFileFilter dirFileFilter;
private static final FileFileFilter fileFileFilter;
static {
fileComparator = new FileComparator();
dirFileFilter = new DirFileFilter();
fileFileFilter = new FileFileFilter();
}
/** Children have been constructed. */
private boolean initialized;
private File file;
public FileTreeNode(File file) {
super(file);
getLogger().log(Level.INFO, file.getPath());
this.file = file;
setAllowsChildren(file.isDirectory());
initialized = false;
}
public boolean getAllowsChildren() {
return file.isDirectory();
}
public TreeNode getChildAt(int index) {
assertChildren();
return super.getChildAt(index);
}
private void assertChildren() {
if(initialized) {
return;
}
initialized = true;
if(!file.isDirectory()) {
return;
}
List<File> dirs = Arrays.asList(file.listFiles(dirFileFilter));
Collections.sort(dirs, fileComparator);
List<File> files = Arrays.asList(file.listFiles(fileFileFilter));
Collections.sort(files, fileComparator);
List<File> all = new ArrayList<File>();
all.addAll(dirs);
all.addAll(files);
for(File f : all) {
FileTreeNode child = new FileTreeNode(f);
add(child);
child.setParent(this);
}
}
public int getChildCount() {
if(file.isDirectory()) {
if(initialized) {
return super.getChildCount();
}
else {
String[] names = file.list();
return names==null ? 0 : names.length;
}
}
return 0;
}
public boolean isLeaf() {
if(file.isDirectory()) {
if(initialized) {
return super.isLeaf();
}
else {
String[] names = file.list();
return names==null ? true : (names.length>0);
}
}
else {
return false;
}
}
}
- Code: Select all
import java.io.*;
import javax.swing.*;
import javax.swing.tree.*;
import com.jidesoft.plaf.*;
import com.jidesoft.swing.*;
@SuppressWarnings("serial")
public class CheckBoxFileTreeFrame extends JFrame {
private CheckBoxTree fileTree;
private TreeModel fileSystemModel;
public CheckBoxFileTreeFrame(String directory) {
super("CheckBoxFileFileTreeFrame");
FileTreeNode top = new FileTreeNode(new File(directory));
fileSystemModel = new DefaultTreeModel(top, true);
fileTree = new CheckBoxTree(fileSystemModel) {
public String convertValueToText(Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
FileTreeNode node = (FileTreeNode) value;
File file = (File) node.getUserObject();
return file.getName();
}
};
fileTree.setEditable(false);
fileTree.getCheckBoxTreeSelectionModel().setDigIn(true);
getContentPane().add(new JScrollPane(fileTree));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(640, 480);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {
e.printStackTrace();
}
LookAndFeelFactory.installJideExtension();
new CheckBoxFileTreeFrame("c:\\");
}
});
}
}
- Code: Select all
import java.io.*;
import javax.swing.*;
import javax.swing.tree.*;
import com.jidesoft.plaf.*;
import com.jidesoft.swing.*;
@SuppressWarnings("serial")
public class FileTreeFrame extends JFrame {
private JTree fileTree;
private DefaultTreeModel fileSystemModel;
public FileTreeFrame(String directory) {
super("JTree FileSystem Viewer");
FileTreeNode top = new FileTreeNode(new File(directory));
fileSystemModel = new DefaultTreeModel(top, true);
fileTree = new JTree(fileSystemModel) {
public String convertValueToText(Object value, boolean selected,
boolean expanded, boolean leaf, int row, boolean hasFocus) {
FileTreeNode node = (FileTreeNode)value;
File file = (File)node.getUserObject();
return file.getName();
}
};
fileTree.setEditable(false);
getContentPane().add(new JScrollPane(fileTree));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(640, 480);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {
e.printStackTrace();
}
new FileTreeFrame("c:\\");
}
});
}
}
- Code: Select all
import java.io.*;
public class DirFileFilter implements FileFilter {
public boolean accept(File file) {
return file.isDirectory();
}
}
- Code: Select all
import java.io.*;
public class FileFileFilter implements FileFilter {
public boolean accept(File file) {
return file.isFile();
}
}