Name: boT120536 Date: 04/11/2001
java version "1.3.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-beta-b15)
Java HotSpot(TM) Server VM (build 2.0fcs-E, mixed mode)
/** Demonstrate a bug in {@link javax.swing.JFileChooser}.
** <p>
** Run the class below in a directory other than the user's home.
** The {@link File_Filter#accept} method prints its activity
** to {@link System#out} to document the strange behavior.
** <p>
** A JFileChooser is created with no argument, which should
** set the chooser's current directory to the user's home.
** The selected file is set to some file in some other
** directory.
** <p>
** 2 [Basic L&F File Loading Thread]s are
** created, so that {@link File_Filter#accept} is called
** twice on on each file in the selected file's directory.
** Even stranger, after the dialog is dismissed, the program
** waits for a minute, then starts 2 or more
** [Basic L&F File Loading Thread]s
** calling {@link File_Filter#accept} on every file in the user's
** home directory. Since the user's 'home' is often C:\WINDOWS,
** or on a remote server, this can be a fairly lengthy computation.
** In a more realistic setting, where the filechooser is just
** part of a larger interface, the responsiveness of interaction
** suffers.
** <p>
** It appears that under some JVMs (eg Comapq's Fast JVM for
** the alpha architecture and OSF1) the multiple file loading
** threads causes a deadlock. However, I haven't been able to
** come up with a simple example that shows this.
**
** @author John Alan McDonald
** @since 2001-04-09
**/
public abstract class
JFileChooser_Bug
extends Object {
public static final String
VERSION = "2001-04-09";
//==========================================================
// bug demonstration
//==========================================================
public static final void
main (final String[] args)
throws java.io.IOException {
final File_Filter filter = new File_Filter();
javax.swing.JFileChooser chooser;
chooser = new javax.swing.JFileChooser();
chooser.setSelectedFile(new java.io.File("./JFileChooser_Bug.java"));
chooser.setFileFilter(filter);
final int result = chooser.showOpenDialog(null);
System.out.println("result=" + result);
System.out.println("selected file=" + chooser.getSelectedFile());
System.out.println(System.getProperties()); }
//==========================================================
// local classes
//==========================================================
private static final class
File_Filter
extends javax.swing.filechooser.FileFilter
implements java.io.FilenameFilter {
//==========================================================
public final boolean
accept (final java.io.File f) {
System.out.println();
System.out.println();
System.out.println();
System.out.println("----------------------------------------------------");
System.out.println("File_Filter.accept(" + f + ")");
print_threads(System.out);
return true; }
//----------------------------------------------------------
public final boolean
accept (final java.io.File dir, final String name) {
return accept(new java.io.File(dir,name)); }
//----------------------------------------------------------
public final String
getDescription () { return "any file"; }
//==========================================================
public
File_Filter () { super(); }
//==========================================================
} // end local class
//==========================================================
//==========================================================
// class methods
//==========================================================
//----------------------------------------------------------
// listing all threads
//----------------------------------------------------------
/** @return the root ancestor of the given
** {@link ThreadGroup group}.
**/
public static final ThreadGroup
root_ThreadGroup (final ThreadGroup group) {
final ThreadGroup
parent = group.getParent();
if (null == parent) { return group; }
else { return root_ThreadGroup(parent); } }
/** @return the root {@link ThreadGroup} for the current
** {@link Thread}.
**/
public static final ThreadGroup
root_ThreadGroup () {
return
root_ThreadGroup(Thread.currentThread().getThreadGroup()); }
//----------------------------------------------------------
/** @return an {@link Thread}<code>[]</code> of all the
** threads in <code>group</code> or any of its descendants.
**/
public static final Thread[]
get_threads (final ThreadGroup group) {
// api doc says activeCount is an 'estimate'
final int m = 2*group.activeCount();
final Thread[] threads = new Thread[m];
group.enumerate(threads);
return threads; }
/** @return an {@link Thread}<code>[]</code> of all the
** threads under the root ancestor {@link ThreadGroup}
** of the current thread.
**/
public static final Thread[]
get_threads () {
return get_threads(root_ThreadGroup()); }
//----------------------------------------------------------
/** @return a {@link String} listing as many
** {@link Thread}s as possible, one per line,
** ending with a new line.
**/
public static final String
list_threads () {
final Thread[] threads = get_threads();
final int n = threads.length;
final StringBuffer b = new StringBuffer(n*32);
final String nl = System.getProperty("line.separator");
for (int i=0;i<n;i++) {
if (null != threads[i]) {
b.append(i);
b.append(": ");
b.append(threads[i].toString());
b.append(nl); } }
return b.toString(); }
//----------------------------------------------------------
/** Print a thread list, for debugging. **/
public static final void
print_threads (final java.io.PrintWriter pw) {
pw.println();
pw.println("In " + Thread.currentThread() + ":");
pw.print(list_threads());
pw.flush(); }
//----------------------------------------------------------
/** Print a stack trace, for debugging. **/
public static final void
print_threads (final java.io.OutputStream s) {
print_threads(new java.io.PrintWriter(s)); }
//==========================================================
} // end class
//==========================================================
(Review ID: 120441)
======================================================================