How to scroll to make Node visible inside ScrollPane content?

Given that a huge AnchorPane with some pods is the contents of a ScrollPane , how can I scroll to make one of the trays outside the current viewport visible?

+7
source share
2 answers

You need to find the coordinates of this inner node inside the content and adjust ScrollPane vValue and hValue .

See the ensureVisible() method in the following small application:

 public class ScrollPaneEnsureVisible extends Application { private static final Random random = new Random(); private static void ensureVisible(ScrollPane pane, Node node) { double width = pane.getContent().getBoundsInLocal().getWidth(); double height = pane.getContent().getBoundsInLocal().getHeight(); double x = node.getBoundsInParent().getMaxX(); double y = node.getBoundsInParent().getMaxY(); // scrolling values range from 0 to 1 pane.setVvalue(y/height); pane.setHvalue(x/width); // just for usability node.requestFocus(); } @Override public void start(Stage primaryStage) { final ScrollPane root = new ScrollPane(); final Pane content = new Pane(); root.setContent(content); // put 10 buttons at random places with same handler final EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { int index = random.nextInt(10); System.out.println("Moving to button " + index); ensureVisible(root, content.getChildren().get(index)); } }; for (int i = 0; i < 10; i++) { Button btn = new Button("next " + i); btn.setOnAction(handler); content.getChildren().add(btn); btn.relocate(2000 * random.nextDouble(), 2000 * random.nextDouble()); } Scene scene = new Scene(root, 300, 250); primaryStage.setScene(scene); primaryStage.show(); // run once to don't search for a first button manually handler.handle(null); } public static void main(String[] args) { launch(); } } 
+10
source

I created a slightly more elegant version for this occasion. However, I could only check on the y axis. Hope this helps.

 private static void ensureVisible(ScrollPane pane, Node node) { Bounds viewport = scrollPane.getViewportBounds(); double contentHeight = scrollPane.getContent().localToScene(scrollPane.getContent().getBoundsInLocal()).getHeight(); double nodeMinY = node.localToScene(node.getBoundsInLocal()).getMinY(); double nodeMaxY = node.localToScene(node.getBoundsInLocal()).getMaxY(); double vValueDelta = 0; double vValueCurrent = scrollPane.getVvalue(); if (nodeMaxY < 0) { // currently located above (remember, top left is (0,0)) vValueDelta = (nodeMinY - viewport.getHeight()) / contentHeight; } else if (nodeMinY > viewport.getHeight()) { // currently located below vValueDelta = (nodeMinY + viewport.getHeight()) / contentHeight; } scrollPane.setVvalue(vValueCurrent + vValueDelta); } 
+9
source

All Articles