【问题标题】:How do I set my FileFilter based on a Map in my custom ComboboxModel?如何根据自定义 ComboboxModel 中的 Map 设置 FileFilter?
【发布时间】:2013-03-28 18:41:34
【问题描述】:

我将简要解释一下我正在做的事情,然后提供一些我的代码。

我有一个小的 GUI,我在其中选择 JComboBox 上的一个选项,然后单击一个按钮,该按钮将打开一个 JFileChooser,它应该根据 JComboBox 中的选择过滤掉文件。

例如,用户从 JComboBox 中选择Text File,当用户单击该按钮时,它将打开仅显示目录和文本文件的 JFileChooser。

在我的主类中,我在构造函数中有这个:

public MyApp() {
    //init components and other logic

    comboBox.setModel(new FileExtensionModel());
}

然后在那个类中我有打开文件选择器的按钮的方法:

private void openFilAction(ActionEvent e) {
    JFileChooser fc = new JFileChooser();

    fc.setFileFilter(new FileFilter() {
        @Override
        public boolean accept(File f) {
            return f.getName().endsWith(myFileType) || f.isDirectory();
        }

        public String getDescription() {
            return "myFileType";
        }
    }

    int choose = fc.showOpenDialog(this);
    //do logic  
}

最后是我对 DefaultComboBoxModel 的基本扩展:

public class FileExtensionModel extends DefaultComboBoxModel {
    Map<String, String> selection;

    public FileExtensionModel() {
        selection = new HashMap<String, String>();
        selection.put("Text File", ".txt");
        selection.put("Rar File", ".rar");
        selection.put("Zip File", ".rar");
        selection.put("Tar File", ".tar");
        selection.put("Ini File", ".ini");

        for(String key : select.keySet()) {
           this.addElement(key);
        }
    }
}

所以我想知道如何将myFileType 替换为我的FileExtensionModel() 中的地图值,因为我无法从我的内部FileFilter() 类中访问它。

欢迎提出任何建议,我不介意稍微移动代码。如果我能在我的 FileExtensionModel 类中处理大部分内容,那就太好了。

【问题讨论】:

    标签: java jcombobox jfilechooser filefilter comboboxmodel


    【解决方案1】:

    你不能在FileExtensionModel 之外创建你的HashMap,它对FileFilter 可见,并将它传递给`FileExtensionModel 的构造函数吗?

    public class MyClass {
    
        Map<String, String> selection;
        FileExtensionModel fem;
    
        MyClass() {
            selection = new HashMap<String, String>();
            selection.put("Text File", ".txt");
            selection.put("Rar File", ".rar");
            selection.put("Zip File", ".rar");
            selection.put("Tar File", ".tar");
            selection.put("Ini File", ".ini");
            fem = new FileExtensionModel(selection);
        }
    }
    
    private void openFilAction(ActionEvent e) {
        JFileChooser fc = new JFileChooser();
    
        fc.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.getName().endsWith(myFileType) || f.isDirectory();
            }
    
            public String getDescription() {
                for (String key : selection.keySet()) {
                   if (selection.get(key).equals(myFileType)) {
                       return key;
                   }
                }
                return "";
            }
        }
    
        int choose = fc.showOpenDialog(this);
        //do logic  
    }
    

    您的 FileExtensionModel 类:

    public class FileExtensionModel extends DefaultComboBoxModel {
    
        public FileExtensionModel(HashMap select) {
    
            for(String key : select.keySet()) {
               this.addElement(key);
            }
        }
    }
    

    更新

    或者您可以创建一个 HashMap 的 FileFilters,扩展名是关键。

    selection = new HashMap<String, String>();
                selection.put("Text File", ".txt");
                selection.put("Rar File", ".rar");
                selection.put("Zip File", ".rar");
                selection.put("Tar File", ".tar");
                selection.put("Ini File", ".ini");
                fem = new FileExtensionModel(selection);
    
    HashMap<String, FileFilter> fileFilters = new HashMap<String, FileFilter>();
    
    for (String key : selection.keySet()) {
        fileFilters.add(new MyFileFilter(key, selection.get(key)));
    }
    

    然后为您的 FileFilter 创建一个类。

    public class MyFileFilter extends FileFiter() {
    
        String extension;
        String description;
    
        public MyFileFilter(String extension, String description) {
            this.extension = extension;
            this.description = description;
       }
    
        ....
    }
    

    【讨论】:

    • 这是可能的,但我仍然无法设置 FileFilter,因为 myFileType 是在 FileFilter() 之外声明的。同样,我认为它也无法访问selection
    • 我认为myFileType 是一个字段。然后您可以创建另一个 HashMap,其中的键是扩展名。我会更新答案。
    • 感谢更新的答案,我可以将值从 String 更改为 FileFilter,但是这样做比 Steiner 提到的使 FileExtensionModel 最终化有什么好处吗?
    • 每个扩展有一个 FileFilter 的优点是不需要更新他们的接受和描述。然后,您可以根据需要在文件选择器上设置多个 FileFilter。
    【解决方案2】:

    您只需将FileExtensionModel 实例添加为字段即可访问MyApp 类中的FileExtensionModel 实例。由于它是在构造函数中实例化的,因此这应该不是问题。但是,由于您在匿名内部类中使用它,因此该字段需要为 final

    public class MyApp {
        private final FileExtensionModel fileExtensionModel;
        // ... your other fields
    
        public MyApp() {
            // ... you other init
            fileExtensionModel = new FileExtensionModel();
            comboBox.setModel(fileExtensionModel);
        }
    }
    

    现在,在 openFileAction 方法中,您应该可以访问 fileExtensionModel 字段,例如提取所选项目(或您应该需要的任何其他方法)。比如:

    myFileType = fileExtensionModel.getSelectedItem();
    

    【讨论】:

    • 有趣,将其定为最终版本有什么缺点吗?这似乎比其他解决方案少了很多工作。
    • 在这种情况下不是,不是。将其设为 final 意味着您不能更改 MyApp 类中的 fileExtensionModel 引用。需要在MyApp类实例化的时候进行初始化,以后不能再设置成不同的值。
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多