Is there any way of auto scroll down a ScrollPane control when it content's height increases ? For example, I have a TitledPane on the bottom of the screen (inside a ScrollPane) and when I expand it I would like the ScrollPane to scroll down so I can see the entire content of the TitledPane.
问题:
回答1:
You can achieve that behaviour With combination of titledPane.localToScene()
and scrollPane.setVvalue()
The first is to get titledPane's coordinates while the second is to set scrollPane's vertical bar position. Note that it's range is between 0 - 1.
回答2:
You can bind
the ScrollPane
vvalue
property with the heightProperty
of the inner container. For example, if you have a VBox
in your ScrollPane
:
scrollPane.vvalueProperty().bind(vBox.heightProperty());
回答3:
You have to tell scrollpane where is the current coordinates before pass a value to the vertical or horizontal bar.
This code works pretty fine for me:
// the owner's node of your scrollPane; titledPane.layout(); // the maxValue for scrollPane bar ( 1.0 it's the default value ) scrollPane.setVvalue( 1.0d );
You have to code this where your scrollpane grows. For example, if you add nodes to the scrollpane inner node, them, add a listener to it's children list.
If the inner node of scrollpane change it's height, add a listener to the heightProperty.
For example, the inner node of your scrollPane it's an AnchorPane and you add nodes to this pane, so do like this:
anchorPane.getChildren().addListener( ( ListChangeListener.Change extends Node> c ) -> { titledPane.layout(); scrollPane.setVvalue( 1.0d ); } );
If it's the height which grows...
heightProperty().addListener( (observable, oldValue, newValue) -> { titledPane.layout(); scrollPane.setVvalue( 1.0d ); } );
That's it!
回答4:
I did it by using an AnimationTimer. I had to wait for 100000000 nanoseconds to be sure that the ScrollPane had reacted to the expanded Titlepane.
public void scrollNodeInTopScrollPane(Node n, ScrollPane s) { final Node node = n; final ScrollPane clientTopScrollPane = s; AnimationTimer timer = new AnimationTimer() { long lng = 0; @Override public void handle(long l) { if (lng == 0) { lng = l; } if (l > lng + 100000000) { if (node.getLocalToSceneTransform().getTy() > 20) { clientTopScrollPane.setVvalue(clientTopScrollPane.getVvalue() + 0.05); if (clientTopScrollPane.getVvalue() == 1) { this.stop(); } } else { this.stop(); } } } }; timer.start(); }