1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| package test.tile;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public final class Main extends Application {
private static final String STORAGE = // chemin des images
private static final int THUMBNAIL_WIDTH = 100;
private static final int THUMBNAIL_HEIGHT = 100;
private static final boolean THUMBNAIL_SMOOTH = true;
private static final boolean THUMBNAIL_PRESERVE_RATIO = true;
private FlowPane flowPane;
private Service<List<ImageData>> loader;
@Override
public void start(final Stage stage) throws Exception {
flowPane = new FlowPane();
flowPane.setOrientation(Orientation.HORIZONTAL);
flowPane.setHgap(5);
flowPane.setVgap(5);
// IntStream.range(0, 100)
// .forEach(index -> flowPane.getChildren().add(new Button(String.valueOf(index))));
final var scrollPane = new ScrollPane(flowPane);
scrollPane.setFitToWidth(true);
final var scene = new Scene(scrollPane);
stage.setTitle("Test");
stage.setWidth(800);
stage.setHeight(600);
stage.setScene(scene);
stage.show();
Platform.runLater(this::loadImagesAsync);
}
private void loadImagesAsync() {
Optional.ofNullable(loader)
.ifPresent(Service::cancel);
loader = null;
flowPane.getChildren().clear();
final var service = new Service<List<ImageData>>() {
@Override
protected Task<List<ImageData>> createTask() {
return new Task<>() {
@Override
protected List<ImageData> call() throws Exception {
final var storagePath = Paths.get(STORAGE);
List<ImageData> imageList = Collections.emptyList();
try (final var stream = Files.list(storagePath)) {
imageList = stream.filter(Files::isRegularFile)
.map(path -> {
final var filename = path.getFileName().toString();
long size = 0;
try {
size = Files.size(path);
} catch (IOException ioe) {
// @todo Log warning.
}
final var fileURL = path.toUri().toString();
final var thumbnail = new Image(fileURL, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, THUMBNAIL_PRESERVE_RATIO, THUMBNAIL_SMOOTH, true);
return new ImageData(filename, fileURL, size, thumbnail);
})
.toList();
}
return imageList;
}
};
}
};
service.setOnSucceeded(event -> {
System.out.println("Service succeeded");
final var imageList = (List<ImageData>) event.getSource().getValue();
imageList.stream()
.map(this::createThumbnail)
.forEach(flowPane.getChildren()::add);
});
service.setOnCancelled(event -> System.out.println("Service cancelled"));
service.setOnFailed(event -> System.out.println("Service failed"));
loader = service;
loader.start();
}
private ImageView createThumbnail(final ImageData imageData) {
final var imageView = new ImageView();
imageView.setImage(imageData.thumbnail());
imageView.setUserData(imageData);
imageView.setOnMouseClicked(event -> showImage((ImageData) imageView.getUserData(), imageView.getScene().getWindow()));
final var tooltip = new Tooltip();
tooltip.setText(imageData.filename());
Tooltip.install(imageView, tooltip);
return imageView;
}
private void showImage(final ImageData imageData, final Window parent) {
final var fileURL = imageData.fileURL();
final var image = new Image(fileURL, true);
final var imageView = new ImageView(image);
final var scrollPane = new ScrollPane(imageView);
final var dialog = new Dialog<>();
dialog.initOwner(parent);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.setTitle(imageData.fileURL());
dialog.setResizable(true);
dialog.getDialogPane().getButtonTypes().setAll(ButtonType.OK);
dialog.getDialogPane().setContent(scrollPane);
dialog.show();
Platform.runLater(() -> {
dialog.setWidth(800);
dialog.setHeight(600);
});
}
private record ImageData(String filename, String fileURL, long size, Image thumbnail) {
}
} |
Partager