Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4760448

MetalFileChooserUI should allow user to bypass ShellFolder methods

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.4.0
    • client-libs



      Name: sv35042 Date: 10/09/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      FULL OPERATING SYSTEM VERSION : NT 4.0 (SP6)


      ADDITIONAL OPERATING SYSTEMS : All other OSs for which JDK
      is available (linux, solaris, hp, ...)



      A DESCRIPTION OF THE PROBLEM :
      This issue is similar to the one reported in Bug #4493369,
      except that it concerns the
      javax.swing.plaf.metal.MetalFileChooserUI class instead of
      the com.sun.java.swing.plaf.windows.WindowsFileChooserUI
      class. I assume the issue affects more people as metal plaf
      is used more widely than windows plaf.
      Similar to the reporter of Bug #4493369, I use JFileChooser
      to view remote files in any cross-platform client/server
      fashion by using a custom FileSystemView. Before 1.4, the
      custom class only needs to override the FileSystemView
      interface (9 methods). My implementation stops working in
      1.4 because:
      1) 12 more public methods are added to FileSystemView,
      which JFileChooser can potential call
      2) sun.awt.shell.ShellFolder class is heavily used in the
      filechooser UI component and FileSystemView. Because
      ShellFolder class extends from java.io.File, it's local-
      system-dependent. (plus, there is no javadoc for
      this "secret" class)

      Issues concerning FileSystemView can be worked around by
      overriding the new interface methods, and overriding any
      FSV methods that makes use of ShellFolder.

      However, the filechooser UI component (in this case
      MetalFileChooserUI class) is quite beyond reach. The source
      code shows that MetalFileChooserUI uses ShellFolder in 3
      places. Two of them happen in the private addItem(File dir)
      method (the first protected by "if (useShellFolder)", the
      other not), and the third one occurs in an actionPerformed
      () concerning changing the "useShellFolder" flag from false
      to true.

      For the two occurrences in addItem(File), both should be
      protected by "if (useShellFolder)" so that as long
      as "useShellFolder" is never set, we can avoid dealing with
      ShellFolder class of the local file system.

      The condition under which "useShellFolder" could be set
      should also be reexamined. Here's a direct quote of code
      comment from the source:
      // Use ShellFolder class to populate combobox only if
      // FileSystemView.getRoots() returns one folder and that is
      // the same as the first item in the ShellFolder combobox
      list.
      Note that if my custom FSV's first root returned happened
      to have the same name as the first root from the local
      ShellFolder, it does not mean we should start using the
      local file system!

      Anyway, the bottom line is, if you decide to continue
      allowing the UI component to interact with local file
      system (ShellFolder) like this, then at least fix the
      MetalFileChooserUI to condition all such interactions on
      the "useShellFolder" flag, and to bullet-proof condition
      when "useShellFolder" will be set.

      A more desired solution is to re-evaluate the
      implementation. JavaDoc for FileSystemView starts
      with "FileSystemView is JFileChooser's gateway to the file
      system." FileChooserUI component, which is part of
      JFileChooser, should "honor" this statement by not by-
      passing FSV and directly talking to local file system
      (ShellFolder). Any dealing with local file system should go
      through FSV.
      Despite some UI bugs, the JFileChooser-FSV relation in Java
      1.3 and earlier is much cleaner than what's in 1.4, and we
      want it back!



      REGRESSION. Last worked in version 1.3.1

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. write a custom file system view class to simulate a non-
      local file system. (this does not have to be a remote file
      system, it could be a fictitious file system you conjured
      up in memory. this way, you don't need a client/server
      program like I have.) Also, to see "useShellFolder" flag of
      MetalFileChooserUI can be incorrectly set, make the first
      element the FSV's getRoots() method returns the same as
      that of the ShellFolder.get("fileChooserComboBoxFolders"),
      while the rest of the roots differ. This should switch you
      midway from not using local ShellFolder to using local
      ShellFolder.
      2. construct a JFileChooser using this custom FSV
      3. navigate via all the buttons in the JFileChooser GUI.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      you may see some local system roots in the "Look In:"
      directory combobox that are not in your custom non-local
      file system.

      currentDirectory will not show in the "Look In:" directory
      combobox when navigating to various directories on the non-
      local file system.

      if your custom FileSystemView class failed to override
      certain method in the
      javax.swing.filechooser.FileSystemView class, (esp. those
      using the ShellFolder class), then you may enounter various
      exceptions at runtime such as "NoSuchFile", or "unable to
      parse path" if the nonlocal file system uses different file
      separator character than the local FS.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      My app is a client/server via RMI containing at least 10 modules. I don't want
      to clutter up the space here by pasting all the source code, especially when it
      won't be very useful anyways. For the MetalFileChooserUI problem, the best
      place is to look at the java source code. (I am quoting relavant snippets
      below.) To decouple FileChooserUI from ShellFolder, some redesign is needed.

      MetalFileChooserUI.java
      ========================
      class ViewButtonListener ... {
        public void actionPerformed(..) {
        ...
        // Use ShellFolder class to populate combobox only if
        // FileSystemView.getRoots() returns one folder and that is
        // the same as the first item in the ShellFolder combobox list.
        {
            useShellFolder = false;
            File[] roots = fsv.getRoots();
            if (roots != null && roots.length == 1) {//<<<--- can be problematic
         File[] cbFolders = (File[])ShellFolder.get
      ("fileChooserComboBoxFolders");
      if (cbFolders != null && cbFolders.length > 0 && roots[0] == cbFolders
      [0]) { //<<<-- can be problematic
      useShellFolder = true;
      }
      }
        }
      }

      ...
      private void addItem(File directory) {
      ...
          // create File instances of each directory leading up to the top
          try {
      File sf = ShellFolder.getShellFolder(canonical); //<<<-- sf
      should be retrieved from ShellFolder on condition that if (useShellFolder)
      File f = sf;
      Vector path = new Vector(10);
      do {
      path.addElement(f);
      } while ((f = f.getParentFile()) != null);
      int pathCount = path.size();
      // Insert chain at appropriate place in vector
      for (int i = 0; i < pathCount; i++) {
      f = (File)path.get(i);
      if (directories.contains(f)) {
      int topIndex = directories.indexOf(f);
      for (int j = i-1; j >= 0; j--) {
      directories.insertElementAt(path.get(j), topIndex+i-j);
      }
      break;
      }
      }
      calculateDepths();
      setSelectedItem(sf);

      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Can't rip out and replace the FileChooserUI component used
      by JFileChooser from UIManager.
      Can't override static methods of ShellFolder used by (Metal)
      FileChooserUI.
      Only option left i can think of is to modify the
      MetalFileChooserUI.java and protecting all uses of
      ShellFolder methods with "useShellFolder" flag.
      Have not figured out a way to prevent "useShellFolder" flag
      from being set incorrectly.
      (Review ID: 144901)
      ======================================================================

            leifs Leif Samuelsson (Inactive)
            svioletsunw Scott Violet (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: