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 3 of 4

The SwingComponentNode class also implements an ExplorableTreeNode interface that I defined with the two methods expore() and isExplored(). The explore() method is called by a tree expansion listener and adds instances of SwingComponentNode as children of the node being expanded.

Figure 7 displays the SwingComponentNode class diagram.

Figure 7. A component node adapter. Click on thumbnail to view full-size image.

Predictably, SwingComponentNode conforms to Figure 2's adapter; it recasts JComponents as ExplorableTreeNodes by delegating to a JComponent instance. SwingComponentNode employs the delegation variation of the Adapter pattern, as shown in Figure 3. Example 2 shows how you use the adapter.

Example 2. Use the SwingComponentNode 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() {
                     SwingComponentNode rootNode = new SwingComponentNode(upperRightPanel);
                     rootNode.explore();
                      return new DefaultTreeModel(rootNode);
                  }
               };
               ...
            }
         }
      });
   }
   public static void main(String args[]) {
      GJApp.launch(new Test(),"UI Builder Prototype", 300,300,600,175);
   }
}


I implemented an abstract TreePanel class that creates a tree, puts it in a scrollpane, and handles tree node expansion events by calling the node's explore() method as needed. Concrete TreePanel extensions must implement createTreeModel(), which supplies the tree's model. The nodes in that model must implement the ExpandableTreeNode interface.

The Test class creates a TreePanel instance with an anonymous inner class that creates a default tree model with a SwingComponentNode for the root node. That node represents the upper-right panel in the application. From there, JTree takes care of the rest.

A file explorer

A true test of any Adapter implementation is how easily you can create and integrate a new adapter. So after I created the UI builder prototype discussed above, I decided to test the Swing Adapter implementation by creating an adapter for files. Figure 8 shows the result.

  • Print
  • Feedback

Resources