我的 TableView 显示图片的地址但不是实际图片

My TableView displays the address of the picture but not the actual picture

嘿,我正在尝试保存名称为 "Avatar" 的对象,然后检索该对象并显示其图片 "image"。我得到了这个结果:

我的头像Class:

@Entity
@Table(name="avatar")
public class Avatar implements java.io.Serializable {

    @Id
    private Integer avatarId;
    @Column(name = "image")
    private byte[] image;
//getters and setters

我如何保存对象:

session.getTransaction().begin();

        File file = new File("PicturePath");
        byte[] bFile = new byte[(int) file.length()];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read(bFile);
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Avatar avatar = new Avatar();
        avatar.setAvatarId(1);
        avatar.setImage(bFile);
        session.save(avatar);
        session.getTransaction().commit();

正在从 Avatar 中检索数据 Table:

public List<Avatar> avatarList(){
        session.getTransaction().begin();
        List<Avatar> avatar = session.createQuery("from Avatar").list();
        session.getTransaction().commit();
        return avatar;
    }

控制器:

 @FXML
    public TableView<Avatar> produits;

    @FXML
    public void initialize(){

        Task<ObservableList<Avatar>> task = new Task<ObservableList<Avatar>>() {
            @Override
            protected ObservableList<Avatar> call() throws Exception {
                return FXCollections.observableArrayList(CategorieTrait.getInstance().avatarList());
            }
        };


        produits.itemsProperty().bind(task.valueProperty());

        new Thread(task).start();
    }

我的 FXML 文件:

<TableView style="-fx-backround-color:#33d9b2;" fx:id="produits" prefWidth="900" prefHeight="600">

            <columnResizePolicy>
                <TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>

            </columnResizePolicy>
            <columns>

                <TableColumn text="Picture" style="-fx-backround-color:#33d9b2">
                    <cellValueFactory>
                        <PropertyValueFactory property="image"/>
                    </cellValueFactory>
                </TableColumn>
            </columns>
        </TableView>

我期待在表格视图中显示实际图片。

您看不到图像的原因是,尽管您正确地为 TableView 提供了图像的字节,但您没有告诉它如何渲染它们。您需要的是将字节数组呈现为 ImageView 的自定义 TableCell。所以我会做以下事情:

首先在你的fxml文件中的TableColumn中添加一个id属性:

<TableColumn fx:id="imageColumn" text="Picture" style="-fx-backround-color:#33d9b2">
    <cellValueFactory>
        <PropertyValueFactory property="image"/>
    </cellValueFactory>
</TableColumn>

然后在你的 Controller 中引用它并添加一个 CellFactory 到它:

@FXML
public TableView<Avatar> produits;

@FXML
public TableColumn<Avatar, byte[]> imageColumn;

@FXML
public void initialize() {
    ...
    imageColumn.setCellFactory(param -> new TableCell<Avatar, byte[]>() {

        private ImageView imageView = new ImageView();

        @Override
        protected void updateItem(byte[] item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                imageView.setImage(getImageFromBytes(item));
                setGraphic(imageView);
            }
            this.setItem(item);
        }
    });
    ...
}

CellFactory 为您的每个 Avatar 项目创建一个 table 单元格,该单元格的 updateItem() 方法将字节转换为 Image呈现为 ImageView(如果单元格不为空)。 这是一种将字节数组转换为 JavaFX Image:

的方法
private Image getImageFromBytes(byte[] imgBytes) {
    try {
        ByteArrayInputStream inputStream = new ByteArrayInputStream(imgBytes);
        BufferedImage bufferedImage = ImageIO.read(inputStream);
        return SwingFXUtils.toFXImage(bufferedImage, null);
    } catch (IOException e) {
        e.printStackTrace();
    } 
    return null;
}

重要说明:我会避免从 updateItem() 内部调用 getImageFromBytes() 方法,尤其是对于具有大量记录的 TableView。为了简单起见,我只是这样做了。您可能想事先转换图像,并可能将它们存储在地图或其他东西中。

编辑:updateItem() 方法更改为每次调用时不创建新的 ImageView