Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / May 2005

Tip: Looking for answers? Try searching our database.

FileSystemView.getRoots() and (system specific) directory tree

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.