Mega Code Archive

 
Categories / Java / Swing JFC
 

Undo Example 6

/* Core SWING Advanced Programming  By Kim Topley ISBN: 0 13 083292 8        Publisher: Prentice Hall   */ import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.dnd.Autoscroll; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import javax.swing.JFrame; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; public class FileTreeTest {   public static void main(String[] args) {     try {         UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");     } catch (Exception evt) {}        try {       JFrame f = new JFrame("File Tree Test");       final FileTree ft = new FileTree("D:\\");       ft.addTreeSelectionListener(new TreeSelectionListener() {         public void valueChanged(TreeSelectionEvent evt) {           TreePath path = evt.getPath();           String name = ft.getPathName(path);           System.out.println("File " + name + " has been "               + (evt.isAddedPath() ? "selected" : "deselected"));         }       });       f.getContentPane().add(new JScrollPane(ft));       f.setSize(300, 300);       f.addWindowListener(new WindowAdapter() {         public void windowClosing(WindowEvent evt) {           System.exit(0);         }       });       f.setVisible(true);     } catch (FileNotFoundException e) {       System.out.println("File " + args[0] + " not found");     }   } } class FileTree extends JTree implements Autoscroll {   public static final Insets defaultScrollInsets = new Insets(8, 8, 8, 8);   protected Insets scrollInsets = defaultScrollInsets;   public FileTree(String path) throws FileNotFoundException,       SecurityException {     super((TreeModel) null); // Create the JTree itself     // Use horizontal and vertical lines     putClientProperty("JTree.lineStyle", "Angled");     // Create the first node     FileTreeNode rootNode = new FileTreeNode(null, path);     // Populate the root node with its subdirectories     boolean addedNodes = rootNode.populateDirectories(true);     setModel(new DefaultTreeModel(rootNode));     // Listen for Tree Selection Events     addTreeExpansionListener(new TreeExpansionHandler());   }   // Returns the full pathname for a path, or null if not a known path   public String getPathName(TreePath path) {     Object o = path.getLastPathComponent();     if (o instanceof FileTreeNode) {       return ((FileTreeNode) o).fullName;     }     return null;   }   // Adds a new node to the tree after construction.   // Returns the inserted node, or null if the parent   // directory has not been expanded.   public FileTreeNode addNode(FileTreeNode parent, String name) {     int index = parent.addNode(name);     if (index != -1) {       ((DefaultTreeModel) getModel()).nodesWereInserted(parent,           new int[] { index });       return (FileTreeNode) parent.getChildAt(index);     }     // No node was created     return null;   }   // Autoscrolling support   public void setScrollInsets(Insets insets) {     this.scrollInsets = insets;   }   public Insets getScrollInsets() {     return scrollInsets;   }   // Implementation of Autoscroll interface   public Insets getAutoscrollInsets() {     Rectangle r = getVisibleRect();     Dimension size = getSize();     Insets i = new Insets(r.y + scrollInsets.top, r.x + scrollInsets.left,         size.height - r.y - r.height + scrollInsets.bottom, size.width             - r.x - r.width + scrollInsets.right);     return i;   }   public void autoscroll(Point location) {     JScrollPane scroller = (JScrollPane) SwingUtilities.getAncestorOfClass(         JScrollPane.class, this);     if (scroller != null) {       JScrollBar hBar = scroller.getHorizontalScrollBar();       JScrollBar vBar = scroller.getVerticalScrollBar();       Rectangle r = getVisibleRect();       if (location.x <= r.x + scrollInsets.left) {         // Need to scroll left         hBar.setValue(hBar.getValue() - hBar.getUnitIncrement(-1));       }       if (location.y <= r.y + scrollInsets.top) {         // Need to scroll up         vBar.setValue(vBar.getValue() - vBar.getUnitIncrement(-1));       }       if (location.x >= r.x + r.width - scrollInsets.right) {         // Need to scroll right         hBar.setValue(hBar.getValue() + hBar.getUnitIncrement(1));       }       if (location.y >= r.y + r.height - scrollInsets.bottom) {         // Need to scroll down         vBar.setValue(vBar.getValue() + vBar.getUnitIncrement(1));       }     }   }   // Inner class that represents a node in this file system tree   public static class FileTreeNode extends DefaultMutableTreeNode {     public FileTreeNode(String parent, String name)         throws SecurityException, FileNotFoundException {       this.name = name;       // See if this node exists and whether it is a directory       fullName = parent == null ? name : parent + File.separator + name;       File f = new File(fullName);       if (f.exists() == false) {         throw new FileNotFoundException("File " + fullName             + " does not exist");       }       isDir = f.isDirectory();       // Hack for Windows which doesn't consider a drive to be a       // directory!       if (isDir == false && f.isFile() == false) {         isDir = true;       }     }     // Override isLeaf to check whether this is a directory     public boolean isLeaf() {       return !isDir;     }     // Override getAllowsChildren to check whether this is a directory     public boolean getAllowsChildren() {       return isDir;     }     // Return whether this is a directory     public boolean isDir() {       return isDir;     }     // Get full path     public String getFullName() {       return fullName;     }     // For display purposes, we return our own name     public String toString() {       return name;     }     // If we are a directory, scan our contents and populate     // with children. In addition, populate those children     // if the "descend" flag is true. We only descend once,     // to avoid recursing the whole subtree.     // Returns true if some nodes were added     boolean populateDirectories(boolean descend) {       boolean addedNodes = false;       // Do this only once       if (populated == false) {         File f;         try {           f = new File(fullName);         } catch (SecurityException e) {           populated = true;           return false;         }         if (interim == true) {           // We have had a quick look here before:           // remove the dummy node that we added last time           removeAllChildren();           interim = false;         }         String[] names = f.list(); // Get list of contents         // Process the contents         ArrayList list = new ArrayList();         for (int i = 0; i < names.length; i++) {           String name = names[i];           File d = new File(fullName, name);           try {             FileTreeNode node = new FileTreeNode(fullName, name);             list.add(node);             if (descend && d.isDirectory()) {               node.populateDirectories(false);             }             addedNodes = true;             if (descend == false) {               // Only add one node if not descending               break;             }           } catch (Throwable t) {             // Ignore phantoms or access problems           }         }         if (addedNodes == true) {           // Now sort the list of contained files and directories           Object[] nodes = list.toArray();           Arrays.sort(nodes, new Comparator() {             public boolean equals(Object o) {               return false;             }             public int compare(Object o1, Object o2) {               FileTreeNode node1 = (FileTreeNode) o1;               FileTreeNode node2 = (FileTreeNode) o2;               // Directories come first               if (node1.isDir != node2.isDir) {                 return node1.isDir ? -1 : +1;               }               // Both directories or both files -               // compare based on pathname               return node1.fullName.compareTo(node2.fullName);             }           });           // Add sorted items as children of this node           for (int j = 0; j < nodes.length; j++) {             this.add((FileTreeNode) nodes[j]);           }         }         // If we were scanning to get all subdirectories,         // or if we found no content, there is no         // reason to look at this directory again, so         // set populated to true. Otherwise, we set interim         // so that we look again in the future if we need to         if (descend == true || addedNodes == false) {           populated = true;         } else {           // Just set interim state           interim = true;         }       }       return addedNodes;     }     // Adding a new file or directory after     // constructing the FileTree. Returns     // the index of the inserted node.     public int addNode(String name) {       // If not populated yet, do nothing       if (populated == true) {         // Do not add a new node if         // the required node is already there         int childCount = getChildCount();         for (int i = 0; i < childCount; i++) {           FileTreeNode node = (FileTreeNode) getChildAt(i);           if (node.name.equals(name)) {             // Already exists - ensure             // we repopulate             if (node.isDir()) {               node.interim = true;               node.populated = false;             }             return -1;           }         }         // Add a new node         try {           FileTreeNode node = new FileTreeNode(fullName, name);           add(node);           return childCount;         } catch (Exception e) {         }       }       return -1;     }     protected String name; // Name of this component     protected String fullName; // Full pathname     protected boolean populated;// true if we have been populated     protected boolean interim; // true if we are in interim state     protected boolean isDir; // true if this is a directory   }   // Inner class that handles Tree Expansion Events   protected class TreeExpansionHandler implements TreeExpansionListener {     public void treeExpanded(TreeExpansionEvent evt) {       TreePath path = evt.getPath(); // The expanded path       JTree tree = (JTree) evt.getSource(); // The tree       // Get the last component of the path and       // arrange to have it fully populated.       FileTreeNode node = (FileTreeNode) path.getLastPathComponent();       if (node.populateDirectories(true)) {         ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);       }     }     public void treeCollapsed(TreeExpansionEvent evt) {       // Nothing to do     }   } }