首页 > 解决方案 > 如何从数据库检索图像(字节类型)到表视图(imageView)/ JavaFx

问题描述

我有两种不同的类型(字节到模型和 imageView 到视图)所以我必须使用两个类“ProductTableColumnModel”(图片列的帮助类)和模型“产品”

pictureColumn.setCellValueFactory(new PropertyValueFactory<ProductTableColumnModel, ImageView>("picture"));

但其他列是这样的:

descColumn.setCellValueFactory(new PropertyValueFactory<Product, String>("description"));

产品类别:

public class Product {


private byte[] picture;

@Column(name= "picture")
public byte[] getPicture() {
    return this.picture;
}

public void setPicture(byte[] picture) {
    
    this.picture = picture;
}
}

ProductTableColumnModel 类:

public class ProductTableColumnModel {


private ImageView picture;


public ImageView getPicture() {
    return this.picture;
}

public void setPicture(ImageView picture) {
    this.picture = picture;
}

在 ProductViewController 类中:

@FXML
TableView <Product> table_Products;

@FXML
TableColumn <Product, String> productName;

@FXML
TableColumn <Product, String> descColumn;

@FXML
TableColumn <ProductTableColumnModel, ImageView> pictureColumn;

.....

// show data in TableView
for(Product  p : getProducts() ) {
        
        Product product = new Product();
        
        product.setProductName(String.valueOf(p.getProductName() ));
        product.setDescription(String.valueOf(p.getDescription()));
        
        byte[] pictureImageInByte = p.getPicture(); 
        
        if(pictureImageInByte != null) {
            
            ByteArrayInputStream imageDate = new ByteArrayInputStream(pictureImageInByte);
            
            Image image = new Image(imageDate);
            
            /* ???????

            */
        }
        tableData.addAll(product);
    }
    /* set table items */
    table_Products.setItems(tableData);
private void intializeTableColumns() {
    
    
    tableData = FXCollections.observableArrayList();
    
    productName.setCellValueFactory(new PropertyValueFactory<Product, String>("productName"));
    
    descColumn.setCellValueFactory(new PropertyValueFactory<Product, String>("description"));
    
    pictureColumn.setCellValueFactory(new PropertyValueFactory<ProductTableColumnModel, ImageView>("picture"));
    

}

任何人都可以在此之后帮助我编写正确的代码吗?

if(pictureImageInByte != null) {

        ByteArrayInputStream imageDate = new ByteArrayInputStream(pictureImageInByte);

        Image image = new Image(imageDate);

        /* ???????

        */
    }

标签: javajavafx

解决方案


如果你有一个TableView<Product>,那么每一列都必须是TableColumn<Product, T>一些T

T每列可以不同,但​​应该始终是“数据类型”,而不是“UI 类型”(即,它不应该是 的子类Node)。

在这里你应该有

@FXML
TableColumn <Product, byte[]> pictureColumn;

因为您在列中每个单元格中显示的数据byte[].

您可以使用cellFactory一般描述如何显示单元格数据的 a 来创建ImageView要在列中的单元格中显示的 。如果图像数据是原始数据,例如 rgb 格式,您可以这样做:

private void intializeTableColumns() {

    // ...

    pictureColumn.setCellValueFactory(cellData -> 
        new SimpleObjectProperty<>(cellData.getValue().getPicture()));

    // or
    // pictureColumn.setCellValueFactory(new PropertyValueFactory<>("picture"));
    // but the previous version is much better

    pictureColumn.setCellFactory(col -> new TableCell<>() {
        private WritableImage image = new WritableImage(WIDTH, HEIGHT);
        private ImageView imageView = new ImageView(image);

        @Override
        protected void updateItem(byte[] imageData, boolean empty) {
            super.updateItem(imageData, empty) ;
            if (empty || imageData == null) {
                setGraphic(null);
            } else {
                PixelWriter pw = image.getPixelWriter();
                // modify the following as needed if you have a different format
                PixelFormat<ByteBuffer> format = PixelFormat.getByteRgbInstance();
                pw.setPixels(0, 0, WIDTH, HEIGHT, format, imageData, 0, 3*WIDTH);
                setGraphic(imageView);
            }
        }
    });

    // ...
}

显然你需要在这里填写一些信息,例如图像的宽度和高度(我刚才假设是恒定的),并根据图像在byte[]数组中的编码方式对其进行修改。

如果图像数据是可识别的格式,即 BMP、GIF、JPEG 或 PNG,您可以执行以下操作:

    pictureColumn.setCellFactory(col -> new TableCell<>() {
        private ImageView imageView = new ImageView();

        @Override
        protected void updateItem(byte[] imageData, boolean empty) {
            super.updateItem(imageData, empty) ;
            if (empty || imageData == null) {
                setGraphic(null);
            } else {
                Image image = new Image(new ByteArrayInputStream(imageData));
                imageView.setImage(image);
                setGraphic(imageView);
            }
        }
    });

推荐阅读