|
Quick Lists
|
|
Bug ID:
|
6207989
|
|
Votes
|
0
|
|
Synopsis
|
JFileChooser setFileSelectionMode() usability issue
|
|
Category
|
java:classes_swing
|
|
Reported Against
|
1.4.2
|
|
Release Fixed
|
mustang(b56)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
2-High
|
|
Related Bugs
|
6248582
,
6333976
,
6431639
,
4322989
,
4151536
|
|
Submit Date
|
14-DEC-2004
|
|
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);
}
});
}
}
xxxxx@xxxxx 2004-12-14 00:59:35 GMT
|
|
Work Around
|
If the setFileSelectionMode() call is absent then I've found that pressing Enter causes the contents of the directory to be shown.
xxxxx@xxxxx 2004-12-14 00:59:35 GMT
|
|
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.
Posted Date : 2005-09-28 23:00:13.0
|
|
Comments
|
Submitted On 15-MAR-2006
cowwoc
This fix is based upon incorrect assumptions and causes more harm than good. There seems to be a misunderstanding among some Sun engineers that Windows does not have a folder-choosing mode and so there is no equivilent native behavior. This is false.
In Visual Studio 2005 (older releases might work as well) select "project properties" -> C/C++ -> General -> Additional Include Directories -> "..." -> Click in an empty slot as if you are about to enter a new directory -> "..."
Now, this will open up a dialog in directory-selection mode. Notice that the dialog will only display folders even if the current directory also contains files. Now, notice if you have a folder selected and it has keyboard focus and you hit ENTER, the dialog will navigate into that folder. This allows keyboard users to navigate into directories easily. Now, if a user wants to the dialog to return a particular directory, he selects it then hits TAB until the focus shifts to the OPEN button, then hits ENTER. This will return the selected folder.
So in a nutshell:
1) Windows has a native folder-selection mode. We shouldn't be going around inventing our own.
2) Typing ENTER when a folder is selected and the keyboard focus is over it should cause JFileChooser to navigate into the directory without returning it.
3) Typing ENTER when a folder is selected but the keyboard focus is over the OPEN button should cause JFileChooser to return the selected folder
4) For cross-platform L&F such as Metal adding CTRL-ENTER makes perfect sense... but please do not impose this on Windows L&F which should act identical to native applications!
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |