[英]JavaFX How do I change the amount by which ScrollPane scrolls?
我需要知道如何更改ScrollPane
object 用于上下移动内容的数量。 例如,一个ScrollBar
有这两种方法:
scrollBar.setUnitIncrement(10);
scrollBar.setBlockIncrement(50);
如何使用ScrollPane
而不是ScrollBar
做同样的事情?
有同样的问题,无法找到答案。 最后从 Erik 提供的链接中得到了正确的方法,并根据我的需要进行了调整。
由于 scrollPane 本身没有触发“setOnScroll”-Event(可能是因为它在这样做之前被消耗了),我必须在 ScrollPane 的内容上设置 EventHandler:
scrollPane_Content.setContent(vBox_Content);
vBox_Content.setOnScroll(new EventHandler<ScrollEvent>() {
@Override
public void handle(ScrollEvent event) {
double deltaY = event.getDeltaY()*6; // *6 to make the scrolling a bit faster
double width = scrollPane_Content.getContent().getBoundsInLocal().getWidth();
double vvalue = scrollPane_Content.getVvalue();
scrollPane_Content.setVvalue(vvalue + -deltaY/width); // deltaY/width to make the scrolling equally fast regardless of the actual width of the component
}
});
这样做可以直接使用滚动条,也可以使用鼠标滚轮上下滚动。
希望这可以帮助其他正在寻找在 scrollPane 上加快滚动速度的人。
在 ScrollPane 中更快的垂直滚动:
final double SPEED = 0.01;
scrollPane.getContent().setOnScroll(scrollEvent -> {
double deltaY = scrollEvent.getDeltaY() * SPEED;
scrollPane.setVvalue(scrollPane.getVvalue() - deltaY);
});
在外部样式表中,您可以执行
.scroll-pane .scroll-bar:vertical {
-fx-unit-increment: 10 ;
-fx-block-increment: 50 ;
}
.scroll-pane .scroll-bar:horizontal {
-fx-unit-increment: 5 ;
-fx-block-increment: 20 ;
}
例如。 如果您希望它仅应用于单个滚动窗格,请为滚动窗格指定一个 id 等。
这通过查看内容和滚动窗格之间的高度差异来修复滚动,以便滚动的数量相同。
//Fix scroll pane slow scrolling
scrollPane.getContent().setOnScroll(scrollEvent -> {
double deltaY = scrollEvent.getDeltaY();
double contentHeight = scrollPane.getContent().getBoundsInLocal().getHeight();
double scrollPaneHeight = scrollPane.getHeight();
double diff = contentHeight - scrollPaneHeight;
if (diff < 1) diff = 1;
double vvalue = scrollPane.getVvalue();
scrollPane.setVvalue(vvalue + -deltaY/diff);
});
该差值设置为最小值 1 以防止被零除。
我想要的是简单的设置,它可以在任何地方工作。 由于没有给出好的答案,我自己做了一些研究。 也许该解决方案也会对您有所帮助。
由于我想要平滑滚动,我创建了过渡类:
import javafx.animation.Transition;
import javafx.util.Duration;
public abstract class SmoothishTransition extends Transition {
private final double mod;
private final double delta;
private final static int TRANSITION_DURATION = 200;
public SmoothishTransition(SmoothishTransition old, double delta) {
setCycleDuration(Duration.millis(TRANSITION_DURATION));
setCycleCount(0);
// if the last transition was moving inthe same direction, and is still playing
// then increment the modifer. This will boost the distance, thus looking faster
// and seemingly consecutive.
if (old != null && sameSign(delta, old.delta) && playing(old)) {
mod = old.getMod() + 1;
} else {
mod = 1;
}
this.delta = delta;
}
public double getMod() {
return mod;
}
@Override
public void play() {
super.play();
// Even with a linear interpolation, startup is visibly slower than the middle.
// So skip a small bit of the animation to keep up with the speed of prior
// animation. The value of 10 works and isn't noticeable unless you really pay
// close attention. This works best on linear but also is decent for others.
if (getMod() > 1) {
jumpTo(getCycleDuration().divide(10));
}
}
private static boolean playing(Transition t) {
return t.getStatus() == Status.RUNNING;
}
private static boolean sameSign(double d1, double d2) {
return (d1 > 0 && d2 > 0) || (d1 < 0 && d2 < 0);
}
}
然后这个类负责滚动:
import javafx.animation.Interpolator;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.ScrollEvent;
public class SmoothScroll {
private final static double BASE_MODIFIER = 1;
public SmoothScroll(final ScrollPane scrollPane, final Node node) {
this(scrollPane, node, 160);
}
public SmoothScroll(final ScrollPane scrollPane, final Node node, final double baseChange) {
node.setOnScroll(new EventHandler<ScrollEvent>() {
private SmoothishTransition transition;
@Override
public void handle(ScrollEvent event) {
if (scrollPane==null) {
return;
}
double deltaYOrg = event.getDeltaY();
if (deltaYOrg==0) {
return;
}
double percents = calculatePercents(deltaYOrg>=0);
final double startingVValue = scrollPane.getVvalue();
smoothTransition(
startingVValue,
getFinalVValue(startingVValue, percents),
BASE_MODIFIER * deltaYOrg
);
}
private void smoothTransition(double startingVValue, double finalVValue, double deltaY) {
Interpolator interp = Interpolator.LINEAR;
transition = new SmoothishTransition(transition, deltaY) {
@Override
protected void interpolate(double frac) {
scrollPane.setVvalue(
interp.interpolate(startingVValue, finalVValue, frac)
);
}
};
transition.play();
}
private double getFinalVValue(double startingVValue, double percents) {
double finalVValueToSet = startingVValue + percents;
if (finalVValueToSet>1) {
return 1d;
}
if (finalVValueToSet<0) {
return 0d;
}
return finalVValueToSet;
}
private double calculatePercents(boolean positive) {
double fullHeight = scrollPane.getContent().getBoundsInLocal().getHeight();
double viewableHeight = scrollPane.getBoundsInLocal().getHeight();
double fullChangeInHeight = fullHeight-viewableHeight;
double percents = baseChange /fullChangeInHeight;
if (positive) {
percents = percents*-1;
}
return percents;
}
});
}
}
以及用法:
new SmoothScroll(mainScroll, mainVbox);
或者
new SmoothScroll(mainScroll, mainVbox, 50);
此代码应该可以帮助您入门。
此处发布的所有解决方案都不适合我。 我正在使用 Java 11.0.2,这可能是问题所在。 我修复它的方法是使用以下代码:
final double boost = 0.025;
scrollPane.vvalueProperty().addListener(
(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
//System.out.println("from "+oldValue+" to "+newValue);
double diff = (double) newValue - (double) oldValue;
if (almostEqual(diff, boost, 0.00001) || almostEqual(diff, (0 - boost), 0.00001) || almostEqual(diff, 0, 0.000001)) {
return;
}
double newww = scrollPane.getVvalue() + (diff > 0 ? boost : (0 - boost));
//System.out.println("\tnewww val - "+newww+"; diff - "+diff);
if (0 < newww && newww < 1) {
//System.out.println("\tsetting value");
scrollPane.setVvalue(newww);
}
});
使用附加方法比较双打:
public static boolean almostEqual(double a, double b, double eps) {
return Math.abs(a - b) < eps;
}
你可以使用这个:
scrollPane.getVerticalScrollBar().setUnitIncrement(20);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.