import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.stream.Stream;

public class FilterTableViewTest extends Application {
    private static final int NUMBER_OF_COLUMNS = 5;
    private static final int NUMBER_OF_ITEMS = 100000;

    private final ObservableList<Integer> itemList = FXCollections.observableArrayList();
    private final FilteredList<Integer> filteredList = new FilteredList<>(itemList);

    @Override
    public void start(Stage primaryStage) {
        itemList.addAll(Stream.iterate(itemList.size(), i -> i + 1).limit(NUMBER_OF_ITEMS).toList());

        TableView<Integer> tableView = new TableView<>();
        tableView.getColumns().addAll(Stream.generate(this::createColumn).limit(NUMBER_OF_COLUMNS).toList());
        tableView.setItems(filteredList);

        // scroll away from the top of the table and click filter button or add button
        final Button filterButton = new Button("Filter Odd Items");
        filterButton.setOnAction(e -> filteredList.setPredicate(i -> i % 2 == 0));

        final Scene scene = new Scene(new VBox(filterButton, tableView), 600, 400);
        VBox.setVgrow(tableView, Priority.ALWAYS);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TableColumn<Integer, ?> createColumn() {
        final TableColumn<Integer, String> column = new TableColumn<>();
        column.setCellValueFactory(p -> new SimpleStringProperty(String.valueOf(p.getValue())));
        return column;
    }
}
