用于选择特定目录的Java FileFilter
我正在尝试创建一个文件过滤器,它只允许用户打开包含特定文件的目录。用例是这些目录是内部有一个名为smart.workspace的文件的工作区 目前我的过滤器如下用于选择特定目录的Java FileFilter,java,jfilechooser,filefilter,Java,Jfilechooser,Filefilter,我正在尝试创建一个文件过滤器,它只允许用户打开包含特定文件的目录。用例是这些目录是内部有一个名为smart.workspace的文件的工作区 目前我的过滤器如下 class SMARTWorkspaceFilter extends javax.swing.filechooser.FileFilter { String description = "SMART Workspace"; String fileNameFilter = "smart.workspace";
class SMARTWorkspaceFilter extends javax.swing.filechooser.FileFilter {
String description = "SMART Workspace";
String fileNameFilter = "smart.workspace";
SMARTWorkspaceFilter() {
}
@Override
public boolean accept(File file) {
log.debug("Testing file: " + file.getName());
if (file.isFile()) {
return false;
}
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
log.debug("Directory: " + f.isDirectory());
log.debug("Name: " + f.getName());
if (f.isDirectory()) {
return true;
}
if (f.getName().equals(fileNameFilter)) {
return true;
}
}
}
return false;
}
@Override
public String getDescription() {
return description;
}
}
显然,我的问题是,为了允许用户导航到工作区文件夹,我必须允许子目录
对于文件选择器,我仅使用选项目录_
是否可以仅允许用户根据目录内容选择目录
例如,目录“workspace”存在于C://Folder1/Folder2/wokspace,我希望允许FileChooser在C://上“启动”,并允许用户导航到“workspace”文件夹并接受它。FileChooser不允许接受Folder1或Folder2,但仍然允许通过Folder1和Folder2进行导航。我认为您不能让FileFilter区分“应该显示的文件/目录可以访问”和“可以选择的文件/目录” 我想到的解决方案是:让用户搜索/选择
smart.workspace
文件,然后从那里导航到父文件夹
如果您需要该对话框完全按照上面描述的那样进行操作,那么您必须详细地了解该对话框。希望扩展该类可以让您有足够的权限根据需要更改行为。您的问题是返回语句相互冲突。您不需要第一个if语句,因为默认情况下返回false(除非它是一个目录并且该目录包含特殊文件)
最终@SebastianH是正确的,它似乎不可能通过文件过滤器实现。相反,我扩展了JFileChooser
javax.swing.JFileChooser fileChooser = new javax.swing.JFileChooser(defaultLocation){
@Override
public boolean isDirectorySelectionEnabled() {
setOpenButtonState(this, false);
File file = getSelectedFile();
if(file == null){
return false;
}
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f : files){
if(f.isFile() && f.getName().equals("smart.workspace")){
setOpenButtonState(this, true);
return true;
}
}
}
return false;
}
private void setOpenButtonState(java.awt.Container c, boolean flag) {
int len = c.getComponentCount();
for (int i = 0; i < len; i++) {
java.awt.Component comp = c.getComponent(i);
if (comp instanceof javax.swing.JButton) {
javax.swing.JButton b = (javax.swing.JButton)comp;
if ( b != null && b.getText() != null && b.getText().equals("Open") ) {
b.setEnabled(flag);
}
} else if (comp instanceof java.awt.Container) {
setOpenButtonState((java.awt.Container) comp, flag);
}
}
}
};
javax.swing.JFileChooser fileChooser=newjavax.swing.JFileChooser(默认位置){
@凌驾
公共布尔值isDirectorySelectionEnabled(){
setOpenButtonState(此选项为false);
File File=getSelectedFile();
if(file==null){
返回false;
}
if(file.isDirectory()){
File[]files=File.listFiles();
用于(文件f:文件){
if(f.isFile()&&f.getName().equals(“smart.workspace”)){
setOpenButtonState(这是真的);
返回true;
}
}
}
返回false;
}
私有void setOpenButtonState(java.awt.Container c,布尔标志){
int len=c.getComponentCount();
对于(int i=0;i
除了防止选择之外,我还添加了禁用打开按钮以避免混淆的精确性
由于禁用了打开按钮-->我做了这些更改,但问题是如果我的工作区文件夹位于C://Folder1/Folder2/workspace,并且文件选择器从C://开始,那么过滤器将阻止导航到“workspace”,因为Folder1和Folder2不包含特殊文件。我想我的问题不是很清楚。然后将FileChooser的基本路径设置为
System.getProperty(“user.dir”)
。这确保了它将始终从运行应用程序的文件夹中打开(该文件夹也是eclipse/NetBeans/etc中未编译项目的工作区)。问题是,如果不允许选择普通文件夹,则无法允许它们。正如@SebastianH所说,如果不考虑扩展JFileChooser
本身,就无法做到这一点。
javax.swing.JFileChooser fileChooser = new javax.swing.JFileChooser(defaultLocation){
@Override
public boolean isDirectorySelectionEnabled() {
setOpenButtonState(this, false);
File file = getSelectedFile();
if(file == null){
return false;
}
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f : files){
if(f.isFile() && f.getName().equals("smart.workspace")){
setOpenButtonState(this, true);
return true;
}
}
}
return false;
}
private void setOpenButtonState(java.awt.Container c, boolean flag) {
int len = c.getComponentCount();
for (int i = 0; i < len; i++) {
java.awt.Component comp = c.getComponent(i);
if (comp instanceof javax.swing.JButton) {
javax.swing.JButton b = (javax.swing.JButton)comp;
if ( b != null && b.getText() != null && b.getText().equals("Open") ) {
b.setEnabled(flag);
}
} else if (comp instanceof java.awt.Container) {
setOpenButtonState((java.awt.Container) comp, flag);
}
}
}
};