In JavaFX if you want the user to be able to zoom the contents inside a scrollpane here’s a small gotcha that you have to be aware of: to accomplish this you must wrap the contents of the scroll node inside a group so that the visual bounds (not the layout bounds) are used for layout calculations.

Scrolling can than be attained by setting a scaling transform on the contents of the Scrollpane and adjusting the scale value to meet the specified zoom level.

Here’s a small snippet of code to illustrate how you could do it:

public class ZoomableScrollPane extends ScrollPane{
  Group zoomGroup;
  Scale scaleTransform;
  Node content;
  (…)
  public ZoomableScrollPane(Node content)
  {
    this.content = content;
    Group contentGroup = new Group();
    zoomGroup = new Group();
    contentGroup.getChildren().add(zoomGroup);
    zoomGroup.getChildren().add(content);
    setContent(contentGroup);
    scaleTransform = new Scale(scaleValue, scaleValue, 0, 0);
    zoomGroup.getTransforms().add(scaleTransform);
    (…)
  }
  (…)
}

8 thoughts on “Zooming inside a Scrollpane

  1. Got a shorter version:
    imageView.setOnScroll(new EventHandler() {
    @Override
    public void handle(ScrollEvent event) {
    event.consume();

    if (event.getDeltaY() == 0) {
    return;
    }

    double scaleFactor =
    (event.getDeltaY() > 0)
    ? SCALE_DELTA
    : 1 / SCALE_DELTA;

    imageView.setScaleX(imageView.getScaleX() * scaleFactor);
    imageView.setScaleY(imageView.getScaleY() * scaleFactor);
    }
    });

  2. DoubleProperty zoomProperty = new SimpleDoubleProperty(200);

    zoomProperty.addListener(new InvalidationListener() {
    @Override
    public void invalidated(Observable arg0) {
    imageView.setFitWidth(zoomProperty.get() * 4);
    imageView.setFitHeight(zoomProperty.get() * 3);
    }
    });

    scrollPane.addEventFilter(ScrollEvent.ANY, new EventHandler() {
    @Override
    public void handle(ScrollEvent event) {
    if (event.getDeltaY() > 0) {
    zoomProperty.set(zoomProperty.get() * 1.1);
    } else if (event.getDeltaY() < 0) {
    zoomProperty.set(zoomProperty.get() / 1.1);
    }
    }
    });

    imageView.setImage(new Image("http://mikecann.co.uk/wp-content/uploads/2009/12/javafx_logo_color_1.jpg&quot;));
    scrollPane.setContent(imageView);

    • There’s no zoom event. You have to catch mouse wheel events or keyboard events or whatever is your case and then zoom by adjusting the scale transform.

Leave a Reply

Your email address will not be published. Required fields are marked *