如何允许用户在 JFileChooser 对话框中输入 Windows 环境变量
How to allow a user to enter Windows Environment Variables in a JFileChooser dialog
我正在为我的 Java GUI 使用 JFileChooser
,以允许用户浏览要导入的文件。我正在使用 TestComplete
为我的程序创建一些测试,并且需要能够在 JFileChooser
window "File Name:" 文本字段中使用环境变量。
例如,我希望能够在 "File Name:" 文本框中输入以下行...
%TEST_FILES%\file_set_1\testfile.xml
有谁知道如何让 JFileChooser
接受 Windows 环境变量。
我希望能够使用环境变量的原因是因为 TestComplete 测试将在各种计算机上进行 运行,并且每个人的测试文件都可能位于不同的位置。
也许你可以动态生成一个批处理脚本然后执行它?
为什么不直接询问用户文件在哪里?
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
方法,获取文件名,展开它并尝试确定文件有问题。因为这段代码将在打开的对话框中使用,所以我在接受例程中采取了一些自由,它要求文件存在而不是返回文件的扩展名。
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);
}
我正在为我的 Java GUI 使用 JFileChooser
,以允许用户浏览要导入的文件。我正在使用 TestComplete
为我的程序创建一些测试,并且需要能够在 JFileChooser
window "File Name:" 文本字段中使用环境变量。
例如,我希望能够在 "File Name:" 文本框中输入以下行...
%TEST_FILES%\file_set_1\testfile.xml
有谁知道如何让 JFileChooser
接受 Windows 环境变量。
我希望能够使用环境变量的原因是因为 TestComplete 测试将在各种计算机上进行 运行,并且每个人的测试文件都可能位于不同的位置。
也许你可以动态生成一个批处理脚本然后执行它?
为什么不直接询问用户文件在哪里?
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
方法,获取文件名,展开它并尝试确定文件有问题。因为这段代码将在打开的对话框中使用,所以我在接受例程中采取了一些自由,它要求文件存在而不是返回文件的扩展名。
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);
}