Display image in table


Question

I am trying to insert an image into table view in JavafX. Here is how I set up my table view:

TableColumn prodImageCol = new TableColumn("IMAGES");
    prodImageCol.setCellValueFactory(new PropertyValueFactory<Product, Image>("prodImage"));
    prodImageCol.setMinWidth(100);
    // setting cell factory for product image        
    prodImageCol.setCellFactory(new Callback<TableColumn<Product,Image>,TableCell<Product,Image>>(){        
        @Override
        public TableCell<Product,Image> call(TableColumn<Product,Image> param) {                
            TableCell<Product,Image> cell = new TableCell<Product,Image>(){
                    public void updateItem(Product item, boolean empty) {                        
                    if(item!=null){                            
                        ImageView imageview = new ImageView();
                        imageview.setFitHeight(50);
                        imageview.setFitWidth(50);
                        imageview.setImage(new Image(product.getImage()));
                    }
                }
            };
            return cell;
        }

    });        

 viewProduct.setEditable(false);
 viewProduct.getColumns().addAll(prodImageCol, prodIDCol, prodNameCol, prodDescCol, prodPriceCol, col_action);
 viewProduct.getItems().setAll(product.populateProductTable(category));

 private SimpleObjectProperty prodImage;

 public void setprodImage(Image value) {
    prodImageProperty().set(value);
}

public Object getprodImage() {
    return prodImageProperty().get();
}

public SimpleObjectProperty prodImageProperty() {
    if (prodImage == null) {
        prodImage = new SimpleObjectProperty(this, "prodImage");
    }
    return prodImage;
}

And this is how I retrieve the image from database:

 Blob blob = rs.getBlob("productImage");
 byte[] data = blob.getBytes(1, (int) blob.length());
 bufferedImg = ImageIO.read(new ByteArrayInputStream(data));
 image = SwingFXUtils.toFXImage(bufferedImg, null);

However I am getting error at the setting up of table view: imageview.setImage(new Image(product.getImage())); The error message as:

no suitable constructor found for Image(Image)
constructor Image.Image(String,InputStream,double,double,boolean,boolean,boolean) is not applicable
  (actual and formal argument lists differ in length)
constructor Image.Image(int,int) is not applicable
  (actual and formal argument lists differ in length)
constructor Image.Image(InputStream,double,double,boolean,boolean) is not applicable
  (actual and formal argument lists differ in length)
constructor Image.Image(InputStream) is not applicable
  (actual argument Image cannot be converted to InputStream by method invocation conversion)
constructor Image.Image(String,double,double,boolean,boolean,boolean) is not applicable
  (actual and formal argument lists differ in length)
constructor Image.Image(String,double,double,boolean,boolean) is not applicab...

I did managed to retrieve and display an image inside an image view but however, I can't display it in table column. Any help would be appreciated. Thanks in advance.

1
1
7/17/2013 3:08:00 PM

Accepted Answer

The problem that's causing the exception is that your method product.getImage() is returning an javafx.scene.Image. There's no need to do anything else at this point: You have an image, so use it (before you were trying to construct new Image(Image) - which is not even possible). This is what you want to be using:

imageview.setImage(product.getImage());

Your second problem is that while you're creating an ImageView every time you update the cell, you're not doing anything with it. Here's your original code:

        TableCell<Product,Image> cell = new TableCell<Product,Image>(){
                public void updateItem(Product item, boolean empty) {                        
                if(item!=null){                            
                    ImageView imageview = new ImageView();
                    imageview.setFitHeight(50);
                    imageview.setFitWidth(50);
                    imageview.setImage(new Image(product.getImage()));
                }
            }
        };
        return cell;

Like @tomsontom suggested, I'd recommend using setGraphic(Node) to attach your ImageView to the TableCell. So you might end up with something like this:

        //Set up the ImageView
        final ImageView imageview = new ImageView();
        imageview.setFitHeight(50);
        imageview.setFitWidth(50);

        //Set up the Table
        TableCell<Product,Image> cell = new TableCell<Product,Image>(){
                public void updateItem(Product item, boolean empty) {                        
                if(item!=null){
                    imageview.setImage(product.getImage());  //Change suggested earlier
                }
            }
        };

        // Attach the imageview to the cell
        cell.setGraphic(imageview) 
        return cell;

The first point @tomsontom was making is that your method of creating an Image is a little roundabout. Sure, it seems to work... but there's a simpler way. Originally you were using:

 bufferedImg = ImageIO.read(new ByteArrayInputStream(data));
 image = SwingFXUtils.toFXImage(bufferedImg, null);

But a better way of doing it would be switching those lines with:

 image = new Image(new ByteArrayInputStream(data));
3
7/17/2013 2:49:00 PM

  1. why are not creating the Image directly from the data new Image(new ByteArrayInputStream(data)) no need to rewrap it our use Swing stuff
  2. I don't see a public Image(Object) constructor in FX8 - why passing it anyways if you are already have an image instance?
  3. you need to set the ImageView on the cell with setGraphic()

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon