Q:

Bind TableView row background color to Boolean Property

I have a boolean property to indicate whether there a corresponding file for the object:
public Track {
    BooleanProperty fileIsMissing = new SimpleBooleanProperty ( false );
    ...
    public BooleanProperty fileIsMissingProperty () {
        return fileIsMissing;
    }

    public boolean isMissingFile() {
        return fileIsMissing.getValue();
    }
    ...
}

The value of this is updated by another thread if the file is removed or added.
I have a TableView that displays Tracks in rows.  
I would like to have the color of the background of the row change when the BooleanProperty changes -- if it's true, I would like for the background to be red, if it is false I'd like for it to be normal colored.
I have the following, which almost works:
trackTable.setRowFactory( tv -> {
    TableRow <CurrentListTrack> row = new TableRow <>();

    row.itemProperty().addListener( (obs, oldValue, newValue ) -> {
        if ( newValue.isMissingFile() ) {
            row.getStyleClass().add( "file-missing" );
        } else {
            row.getStyleClass().removeAll( Collections.singleton("file-missing") );
        }
    });

    ...
}

And in CSS:
.file-missing {
    -fx-control-inner-background: palevioletred;
}

This sets the background properly when the track is first added to the table, but it doesn't update as the value of fileIsMissing changes, which makes sense, since I am not binding to the property at all.
How can I accomplish this? 

A:

Probably you need to listen your fileIsMissing property too.
The current your listener will react on added new Track record, the nested listener will react on Track changes.
May be something like this:
row.itemProperty().addListener((obs, oldValue, newTrackValue) -> {
    if (newTrackValue != null) {
        newTrackValue.fileIsMissingProperty().addListener((o, old, newValue) -> {
        if (newValue) {
            row.getStyleClass().add("file-missing");
        } else {
            row.getStyleClass().remove("file-missing");
        }
    }
});

BTW, to remove one list element you may use list.remove(Object) rather removeAll by a list.

