gpt4 book ai didi

JavaFX ScrollBar 值混淆

转载 作者:行者123 更新时间:2023-12-02 09:38:10 25 4
gpt4 key购买 nike

我有一个带有 Canvas 和 ScrollBar 的简单 JavaFX 应用程序。Canvas 充当虚拟 Canvas ,其内容可以使用 ScrollBar 滚动。

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

这是一直向左滚动的示例。滚动条看起来不错。它的可见宽度是窗口大小的 50%。

enter image description here

这是向右滚动一半的示例。到这里问题就清楚了。 Canvas 已向右滚动 500 像素,但如果 Canvas 正确滚动一半,则只会滚动 250 像素。

enter image description here

这是一直向右滚动的示例。 enter image description here

import javafx.application.Application;
import javafx.beans.value.*;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.*;
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 Sc extends Application {

public ScrollBar scrollBar;
double scrolled;
Canvas canvas;

@Override
public void start(Stage stage) {
VBox vbox = new VBox();
Scene scene = new Scene(vbox);
stage.setScene(scene);

canvas = new Canvas(500, 100);
scrollBar = new ScrollBar();
scrollBar.setMin(0);
scrollBar.setMax(1000);
scrollBar.setVisibleAmount(500);
vbox.getChildren().addAll(canvas, scrollBar);
draw();

scrollBar.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
scrolled = new_val.doubleValue();
draw();
}
});

stage.show();
}

private void draw()
{
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-scrolled, 30, 1000, 40);
}

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

最佳答案

这样想:

minmaxvalue 是滚动条的逻辑值。 value 的范围在 minmax 之间,并且当且仅当滚动条滚动到所有位置时才等于 min向左(或顶部,对于垂直滚动条)。当且仅当滚动条尽可能向右(或底部)滚动时,它才等于 max。

visibleAmount 属性实际上只是一个决定“拇指”大小的视觉属性。关系类似于

thumbSize / trackSize = visibleAmount / (max - min)

visibleAmount会影响实际像素和“逻辑单位”之间的关系;但是,它不会改变 value 可以在 [min, max] 的整个范围内变化的事实。

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

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

关于JavaFX ScrollBar 值混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26268154/

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