gpt4 book ai didi

用于 ListView 的 JavaFX 平滑滚动

转载 作者:搜寻专家 更新时间:2023-11-01 03:34:35 25 4
gpt4 key购买 nike

我想知道是否有一种方法可以调整 JavaFX 的 ListView 的滚动。

你可能会说它很慢,因为我的集合太大和/或我的 CellFactory 太重了……只是帧率似乎太低了,即使是一个小的字符串集合。 .

所以我想知道是否有某处的设置或指南可以实现平滑滚动。

提前致谢

最佳答案

这是 JFoenix's smooth scrolling created for ScrollPanes ,但为 ListViews 稍作修改(也适用于 JFoenix 的 JFXListView)

public class JFXSmoothScroll  {



private static ScrollBar getScrollbarComponent(ListView<?> control, Orientation orientation) {
Node n = control.lookup(".scroll-bar");
if (n instanceof ScrollBar) {
final ScrollBar bar = (ScrollBar) n;
if (bar.getOrientation().equals(orientation)) {
return bar;
}
}

return null;
}

public static void smoothScrollingListView(ListView<?> listView, double speed) {
smoothScrollingListView(listView, speed, Orientation.VERTICAL, bounds -> bounds.getHeight());
}

public static void smoothHScrollingListView(ListView<?> listView, double speed) {
smoothScrollingListView(listView, speed, Orientation.HORIZONTAL, bounds -> bounds.getHeight());
}

private static void smoothScrollingListView(ListView<?> listView, double speed, Orientation orientation, Function<Bounds, Double> sizeFunc) {
ScrollBar scrollBar = getScrollbarComponent(listView, orientation);
if (scrollBar == null) {
return;
}
scrollBar.setUnitIncrement(5);
final double[] frictions = {0.99, 0.1, 0.05, 0.04, 0.03, 0.02, 0.01, 0.04, 0.01, 0.008, 0.008, 0.008, 0.008, 0.0006, 0.0005, 0.00003, 0.00001};
final double[] pushes = {speed};
final double[] derivatives = new double[frictions.length];
final double[] lastVPos = {0};
Timeline timeline = new Timeline();
final EventHandler<MouseEvent> dragHandler = event -> timeline.stop();
final EventHandler<ScrollEvent> scrollHandler = event -> {
scrollBar.valueProperty().set(lastVPos[0]);
if (event.getEventType() == ScrollEvent.SCROLL) {
double direction = event.getDeltaY() > 0 ? -1 : 1;
for (int i = 0; i < pushes.length; i++) {
derivatives[i] += direction * pushes[i];
}
if (timeline.getStatus() == Animation.Status.STOPPED) {
timeline.play();
}

}
event.consume();
};
if (scrollBar.getParent() != null) {
scrollBar.getParent().addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
scrollBar.getParent().addEventHandler(ScrollEvent.ANY, scrollHandler);
}
scrollBar.parentProperty().addListener((o,oldVal, newVal)->{
if (oldVal != null) {
oldVal.removeEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
oldVal.removeEventHandler(ScrollEvent.ANY, scrollHandler);
}
if (newVal != null) {
newVal.addEventHandler(MouseEvent.DRAG_DETECTED, dragHandler);
newVal.addEventHandler(ScrollEvent.ANY, scrollHandler);
}
});

timeline.getKeyFrames().add(new KeyFrame(Duration.millis(3), (event) -> {
for (int i = 0; i < derivatives.length; i++) {
derivatives[i] *= frictions[i];
}
for (int i = 1; i < derivatives.length; i++) {
derivatives[i] += derivatives[i - 1];
}
double dy = derivatives[derivatives.length - 1];
double size = sizeFunc.apply(scrollBar.getLayoutBounds());
scrollBar.valueProperty().set(Math.min(Math.max(scrollBar.getValue() + dy / size, 0), 1));
lastVPos[0] = scrollBar.getValue();
if (Math.abs(dy) < 1) {
if (Math.abs(dy) < 0.001) {
timeline.stop();
}
}
}));
timeline.setCycleCount(Animation.INDEFINITE);
}

}

这有点hacky

final double[] lastVPos = {0};

因为出于某种原因我无法在触发 ScrollEvent 之前找到触发器并在此之前设置初始滚动值。方法需要在第一次初始化列表后调用,否则找不到滚动条

关于用于 ListView 的 JavaFX 平滑滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35065310/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com