1

I have a Scrollpane with large-enough content to active the vertical scroll bar. fx:id of the Scrollpane is myScrollPane. I also have a button called Scroll To The Bottom. I have set the Action Event of the Scroll To The Bottom button as below in the fxml controller.

@FXML
private voide myButtonOnAction(ActionEvent evt) {
    myScrollPane.setVvalue(1.0);
}

This,however, scrolls to the bottom very fast.It can't be told whether it was scrolled either. I want to know a way to make Scrollpane scrolls SLOWLY.

dumbPotato21
  • 5,669
  • 5
  • 21
  • 34
Lakshitha Kanchana
  • 844
  • 2
  • 12
  • 32

3 Answers3

10

Do not use a Timer for this, unless you are prepared to wrap each update to the scrollbar value in a call to Platform.runLater.

The correct approach is to use a Timeline animation:

static void slowScrollToBottom(ScrollPane scrollPane) {
    Animation animation = new Timeline(
        new KeyFrame(Duration.seconds(2),
            new KeyValue(scrollPane.vvalueProperty(), 1)));
    animation.play();
}
VGR
  • 40,506
  • 4
  • 48
  • 63
  • 1
    What is "new KeyValue()" – Lakshitha Kanchana Jan 18 '17 at 17:15
  • 1
    A key value is the actual change that should take place in an Animation. As you can see, it changes the scrollPane’s `vvalue` to 1. Each KeyValue is associated with a particular KeyFrame, which as you can see in the code, will make the KeyValue take effect after 2 seconds. – VGR Jan 18 '17 at 17:17
  • amazing it's working! Can you tell me a place to learn javaFX animation Please?? – Lakshitha Kanchana Jan 18 '17 at 17:28
  • 1
    I would definitely start with the link to the Timeline class documentation that is in my answer; it explains the concept pretty well. The documentation of each class in [the javafx.animation package](http://docs.oracle.com/javase/8/javafx/api/javafx/animation/package-summary.html) explains its class pretty well, in fact. You can also try [the official tutorial](http://docs.oracle.com/javafx/2/get_started/animation.htm). – VGR Jan 18 '17 at 17:29
2

To be quick I will use a Timer and gradually increment the vValue to 1. You can refer to this thread to see how to use Timer in Java

Community
  • 1
  • 1
-1
@FXML
private void myButtonOnAction(ActionEvent evt) {
    double vVal = myScrollPane.getVvalue();
    double d = (1.0-vVal)/100;
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        boolean isTheStart = true;
        double difference;
        @Override
        public void run() {
            double currentVVal = myScrollPane.getVvalue();
            if (isTheStart) {
                isTheStart = false;
                difference = (1.0 - currentVVal)/100;
            }
            myScrollPane.setVvalue(currentVVal+difference);
            if (currentVVal >= 1.0) {
                this.cancel();
            }
        }
    }, 1*500, 10);
}
Lakshitha Kanchana
  • 844
  • 2
  • 12
  • 32
  • 1
    This violates the threading rules of JavaFX. You cannot call `myScrollPane.setVvalue(...)` from a background thread. – James_D Jan 18 '17 at 18:48
  • @James_D true! What will be the right way to do it in such requirements? I am not really aware of threading rules of JavaFX. Could you please post a reference here to look at? – Himanshu Chaudhary Jan 18 '17 at 20:37
  • The one with the Timeline animation is the best answer :) Mine approach was a hack to start with. – Himanshu Chaudhary Jan 18 '17 at 20:40
  • Best way is to use a timeline. If you use a background thread, the UI must be accessed on the FX Application Thread using `Platform.runLater(...)`. – James_D Jan 18 '17 at 20:47