I'm using a TableView backed by an ObservableList of Renderer objects which is set up like this:
private ObservableList<Renderer> renderers = FXCollections.observableArrayList();
@FXML
private TableView<Renderer> renderersTable;
@FXML
private TableColumn<Renderer, String> nameColumn;
@FXML
private TableColumn<Renderer, Boolean> approvedColumn;
@FXML
private void initialize() {
    nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
    approvedColumn.setCellValueFactory(new PropertyValueFactory<>("approved"));
    renderersTable.setItems(renderers);
}
The Renderer objects are very simple and look like this:
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class Renderer extends Model {
    private String name;
    private boolean approved;
    // ...
}
I have a function that gets called from the UI, by pressing a button and contains something like:
@FXML
private void approveSelectedRenderers() {
    List<Renderer> selectedRenderers = new ArrayList<>();
    selectedRenderers.addAll(renderersTable.getSelectionModel().getSelectedItems());
    for (Renderer renderer : selectedRenderers) {
        renderer.setApproved(true);
        renderers.set(renderers.indexOf(renderer), renderer);
        Thread.sleep(3000); // Simulate slowly talking to the network.
    }
}
I was expecting to see the change to approved on each row once every 3 seconds, but instead, it does all the rows, and only after that it updates the UI. Why is that? How do I make the UI update?
 
    