当您显示设置为 DIRECTORIES_ONLY 模式的 JFileChooser 实例时,它仍然允许在文本字段中手动输入文件名。可以重写
approveSelection()
方法来进一步验证用户所做的任何选择,但是在此模式下选择有效文件时甚至不会调用此方法,因为当您单击 Approve 按钮时 JFileChooser 只是取消。
我怎样才能改变这种行为?我想在用户选择文件而不是目录时显示警告消息,并保持对话框打开,以便他们必须重试。类似于在保存已存在的文件时,在关闭对话框之前单击“批准”按钮时覆盖
approveSelection()
以显示确认对话框。
(我不明白为什么 JFileChooser 在仅目录模式下的默认行为无论如何都允许进行文件选择)
我已经研究了 FileChooserUI 类来检查实际调用
approveSelection()
和 cancelSelection()
的内部行为,但对于像这样的简单目标来说,它看起来太复杂而无法覆盖。
要使
JFileChooser
返回 APPROVE_OPTION
状态并选择一个文件来代替 CANCEL_OPTION
和 null
,可以使用 FILES_AND_DIRECTORIES
选择模式和自定义 FileFilter
(不匹配任何内容)。
要重复显示选择器(如评论中已建议的那样),可以将对话框打开放置在循环(不是递归)内,如果用户继续选择无效的文件,则循环将继续仅。这取决于用例,但可以进行额外的检查以确保所选目录存在。
一旦循环结束,选择器返回状态将保存在一个变量中,以便区分批准、取消和错误操作。
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fc.setFileFilter(new FileNameExtensionFilter("Directories", "NON_EXISTENT_EXTENSION"));
fc.setAcceptAllFileFilterUsed(false);
int fcReturnState;
while (true) {
fcReturnState = fc.showOpenDialog(null);
File file = fc.getSelectedFile();
boolean valid = (file != null && file.exists() && file.isDirectory());
if (fcReturnState == JFileChooser.APPROVE_OPTION && !valid) {
String message = String.format(
"%s \"%s\" %s. Please try again.",
(file.exists() ? "File" : "Directory"), file.getAbsolutePath(),
(!file.exists() ? "does not exist" : "is not a directory"));
JOptionPane.showMessageDialog(null, message, "Warning", JOptionPane.ERROR_MESSAGE);
} else {
break;
}
}
if (fcReturnState == JFileChooser.APPROVE_OPTION) {
System.out.println("Directory selected: " + fc.getSelectedFile().getAbsolutePath());
} else if (fcReturnState == JFileChooser.CANCEL_OPTION) {
System.out.println("Selection cancelled");
} else if (fcReturnState == JFileChooser.ERROR_OPTION) {
System.out.println("Selection error occurred");
}