This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 47737

Summary: Desire API for tracking last-selected file (in file choosers) based on various keys
Product: platform Reporter: Jesse Glick <jglick>
Component: -- Other --Assignee: _ tboudreau <tboudreau>
Status: RESOLVED FIXED    
Severity: blocker CC: dsimonek, jrechtacek, jskrivanek, mkrauskopf, pfiala, pjiricka, tboudreau, tmysik
Priority: P2 Keywords: API, API_REVIEW_FAST
Version: 4.x   
Hardware: All   
OS: All   
Issue Type: ENHANCEMENT Exception Reporter:
Bug Depends on: 73474    
Bug Blocks: 82427    
Attachments: Diff of module to use this API
Updated FileChooserBuilder

Description Jesse Glick 2004-08-23 20:58:04 UTC
Cf. issue #44731. Seems it is quite common for
different pieces of code (in different modules) to
want to share the last file selection (or
containing directory?) in a JFileChooser, so that
the user does not have to keep on hunting around
for the right location. Probably needs to be based
on several keys, e.g.

- project type (for New Project wizards)

- project (for customizers of various sorts)

- misc. constants (for Open File etc.)

And the selections should be persistent.

Suggest something like

public class Utilities/* ? */ {
  // ...
  public static File getLastFileSelection(Object key);
  public static void putLastFileSelection(Object
key, File file);
}
Comment 1 Petr Jiricka 2004-09-03 14:11:05 UTC
Jesse, any chance of implementing this for NetBeans 4.0? Looks like it
would be useful in many places.
Comment 2 Jesse Glick 2004-09-03 21:20:15 UTC
It's an API change, and not required for a priority bug. Not up to me
whether it goes into 4.0 or not. Talk to whoever controls the schedule.
Comment 3 Pavel Fiala 2004-09-13 14:28:43 UTC
See our solution in org.netbeans.modules.web.project.ui.JFileChooser

Perhaps it would be generally usable after slight modification.
Comment 4 Pavel Fiala 2004-09-13 14:32:15 UTC
Mea culpa.
It should be org.netbeans.modules.web.project.ui.JFileChooser
Comment 5 Pavel Fiala 2004-09-13 14:35:09 UTC
I am sorry. It seems I am too tired. The last correction:
org.netbeans.modules.web.project.ui.FileChooser
Comment 6 Jesse Glick 2005-08-09 02:54:00 UTC
*** Issue 23125 has been marked as a duplicate of this issue. ***
Comment 7 Jesse Glick 2005-08-09 02:54:10 UTC
*** Issue 43567 has been marked as a duplicate of this issue. ***
Comment 8 Jesse Glick 2005-08-09 02:54:41 UTC
*** Issue 46913 has been marked as a duplicate of this issue. ***
Comment 9 _ tboudreau 2005-08-09 08:05:06 UTC
I'd suggest something somewhat simpler - don't try to listen to the filechooser
or anything, just something like:

private String pathFromLastPut = null;
private static final String DEFAULT_TOKEN = "default";
public File getLastFolder (String token) {
   String name = token == null ? pathFromLastPut :
Preferences.getUserNodeForPackage (FileUtil.class).get(token);
   if (file == null) {
       file = pathFromLastPut;
   }
   if (!File.exists()) {
       file = System.getProperty("user.home");
   }
   return file;
}

public void putLastFolder (String token, File file) {
   if (file.isDirectory()) file = file.getParentFile();
   pathFromLastPut = file.getPath();
   Preferences.getUserNodeForPackage(FileUtil.class).put (token, file.getPath());
}

Modules can then have whatever contract they want to have for sharing tokens.  I
suppose it would be a little bit nicer to be able to listen to the file chooser
and make it all nice and transparent, but the above solves a lot of it and I
can't imagine it being a big deal to implement.

Re using Preferences, this seems like exactly the sort of thing where it's
perfectly safe to do - trivial data that's never going to break anything by
being global.

Even doing the listening would be pretty painless - have a createFileChooser
method, pass it a token, and attach a weak listener that caches the file path
but can lose the file chooser, and some kind of timer to check if the file
chooser is gone, and if so store the value by the token.  A little more
complicated to do right though - do you want to store the selection even if the
user cancelled the file chooser?  You won't necessarily know.  Rather than a
lengthy debate, the above approach would allow us to solve the major problem
quickly, and give code a choice about whether it really wants to save the value
or not.
Comment 10 Jesse Glick 2005-10-12 01:59:31 UTC
*** Issue 66537 has been marked as a duplicate of this issue. ***
Comment 11 Jesse Glick 2005-10-27 21:37:52 UTC
*** Issue 66537 has been marked as a duplicate of this issue. ***
Comment 12 Jesse Glick 2005-11-04 19:22:05 UTC
*** Issue 68056 has been marked as a duplicate of this issue. ***
Comment 13 Jesse Glick 2008-11-10 17:30:49 UTC
*** Issue 82425 has been marked as a duplicate of this issue. ***
Comment 14 Jesse Glick 2008-11-10 17:31:29 UTC
*** Issue 152750 has been marked as a duplicate of this issue. ***
Comment 15 _ tboudreau 2008-11-11 22:44:03 UTC
See the patch attached to duplicate issue 152750 - I've been using a version of this in another application for some time.

The basic pattern is 
JFileChooser createFileChooser (String adHocKey);
to handle the current directory on initialization.

It also handles the case of needing badging in file choosers - both the platform and project file choosers do this, and
AFAIK all of the above contain copies of the same code.  It also generally makes working with file choosers easier than
remembering abstruse JFileChooser.* constants for most uses in NetBeans.
Comment 16 Jesse Glick 2008-11-12 01:06:48 UTC
If you mean to ask for a review, please see

http://openide.netbeans.org/tutorial/review-steps.html
Comment 17 _ tboudreau 2008-11-12 01:46:20 UTC
That's exactly what I did, but you closed it as a duplicate :-)

Reviewers, I am requesting review for the attachment to duplicate issue 152750.
Comment 18 Jesse Glick 2008-11-18 16:10:39 UTC
http://www.netbeans.org/nonav/issues/showattachment.cgi/73522/FileChooserBuilder.java

in other words.


[JG01] I want to see a complete patch that includes various clients - say, three or more - using the new API with all or
most of its features, and being significantly simplified or functionally improved as a result. (The dozen or so
duplicate issues were filed just for the ability to remember a default CWD by key, but I have not heard requests for the
other features of this API.)


[JG02] Your @see tag on BadgeProvider is incorrect. Try just "@see FileChooserBuilder#setBadgeProvider".


[JG03] Who is going to use BadgeProvider? Not the project chooser, which implements its own highly tuned icon badging
which cannot be accommodated by this interface. Perhaps the platform choosers?


[JG04] preventFileChooserSymlinkTraversal should probably be on by default, maybe even with no option to disable it. It
anyway only applies to Unixy platforms running JDK 5 - the default behavior on JDK 6 is correct.


[JG05] Is issue #82427 still considered important? If so, shouldn't that be covered by FileChooserBuilder as an
implementation detail?


[JG06] Utilities.showJFileChooser should refer the reader to FileChooserBuilder. (BTW you need to use the syntax
@org-openide-filesystems@ to link to a downstream API in Javadoc.)
Comment 19 Milan Kubec 2008-11-19 15:11:20 UTC
*** Issue 53023 has been marked as a duplicate of this issue. ***
Comment 20 greggwon 2008-11-19 23:08:22 UTC
There should be some ability for users to completely turn this off, as it amounts to a history archive which some may
feel exposes information that other software or persons may consume and abuse.
Comment 21 _ tboudreau 2008-11-20 05:38:52 UTC
[JG01] I want to see a complete patch that includes various clients
Easy enough.


[JG02] Your @see tag on BadgeProvider is incorrect. Try just "@see FileChooserBuilder#setBadgeProvider".
Thx.


[JG03] Who is going to use BadgeProvider? Not the project chooser, which implements its own highly tuned icon badging
which cannot be accommodated by this interface. Perhaps the platform choosers?

I just copied the code in java.platform to achieve this for CLDC, and it needs to be done for CDC and others as well; 
anybody implementing something platform-like will need it as well.  Would much prefer the code for this to be in one place.


[JG04] preventFileChooserSymlinkTraversal should probably be on by default, maybe even with no option to disable it. It
anyway only applies to Unixy platforms running JDK 5 - the default behavior on JDK 6 is correct.

If we can be sure there will never be a case where the default behavior is desirable, that sounds good to me.

[JG05] Is issue #82427 still considered important? If so, shouldn't that be covered by FileChooserBuilder as an
implementation detail?

Yes, it should.  I'd rather get the API in place, and then if we want to do that (it sounds like maybe Dafe already did
for some file choosers), do that after some people are using it - i.e. debug one thing at a time.

[JG06] Utilities.showJFileChooser should refer the reader to FileChooserBuilder. (BTW you need to use the syntax
@org-openide-filesystems@ to link to a downstream API in Javadoc.)

Ok.

> There should be some ability for users to completely turn this off

We can provide a system property to disable it, e.g. -J-Ddisable.filechooser.history=true
Comment 22 _ tboudreau 2008-11-20 07:52:09 UTC
Annoying that hg doesn't include things added with 'hg addremove' in a diff unless you commit them locally.  Anyway,
diff attached;  I'll also attach an updated version of FileChooserBuilder.
Comment 23 _ tboudreau 2008-11-20 07:52:56 UTC
Created attachment 73937 [details]
Diff of module to use this API
Comment 24 _ tboudreau 2008-11-20 07:54:10 UTC
Created attachment 73938 [details]
Updated FileChooserBuilder
Comment 25 Jesse Glick 2008-11-20 22:06:21 UTC
"hg doesn't include things added with 'hg addremove' in a diff" - uh, yes it does. Make sure you have

[diff]
git = 1

in your ~/.hgrc (though you should not need that just to get added/removed files displayed). For more, see

http://wiki.netbeans.org/HgHowTos#section-HgHowTos-DevelopAPIReviewPatchesUsingMQ


JG06 - The syntax in Utilities.java is wrong. @org-openide-filesystems@ refers to the root of the foreign Javadoc. You
still need to interject a path and manually construct the hyperlink. Something like

@see <a href="@org-openide-filesystems@/org/openide/filesystems/FileChooserBuilder.html"><code>FileChooserBuilder</code></a>

but try actually building Javadoc and verifying that the link works.


[JG07] Do not use new FileChooserBuilder(getClass()). Use new FileChooserBuilder(ThisClass.class). Otherwise the key
will silently change when the method is ever called on a subclass. (We have the same rule for NbBundle.)
Comment 26 Jiri Skrivanek 2008-12-02 07:33:15 UTC
[JS01] The current dir is not saved. Please, fix NbPreferences.forModule(FileChooserBuilder.class).put(dirKey, dirKey).
Comment 27 _ tboudreau 2008-12-02 15:51:29 UTC
Yup, already fixed.
Comment 28 _ tboudreau 2008-12-02 16:37:39 UTC
All comments addressed, tests added and documentation improved; committed in changeset f989a1086333

Notes:
 - System property allow.filechooser.symlink.traversal can be used to disable preventing symlink traversal;  it is on by
default, this is just in case there is some weird corner case in the future
 - System property forget.recent.dirs will disable collecting of directory history (but not delete anything already
written to NbPreferences)