Swing JFC Java

/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly 
*/
// SortTreeDemo.java
//This class creates a tree model using the SortTreeModel with
//a File hierarchy as input.
//
import java.io.File;
import java.util.Comparator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
public class SortTreeDemo extends JFrame {
  public SortTreeDemo(String startDir) {
    super("SortTreeModel Demonstration");
    setSize(300, 400);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    PrettyFile f = new PrettyFile(startDir);
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(f);
    SortTreeModel model = new SortTreeModel(root,
        new TreeStringComparator());
    fillModel(model, root);
    JTree tree = new JTree(model);
    getContentPane().add(new JScrollPane(tree));
  }
  protected void fillModel(SortTreeModel model, DefaultMutableTreeNode current) {
    PrettyFile pf = (PrettyFile) current.getUserObject();
    File f = pf.getFile();
    if (f.isDirectory()) {
      String files[] = f.list();
      // ignore "." files
      for (int i = 0; i < files.length; i++) {
        if (files[i].startsWith("."))
          continue;
        PrettyFile tmp = new PrettyFile(pf, files[i]);
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(tmp);
        model.insertNodeInto(node, current);
        if (tmp.getFile().isDirectory()) {
          fillModel(model, node);
        }
      }
    }
  }
  public class PrettyFile {
    File f;
    public PrettyFile(String s) {
      f = new File(s);
    }
    public PrettyFile(PrettyFile pf, String s) {
      f = new File(pf.f, s);
    }
    public File getFile() {
      return f;
    }
    public String toString() {
      return f.getName();
    }
  }
  public static void main(String args[]) {
    SortTreeDemo demo = new SortTreeDemo(args.length == 1 ? args[0] : ".");
    demo.setVisible(true);
  }
}
//SortTreeModel.java
//This class is similar to the DefaultTreeModel, but it keeps
//a node's children in alphabetical order.
//
class SortTreeModel extends DefaultTreeModel {
  private Comparator comparator;
  public SortTreeModel(TreeNode node, Comparator c) {
    super(node);
    comparator = c;
  }
  public SortTreeModel(TreeNode node, boolean asksAllowsChildren, Comparator c) {
    super(node, asksAllowsChildren);
    comparator = c;
  }
  public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent) {
    int index = findIndexFor(child, parent);
    super.insertNodeInto(child, parent, index);
  }
  public void insertNodeInto(MutableTreeNode child, MutableTreeNode par, int i) {
    // The index is useless in this model, so just ignore it.
    insertNodeInto(child, par);
  }
  // Perform a recursive binary search on the children to find the right
  // insertion point for the next node.
  private int findIndexFor(MutableTreeNode child, MutableTreeNode parent) {
    int cc = parent.getChildCount();
    if (cc == 0) {
      return 0;
    }
    if (cc == 1) {
      return comparator.compare(child, parent.getChildAt(0)) <= 0 ? 0 : 1;
    }
    return findIndexFor(child, parent, 0, cc - 1); // First & last index
  }
  private int findIndexFor(MutableTreeNode child, MutableTreeNode parent,
      int i1, int i2) {
    if (i1 == i2) {
      return comparator.compare(child, parent.getChildAt(i1)) <= 0 ? i1
          : i1 + 1;
    }
    int half = (i1 + i2) / 2;
    if (comparator.compare(child, parent.getChildAt(half)) <= 0) {
      return findIndexFor(child, parent, i1, half);
    }
    return findIndexFor(child, parent, half + 1, i2);
  }
}
//TreeStringComparator.java
//This class compares the contents of the userObject as strings.
//It's case-insensitive.
//
class TreeStringComparator implements Comparator {
  public int compare(Object o1, Object o2) {
    if (!(o1 instanceof DefaultMutableTreeNode && o2 instanceof DefaultMutableTreeNode)) {
      throw new IllegalArgumentException(
          "Can only compare DefaultMutableTreeNode objects");
    }
    String s1 = ((DefaultMutableTreeNode) o1).getUserObject().toString();
    String s2 = ((DefaultMutableTreeNode) o2).getUserObject().toString();
    return s1.compareToIgnoreCase(s2);
  }
}