我想在TableView中得到滚动事件的通知。
我目前有这个:
scrollBar = (ScrollBar) tableView.lookup(".scroll-bar:vertical");
scrollBar.valueProperty().addListener((observable, oldValue, newValue) -> {
System.err.println(newValue);
if ((newValue != null) && ((Double) newValue == 0.0)) {
addMoreDataTop(4);
}
if ((newValue != null) && ((Double) newValue == 1.0)) {
addMoreDataBottom(4);
}
});
只要新值在0到1.0之间(只要值不断变化),此方法就很好。
但是我对列表的“边缘”上的scrollEvents 特别感兴趣,这意味着当滚动值已经为0或1.0时。
valueProperty不再更改,因此不会通知侦听器。但是滚动(意图)仍然在发生。我可以收到有关此类滚动事件的通知,但这些事件不会更改列表/表的滚动吗?
答案 0 :(得分:2)
根据Slaw的评论,我想到了这一点:
tableView.setOnScroll(e -> {
if (e.getDeltaY() > 0) {
fillAtTop();
} else if (e.getDeltaY() < 0) {
fillAtBottom();
}
});
这正如预期的那样工作,因为tableView的滚动条将使用更改表的“滚动状态”的滚动事件。
只有当scrollBar不再更改时,才会调用已注册的侦听器。
当用户滚动到表的开头或结尾时,我用它来延迟加载表内容。
以下是提取的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());
}
}