Я пытаюсь улучшить производительность Application
с несколькими Tableviews
, которые постоянно обновляются. При каждом обновлении изменяется только 1 элемент внутри ObservableList
. Перезагрузка строк этих Tableviews
и применение к этим строкам CSS-стилей значительно замедляют работу приложения.
Я посмотрел на то, что Tableviews
перезагружает свои строки, и понял,что все строки постоянно восстанавливаются с нуля, независимо от типа изменения базового ObservableList
. Изменение 1 элемента в области просмотра / 1 элемента вне области просмотра / полная замена списка приводит к точному количеству конструкций строк.
Есть ли способ предотвратить перезагрузку Javafx Tableviews
всех отображаемых Rows
, когда изменяется только определенное значение Items
?
Другие возможные настройки для повышения производительности при постоянной перезагрузке Tableviews
будет принята с благодарностью.
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class FXApplication extends Application {
private BorderPane border;
private TableView<Item> tableView;
private Button addItemToTv = new Button("Add");
private Button replaceFirst = new Button("Replace first");
private Button replaceLast = new Button("Replace last");
private Button fullReplace = new Button("Full replace");
private int counter = 0;
protected Map<Integer, TableRow<Item>> rowsByIndex = new HashMap<>();
@Override
public void start(Stage primaryStage) {
constructTv();
setButtonActions();
Scene s = constructScene();
primaryStage.setScene(s);
primaryStage.show();
}
private Scene constructScene() {
border = new BorderPane();
border.setCenter(tableView);
border.setTop(new HBox(addItemToTv, replaceFirst, replaceLast, fullReplace));
ScrollPane scp = new ScrollPane();
scp.setFitToHeight(true);
scp.setFitToWidth(true);
scp.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scp.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scp.setContent(border);
return new Scene(scp);
}
private void setButtonActions() {
addItemToTv.setOnAction(e -> {
tableView.getItems().add(new Item("bla"));
Platform.runLater(this::resetCounter);
});
replaceFirst.setOnAction(e -> {
tableView.getItems().set(0, new Item("blub"));
Platform.runLater(this::resetCounter);
});
fullReplace.setOnAction(e -> {
ArrayList<Item> items = new ArrayList<>(tableView.getItems());
tableView.getItems().setAll(items);
Platform.runLater(this::resetCounter);
});
replaceLast.setOnAction(e -> {
tableView.getItems().set(tableView.getItems().size()-1, new Item("blub"));
Platform.runLater(this::resetCounter);
});
}
private void resetCounter() {
Timeline tl = new Timeline(new KeyFrame(Duration.millis(500), (ee) -> {
System.out.println(counter + " row calls");
counter = 0;
}));
tl.play();
}
private Node constructTv() {
tableView = new TableView<>();
for(int i = 0; i<10; i++){
TableColumn<Item, String> col = new TableColumn<>("col " + i);
col.setCellValueFactory(param -> {
return new SimpleStringProperty(param.getValue().getString());
});
tableView.getColumns().add(col);
}
for (int i = 0; i < 30 ; i++) {
tableView.getItems().add(new Item("bla"));
}
tableView.setRowFactory(param -> {
TableRow<Item> row = new TableRow<>();
row.itemProperty().addListener((observable, oldValue, newValue) -> {
Platform.runLater(() -> {
rowsByIndex.put(row.getIndex(), row);
System.err.println("row change " + row.getIndex());
counter++;
});
});
return row;
});
return tableView;
}
public static void main(String[] args) {
FXApplication.launch(args);
}
}
class Item {
private String string;
public Item(String s) {
string = s;
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
}