Co zrobić, aby "bieżący katalog" dialogów nadal występował w różnych wywołaniach?
Można zmodyfikować podejście Singleton Pattern tego
Przy czym należy użyć tylko jednego FileChooser
i monitor/kontrolować początkowy katalog istnieje, ale nie bezpośrednio narażając instancji do modyfikacji poza klasą
Na przykład:
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;
}
}
Spowoduje to ustawienie początkowy katalog z FileChooser
być katalog pliku użytkownik ostatni otwieranych/zapisywanych gdy jest ponownie wykorzystywane
Przykład użycia:
File chosenFile = RetentionFileChooser.showOpenDialog();
Jednak istnieje ograniczenie o:
//Set the FileExtensions you want to allow
instance.getExtensionFilters().setAll(new ExtensionFilter("png files (*.png)", "*.png"));
Jak bez podawania ExtensionFilter
„s FileChooser
jest mniej przyjazna dla użytkownika, wymaga od użytkownika ręcznie appe nd typ pliku, ale dostarczenie filtrów podczas tworzenia instancji bez możliwości ich aktualizacji ogranicza je do tych samych filtrów
Jednym ze sposobów ulepszenia tego jest odsłonięcie opcjonalnych filtrów w ramach RetentionFileChooser
, które można uzyskać za pomocą varargs, przy czym można wybrać podczas modyfikowania filtrów podczas wyświetlania okien dialogowych
na przykład, w oparciu o poprzedni:
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;
}
}
przykład użycia:
//Note the previous example still holds
File chosenFile = RetentionFileChooser.showOpenDialog();
File file = RetentionFileChooser.showSaveDialog(FilterMode.PNG_FILES);
ale to nie działa, jeśli okno dialogowe jest zamknięte lub anulowane.
Niestety nie ma informacji o tym, który katalog był badany przed jego zamknięciem/zakończeniem. Jeśli usuniesz kompilację klasy i prześledzisz ją, w końcu trafi ona na wywołanie native
.Więc nawet jeśli FileChooser
nie byłby final
pozwalający na jego subklasę, to jest mało prawdopodobne, aby móc uzyskać te informacje. Jedyną korzyścią, jaką daje powyższe podejście, jest to, że nie zmienia katalogu początkowego, jeśli ten scenariusz jest trafiony
Jeśli jesteś zainteresowany, istnieje kilka bardzo dobrych odpowiedzi na słowa kluczowego native
w tej kwestii i te powiązane:
Prostym rozwiązaniem propozycji rozszerzeń plików jest resetowanie rozszerzeń plików za każdym razem, gdy je wywołasz. IE: 'fileChooser.getExtensionFilters(). Clear(); fileChooser.getExtensionFilters(). Add (nowy FileChooser.ExtensionFilter ("PNG", "* .png")); ' –