На основании комментария Слава я придумал следующее:
tableView.setOnScroll(e -> {
if (e.getDeltaY() > 0) {
fillAtTop();
} else if (e.getDeltaY() < 0) {
fillAtBottom();
}
});
Это работает так, как задумано, поскольку полоса прокрутки tableView будет использовать события прокрутки, которые изменяют состояние прокрутки таблицы.
Зарегистрированный слушатель будет вызываться только тогда, когда полоса прокрутки не изменится (больше).
Я использую это для ленивой загрузки содержимого таблицы, когда пользователь прокручивает до начала или конца таблицы.
Вот извлеченный MWE:
public class MainApp extends Application {
final AtomicInteger cnt = new AtomicInteger(0);
final ObservableList<String> content = FXCollections.observableArrayList();
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
preFillContent();
final TableView<String> tableView = new TableView<>();
final TableColumn<String, String> c1 = new TableColumn<>("C1");
c1.setCellValueFactory(e -> new ReadOnlyObjectWrapper<>(e.getValue().toString()));
tableView.getColumns().add(c1);
tableView.setItems(content);
tableView.setOnScroll(e -> {
if (e.getDeltaY() > 0) {
fillAtTop();
} else if (e.getDeltaY() < 0) {
fillAtBottom();
}
});
final StackPane root = new StackPane();
root.getChildren().add(tableView);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
private void preFillContent() {
for (int i = 0; i < 10; i++) {
content.add("element " + cnt.incrementAndGet());
}
}
private void fillAtBottom() {
content.add("element " + cnt.incrementAndGet());
}
private void fillAtTop() {
content.add(0, "element " + cnt.incrementAndGet());
}
}