This discussion is archived
5 Replies Latest reply: Jan 5, 2013 5:31 PM by 983110 RSS

[TableView] how to force table row/cell refresh ?

bouye Journeyer
Currently Being Moderated
Hi,
I have a TableView that contains plain Java objects (no FX properties) on each rows, with custom cellValueFactory and cellFactory that extract and display the proper value in each cell.
Everything displays ok but, of course (as there are no FX properties), if I modify the content of the object, the table row or cell is not refreshed with the new value.

My original code was something similar to:
public class Foo {
  Whatever value;
}


[...]
TableColumn<Foo, Whatever> column = new TableColumn<>("Whatever");
column.setCellValueFactory(new Callback<CellDataFeatures<Foo, Whatever>, ObservableValue<Whatever>>() {
  @Override
  public ObservableValue<Whatever> call(CellDataFeatures<Foo, Whatever> cellDataFeature) {
    Foo foo = cellDataFeature.getValue();
    return new ReadOnlyObjectWrapper<>(foo.value);
 }
});
column.setCellFactory(new Callback<TableColumn<Foo, Whatever>, TableCell<Foo, Whatever>>() {
  @Override
  public TableCell<Foo, Whatever> call(TableColumn<Foo, Whatever> column) {
    return new FooTableCell<>();
  }
});
TableView<foo> tableView = new TableView<>();
tableView.getColumns().add(column);
As said, if the content of a Foo instance that is in the TableView is modified, the row or cell is not updated.
I then created an adapter object that maps members of my class to FX properties. Something similar to:
public class FooAdapter {

  private Foo foo;

  public FooAdapter(Foo delegated) {
    this.foo = delegated;
    setValue(foo.value);
    valueProperty().addListener(new ChangeListener<Whatever>() {
      @Override
      public void changed(ObservableValue<? extends Whatever> observableValue, Whatever oldValue, Whatever newValue) {
        foo.value = newValue;
      }
    });
  }

  private final ObjectProperty<Whatever> value = new SimpleObjectProperty<>(this, "value", null);

  public final Whatever getValue() {
    return value.get();
  }

  public final void setValue(Whatever val) {
    value.set(val);
  }

  public final ObjectProperty<Whatever> valueProperty() {
    return value;
  }
}


[...]
TableColumn<FooAdapter, Whatever> column = new TableColumn<>("Whatever");
column.setCellValueFactory(new PropertyValueFactory("value"));
column.setCellFactory(new Callback<TableColumn<FooAdapter, Whatever>, TableCell<FooAdapter, Whatever>>() {
  @Override
  public TableCell<FooAdapter, Whatever> call(TableColumn<FooAdapter, Whatever> column) {
    return new FooAdapterTableCell<>();
  }
});
TableView<FooAdapter> tableView = new TableView<>();
tableView.getColumns().add(column);
And it works good: if I modified the property of a FooAdapter, the Foo instance within is modified and the row in the table properly display the new value.
The problem is that I had to change the TableCell's code, most of the logic behind the table and the editor that allow to change the Foo properties as well as to code a new adapter class (which is small here because there is only 1 single property, but which is much longer in the real code).

So is there anyway to ask the TableView to force refresh one (or more) of its rows, to avoid doing all of this.

Edited by: bouye on Mar 16, 2012 5:41 AM - corrected last sentence

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points