Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8187665

TableView/Row/Cell: must update cells on receiving an update event from the items




      The example below has a custom TableCell that wants to style itself based on data in another column (the "real" use-case is at SO https://stackoverflow.com/q/46290417/203657). It does so in its updateItem. Which must be called whenever the underlying item changed in any way - but isn't if the change is an update.

      To reproduce, run and click the checkbox in the second column
      - expected: background of first column in same row is changed
      - actual: nothing happens

      Not certain if this is a regression somehow (even if technically it can't ;) maybe introduced when virtualizing the row - because I seem to (very) vaguely remember that in earlier versions there was no problem ... mere speculation;) And didn't try yet to nail the exact location.

      The example:

      import java.util.logging.Logger;

      import de.swingempire.fx.util.FXUtils;
      import javafx.application.Application;
      import javafx.beans.Observable;
      import javafx.collections.FXCollections;
      import javafx.collections.ListChangeListener;
      import javafx.collections.ObservableList;
      import javafx.scene.Scene;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableRow;
      import javafx.scene.control.TableView;
      import javafx.scene.control.cell.CheckBoxTableCell;
      import javafx.scene.control.cell.PropertyValueFactory;
      import javafx.scene.control.cell.TextFieldTableCell;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;
      import javafx.util.converter.DefaultStringConverter;

       * CheckBoxTableCell: update editable state of one column based of
       * the boolean in another column
       * https://stackoverflow.com/q/46290417/203657
       * Bug in skins: cell not updated on listChange.wasUpdated
      @SuppressWarnings({ "rawtypes", "unchecked" })
      public class TableViewUpdateBug extends Application {

           * TableCell that updates state based on another value in the row.
          public static class DisableTextFieldTableCel extends TextFieldTableCell {
              public DisableTextFieldTableCel() {
                  super(new DefaultStringConverter());

               * Just to see whether or not this is called on update notification
               * from the items (it's not)
              public void updateIndex(int index) {
      // LOG.info("called? " + index);
               * Implemented to change background based on
               * visible property of row item.
              public void updateItem(Object item, boolean empty) {
                  super.updateItem(item, empty);
                  TableRow<TableColumn> currentRow = getTableRow();
                  boolean editable = false;
                  if (!empty && currentRow != null) {
                      TableColumn column = currentRow.getItem();
                      if (column != null) {
                          editable = column.isVisible();
                  if (!empty) {
                      if (editable) {
                          this.setStyle("-fx-background-color: red");
                      } else {
                          this.setStyle("-fx-background-color: green");
                  } else {
                      setStyle("-fx-background-color: null");
          public void start(Stage primaryStage) {
              // data: list of tableColumns with extractor on visible property
              ObservableList<TableColumn> data = FXCollections.observableArrayList(
                      c -> new Observable[] {c.visibleProperty()});
              data.addAll(new TableColumn("first"), new TableColumn("second"));
              TableView<TableColumn> table = new TableView<>(data);
              // verify that we get an update
              data.addListener((ListChangeListener) c -> {
                  while(c.next()) {
                      if (c.wasUpdated()) {
                          LOG.info("was update on " + (((TableColumn) c.getList().get(c.getFrom())).getText()));
              TableColumn<TableColumn, String> text = new TableColumn<>("Text");
              text.setCellFactory(c -> new DisableTextFieldTableCel()); //TextFieldTableCell.forTableColumn());
              text.setCellValueFactory(new PropertyValueFactory<>("text"));

              TableColumn<TableColumn, Boolean> visible = new TableColumn<>("Visible");
              visible.setCellValueFactory(new PropertyValueFactory<>("visible"));
              table.getColumns().addAll(text, visible);
              BorderPane root = new BorderPane(table);
              Scene scene = new Scene(root, 300, 150);


          public static void main(String[] args) {
          private static final Logger LOG = Logger




            aghaisas Ajit Ghaisas
            fastegal Jeanette Winzenburg
            0 Vote for this issue
            2 Start watching this issue