Skip to content

Commit

Permalink
Feature | Register an extensionFilters listener to the NativeFileSa…
Browse files Browse the repository at this point in the history
…vePicker (#46)

* Register an `extensionFilters` listener to the NativeFileSavePicker

* Update changelog

* Update `TextEditor` sample
  • Loading branch information
besidev authored Oct 3, 2024
1 parent c22b4b0 commit f848b9b
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 22 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#### Improvements
* Updated **JPro** to version `2024.3.3`.

#### Features
* Register an `extensionFilters` listener to the native (desktop) implementation FileSavePicker in the `jpro-file`
module. The listener can be used to filter the files that are displayed in the file save picker dialog based on the file
extension.

#### Bugfixes
* Fixed the binding of the port in the local server implementation inside the `jpro-core` module to occur only when
necessary, rather than during server creation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@
*/
public class TextEditorSample extends Application {

private static final Logger logger = LoggerFactory.getLogger(TextEditorSample.class);
private static final Logger LOGGER = LoggerFactory.getLogger(TextEditorSample.class);

private static final PseudoClass FILES_DRAG_OVER_PSEUDO_CLASS = PseudoClass.getPseudoClass("files-drag-over");
private static final ExtensionFilter textExtensionFilter = ExtensionFilter.of("Text files", ".txt", ".srt", ".md", ".csv");
private static final ExtensionFilter TEXT_EXTENSION_FILTER = ExtensionFilter.of("Text files", ".txt", ".srt", ".md", ".csv");
private final ObjectProperty<File> lastOpenedFile = new SimpleObjectProperty<>(this, "lastOpenedFile");

@Override
Expand All @@ -76,15 +77,15 @@ public void start(Stage stage) {
}

public Parent createRoot(Stage stage) {
Label dropLabel = new Label("Drop " + textExtensionFilter.description().toLowerCase() + " here!");
Label dropLabel = new Label("Drop " + TEXT_EXTENSION_FILTER.description().toLowerCase() + " here!");
StackPane dropPane = new StackPane(dropLabel);
dropPane.getStyleClass().add("drop-pane");

TextArea textArea = new TextArea();
StackPane contentPane = new StackPane(textArea, dropPane);

FileDropper fileDropper = FileDropper.create(contentPane);
fileDropper.setExtensionFilter(textExtensionFilter);
fileDropper.setExtensionFilter(TEXT_EXTENSION_FILTER);
fileDropper.setOnDragEntered(event -> {
dropPane.pseudoClassStateChanged(FILES_DRAG_OVER_PSEUDO_CLASS, true);
contentPane.getChildren().setAll(textArea, dropPane);
Expand All @@ -105,7 +106,7 @@ public Parent createRoot(Stage stage) {

Button openButton = new Button("Open", new FontIcon(Material2AL.FOLDER_OPEN));
FileOpenPicker fileOpenPicker = FileOpenPicker.create(openButton);
fileOpenPicker.setSelectedExtensionFilter(textExtensionFilter);
fileOpenPicker.setSelectedExtensionFilter(TEXT_EXTENSION_FILTER);
fileOpenPicker.setOnFilesSelected(fileSources -> {
openFile(fileSources, textArea);
contentPane.getChildren().setAll(textArea);
Expand Down Expand Up @@ -133,7 +134,7 @@ public Parent createRoot(Stage stage) {
fileSavePicker.initialFileNameProperty().bind(lastOpenedFile.map(file ->
FilenameUtils.getName(file.getName())).orElse("subtitle"));
fileSavePicker.initialDirectoryProperty().bind(lastOpenedFile.map(File::getParentFile));
fileSavePicker.setSelectedExtensionFilter(ExtensionFilter.of("Subtitle format (.srt)", ".srt"));
fileSavePicker.setSelectedExtensionFilter(TEXT_EXTENSION_FILTER);
fileSavePicker.setOnFileSelected(file -> saveToFile(textArea).apply(file));

BorderPane rootPane = new BorderPane(contentPane);
Expand All @@ -151,16 +152,16 @@ public Parent createRoot(Stage stage) {
private void openFile(List<? extends FileSource> fileSources, TextArea textArea) {
fileSources.stream().findFirst().ifPresentOrElse(fileSource -> // Set the last opened file
fileSource.uploadFileAsync()
.thenCompose(file -> {
try {
final String fileContent = new String(Files.readAllBytes(file.toPath()));
Platform.runLater(() -> textArea.setText(fileContent));
return CompletableFuture.completedFuture(file);
} catch (IOException ex) {
logger.error("Error reading file: " + ex.getMessage(), ex);
return CompletableFuture.failedFuture(ex);
}
}).thenAccept(lastOpenedFile::set), () -> logger.warn("No file selected"));
.thenCompose(file -> {
try {
final String fileContent = new String(Files.readAllBytes(file.toPath()));
Platform.runLater(() -> textArea.setText(fileContent));
return CompletableFuture.completedFuture(file);
} catch (IOException ex) {
LOGGER.error("Error reading file: {}", file.getAbsolutePath(), ex);
return CompletableFuture.failedFuture(ex);
}
}).thenAccept(lastOpenedFile::set), () -> LOGGER.warn("No file selected"));
}

/**
Expand All @@ -174,10 +175,10 @@ private Function<File, CompletableFuture<Void>> saveToFile(TextArea textArea) {
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(textArea.getText().getBytes());
} catch (IOException ex) {
logger.error("Error writing file: " + ex.getMessage(), ex);
LOGGER.error("Error writing file: {}", file.getAbsolutePath(), ex);
}
lastOpenedFile.set(file);
System.out.println("Saved file: " + file.getAbsolutePath());
LOGGER.info("Saved to file: {}", file.getAbsolutePath());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class NativeFileOpenPicker extends BaseFileOpenPicker {

private final FileChooser fileChooser = new FileChooser();
private List<NativeFileSource> nativeFileSources = List.of();
private final ListChangeListener<ExtensionFilter> extensionListFiltersListener = change -> {
private final ListChangeListener<ExtensionFilter> extensionFiltersListChangeListener = change -> {
while (change.next()) {
if (change.wasAdded()) {
for (ExtensionFilter extensionFilter : change.getAddedSubList()) {
Expand All @@ -57,7 +57,7 @@ public NativeFileOpenPicker(Node node) {

// Wrap the listener into a WeakListChangeListener to avoid memory leaks,
// that can occur if observers are not unregistered from observed objects after use.
getExtensionFilters().addListener(new WeakListChangeListener<>(extensionListFiltersListener));
getExtensionFilters().addListener(new WeakListChangeListener<>(extensionFiltersListChangeListener));

// Define the action that should be performed when the user clicks on the node.
node.addEventHandler(MouseEvent.MOUSE_CLICKED, actionEvent -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.WeakListChangeListener;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.FileChooser;
Expand All @@ -23,11 +25,30 @@
*/
public class NativeFileSavePicker extends BaseFileSavePicker {

private final FileChooser fileChooser;
private final FileChooser fileChooser = new FileChooser();
private final ListChangeListener<ExtensionFilter> extensionFiltersListChangeListener = change -> {
while (change.next()) {
if (change.wasAdded()) {
for (ExtensionFilter extensionFilter : change.getAddedSubList()) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(
extensionFilter.description(), extensionFilter.extensions().stream()
.map(ext -> "*" + ext).toList()));
}
} else if (change.wasRemoved()) {
for (ExtensionFilter extensionFilter : change.getRemoved()) {
fileChooser.getExtensionFilters().removeIf(filter ->
filter.getDescription().equals(extensionFilter.description()));
}
}
}
};

public NativeFileSavePicker(Node node) {
super(node);
fileChooser = new FileChooser();

// Wrap the listener into a WeakListChangeListener to avoid memory leaks,
// that can occur if observers are not unregistered from observed objects after use.
getExtensionFilters().addListener(new WeakListChangeListener<>(extensionFiltersListChangeListener));
}

@Override
Expand Down

0 comments on commit f848b9b

Please sign in to comment.