Làm cách nào để làm cho "thư mục hiện tại" của các hộp thoại vẫn tồn tại trên các lời gọi khác nhau?
Bạn có thể thay đổi cách tiếp cận Singleton Pattern cho điều này
Nhờ đó mà bạn sẽ chỉ sử dụng một FileChooser
và theo dõi/kiểm soát thư mục ban đầu có, nhưng không trực tiếp phơi bày các ví dụ để thay đổi bên ngoài của lớp
Ví dụ:
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;
}
}
Điều này sẽ thiết lập các thư mục ban đầu của FileChooser
là thư mục của tập tin người dùng mở cuối cùng/lưu khi nó là tái sử dụng
sử dụng Ví dụ:
File chosenFile = RetentionFileChooser.showOpenDialog();
Tuy nhiên có một hạn chế ở đây:
//Set the FileExtensions you want to allow
instance.getExtensionFilters().setAll(new ExtensionFilter("png files (*.png)", "*.png"));
Như mà không cung cấp bất kỳ ExtensionFilter
's các FileChooser
trở nên ít người dùng thân thiện, đòi hỏi người sử dụng bằng tay appe loại tệp, nhưng việc cung cấp các bộ lọc khi tạo cá thể không có cách nào cập nhật chúng sẽ giới hạn nó với cùng một bộ lọc đó
Một cách để cải thiện điều này là phơi bày các bộ lọc tùy chọn trong RetentionFileChooser
có thể được cung cấp bằng cách sử dụng varargs. bạn có thể chọn khi nào nên sửa đổi các bộ lọc như bạn hiển thị các hộp thoại
Ví dụ, xây dựng trên theo thời gian: sử dụng
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;
}
}
Ví dụ:
//Note the previous example still holds
File chosenFile = RetentionFileChooser.showOpenDialog();
File file = RetentionFileChooser.showSaveDialog(FilterMode.PNG_FILES);
nhưng điều này không hoạt động nếu hộp thoại bị đóng hoặc hủy.
Không may hiển thị thông tin về thư mục nào trước khi đóng/chấm dứt. Nếu bạn loại bỏ lớp và theo dõi, cuối cùng nó sẽ truy cập cuộc gọi native
.Vì vậy, ngay cả khi FileChooser
không final
cho phép nó được subclassed, nó chỉ là như khó có khả năng có thể nhận được thông tin này
duy nhất đạt được cách tiếp cận trên đây cung cấp khoảng này là nó không làm thay đổi thư mục ban đầu nếu kịch bản này được đánh
Nếu bạn quan tâm, có một số câu trả lời rất tốt trên các từ khóa native
trong câu hỏi này và những liên kết:
Một giải pháp đơn giản cho đề xuất mở rộng tệp sẽ là đặt lại tiện ích mở rộng tệp mỗi khi bạn gọi. IE: 'fileChooser.getExtensionFilters(). Clear(); fileChooser.getExtensionFilters(). Thêm (FileChooser.ExtensionFilter mới ("PNG", "* .png")); ' –