0

I'm trying to add an image to a tableView and went through several questions and answers and it still doesn't work.

The other fields in the tableView like name are loaded correctly.

Intelij tells me that updateItem is never used, which is probably why it doesn't work, but I have no idea how to debug this...

Here's what I got so far

    @FXML private TableColumn<PlayerManager, Image> tableColumnType;
    @FXML private void initialize(){

    tableColumnType.setCellFactory(param -> {
        //Set up the ImageView
        final ImageView imageview = new ImageView();
        imageview.setFitHeight(10);
        imageview.setFitWidth(10);
        ///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
        //Set up the Table
        TableCell<PlayerManager, Image> cell = new TableCell<PlayerManager, Image>() {
            public void updateItem(PlayerManager item, boolean empty) {
                if (item != null) {  // choice of image is based on values from item, but it doesn't matter now
                    imageview.setImage(imageComputer);
                }
            }
        };

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

The questions I went through are:

How to add an Image into a JavaFx TableView column

Display image in table

Inserting images into TableView rows - JavaFX

Community
  • 1
  • 1
shinzou
  • 5,850
  • 10
  • 60
  • 124
  • Please [edit] the question to show the cell value factory for the column, as well as the cell factory. – James_D Sep 10 '16 at 22:51
  • Did you run this in the debugger? What happened? – Robert Sep 10 '16 at 23:00
  • @James_D I didn't know it needs a `cellValueFactory` too, and what other `cellFactory` there should be? – shinzou Sep 10 '16 at 23:01
  • The cell value factory determines what data the cell displays. The cell factory determines what cell is used to display the data. If you don't have a cell value factory, then the data (i.e. the `item`) passed to the cell will always be null. So if you have a `TableColumn` the cell value factory should be a function that returns an `ObservableValue`. The answer to the first question you linked starts "You forgot to [use] a cellValueFactory". The other questions also use cell value factories. – James_D Sep 10 '16 at 23:05

2 Answers2

2

The signature of the updateItem method is wrong: it should be

public void updateItem(Image item, boolean empty) { /* ... */ }

If the compiler rejects the @Override annotation, then you know you are not defining the correct method. So you should use @Override and if you get a compile error, it is a signal that something is not right.

So you should be able to do

@FXML private TableColumn<PlayerManager, Image> tableColumnType;
@FXML private void initialize(){

tableColumnType.setCellFactory(param -> {
        //Set up the ImageView
        final ImageView imageview = new ImageView();
        imageview.setFitHeight(10);
        imageview.setFitWidth(10);
        ///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
        //Set up the Table
        TableCell<PlayerManager, Image> cell = new TableCell<PlayerManager, Image>() {
            @Override
            public void updateItem(Image item, boolean empty) {
                if (item != null) {  // choice of image is based on values from item, but it doesn't matter now
                    imageview.setImage(imageComputer);
                }
            }
        };

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

If your table cell needs to access the actual PlayerManager object, then you need to make the table column a TableColumn<PlayerManager, PlayerManager> and update the cellValueFactory (which you haven't shown) accordingly.

Finally, note that your updateItem(...) method needs to deal with all cases, including empty cells for which the item is null.

So you may need something like

@FXML private TableColumn<PlayerManager, PlayerManager> tableColumnType;
@FXML private void initialize(){

    tableColumnType.setCellValueFactory(cellData -> new SimpleObjectProperty<PlayerManager>(cellData.getValue());

    tableColumnType.setCellFactory(param -> {
        //Set up the ImageView
        final ImageView imageview = new ImageView();
        imageview.setFitHeight(10);
        imageview.setFitWidth(10);
        ///imageview.setImage(imageComputer); //uncommenting this places the image on all cells, even empty ones
        //Set up the Table
        TableCell<PlayerManager, PlayerManager> cell = new TableCell<PlayerManager, PlayerManager>() {
            @Override
            public void updateItem(PlayerManager item, boolean empty) {
                if (item != null) {  // choice of image is based on values from item, but it doesn't matter now
                    imageview.setImage(imageComputer);
                } else {
                    imageView.setImage(null);
                }
            }
        };

        // Attach the imageview to the cell
        cell.setGraphic(imageview);
        return cell;
    });
}
James_D
  • 201,275
  • 16
  • 291
  • 322
1

The signature of the updateItem() method is wrong. Try to use:

@Override
protected void updateItem(Image item, boolean empty){
    //your code
}

Edit: I think you can solve your problem by also setting a CellValueFactory for your TableColumn:

tableColumnType.setCellValueFactory(
                new Callback<CellDataFeatures<PlayerManager, Image>, ObservableValue<Image>(){
                @Override
                public ObservableValue<Image> call(
                        CellDataFeatures<PlayerManager, Image> param) {
                    return param.getValue().exampleMethod; /* Method of your PlayerManager which returns an Image as ObservableValue. To do so you could wrap it in an `ObjectProperty<Image>`*/
                }

            }
    );
SilverMonkey
  • 1,003
  • 7
  • 16
  • It now gives an error saying the method does not override from its superclass. – shinzou Sep 10 '16 at 22:06
  • Could you try using Image instead of PlayerManager in the updateItem method? Does the error persist? – SilverMonkey Sep 10 '16 at 22:18
  • Now there's no error, and intelij ungrayed `updateItem`. But there's no image... Also, I'll need access to the current `PlayerManager` for choosing the right image, but now there's no access to it... – shinzou Sep 10 '16 at 22:25
  • The problem is, that you told your TableColumn, that your TableView contains PlayerManager and displays images. Does your PlayerManager "gives" you the images? – SilverMonkey Sep 10 '16 at 22:30