gpt4 book ai didi

java - JavaFX FileChooser "remember"可以是它打开的最后一个目录吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:12 25 4
gpt4 key购买 nike

我的 View Controller 有一个 FileChooser 实例用于打开和保存文件。

每次我从该实例调用 showOpenDialog()showSaveDialog() 时,我希望生成的对话框与我上次离开时​​位于同一目录中我调用其中一个。

相反,每次我调用其中一个方法时,对话框都会在用户主目录中打开。

如何使对话框的“当前目录”在不同的调用中保持不变?


当前行为示例:

import java.io.File;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

/**
* Demonstrates the use of an open dialog.
*
* @author N99x
*/
public class FileChooserTest extends Application {

private final FileChooser open = new FileChooser();
private File lastOpened = null;

@Override
public void start(Stage primaryStage) {
Label lbl = new Label("File Opened: <null>");
lbl.setPadding(new Insets(8));
Button btn = new Button();
btn.setPadding(new Insets(8));
btn.setText("Open");
btn.setOnAction((ActionEvent event) -> {
open.setInitialDirectory(lastOpened);
File selected = open.showOpenDialog(primaryStage);
if (selected == null) {
lbl.setText("File Opened: <null>");
// lastOpened = ??;
} else {
lbl.setText("File Opened: " + selected.getAbsolutePath());
lastOpened = selected.getParentFile();
}
});

VBox root = new VBox(lbl, btn);
root.setPadding(new Insets(8));
root.setAlignment(Pos.TOP_CENTER);
Scene scene = new Scene(root, 300, 300);

primaryStage.setTitle("FileChooser Testing!");
primaryStage.setScene(scene);
primaryStage.show();
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}

}

我设法通过存储打开的值解决了部分问题,但如果对话框关闭或取消,这将不起作用。

最佳答案

How do I make the "current directory" of the dialogs persist across different invocations?

您可以修改 Singleton Pattern方法

因此您将只使用一个 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"));

由于不提供任何 ExtensionFilterFileChooser 变得不太用户友好,需要用户手动附加文件类型,但在创建实例时提供过滤器无法更新它们将其限制为那些相同的过滤器

对此进行改进的一种方法是在 RetentionFileChooser 中公开可选过滤器,可以使用 varargs 提供。 ,您可以在显示对话框时选择何时修改过滤器

例如,在之前的基础上构建:

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);

but this does not work if the dialog is closed or canceled.

不幸的是,FileChooser 没有公开有关在关闭/终止之前正在检查的目录的信息。如果您反编译该类并进行跟踪,它最终会遇到一个 native 调用。因此,即使 FileChooser 不是 final 允许它被子类化,它也不太可能获得此信息

上述方法提供的唯一好处是,如果遇到这种情况,它不会更改初始目录


如果您有兴趣,在这个问题和链接中的 native 关键词上有一些非常好的答案:

关于java - JavaFX FileChooser "remember"可以是它打开的最后一个目录吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36920131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com