如何允许用户在JFileChooser对话框中输入Windows环境变量

时间:2015-04-08 19:51:56

标签: java environment-variables jfilechooser

我在我的Java GUI中使用JFileChooser来允许用户浏览要导入的文件。我正在使用TestComplete为我的程序创建一些测试,并且需要能够在JFileChooser窗口“文件名:”文本字段中使用环境变量。

例如,我希望能够在“文件名:”文本框中键入以下行...

%TEST_FILES%\file_set_1\testfile.xml

有谁知道如何启用JFileChooser接受Windows环境变量。

我希望能够使用环境变量的原因是因为TestComplete测试将在各种计算机上运行,​​并且每个人都可能将测试文件放在不同的位置。

2 个答案:

答案 0 :(得分:0)

也许您可以动态生成批处理脚本然后执行它?

为什么不直接询问用户文件的位置?

答案 1 :(得分:0)

JFileChooser不会自动执行此操作,但您可以通过解释从接受处理程序中的JFileChooser返回的文件名字符串的内容来自行完成。

所以我们有一个例程来获取所有环境变量,这些变量被设置成小写以使它们更容易匹配:

private Map<String, String> getEnv() {
    Map<String, String> fromEnv = System.getenv();
    Map<String, String> toReturn = new HashMap<>();
    for (String key : fromEnv.keySet()) {
        toReturn.put(key.toLowerCase(), fromEnv.get(key));
    }
    return toReturn;
}

这将由扩展文件名的例程使用,这是相对简单的 - 只需找到%VAR%项,然后替换它们。在不匹配的变量的情况下,只需将其分解,将字符串部分解析。

private String expandFileName(String filename) {
    Pattern p = Pattern.compile("%([^%]*)%");
    Matcher m = p.matcher(filename);
    Map<String, String> env = getEnv();
    while (m.find()) {
        String var = m.group(1);
        String value = env.get(var.toLowerCase());
        if (value != null) {
            filename = filename.replaceAll("%" + var + "%",
                    Matcher.quoteReplacement(value));
        } else {
            return filename;
        }
        m = p.matcher(filename);
    }
    return filename;
}

接下来,我们需要使用JFileChooser的子类来处理使用文件名的尝试,因此我们需要覆盖approveSelection方法,获取文件名,展开文件并尝试确定相关文件。因为这个代码将在一个打开的对话框中使用,所以我在accept例程中采取了一些自由,它要求文件存在而不是使用文件的扩展名返回。

public void approveSelection() {
    File f = getSelectedFile();
    // remove the CWD from the string - leaving the text from the edit box
    String prena = f.toString().replace(getCurrentDirectory().toString() + File.separator, "");
    String name = expandFileName(prena);
    if (prena.equals(name)) {
        if (!f.exists()) {
            return;
        }
        // This expanded to the same, and the file is there
        super.approveSelection();
        return;
    }
    // try to use the name
    f = new File(name);
    if (f.isFile()) { // file, ok
        setSelectedFile(f);
        super.approveSelection();
    } else if (f.isDirectory()) { // change to dir
        setCurrentDirectory(f);
        return;
    } else if (!f.exists()) { // try with cwd and name in field
        f = new File(getCurrentDirectory(), name);
        if (f.exists()) {
            setSelectedFile(f);
            super.approveSelection();
        }
    }
}

逻辑相当复杂,但关键是要设法捕捉你会考虑的大部分条件。

它的长期和短缺是你必须手动完成,但所需的工作量实际上并不多。

然后您可以将它们全部粘贴到:

JFileChooser chooser = new JFileChooser() {
    // put in all the routines as listed earlier
};
chooser.setAcceptAllFileFilterUsed(true);
int choice = chooser.showOpenDialog(null);
if (choice == JFileChooser.APPROVE_OPTION) {
    String name = chooser.getSelectedFile().getAbsolutePath();
    System.out.println(name);
}