标签缓慢向后移动

Label moves backwards slowly

下面的代码应根据水平滚动条的位置移动 Label,以便 Label 看起来保持静止。这几乎可以完美地工作,但是当您将滚动条移动到末尾时,标签会稍微移动,因此它看起来不像在同一位置。

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class LblMoves extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        try {
            VBox images = new VBox();
            images.setPadding(new Insets(0, 0, 0, 0));
            Label posLbl = new Label("0");

            images.getChildren().add(posLbl);

            images.setPrefSize(Integer.MAX_VALUE, 50);
            ScrollPane scrollPane = new ScrollPane(images);
            scrollPane.setStyle("-fx-background: #FFFFFF;");

            scrollPane.hvalueProperty().addListener(new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) {
                    double screenPer = scrollPane.getHvalue() * scrollPane.getWidth();
                    double pos = scrollPane.getHvalue() * images.getWidth();
                    double marg = pos - screenPer;
                    posLbl.setPadding(new Insets(0, 0, 0, marg));
                }
            });

            Scene scene = new Scene(scrollPane, 600, 600);
            primaryStage.setScene(scene);
            primaryStage.setMaximized(true);

            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

你用的是ScrollPane的宽度。但是 ScrollPane 计算中使用的宽度使用 viewportBounds.
此外,由于默认情况下位置四舍五入为完整像素,这会导致 Label 发生一些移动(可以通过使用 translateX 而不是 padding 来修复)。

InvalidationListener listener = o -> {
    double marg = (images.getWidth() - scrollPane.getViewportBounds().getWidth()) * scrollPane.getHvalue();
    posLbl.setTranslateX(marg);
    // posLbl.setPadding(new Insets(0, 0, 0, marg));
};

scrollPane.hvalueProperty().addListener(listener);
scrollPane.viewportBoundsProperty().addListener(listener);
listener.invalidated(null);