我可以听滚动事件:
tableView.addEventFilter(javafx.scene.input.ScrollEvent.SCROLL,
new EventHandler<javafx.scene.input.ScrollEvent>() {
@Override
public void handle(final javafx.scene.input.ScrollEvent scrollEvent) {
System.out.println("Scrolled.");
}
});
但是如果到达表格的底部/顶部,如何通知我?
答案 0 :(得分:2)
如果您使用的是Java 10+,则可以继承TableViewSkin
的子类并访问VirtualFlow
。后者具有position
属性,您可以使用该属性来确定是否达到顶部或底部。
以下是使用自定义事件的示例:
MyEvent.java
import javafx.event.Event;
import javafx.event.EventType;
public class MyEvent extends Event {
public static final EventType<MyEvent> ANY = new EventType<>(Event.ANY, "MY_EVENT");
public static final EventType<MyEvent> TOP_REACHED = new EventType<>(ANY, "TOP_REACHED");
public static final EventType<MyEvent> BOTTOM_REACHED = new EventType<>(ANY, "BOTTOM_REACHED");
public MyEvent(EventType<? extends MyEvent> eventType) {
super(eventType);
}
}
MyTableViewSkin.java
import javafx.scene.control.TableView;
import javafx.scene.control.skin.TableViewSkin;
public class MyTableViewSkin<T> extends TableViewSkin<T> {
public MyTableViewSkin(TableView<T> control) {
super(control);
getVirtualFlow().positionProperty().addListener((obs, oldVal, newVal) -> {
if (newVal.doubleValue() == 0.0) {
control.fireEvent(new MyEvent(MyEvent.TOP_REACHED));
} else if (newVal.doubleValue() == 1.0) {
control.fireEvent(new MyEvent(MyEvent.BOTTOM_REACHED));
}
});
}
}
App.java
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
var table = new TableView<Integer>();
for (int i = 0; i < 250; i++) {
table.getItems().add(i);
}
var column = new TableColumn<Integer, Number>("Value");
column.setCellValueFactory(features -> new SimpleIntegerProperty(features.getValue()));
table.getColumns().add(column);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setSkin(new MyTableViewSkin<>(table));
table.addEventHandler(MyEvent.ANY, event -> System.out.printf("%s%n", event.getEventType()));
primaryStage.setScene(new Scene(table, 500, 300));
primaryStage.setTitle("Example");
primaryStage.show();
}
}
在此示例中,我手动调用table.setSkin
。另一个选择是子类TableView
并覆盖createDefaultSkin
,这将返回您要使用的皮肤。
答案 1 :(得分:2)
一种简单的方法是使用ScrollBar
来检索lookup
:
ScrollBar tvScrollBar = (ScrollBar) tableView.lookup(".scroll-bar:vertical");
然后,您可以添加一个侦听器以检查其是否到达底部(valueProperty
的{{1}}用滚动百分比表示,因此ScrollBar
是顶部,{ {1}}是底部):
0.0
下面是一个简单的MCVE,演示了如何将它们组合在一起:
1.0
答案 2 :(得分:-1)
tableView.addEventFilter(javafx.scene.input.ScrollEvent.SCROLL,
new EventHandler<javafx.scene.input.ScrollEvent>() {
@Override
public void handle(final javafx.scene.input.ScrollEvent scrollEvent) {
Object virtualFlow = ((javafx.scene.control.SkinBase<?>) tableView.getSkin()).getChildren().get(1);
double position = -1;
try {
position = (double) virtualFlow.getClass().getMethod("getPosition").invoke(virtualFlow);
} catch (Exception ignored) { }
if(position == 0.0) {
System.out.println("scrolled to top!");
}
else if(position == 1.0) {
System.out.println("scrolled to bottom!");
}
}
});