Я стараюсь часто обновлять ячейки в JFX TableView (доказательство концептуального приложения). Я загружаю TableView через FXML и запускаю ExecutorService для изменения значения ячейки.JavaFX TableView с частыми обновлениями
Когда я запускаю приложение, я замечаю, что обновление работает для первых 3-4 миллионов элементов, а затем оно запускается. Если я замедляю обновления (см. MAGIC# 1), он работает (10 мс все еще слишком быстро, но работает задержка 100 мс). Поэтому я подумал, что это может быть проблема с потоками.
Но потом я узнал, что если я добавлю пустой ChangeListener (см. MAGIC# 2) в свойство, он отлично работает. Даже без необходимости MAGIC# 1.
Я что-то не так? Нужно ли мне обновлять ячейки по-другому?
Заранее благодарим за помощь!
Элементы в 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() ...
}
Контроллер для 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);
}
}
Большое спасибо. Это решает мою проблему :-) –