我想加快我的ScrollPane滚动速度。我需要这样的东西:
scrollPane.vvalueProperty().addListener((observable, oldValue, newValue) -> {
scrollPane.setVvalue(oldValue.doubleValue() + (newValue.doubleValue() - oldValue.doubleValue()) * 2);
});
但没有stackowerflow执行和工作..
可能有办法像活动那样消费吗?
P.S。顺便说一句,为什么setOnScroll()仅在滚动达到max(top)或min(bot)位置时触发?
答案 0 :(得分:2)
我真的不建议在属性已经改变时修改它,但如果你想这样做,你需要设置一个标志来抑制递归调用。这是一个例子:
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.TilePane;
import javafx.stage.Stage;
public class ModifyScrollSpeed extends Application {
@Override
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane(createContent());
DoublingListener.register(scrollPane.vvalueProperty());
Scene scene = new Scene(scrollPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private static class DoublingListener implements ChangeListener<Number> {
private boolean doubling ;
private Property<Number> target ;
private DoublingListener(Property<Number> target) {
this.target = target ;
}
public static void register(Property<Number> target) {
target.addListener(new DoublingListener(target));
}
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
if (! doubling) {
doubling = true ;
target.setValue(oldValue.doubleValue() + 2 * (newValue.doubleValue() - oldValue.doubleValue()));
}
doubling = false ;
}
}
private Node createContent() {
TilePane tilePane = new TilePane();
Random rng = new Random();
for (int i = 0; i < 200; i++) {
Region region = new Region();
region.setMinSize(40, 40);
region.setPrefSize(40, 40);
region.setMaxSize(40, 40);
region.setStyle(String.format("-fx-background-color: #%02x%02x%02x;",
rng.nextInt(256), rng.nextInt(256), rng.nextInt(256)));
tilePane.getChildren().add(region);
}
return tilePane ;
}
public static void main(String[] args) {
launch(args);
}
}
我实际上没有看到任何其他方法来更改滚动窗格的增量。请注意,ScrollBar
具有用于通过其unitIncrement
和blockIncrement
属性更改增量金额的API,但ScrollPane
没有等效属性。
source code for ScrollPane
中有评论
/*
* TODO The unit increment and block increment variables have been
* removed from the public API. These are intended to be mapped to
* the corresponding variables of the scrollbars. However, the problem
* is that they are specified in terms of the logical corrdinate space
* of the ScrollPane (that is, [hmin..hmax] by [vmin..vmax]. This is
* incorrect. Scrolling is a user action and should properly be based
* on how much of the content is visible, not on some abstract
* coordinate space. At some later date we may add a finer-grained
* API to allow applications to control this. Meanwhile, the skin should
* set unit and block increments for the scroll bars to do something
* reasonable based on the viewport size, e.g. the block increment
* should scroll 90% of the pixel size of the viewport, and the unit
* increment should scroll 10% of the pixel size of the viewport.
*/
滚动窗格的当前skin以此评论中描述的方式硬编码单位并阻止其滚动条(在updateHorizontalSB
和updateVerticalSB
方法中)的增量(即10%和90%的可见量),所以我认为没有真正的方法来实现这些目标。在Java 9中,skin类将成为一个公共类,因此至少可以将它子类化并修改此行为。
答案 1 :(得分:0)
您可以尝试这样的事情 -
private boolean scrolllChanging = false;
private void myScroll(ObservableDoubleValue observable, Double oldValue, Double newValue) {
if (!scrollChanging) {
try {
scrollChanging = true;
// Insert logic here. Any subsequent changes won't reach here until `scrollChanging` is set to false again.
} finally {
scrollChanging = false;
}
}
}
scrollPane.vvalueProperty().addListener(this::myScroll);
原谅任何次要类型的错误,我还没有编译过。