I try to high frequently update the cells in a JFX TableView (proof of concept application). I load a TableView via FXML and start an ExecutorService to change the value of a cell.
When I start the application I notice, that the update works for the first 3-4 million elements and then it stucks. If I slow down the updates (see MAGIC#1) it works (10ms is still too fast, but 100ms delay works). So I thought it might be a threading issue.
But then I found out that if I add an empty ChangeListener (see MAGIC#2) to the property it works fine. Even without the need of MAGIC#1.
Am I doing something wrong? Do I have to update the cells in a different way?
Thanks in advance for your help!!
The elements in the TableView:
public class Element {
public static final AtomicInteger x = new AtomicInteger(0);
private final StringProperty nameProperty = new SimpleStringProperty("INIT");
public Element() {
// MAGIC#2
// this.nameProperty.addListener((observable, oldValue, newValue) -> {});
}
public void tick() {
this.setName(String.valueOf(x.incrementAndGet()));
}
public String getName() ...
public void setName(String name)...
public StringProperty nameProperty() ...
}
The controller for FXML:
public class TablePerformanceController implements Initializable {
private final ObservableList<Element> data = FXCollections.observableArrayList();
public Runnable changeValues = () -> {
while (true) {
if (Thread.currentThread().isInterrupted()) break;
data.get(0).tick();
// MAGIC#1
// try { Thread.sleep(100); } catch (Exception e) {}
}
};
private ExecutorService executor = null;
@FXML
public TableView<Element> table;
@Override
public void initialize(URL location, ResourceBundle resources) {
this.table.setEditable(true);
TableColumn<Element, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(cell -> cell.getValue().nameProperty());
this.table.getColumns().addAll(nameCol);
this.data.add(new Element());
this.table.setItems(this.data);
this.executor = Executors.newSingleThreadExecutor();
this.executor.submit(this.changeValues);
}
}