如何使对话框的“当前目录”在不同的调用中持久存在?
您可以为此修改单例模式方法
这样,您只能使用一个并监视/控制那里的初始目录,但不会直接将实例暴露给类外部的修改FileChooser
例如:
public class RetentionFileChooser {
private static FileChooser instance = null;
private static SimpleObjectProperty<File> lastKnownDirectoryProperty = new SimpleObjectProperty<>();
private RetentionFileChooser(){ }
private static FileChooser getInstance(){
if(instance == null) {
instance = new FileChooser();
instance.initialDirectoryProperty().bindBidirectional(lastKnownDirectoryProperty);
//Set the FileExtensions you want to allow
instance.getExtensionFilters().setAll(new ExtensionFilter("png files (*.png)", "*.png"));
}
return instance;
}
public static File showOpenDialog(){
return showOpenDialog(null);
}
public static File showOpenDialog(Window ownerWindow){
File chosenFile = getInstance().showOpenDialog(ownerWindow);
if(chosenFile != null){
//Set the property to the directory of the chosenFile so the fileChooser will open here next
lastKnownDirectoryProperty.setValue(chosenFile.getParentFile());
}
return chosenFile;
}
public static File showSaveDialog(){
return showSaveDialog(null);
}
public static File showSaveDialog(Window ownerWindow){
File chosenFile = getInstance().showSaveDialog(ownerWindow);
if(chosenFile != null){
//Set the property to the directory of the chosenFile so the fileChooser will open here next
lastKnownDirectoryProperty.setValue(chosenFile.getParentFile());
}
return chosenFile;
}
}
这会将 的初始目录设置为用户上次在重复使用时打开/保存的文件的目录FileChooser
用法示例:
File chosenFile = RetentionFileChooser.showOpenDialog();
但是,这里有一个限制:
//Set the FileExtensions you want to allow
instance.getExtensionFilters().setAll(new ExtensionFilter("png files (*.png)", "*.png"));
由于不提供任何 's 变得不那么用户友好,要求用户手动附加文件类型,但在创建实例时提供过滤器而无法更新它们会将其限制为相同的过滤器ExtensionFilter
FileChooser
对此进行改进的一种方法是公开可以使用 varargs 提供的可选筛选器,从而可以选择在显示对话框时修改筛选器的时间RetentionFileChooser
例如,在上一个的基础上构建:
public class RetentionFileChooser {
public enum FilterMode {
//Setup supported filters
PNG_FILES("png files (*.png)", "*.png"),
TXT_FILES("txt files (*.txt)", "*.txt");
private ExtensionFilter extensionFilter;
FilterMode(String extensionDisplayName, String... extensions){
extensionFilter = new ExtensionFilter(extensionDisplayName, extensions);
}
public ExtensionFilter getExtensionFilter(){
return extensionFilter;
}
}
private static FileChooser instance = null;
private static SimpleObjectProperty<File> lastKnownDirectoryProperty = new SimpleObjectProperty<>();
private RetentionFileChooser(){ }
private static FileChooser getInstance(FilterMode... filterModes){
if(instance == null) {
instance = new FileChooser();
instance.initialDirectoryProperty().bindBidirectional(lastKnownDirectoryProperty);
}
//Set the filters to those provided
//You could add check's to ensure that a default filter is included, adding it if need be
instance.getExtensionFilters().setAll(
Arrays.stream(filterModes)
.map(FilterMode::getExtensionFilter)
.collect(Collectors.toList()));
return instance;
}
public static File showOpenDialog(FilterMode... filterModes){
return showOpenDialog(null, filterModes);
}
public static File showOpenDialog(Window ownerWindow, FilterMode...filterModes){
File chosenFile = getInstance(filterModes).showOpenDialog(ownerWindow);
if(chosenFile != null){
lastKnownDirectoryProperty.setValue(chosenFile.getParentFile());
}
return chosenFile;
}
public static File showSaveDialog(FilterMode... filterModes){
return showSaveDialog(null, filterModes);
}
public static File showSaveDialog(Window ownerWindow, FilterMode... filterModes){
File chosenFile = getInstance(filterModes).showSaveDialog(ownerWindow);
if(chosenFile != null){
lastKnownDirectoryProperty.setValue(chosenFile.getParentFile());
}
return chosenFile;
}
}
用法示例:
//Note the previous example still holds
File chosenFile = RetentionFileChooser.showOpenDialog();
File file = RetentionFileChooser.showSaveDialog(FilterMode.PNG_FILES);
但如果对话框关闭或取消,则此操作不起作用。
不幸的是,在关闭/终止目录之前,不会公开有关正在检查的目录的信息。如果对类进行反编译并跟踪,它最终会命中一个调用。因此,即使不允许它被子类化,它也不太可能获得这些信息。FileChooser
native
FileChooser
final
上述方法在这方面提供的唯一好处是,如果遇到这种情况,它不会更改初始目录
如果您有兴趣,那么在这个问题和链接的关键词上有一些非常好的答案:native