//***************************************************************************** //* //* (c) Copyright 2004. Glub Tech, Incorporated. All Rights Reserved. //* //* $Id: FileTree.java 37 2009-05-11 22:46:15Z gary $ //* //***************************************************************************** package com.glub.gui.tree; import com.glub.util.*; import java.awt.*; import java.awt.dnd.*; import java.awt.datatransfer.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.filechooser.*; import javax.swing.tree.*; public class FileTree extends JTree implements DropTargetListener { private static boolean showHiddenFiles = false; private DefaultTreeModel treeModel = null; protected static final long serialVersionUID = 1L; public FileTree() { this( "My Computer", false ); } public FileTree( String rootName, boolean shf ) { showHiddenFiles = shf; String passedInName = System.getProperty("hostname"); if ( passedInName != null && passedInName.length() > 0 ) { rootName = passedInName; } new DropTarget( this, DnDConstants.ACTION_COPY_OR_MOVE, this ); setDragEnabled( true ); FileTreeNode rootNode = new FileTreeNode( rootName ); treeModel = new DefaultTreeModel( rootNode ); ToolTipManager.sharedInstance().registerComponent(this); treeModel.setAsksAllowsChildren( true ); setModel( treeModel ); setEditable( false ); setRootVisible( true ); setShowsRootHandles( true ); setCellRenderer( new FileTreeRenderer() ); getSelectionModel().setSelectionMode (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); File[] roots = File.listRoots(); if (roots != null) { for (int i = 0; i < roots.length; i++) { // on the mac, the roots can be found in /Volumes if ( !Util.isMacOS() ) { treeModel.insertNodeInto( new FileTreeNode( roots[i] ), rootNode, rootNode.getChildCount() ); } } // on mac, /Volumes lists mounted disks if ( Util.isMacOS() ) { File volumes = new File("/Volumes"); File[] mountedDisks = volumes.listFiles(); int numKids = rootNode.getChildCount(); int rootDrive = 0; for (int i = 0; i < mountedDisks.length; i++) { try { if ( mountedDisks[i].getCanonicalPath().equals("/") ) { rootDrive = i; treeModel.insertNodeInto( new FileTreeNode( mountedDisks[i] ), rootNode, numKids++ ); break; } } catch ( Exception e ) {} } for (int i = 0; i < mountedDisks.length; i++) { if ( rootDrive == i ) { continue; } if ( mountedDisks[i].isDirectory() ) { treeModel.insertNodeInto( new FileTreeNode( mountedDisks[i] ), rootNode, numKids++ ); } } } } addTreeExpansionListener( new TreeExpansionListener() { // Required by TreeExpansionListener interface. public void treeExpanded(TreeExpansionEvent e) { //System.err.println( "tree expanded, path = " + e.getPath() ); TreePath path = e.getPath(); if (path == null) { return; } FileTreeNode expandNode = (FileTreeNode)path.getLastPathComponent(); if (expandNode == null) { return; } //expandNode.buildChildNodes(); File file = expandNode.getFile(); if (file == null || !file.isDirectory()) { return; } File[] subFiles = file.listFiles(); if (subFiles == null) { return; } expandNode.removeAllChildren(); HashMap hiddenFileMap = new HashMap(); final boolean showHiddenFiles = FileTree.showHiddenFiles(); if ( !showHiddenFiles ) { if ( Util.isMacOS() ) { File hiddenFileList = new File(file.getAbsolutePath(), ".hidden"); if ( hiddenFileList != null && !hiddenFileList.exists() ) { hiddenFileList = new File("/.hidden"); } if ( hiddenFileList != null && hiddenFileList.exists() ) { FileInputStream fis = null; try { fis = new FileInputStream( hiddenFileList ); BufferedReader br = new BufferedReader( new InputStreamReader(fis) ); String line = null; while ( (line = br.readLine()) != null ) { hiddenFileMap.put( line, "true" ); } } catch ( Exception e1 ) {} finally { if ( fis != null ) { try { fis.close(); } catch ( IOException ioe ) {} } } hiddenFileMap.put( "Cleanup At Startup", "true" ); hiddenFileMap.put( "TheFindByContentFolder", "true" ); hiddenFileMap.put( "TheVolumeSettingsFolder", "true" ); } } } int numKids = expandNode.getChildCount(); for ( int i = 0; i < subFiles.length; i++ ) { String fileName = subFiles[i].getName(); boolean addFile = true; if ( !showHiddenFiles && Util.isMacOS() ) { if ( fileName.startsWith(".") ) { addFile = false; } else if ( fileName.endsWith("Move&Rename") ) { addFile = false; } else if ( subFiles[i].isHidden() ) { addFile = false; } else if ( hiddenFileMap.get(fileName) != null ) { addFile = false; } } else if ( !showHiddenFiles ) { if ( FileSystemView.getFileSystemView().isHiddenFile(subFiles[i]) ) addFile = false; } if ( addFile ) { treeModel.insertNodeInto( new FileTreeNode( subFiles[i] ), expandNode, numKids++ ); } } treeModel.nodeStructureChanged( expandNode ); } // Required by TreeExpansionListener interface. public void treeCollapsed(TreeExpansionEvent e) { //System.err.println( "tree collapsed, path = " + e.getPath() ); } } ); } // taken from Java Forums (by lavansesh) public Point getToolTipLocation( MouseEvent e ) { Point location = null; Point point = e.getPoint(); TreePath path = getPathForLocation(point.x, point.y); if ( null != path && false == isTextVisible(path) ) { TreeCellRenderer renderer = getCellRenderer(); Component c = renderer.getTreeCellRendererComponent( this, path.getLastPathComponent(), false, false, false, 0, false ); if ( c instanceof JLabel ) { JLabel label = (JLabel)c; int icon = label.getIcon().getIconWidth(); Rectangle cellBounds = getPathBounds(path); location = new Point(cellBounds.x + icon + label.getIconTextGap(), cellBounds.y); } } return location; } private boolean isTextVisible( TreePath path ) { boolean result = false; /* Rectangle cellBounds = getPathBounds(path); Rectangle visibleRect = getVisibleRect(); if ( (visibleRect.width - cellBounds.x) < cellBounds.width ) { result = false; } */ return result; } public void drop( DropTargetDropEvent dtde ) { try { DataFlavor fileFlavor = DataFlavor.javaFileListFlavor; Transferable tr = dtde.getTransferable(); if ( dtde.isDataFlavorSupported(fileFlavor) ) { dtde.acceptDrop( DnDConstants.ACTION_COPY ); java.util.List fileList = (java.util.List)tr.getTransferData( fileFlavor ); dtde.dropComplete( true ); final Iterator iter = fileList.iterator(); if ( iter.hasNext() ) { Thread t = new Thread() { public void run() { changeDir( (File)iter.next() ); } }; t.start(); } } else if ( canHandleDrop(dtde) ) { handleDrop(dtde); } else { dtde.rejectDrop(); } } catch ( Exception e ) { /* e.printStackTrace(); */ } } protected boolean canHandleDrop( DropTargetDropEvent dtde ) { System.out.println("hello"); return false; } protected void handleDrop( DropTargetDropEvent dtde ) throws UnsupportedFlavorException, IOException { } public void dragEnter( DropTargetDragEvent e ) {} public void dragExit( DropTargetEvent e ) {} public void dragOver( DropTargetDragEvent e ) {} public void dropActionChanged( DropTargetDragEvent e ) {} public void changeDir( File toDir ) { if ( !toDir.isDirectory() ) { toDir = toDir.getParentFile(); } if ( toDir == null ) { return; } // tokenize the file try { String fullPath = toDir.getCanonicalPath(); StringTokenizer tok = new StringTokenizer( fullPath, System.getProperty("file.separator") ); // get root FileTreeNode root = (FileTreeNode)treeModel.getRoot(); Enumeration rootEnum = root.children(); Vector vector = new Vector(); vector.add( root ); FileTreeNode child = null; if ( tok.hasMoreTokens() ) { String pathToken = tok.nextToken(); // search root for drive while ( rootEnum.hasMoreElements() ) { child = (FileTreeNode)rootEnum.nextElement(); if ( child != null && child.toString().startsWith(pathToken) ) { vector.add( child ); break; } } } final TreePath tp = new TreePath( vector.toArray() ); Thread t = new Thread() { public void run() { //System.out.println(tp); expandPath( tp ); setSelectionPath( tp ); scrollPathToVisible( tp ); } }; SwingUtilities.invokeAndWait( t ); // for the rest of the path while ( tok.hasMoreElements() ) { String pathToken = tok.nextToken(); Enumeration childEnum = child.children(); while ( childEnum.hasMoreElements() ) { child = (FileTreeNode)childEnum.nextElement(); if ( child.toString().equals(pathToken) ) { vector.add( child ); break; } } final TreePath tp2 = new TreePath( vector.toArray() ); t = new Thread() { public void run() { //System.out.println(tp2); expandPath( tp2 ); setSelectionPath( tp2 ); scrollPathToVisible( tp2 ); } }; SwingUtilities.invokeAndWait( t ); } } catch ( Exception e ) {} } public static boolean showHiddenFiles() { return showHiddenFiles; } public static void main( String[] args ) { JFrame frame = new JFrame( "filetree" ); frame.getContentPane().setLayout( new BorderLayout() ); frame.getContentPane().add( new FileTree(), BorderLayout.CENTER ); frame.setSize( 640, 480 ); frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE ); frame.setVisible( true ); } }