Java Forum / GUI / May 2005
FileSystemView.getRoots() and (system specific) directory tree
Karsten Wutzke - 24 May 2005 15:57 GMT Hi all!
I'm trying to implement a directory file system tree to select and view a directories' contents, pretty much as in the Windows explorer.
I was reading several articles and I have basically implemented a solution. There's one critical thing though: The FileSystemView.getRoots method only enumerates my desktop directory as the *only* root. So this gives me "C:\Dokumente und Einstellungen\kawu\Desktop" as the only starting point.
When adding subdirs, it only adds the test directory I put onto my desktop, instead of listing the whole (Windows-specific hierarchy). Like this, it is not possible to create the typical system-like directory tree at all.
On Windows, I want to show the user a tree like that:
Desktop + --- Eigene Dateien (My Files) + --- Arbeitsplatz (My Computer) | | | + --- WORK (C:) | + --- STORAGE (D:) | + --- MUSIC (E:) | + --- Gemeinsame Dateien (Shared Files) | + --- Dateien von kawu (Kawu's Files) | + --- Netzwerkumgebung + --- test
I might not need "Gemeinsame Dateien" and "Dateien von Kawu", but at least I need the rest ("Eigene Dateien", drives, "Netzwerkumgebung").
On other systems, I want the tree to appear in the "same" system specific look. As long as I can't get the Windows style done, I'm not happy.
Can anyone help me with this? How can I get this done with Java not enumerating the correct roots?
TIA, Karsten
PS: I have no problem retrieving the system specific icons and names. I just can't get the hierarchy right. I tried "C:\" as root without problems, but I need the "total" tree...
Andrew Thompson - 24 May 2005 16:42 GMT > The FileSystemView.getRoots > method only enumerates my desktop directory as the *only* root. What does this report? <http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#listRoots()>
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Karsten Wutzke - 24 May 2005 16:51 GMT >>The FileSystemView.getRoots >>method only enumerates my desktop directory as the *only* root. > > What does this report? > <http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#listRoots()> It lists 'C:\', 'D:\', 'E:\', and 'F:\'. These are my 3 HD partitions plus my DVD-RAM which I forgot to mention. It's an improvement over the previous call, definitely.
However, how can I compile a Windows-like tree out of this incomplete info?
Karsten
Andrew Thompson - 24 May 2005 17:08 GMT >>>The FileSystemView.getRoots >>>method only enumerates my desktop directory as the *only* root. ..
>> <http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#listRoots()> ..
> It lists 'C:\', 'D:\', 'E:\', and 'F:\'. These are my 3 HD partitions > plus my DVD-RAM which I forgot to mention. It's an improvement over the > previous call, definitely. > > However, how can I compile a Windows-like tree out of this incomplete info? ..errrmmm. Loops?
File[] allRoots = File.listRoots(); for (int ii=0; ii<allRoots.length; ii++) { // get files and directories.. File[] allFiles = allRoots[ii].listFiles(); .... }
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Karsten Wutzke - 24 May 2005 18:11 GMT >>>>The FileSystemView.getRoots >>>>method only enumerates my desktop directory as the *only* root. [quoted text clipped - 19 lines] > .... > } Eerrm. Sure. ;-)
I have implemented this completely and displaying the sub directories works for any drive. It's just that I would like to see a "Windows-native" view of the tree as described in my original post:
Desktop + --- Eigene Dateien (My Files) + --- Arbeitsplatz (My Computer) | | | + --- WORK (C:) | + --- STORAGE (D:) | + --- MUSIC (E:) | + --- DVD-RAM-Laufwerk (F:) | + --- Gemeinsame Dateien (Shared Files) | + --- Dateien von kawu (Kawu's Files) | + --- Netzwerkumgebung (Network Neighborhood) + --- test
The problem is how to get this to work, considering the application (Applet someday) will run on computers with different languages. So I can't simply set the File object for "Eigene Dateien" to e.g. "C:\Eigene Dateien", because
1. In other language's Windows' the dir will be named differently and 2. I put it there into C: manually, and on another machine this will be on a different drive and/or dir.
I could work with "language packs", classes that collected just this Windows-specific info, like the names of "Desktop", "My Files", "My Computer", "Network Neighborhood" and maybe some more. But I'd rather like to avoid such complicated programming and file searching if at all possible.
My tree, or at least the enumeration shall be "as is" for each system. On Unix, I want the tree to look basically something like this:
root + --- /bin + --- /dev + --- /dvd-ram + --- /music + --- /storage + --- /usr + --- /work
Whatever the mounting points for the drives are. But I need some help from Java for the system specific stuff, which I don't seem to get.
I hoped to get a more system-like enumeration of the systems directory structure...
So, am I really stuck manually building such a tree view?
Karsten
Roland - 24 May 2005 21:11 GMT > Hi all! > [quoted text clipped - 43 lines] > just can't get the hierarchy right. I tried "C:\" as root without > problems, but I need the "total" tree... Once saw this FileSystemModel <http://geosoft.no/software/filesystem/FileSystemModel.java.html>, but I improved it, to traverse filesystem nodes correctly (I hope) and show OS icons for each file and folder.
import java.awt.Component; import java.io.File; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.TreeSet;
import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.filechooser.FileSystemView; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath;
public class FileSystemTreeModel implements TreeModel {
public static void main(String[] args) { FileSystemTreeModel model = new FileSystemTreeModel(); JTree tree = new JTree(model); tree.setCellRenderer(new FileSystemTreeRenderer(model.fsv)); tree.setRootVisible(false); tree.setShowsRootHandles(true); JFrame app = new JFrame(); app.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); app.getContentPane().add(new JScrollPane(tree)); app.setSize(300, 500); app.setLocationRelativeTo(null); // center on screen app.setVisible(true); }
private final Object fakeRoot = new Object();
private FileSystemView fsv;
private boolean hiddenVisible;
private HashMap lastModifiedTimes;
private Collection listeners;
private File[] roots;
private Comparator sortComparator = new Comparator() {
public int compare(File a, File b) { Collator collator = Collator.getInstance();
if (a.isDirectory() && b.isFile()) return -1; else if (a.isFile() && b.isDirectory()) return +1;
int result = collator.compare(a.getName(), b.getName()); if (result != 0) return result;
result = collator.compare(a.getAbsolutePath(), b.getAbsolutePath()); return result; }
public int compare(Object a, Object b) { return compare((File) a, (File) b); } };
private HashMap sortedChildren;
public FileSystemTreeModel() { this(FileSystemView.getFileSystemView()); }
public FileSystemTreeModel(FileSystemView fsv) { this(fsv, fsv.getRoots()); }
public FileSystemTreeModel(FileSystemView fsv, File[] roots) { this.fsv = fsv; this.roots = roots;
listeners = new ArrayList(); sortedChildren = new HashMap(); lastModifiedTimes = new HashMap(); }
public void addTreeModelListener(TreeModelListener listener) { if (listener != null && !listeners.contains(listener)) listeners.add(listener); }
public void fireTreeNodesChanged(TreeModelEvent event) { for (Iterator i = listeners.iterator(); i.hasNext();) { TreeModelListener listener = (TreeModelListener) i.next(); listener.treeNodesChanged(event); } }
public void fireTreeNodesInserted(TreeModelEvent event) { for (Iterator i = listeners.iterator(); i.hasNext();) { TreeModelListener listener = (TreeModelListener) i.next(); listener.treeNodesInserted(event); } }
public void fireTreeNodesRemoved(TreeModelEvent event) { for (Iterator i = listeners.iterator(); i.hasNext();) { TreeModelListener listener = (TreeModelListener) i.next(); listener.treeNodesRemoved(event); } }
public void fireTreeStructureChanged(TreeModelEvent event) { for (Iterator i = listeners.iterator(); i.hasNext();) { TreeModelListener listener = (TreeModelListener) i.next(); listener.treeStructureChanged(event); } }
public Object getChild(Object parent, int index) { if (parent == fakeRoot) { return roots[index]; } else { List children = (List) sortedChildren.get(parent); return children == null ? null : children.get(index); } }
public int getChildCount(Object parent) { if (parent == fakeRoot) { return roots.length; } else { File file = (File) parent; if (!fsv.isTraversable(file).booleanValue()) return 0;
File[] children = fsv.getFiles(file, !hiddenVisible); int nChildren = children == null ? 0 : children.length;
long lastModified = file.lastModified();
boolean isFirstTime = lastModifiedTimes.get(file) == null; boolean isChanged = false;
if (!isFirstTime) { Long modified = (Long) lastModifiedTimes.get(file); long diff = Math.abs(modified.longValue() - lastModified);
// MS/Win or Samba HACK. Check this! isChanged = diff > 4000; }
// Sort and register children info if (isFirstTime || isChanged) { lastModifiedTimes.put(file, new Long(lastModified));
TreeSet sorted = new TreeSet(sortComparator); for (int i = 0; i < nChildren; i++) { sorted.add(children[i]); }
sortedChildren.put(file, new ArrayList(sorted)); }
// Notify listeners (visual tree typically) if changes if (isChanged) { TreeModelEvent event = new TreeModelEvent(this, getTreePath(file)); fireTreeStructureChanged(event); }
return nChildren; } }
public int getIndexOfChild(Object parent, Object child) { List children = (List) sortedChildren.get(parent); return children.indexOf(child); }
public Object getRoot() { return fakeRoot; }
private Object[] getTreePath(Object obj) { List path = new ArrayList(); while (obj != fakeRoot) { path.add(obj); obj = fsv.getParentDirectory((File) obj); }
path.add(fakeRoot);
int nElements = path.size(); Object[] treePath = new Object[nElements];
for (int i = 0; i < nElements; i++) { treePath[i] = path.get(nElements - i - 1); }
return treePath; }
public boolean isLeaf(Object node) { if (node == fakeRoot) return false; else return !fsv.isTraversable((File) node).booleanValue(); }
public void removeTreeModelListener(TreeModelListener listener) { if (listener != null) listeners.remove(listener); }
public void valueForPathChanged(TreePath path, Object newValue) { } }
class FileSystemTreeRenderer extends DefaultTreeCellRenderer { private FileSystemView fsv;
public FileSystemTreeRenderer() { this(FileSystemView.getFileSystemView()); }
public FileSystemTreeRenderer(FileSystemView fsv) { this.fsv = fsv; }
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { if (!(value instanceof File)) { return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); }
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
setText(fsv.getSystemDisplayName((File) value)); setIcon(fsv.getSystemIcon((File) value));
return this; } }
 Signature Regards,
