Creare una ListView di immagini in JavaFX

Mattepuffo's logo
Creare una ListView di immagini in JavaFX

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!


Condividi

Commentami!