The code below should move the Label
based on the position of the horizontal scroll bar so that the Label
appears to remain stationary. This almost works perfectly however when you move the scrollbar to the end the label has moved slightly so it does not look like it is in the same position.
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();
}
}
}
You use the width of the ScrollPane
. However the width used in the calculations for ScrollPane
use the viewportBounds
.
Also since by default the position is rounded to full pixels, which causes some movement of the Label
(which could be fixed by using translateX
instead of the 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);