|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 4

Figure 8. A file explorer
The preceding application explores a filesystem with a Swing tree. First, I implemented a new tree node adapter for files, which Example 3 lists.
import java.io.File;
import javax.swing.tree.*;
class FileNode extends DefaultMutableTreeNode
implements ExplorableTreeNode {
private boolean explored = false;
public FileNode(File file) {
setUserObject(file);
}
public boolean getAllowsChildren() { return isDirectory(); }
public boolean isLeaf() { return !isDirectory(); }
public File getFile() { return (File)getUserObject(); }
public boolean isDirectory() {
File file = getFile();
return file.isDirectory();
}
public String toString() {
File file = (File)getUserObject();
String filename = file.toString();
int index = filename.lastIndexOf(File.separator);
return (index != -1 && index != filename.length()-1) ?
filename.substring(index+1) :
filename;
}
public boolean isExplored() {
return explored;
}
public void explore() {
if(!isDirectory())
return;
if(!isExplored()) {
File file = getFile();
File[] children = file.listFiles();
for(int i=0; i < children.length; ++i)
add(new FileNode(children[i]));
explored = true;
}
}
}
Notice the similarities between Example 1 and Example 3; once you have one adapter, it's easy to create new ones. Figure 9
shows the FileNode adapter's class diagram. Notice the similarities between Figure 9 and Figure 7.
Figure 9. A file node adapter. Click on thumbnail to view full-size image.
You use file node adapters just like Swing component nodes. Example 4 shows how you can use FileNodes.
import java.io.File;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
abstract class TreePanel extends JPanel {
abstract TreeModel createTreeModel();
public void createTree() {
final JTree tree = new JTree(createTreeModel());
JScrollPane scrollPane = new JScrollPane(tree);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
tree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeCollapsed(TreeExpansionEvent e) {
// Don't care about collapse events.
}
public void treeExpanded(TreeExpansionEvent e) {
...
TreePath path = e.getPath();
ExplorableTreeNode node = (ExplorableTreeNode)
path.getLastPathComponent();
if( ! node.isExplored()) {
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
...
node.explore();
model.nodeStructureChanged(node);
}
}
...
});
}
}
public class Test extends JFrame {
...
public Test() {
...
updateButton.addActionListener(new ActionListener() {
private boolean treeCreated = false;
public void actionPerformed(ActionEvent event) {
if(!treeCreated) {
TreePanel treePanel = new TreePanel() {
public TreeModel createTreeModel() {
FileNode rootNode = new FileNode(new File("/"));
rootNode.explore();
return new DefaultTreeModel(rootNode);
}
};
...
}
}
});
}
public static void main(String args[]) {
GJApp.launch(new Test(),"UI Builder Prototype", 300,300,600,175);
}
}
// Class GJApp omitted for brevity.
The file adapter showcases the Adapter pattern's power. With very little effort, you can adapt any type of tree structure
into objects JTree can manipulate.
The Adapter pattern lets disparate object types work together. It allows Swing trees to manipulate and display any type of tree structure. The requisite adapters are simple and easy to plug into the tree's model.
Read more about Core Java in JavaWorld's Core Java section.
Archived Discussions (Read only)