JavaFX滚动条值混淆

JavaFX滚动条值混淆,javafx,javafx-2,scrollbar,Javafx,Javafx 2,Scrollbar,我有一个带有画布和滚动条的简单JavaFX应用程序。 画布充当虚拟化画布,其内容可以通过滚动条滚动 画布的宽度为500像素,但画布的逻辑宽度为1000像素。 我已经将滚动条的最大值设置为1000,将滚动条的可见量设置为500。 问题是当滚动条一直向右滚动时 滚动条是1000,而不是500。 从逻辑上讲,当滚动条一直向右滚动时,应该有某种方法来确定实际的滚动偏移量,而这似乎是不可能的。 请建议如何获得所需的卷轴数量。多谢各位 下面是一直滚动到左侧的示例。 滚动条看起来不错。其可见宽度为窗口大小的5

我有一个带有画布和滚动条的简单JavaFX应用程序。 画布充当虚拟化画布,其内容可以通过滚动条滚动

画布的宽度为500像素,但画布的逻辑宽度为1000像素。 我已经将滚动条的最大值设置为1000,将滚动条的可见量设置为500。 问题是当滚动条一直向右滚动时 滚动条是1000,而不是500。 从逻辑上讲,当滚动条一直向右滚动时,应该有某种方法来确定实际的滚动偏移量,而这似乎是不可能的。 请建议如何获得所需的卷轴数量。多谢各位

下面是一直滚动到左侧的示例。 滚动条看起来不错。其可见宽度为窗口大小的50%

下面是向右滚动了一半的示例。 这里的问题很清楚。画布已向右滚动500像素,但如果画布正确滚动到一半,则只能滚动250像素

下面是一直向右滚动的示例。

导入javafx.application.application;
导入javafx.beans.value.*;
导入javafx.scene.scene;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.control.ScrollBar;
导入javafx.scene.layout.*;
导入javafx.scene.paint.Color;
导入javafx.scene.paint.CycleMethod;
导入javafx.scene.paint.LinearGradient;
导入javafx.scene.paint.Stop;
导入javafx.stage.stage;
公共类Sc扩展应用程序{
公共滚动条;
双卷轴;
帆布;
@凌驾
公众假期开始(阶段){
VBox VBox=新的VBox();
场景=新场景(vbox);
舞台场景;
画布=新画布(500100);
scrollBar=新的scrollBar();
滚动条设置最小值(0);
滚动条设置最大值(1000);
滚动条。设置可视性安装(500);
vbox.getChildren().addAll(画布、滚动条);
draw();
scrollBar.valueProperty().addListener(新的ChangeListener()){
公共空间发生了变化(observeValue可以这样想:

min
max
value
是滚动条的逻辑值。
value
的范围介于
min
max
之间,当且仅当滚动条一直向左滚动(或垂直滚动条的顶部)时,该值等于
min
。当且仅当滚动条尽可能向右(或向下)滚动时,它等于max

visibleAmount
属性实际上只是一个确定“拇指”大小的可视属性

thumbSize / trackSize = visibleAmount / (max - min)
visibleAmount
将影响实际像素和“逻辑单元”之间的关系;但是它不会改变
值可以在
[min,max]
的整个范围内变化的事实

因此,您需要对代码进行的唯一更改是将滚动条的最大值设置为可以滚动的最大值(而不是您正在绘制的图像的大小),即
1000-canvas.getWidth()

导入javafx.application.application;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.scene.scene;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.control.ScrollBar;
导入javafx.scene.layout.VBox;
导入javafx.scene.paint.Color;
导入javafx.scene.paint.CycleMethod;
导入javafx.scene.paint.LinearGradient;
导入javafx.scene.paint.Stop;
导入javafx.stage.stage;
公共类ScrollBarExample扩展了应用程序{
专用最终静态双总_宽度=1000;
@凌驾
公众假期开始(阶段){
VBox VBox=新的VBox();
场景=新场景(vbox,500130);
舞台场景;
画布=新画布(500100);
ScrollBar ScrollBar=新的ScrollBar();
滚动条设置最小值(0);
scrollBar.setMax(总宽度-canvas.getWidth());
scrollBar.setVisibleMount(scrollBar.getMax()*canvas.getWidth()/总宽度);
vbox.getChildren().addAll(画布、滚动条);
绘制(画布,滚动条.getValue());
scrollBar.valueProperty().addListener(新的ChangeListener()){
@凌驾

公共空间改变了(谢谢!这实际上是我在等待你的建议时开始做的。我只是觉得这个解决方案太粗糙了,一定有更好的方法哈哈哈!
thumbSize / trackSize = visibleAmount / (max - min)
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.stage.Stage;

public class ScrollBarExample extends Application {

    private final static double TOTAL_WIDTH = 1000 ;


    @Override
    public void start(Stage stage) {
        VBox vbox = new VBox();

        Scene scene = new Scene(vbox, 500, 130);
        stage.setScene(scene);

        Canvas canvas = new Canvas(500, 100);
        ScrollBar scrollBar = new ScrollBar();
        scrollBar.setMin(0);
        scrollBar.setMax(TOTAL_WIDTH - canvas.getWidth());

        scrollBar.setVisibleAmount(scrollBar.getMax() * canvas.getWidth() / TOTAL_WIDTH);

        vbox.getChildren().addAll(canvas, scrollBar);
        draw(canvas, scrollBar.getValue());

        scrollBar.valueProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov,
                Number old_val, Number new_val) {
                draw(canvas, scrollBar.getValue());
            }
        });


        stage.show();
    }

    private void draw(Canvas canvas, double scrollAmount)
    {
        GraphicsContext graphics = canvas.getGraphicsContext2D();
        graphics.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        Stop[] stops = new Stop[] { new Stop(0, Color.BLACK), new Stop(1, Color.RED)};
        LinearGradient lg = new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, stops);
        graphics.setFill(lg);
        graphics.fillRect(0-scrollAmount, 30, TOTAL_WIDTH, 40);
    }

    public static void main(String[] args) {
        launch(args);
    }
}