Javafx ListView with Images instead of Strings

烂漫一生 提交于 2019-12-02 09:54:58

Use a cell factory. You need this code where you create the ListView (or in the initialize() method if you are in an FXML controller):

banner.setCellFactory(listView -> new ListCell<String>() {
    private ImageView imageView = new ImageView();

    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setGraphic(null);
        } else {
            // true makes this load in background
            // see other constructors if you want to control the size, etc
            Image image = new Image(item, true) ; 
            imageView.setImage(image);
            setGraphic(imageView);
        }
    }
});

Here is a complete example which displays images in a ListView:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;

public class ListViewImageBrowser extends Application {

    @Override
    public void start(Stage primaryStage) {
        ObservableList<Path> imageFiles = FXCollections.observableArrayList();

        TextField directoryField = new TextField();
        Button browseButton = new Button("Browse");
        Button loadButton = new Button("Load");

        EventHandler<ActionEvent> loadHandler = event -> imageFiles.setAll(load(Paths.get(directoryField.getText())));
        loadButton.setOnAction(loadHandler);
        directoryField.setOnAction(loadHandler);

        browseButton.setOnAction(event -> {
            DirectoryChooser chooser = new DirectoryChooser();
            File file = chooser.showDialog(primaryStage);
            if (file != null) {
                directoryField.setText(file.toString());
                imageFiles.setAll(load(file.toPath()));
            }
        });

        HBox controls = new HBox(5, directoryField, browseButton, loadButton);
        controls.setAlignment(Pos.CENTER);
        controls.setPadding(new Insets(5));

        ListView<Path> imageFilesList = new ListView<>(imageFiles);
        imageFilesList.setCellFactory(listView -> new ListCell<Path>() {
            private final ImageView imageView = new ImageView();

           @Override
            public void updateItem(Path path, boolean empty) {
                super.updateItem(path, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else {
                    setText(path.getFileName().toString());
                    imageView.setImage(new Image(path.toUri().toString(), 80, 160, true, true, true));
                    setGraphic(imageView);
                }
            }
        });


        ImageView imageView = new ImageView();
        imageFilesList.getSelectionModel().selectedItemProperty().addListener((obs, oldFile, newFile) -> {
            if (newFile == null) {
                imageView.setImage(null);
            } else {
                imageView.setImage(new Image(newFile.toUri().toString(), true));
            }
        });
        imageFilesList.setMinWidth(200);

        StackPane imageHolder = new StackPane(imageView);
        imageView.fitWidthProperty().bind(imageHolder.widthProperty());
        imageView.fitHeightProperty().bind(imageHolder.heightProperty());
        imageView.setPreserveRatio(true);

        BorderPane root = new BorderPane(imageHolder, controls, null, null, imageFilesList);

        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private List<Path> load(Path directory) {
        List<Path> files = new ArrayList<>();
        try {
            Files.newDirectoryStream(directory, "*.{jpg,jpeg,png,JPG,JPEG,PNG}").forEach(file -> files.add(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return files ;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

James_D gave you the answer for a non base fxml app , if you are developing in a FXM and Controlller app remember to refresh or load your Listview with myListViewWithPath.setItems(myObserverFilledWithImages);

@FXML
    private void browseButton(ActionEvent event) throws Exception {
        System.out.println("browseButton");
        DirectoryChooser chooser = new DirectoryChooser();
        File file = chooser.showDialog(myStage);
        file = new File("E:\\FOLDER\\Imagen_File");

        if (file != null) {
            directoryField.setText(file.toString());
            oImage.setAll(load(file.toPath()));
        }
        imageFilesList.setItems(oImage); //this one load or refresh the ListView
    }

The best answer is:

ListView<ImageView> listView = new listView();
ObservableList<ImageView> items = FXCollections.observableArrayList();
listView.setItems(items);

ListView is generic - make use of it.

Then use to add items (in this case, images) to your list:

ImageView item = new ImageView("file:myimage.png");
listView.getItems().add(item);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!