1

我正在尝试提高不断更新的Application倍数的性能。Tableviews在每次更新中,只有 1 项ObservableList更改。重新加载这些行Tableviews并将 css 样式应用于这些行正在显着降低应用程序的速度。

我查看了Tableviews重新加载行的方式,并意识到所有行都在不断地从头开始重建,而与底层的更改类型无关ObservableList。更改视口内的 1 个项目/视口外的 1 个项目/完全替换 List 会导致行构造的确切数量。

有没有办法阻止 JavafxTableviews重新加载所有显示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;
    }
}
4

0 回答 0