Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

Adopt Adapter

Understand how adapters let disparate systems work together

  • Print
  • Feedback

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.

Example 3. FileNode tree node adapter

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.

Example 4. Use the FileNode adapter

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.

Keep adapting

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.

About the author

David Geary is the author of Core JSTL Mastering the JSP Standard Tag Library (Prentice Hall, 2002; ISBN: 0131001531), Advanced JavaServer Pages (Prentice Hall, 2001; ISBN: 0130307041), and the Graphic Java series (Prentice Hall). David has been developing object-oriented software with numerous object-oriented languages for almost 20 years. Since reading the GOF Design Patterns book in 1994, David has been an active proponent of design patterns, and has used and implemented design patterns in Smalltalk, C++, and Java. In 1997, David began working full-time as an author and occasional speaker and consultant. David is a member of the expert groups defining the JSP Standard Tag Library and JavaServer Faces, and is a contributor to the Apache Struts JSP framework. David is currently working on Core JavaServer Faces, which will be published in the spring of 2004.

Read more about Core Java in JavaWorld's Core Java section.

  • Print
  • Feedback

Resources