JDK-6207989 : JFileChooser setFileSelectionMode() usability issue
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.0b,1.4.2
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: other,x86
  • Submitted: 2004-12-14
  • Updated: 2011-04-19
  • Resolved: 2005-10-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b56Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
I need to present a dialog for the user to select a directory (on the local system). Using Swing's JFileChooser there are issues from a usability perspective.  First the code I use in a button's actionPerformed method:

JFileChooser fc = new JFileChooser();

fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

if (fc.showDialog(_panel, "Select")== JFileChooser.APPROVE_OPTION) {

.

}

The problem I have is if I type in a directory in the File name field and hit Enter the dialog closes (as opposed to the dialog showing the contents of that directory).  What's interesting is that the behaviour is only apparent in the presence of the
setFileSelectionMode() call. Similar behaviour is seen when selecting a directory in the pane which contains the contents and pressing Enter - and once again if the setFileSelectionMode() statement is absent the behavior is different. Nothing in the documentation seems to suggest that setFileSelectionMode() should cause such behavior, which makes keyboard navigation problematic.

Sample Code:

/*
* JFileChooserTest.java
* JFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY) does not work
* 
*/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class JFileChooserTest extends JPanel implements ActionListener, ItemListener {
JFrame f = new JFrame ();
JPanel infoPanel = new JPanel ();
JPanel p1 = new JPanel ();
JPanel p2 = new JPanel ();
JButton b = new JButton ("Show JFileChooser");
JFileChooser fchooser = new JFileChooser();
JRadioButton filesOnly = new JRadioButton("FILES_ONLY");
JRadioButton directoriesOnly = new JRadioButton("DIRECTORIES_ONLY");
JRadioButton filesAndDirectories = new JRadioButton("FILES_AND_DIRECTORIES");
ButtonGroup bg = new ButtonGroup();

public JFileChooserTest() {
f.addWindowListener (new WindowAdapter () {
public void windowClosing (WindowEvent e)
{
f.dispose ();
System.exit (0);
}
});

f.getContentPane().setLayout (new BorderLayout());
infoPanel.setLayout (new GridLayout(0,1));
p1.setLayout (new FlowLayout());
p2.setLayout (new FlowLayout());
p1.setBackground (Color.white);
p2.setBackground (Color.pink);

p1.add (b);
p2.add (new JLabel("File selection mode: "));
bg.add(filesOnly);
bg.add(directoriesOnly);
bg.add(filesAndDirectories);
filesOnly.setToolTipText("Invokes JFileChooser.setFileSelectionMode().");
directoriesOnly.setToolTipText("Invokes JFileChooser.setFileSelectionMode().");
filesAndDirectories.setToolTipText("Invokes JFileChooser.setFileSelectionMode().");
p2.add (filesOnly);
p2.add (directoriesOnly);
p2.add (filesAndDirectories);

infoPanel.add (new JLabel("JFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY) does not work; the filechooser"));
infoPanel.add (new JLabel("displays both files and directories if setFileSelectionMode(JFileChooser.FILES_ONLY) is invoked on it."));
infoPanel.add (new JLabel("Use the radiobuttons to set the file selection mode of the filechooser."));
infoPanel.add (new JLabel(""));
f.getContentPane().add (BorderLayout.NORTH, infoPanel);
f.getContentPane().add (BorderLayout.CENTER, p1);
f.getContentPane().add (BorderLayout.SOUTH, p2);
f.setTitle("JFileChooser.setFileSelectionMode() Test");
f.pack();
f.setSize (730, 300);
f.setVisible(true);

if (fchooser.getFileSelectionMode() == JFileChooser.FILES_ONLY) {
filesOnly.setSelected(true);
System.out.println("Initial file selection mode of filechooser: JFileChooser.FILES_ONLY");
}
else if (fchooser.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
directoriesOnly.setSelected(true);
System.out.println("Initial file selection mode of filechooser: JFileChooser.DIRECTORIES_ONLY"); 
}
else if (fchooser.getFileSelectionMode() == JFileChooser.FILES_AND_DIRECTORIES) {
filesAndDirectories.setSelected(true);
System.out.println("Initial file selection mode of filechooser: JFileChooser.FILES_AND_DIRECTORIES"); 
}

b.addActionListener(this);
filesOnly.addItemListener(this);
directoriesOnly.addItemListener(this);
filesAndDirectories.addItemListener(this);
}

public void actionPerformed(ActionEvent evt) {
String command = evt.getActionCommand();
if (command == "Show JFileChooser") 
fchooser.showOpenDialog(this);
}

public void itemStateChanged(ItemEvent evt) {
JToggleButton tb = (JToggleButton)evt.getSource();
if (tb.getText().equals("FILES_ONLY")) {
System.out.println("Invoking JFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY)... ");
fchooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
}
else if (tb.getText().equals("DIRECTORIES_ONLY")) {
System.out.println("Invoking JFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)... ");
fchooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
else if (tb.getText().equals("FILES_AND_DIRECTORIES")) {
System.out.println("Invoking JFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES)... ");
fchooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
}
}

public static void main (String[] args) {
new JFileChooserTest();
}

}

=====================================================================

/* dirs.java */

import java.io.File;
   import javax.swing.*;

   public class Dirs {

     public static void main(String args[]) {
       SwingUtilities.invokeLater(new Runnable() {
         public void run() {
           JFileChooser fileChooser = 
                  new JFileChooser(".");
           fileChooser.setMultiSelectionEnabled(true);
           fileChooser.setFileSelectionMode(
                  JFileChooser.DIRECTORIES_ONLY);
           int status = fileChooser.showOpenDialog(null);
           if (status == JFileChooser.APPROVE_OPTION) {
             File selectedFiles[] = 
                 fileChooser.getSelectedFiles();
             for 
               (int i=0, n=selectedFiles.length; i<n; i++) {
                     System.out.println("Selected: " 
                        + selectedFiles[i].getParent() 
                        + " --- " 
                        + selectedFiles[i].getName());
             }
           }
           System.exit(0);
         }
       });
     }
   }



###@###.### 2004-12-14 00:59:35 GMT

Comments
EVALUATION A new keystroke action will be added so that Ctrl-Enter always navigates into a directory, regardless of file selection mode. This will work as long as a single directory is selected or a single directory name is entered in the text field. Note that the Enter key will still work as before, navigating to a directory in FILES_ONLY mode, and returning the directory in DIRECTORIES_ONLY or FILES_AND_DIRECTORIES mode. This fix applies to all supported L&F's.
05-08-2005

WORK AROUND If the setFileSelectionMode() call is absent then I've found that pressing Enter causes the contents of the directory to be shown. ###@###.### 2004-12-14 00:59:35 GMT
14-12-2004