Manku
Manku

Reputation: 471

JavaFX TableView with ImageView array in column

JavaFX TableView is not displaying List of Images in TableColumn. Can Someone help me to display multiple image in TableColumn for particular entry of in tableview. Here is code:

Controller class has following code:

@Override
public void initialize(URL arg0, ResourceBundle arg1) {
    RecordInfo recordInfo;
    Image ii;
    ObservableList<RecordInfo>list=FXCollections.observableArrayList();
    for(int i=1;i<10;i++){
        recordInfo=new RecordInfo();

        String p=i+".jpg";

        ii=new Image(p);
        ImageView[] img=new ImageView[3];

        img[0]=new ImageView();
        img[0].setImage(ii);
        img[0].setFitHeight(120);
        img[0].setFitWidth(240);    

        recordInfo.setPic(img);

        pic.setCellValueFactory(new PropertyValueFactory<RecordInfo, ImageView[]>("pic"));          
        list.add(recordInfo);
    }
}

While Record class has:

public class RecordInfo {
   private ImageView[] pic;
   public ImageView[] getPic() {
     return pic;
   }
   public void setPic(ImageView[] pic) {
     this.pic = pic;
   }    

   }

Upvotes: 1

Views: 405

Answers (2)

Invest
Invest

Reputation: 645

@fabian 's answer was not 100% what I was looking for but I was able to get my solution out of it using an HBox.

I wanted to show 3 pictures next to each other in a table cell.

Code my view:

@FXML
private TableColumn<ImageWrapper, HBox> tableColumnVereinzelung;    

tableColumnImages.setCellValueFactory(cdf -> {
    return new ReadOnlyObjectWrapper<HBox>(cdf.getValue()
            .getImagesForTableCell());

});

Method "getImagesForTableCell" that is in "ImageWrapper":

public HBox getImagesForTableCell() {
    HBox container = new HBox();
    ObservableList<Node> children = container.getChildren();

    for (int i = 1; i <= myImages.size(); i++) {
        children.add(new ImageView(this.myImages.get(i)));
    }
    return container;
}   

Upvotes: 1

fabian
fabian

Reputation: 82531

You need a custom cellFactory for this. Furthermore I recommend using a Image[] array in RecordInfo instead:

public class RecordInfo {

    private Image[] pic;

    public Image[] getPic() {
        return pic;
    }

    public void setPic(Image[] pic) {
        this.pic = pic;
    }

}
public class ImagesTableCell<T> extends TableCell<T, Image[]> {

    private final List<ImageView> imageViews;
    private final HBox container;

    private ImagesTableCell(List<ImageView> imageViews) {
        this.container = new HBox();
        this.imageViews = imageViews;
    }

    private ImageView getOrCreateImageView() {
        if (!imageViews.isEmpty()) {
            return imageViews.remove(imageViews.size() - 1);
        } else {
            ImageView iv = new ImageView();
            iv.setFitHeight(20);
            iv.setFitWidth(20);
            return iv;
        }
    }

    @Override
    protected void updateItem(Image[] item, boolean empty) {
        super.updateItem(item, empty);

        ObservableList<Node> children = container.getChildren();
        int newLength = (empty || item == null) ? 0 : item.length;

        if (newLength < children.size()) {
            // remove ImageViews that are not required
            for (int i = newLength; i < children.size(); i++) {
                ImageView iv = (ImageView) children.get(i);
                imageViews.add(iv); // allow reuse of imageviews
                iv.setImage(null); // don't prevent garbagecollection of image
            }
            children.remove(newLength, children.size());
        }

        // add missing imageviews
        for (int i = children.size(); i < newLength; i++) {
            children.add(getOrCreateImageView());
        }

        // fill imageviews
        for (int i = 0; i < newLength; i++) {
            ((ImageView) children.get(i)).setImage(item[i]);
        }

        setGraphic(newLength == 0 ? null : container);
    }

    public static <E> Callback<TableColumn<E, Image[]>, TableCell<E, Image[]>> forTableColumn() {
        List<ImageView> views = new ArrayList<>();
        return c -> new ImagesTableCell<>(views);
    }

}
pic.setCellFactory(ImagesTableCell.forTableColumn());

Upvotes: 1

Related Questions