My TableView отображает адрес картинки, но не фактическую картинку - PullRequest
0 голосов
/ 17 января 2020

Привет, я пытаюсь сохранить объект с именем «Аватар», а затем извлечь объект и отобразить его изображение «изображение». я получил этот результат: enter image description here

мой класс аватара:

@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();

Получение данные из таблицы аватаров:

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();
    }

Мой файл F XML:

<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>

Я ожидал, что фактическое изображение отобразится в стол.

1 Ответ

3 голосов
/ 18 января 2020

Причина, по которой вы не видите изображение, заключается в том, что, хотя вы правильно предоставляете свои TableView байты изображения, вы не указываете, как их визуализировать. Вам нужен пользовательский TableCell, который отображает байтовый массив в ImageView. Поэтому я бы сделал следующее:

Сначала добавьте свойство id в ваш TableColumn в вашем файле f xml:

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

Затем сделайте ссылку на него внутри вашего контроллера и добавьте 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 создает ячейку таблицы для каждого элемента Аватара, а метод 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;
}

Важное примечание: Я бы не стал вызывать метод getImageFromBytes() изнутри updateItem(), особенно для TableView с большим количеством записей. Я просто сделал это для простоты. Возможно, вы захотите заранее преобразовать изображения и, возможно, сохранить их на карте или что-то в этом роде.

Редактировать: Изменен метод updateItem(), чтобы каждый раз не создавать новый ImageView называется.

...