JDK-6637181 : JFileChooser.setCurrentDirectory() results in IndexOutOfBoundsException
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-12-04
  • Updated: 2010-04-04
  • Resolved: 2007-12-05
Description
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Calling setSelectedFile on a JFileChooser (configured as a SAVE_DIALOG) which results in a call to setCurrentDirectory occasionally results in an IndexOutOfBoundsException thrown by the DefaultRowSorter.convertRowIndexToModel() method.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the supplied code until the IndexOutOfBoundsException is thrown.

Note - I have imbedded IMPORTANT comments in the supplied code.  In the supplied code there are 3 calls to JFileChooser.setCurrentDirectory:

1. The first call happens when the JFileChooser is created.  The current directory will be set to the user's default directory.

2. The second call in the code must set the JFileChooser current directory to a directory that has FEWER elements than the user's default directory.

3. The third call happens when setSelectedFile is called with a file whose parent is the user's default directory.  This is the call to setCurrentDirectory that results in the IndexOutOfBoundsException.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The JFileChooser should be displayed.  Its current directory should be the parent directory of the selected file (i.e. the user's default directory), and the selected file name should be displayed in the File Name text box.
ACTUAL -
The dialog is not displayed.  Instead an IndexOutOfBoundsException is thrown.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IndexOutOfBoundsException: Invalid index
	at javax.swing.DefaultRowSorter.convertRowIndexToModel(Unknown Source)
	at sun.swing.FilePane$SortableListModel.getElementAt(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.updateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(Unknown Source)
	at javax.swing.plaf.basic.BasicListUI.getCellBounds(Unknown Source)
	at javax.swing.JList.getCellBounds(Unknown Source)
	at javax.swing.JList.ensureIndexIsVisible(Unknown Source)
	at sun.swing.FilePane.ensureIndexIsVisible(Unknown Source)
	at sun.swing.FilePane.doDirectoryChanged(Unknown Source)
	at sun.swing.FilePane.propertyChange(Unknown Source)
	at java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
	at java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
	at java.awt.Component.firePropertyChange(Unknown Source)
	at javax.swing.JFileChooser.setCurrentDirectory(Unknown Source)
	at javax.swing.JFileChooser.setSelectedFile(Unknown Source)
	at Main.main(Main.java:44)

REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileSystemView;


/**
 * <P>
 * Program to reproduce JFileChooser bug.
 * </P>
 *
 * <!-- Created on Nov 13, 2007 at 1:02:59 PM -->
 *
 * @author Kimberly Doring
 */
public class Main {

   /**
    * @param args the command line arguments; none needed/expected
    */
   public static void main(String[] args) {
      JFrame myFrame = new JFrame();
      try {
         // Note - this call will result in a call to
         // JFileChooser.setCurrentDirectory(null) which will set the
         // current directory to the user's default directory
         JFileChooser myFileChooser = new JFileChooser((FileSystemView)null);
         myFileChooser.setDialogType( JFileChooser.SAVE_DIALOG );
         myFileChooser.setDialogTitle("Save");
         myFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
         myFileChooser.setAcceptAllFileFilterUsed( true );
         
         // set the current directory to a directory that has FEWER elements
         // than the user's default directory
         myFileChooser.setCurrentDirectory(new File("C:\\temp"));
         
         // set the selected file to a file in the user's default directory -
         // this will result in setCurrentDirectory being called again on the
         // JFileChooser (note that "myFile" in this case is a non-existent file)
         File dir = FileSystemView.getFileSystemView().getDefaultDirectory();
         File selectedFile = new File( dir, "myFile");
         myFileChooser.setSelectedFile(selectedFile);
         
         myFileChooser.showDialog(myFrame, null);
         myFrame.dispose();
         System.exit(0);
      } catch (IndexOutOfBoundsException ex) {
         ex.printStackTrace();
         myFrame.dispose();
         System.exit(-1);
      }

   }

}

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

CUSTOMER SUBMITTED WORKAROUND :
I have not found a workaround.

Comments
EVALUATION The test case is incorrect; all Swing must be accessed from EventDispatchThread http://java.sun.com/docs/books/tutorial/uiswing/concurrency/initial.html The submitter reported that IndexOutOfBoundsException is occasionaly thrown, it often happens when you work with Swing from the wrong thread
05-12-2007