Roland de Ruiter ___ ___ /__/ w_/ /__/ / \ /_/ / \
Chris Smith - 25 May 2005 04:06 GMT > Once saw this FileSystemModel > <http://geosoft.no/software/filesystem/FileSystemModel.java.html>, > but I improved it, to traverse filesystem nodes correctly (I hope) and > show OS icons for each file and folder. Interesting... I did exactly the same thing in response to a thread last December. You could have saved yourself the effort! :) You can find my implementation at:
> http://groups-beta.google.com/group/comp.lang.java.programmer/msg/aa6a5ab63ac9a7 ac?hl=en
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roland - 25 May 2005 08:27 GMT >>Once saw this FileSystemModel >><http://geosoft.no/software/filesystem/FileSystemModel.java.html>, [quoted text clipped - 6 lines] > >>http://groups-beta.google.com/group/comp.lang.java.programmer/msg/aa6a5ab63ac9a7 ac?hl=en Darn, I thought I changed it myself. Sorry, Chris. It is *your* code.
 Signature Regards,
Roland de Ruiter ___ ___ /__/ w_/ /__/ / \ /_/ / \
Chris Smith - 25 May 2005 04:06 GMT > I'm trying to implement a directory file system tree to select and view > a directories' contents, pretty much as in the Windows explorer. [quoted text clipped - 7 lines] > When adding subdirs, it only adds the test directory I put onto my > desktop, instead of listing the whole (Windows-specific hierarchy). Listing Desktop as the only root is correct behavior. That's the way the Windows logical filesystem looks. The problem is that you're only getting back 'test' as a child of that root.
Can you post the code you are using for doing this? Something makes me suspect that you're getting the children of that directory using File.listFiles instead of using FileSystemView.getFiles. That would have exactly the effect you describe. Remember that when you're using the logical filesystem a la FileSystemView, you have to stick with it. The physical filesystem looks different, and in the physical filesystem, 'test' IS the only child of 'Desktop'.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Karsten Lentzsch - 26 May 2005 08:33 GMT > [...] The FileSystemView.getRoots > method only enumerates my desktop directory as the *only* root. So this [quoted text clipped - 15 lines] > + --- Netzwerkumgebung > + --- test I'm using FileSystemView#getRoots() without modifications, and with the Windows file system view I get the tree you want. See the directory chooser in JDiskReport; it has Desktop as root and the tree expanded.
To actually see this in JDiskReport, make sure you have the Windows Look&Feel activated in the tool's preferences.
You can download the tool from http://www.jgoodies.com/freeware/jdiskreport/ Then click "Analyse a fire tree" in the launch screen.
Regards, Karsten
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|