1

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

   }

2 Answers 2

1

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());
Sign up to request clarification or add additional context in comments.

2 Comments

c -> new ImagesTableCell<>(views); is a lambda expression supported in java 1.8 or above. I am naive java programmer. Please can you write the above statement without lambda expression, so that it will work on 1.7 also
new Callback<TableColumn<E, Image[]>, TableCell<E, Image[]>>() { @Override public TableCell<E, Image[]> call(TableColumn<E, Image[]> c) { return new ImagesTableCell<E>(views); }} BTW: If you're using a IDE capable of java 8, there's a good chance it features a tool to automatically convert from a lambda expression to an anyonymus class. At least NetBeans provides this feature...
1

@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;
}   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.