Scroll 如何在属性侦听器中设置另一个值?

Scroll 如何在属性侦听器中设置另一个值?,scroll,javafx,listener,Scroll,Javafx,Listener,我想加快滚动窗格的速度。我需要像这样的东西: scrollPane.vvalueProperty().addListener((observable, oldValue, newValue) -> { scrollPane.setVvalue(oldValue.doubleValue() + (newValue.doubleValue() - oldValue.doubleValue()) * 2); }); 但是没有stackowerflow执行

我想加快滚动窗格的速度。我需要像这样的东西:

scrollPane.vvalueProperty().addListener((observable, oldValue, newValue) -> {
            scrollPane.setVvalue(oldValue.doubleValue() + (newValue.doubleValue() - oldValue.doubleValue()) * 2);
        });
但是没有stackowerflow执行和工作

有没有一种方法可以像一个事件一样使用它


顺便说一句,为什么只有当滚动达到最大(顶部)或最小(底部)位置时,setOnScroll()才会启动?

您可以尝试以下方法-

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);

请原谅任何小的类型错误,我还没有编译它。

您可以尝试这样的方法-

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);

请原谅任何小的类型错误,我还没有编译它。

我并不建议在属性已经更改时修改它,但是如果您想这样做,您需要设置一个标志来禁止递归调用。下面是一个例子:

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);
    }
}

滚动窗格的当前值按此注释中描述的方式(即可见量的10%和90%)硬编码滚动条的单位和块增量(在
updateHorizontalSB
updateVerticalSB
方法中),因此我看不到真正的方法来实现这些。在Java 9中,skin类将成为一个公共类,因此您至少可以对其进行子类化并修改此行为。

我并不建议在属性已经发生更改时修改属性,但如果您想这样做,则需要设置一个标志以禁止递归调用。下面是一个例子:

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);
    }
}

滚动窗格的当前值按此注释中描述的方式(即可见量的10%和90%)硬编码滚动条的单位和块增量(在
updateHorizontalSB
updateVerticalSB
方法中),因此我看不到真正的方法来实现这些。在Java 9中,skin类将成为一个公共类,因此您至少可以将其子类化并修改此行为。

那么在Java 9中,我将能够简单地提高鼠标滚轮滚动速度?如果是这样的话,我同意,“简单”?不可以。在Java 9中,您可以创建一个子类
ScrollPaneSkin
,实现缺少的功能,并将其安装到
ScrollPane
中。在未来的版本中,他们可能会提供这种功能,但据我所知,Java 9并没有计划提供这种功能。现在我开始怀念用JS编写的时候。。谢谢@James_Dso在java9中我能简单地提高鼠标滚轮的滚动速度吗?如果是这样的话,我同意,“简单”?不可以。在Java 9中,您可以创建一个子类
ScrollPaneSkin
,实现缺少的功能,并将其安装到
ScrollPane
中。在未来的版本中,他们可能会提供这种功能,但据我所知,Java 9并没有计划提供这种功能。现在我开始怀念用JS编写的时候。。谢谢你@James\u D