嘿,我正在尝试保存一个名为“阿凡达”的对象,然后检索该对象并显示其图片“图像”。我得到这个结果:
我的头像课程:
@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();
}
我的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
提供了图像的字节,但是您没有告诉它如何呈现它们。您需要的是自定义TableCell
,它将字节数组呈现为ImageView
。因此,我将执行以下操作:
首先在fxml文件的TableColumn
中添加一个id属性:
<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[]>() {
@Override
protected void updateItem(byte[] item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
Image img = getImageFromBytes(item);
setGraphic(new ImageView(img));
}
this.setItem(item);
}
});
...
}
[CellFactory
为您的每个Avatar项目创建一个表格单元,该单元的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。为了简单起见,我只是这样做了。您可能需要预先转换图像,然后将其存储在地图或其他内容中。