Creare una ListView di immagini in JavaFX
Quello che faremo oggi è questo: da una voce di menu creato in FXML, avviamo un DirectoryChooser, dal quale prendiamo tutte le immagini della directory scelta, e le mettiamo in una ListView.
Inoltre, metteremo l'immagine selezionata dentro ad un ImageView.
Cominciamo con il file FXML:
<BorderPane fx:id="mainPane" xmlns="http://javafx.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.mp.photogallery.MainController">
<top>
<VBox>
<children>
<MenuBar fx:id="menuBar">
<menus>
<Menu text="File">
<items>
<MenuItem accelerator="Ctrl+O" onAction="#openDirectory"
text="Open phpto directory" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</VBox>
</top>
<bottom>
<ListView fx:id="listViewImages" maxHeight="200" orientation="HORIZONTAL" />
</bottom>
<center>
<ScrollPane pannable="true">
<content>
<ImageView fx:id="currentImage" />
</content>
</ScrollPane>
</center>
</BorderPane>
Nel nostro controller abbiamo una cosa del genere:
public class MainController {
private Stage stage = null;
private ArrayList images = null;
private ObservableList items = null;
@FXML
private BorderPane mainPane;
@FXML
private ListView listViewImages;
@FXML
private ImageView currentImage;
@FXML
public void initialize() {
}
private Stage getStage() {
stage = (Stage) mainPane.getScene().getWindow();
return stage;
}
@FXML
private void openDirectory() {
if (images != null) {
items.clear();
images.clear();
listViewImages.refresh();
}
images = ListImages.getImages(getStage());
items = FXCollections.observableArrayList(images);
listViewImages.setItems(items);
listViewImages.setCellFactory(param -> new ListCell() {
private ImageView imageView = new ImageView();
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
imageView.setImage(null);
setGraphic(null);
setText(null);
} else {
imageView.setImage(new Image(new File(item).toURI()
.toString(), 0, 100, true, true));
setGraphic(imageView);
//setText(item);
}
}
});
listViewImages.getSelectionModel().selectedItemProperty()
.addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
File f = new File(newValue);
currentImage.setImage(new Image(f.toURI().toString()));
}
});
}
}
In pratica abbiamo impostato un nuovo ListCell con setCellFactory.
Qui dentro abbiamo usato delle ImageView andando a prendere tutte le immagini create; la lista di immagini viene creata con un DirectoryChooser:
public class ListImages {
public static ArrayList getImages(Stage stage) {
ArrayList images = new ArrayList<>();
DirectoryChooser dc = new DirectoryChooser();
dc.setTitle("Open photo directory");
dc.setInitialDirectory(new File(System.getProperty("user.home")));
File dir = dc.showDialog(stage);
if (dir != null) {
File[] files = dir.listFiles(
(dir1, name) -> (
name.endsWith(".jpg") ||
name.endsWith(".jpeg")
|| name.endsWith(".png")
));
for (File f : files) {
images.add(f.getAbsolutePath());
}
}
return images;
}
}
Inoltre abbiamo aggiunto un listener per impostare l'immagine nell'ImageView centrale.
Quando richiamiamo il metodo openDirectory, prima verifichiamo che la lista non sia vuota; nel caso la cencelliamo e "refresciamo" la ListView.
Enjoy!
java javafx imageview listview listcell setcellfactory imageview directorychooser fxml
Commentami!