Mr.Mountain
Mr.Mountain

Reputation: 883

JavaFX ScrollPane scroll bars not showing if contained Group of nodes is zoomed in

I have a group of nodes. The first node added is an ImageView. Then this group is set as content child node for a scrollable pane. The group is bound to a scale transformation in order to resize the group.

If added an event filter to the scrollable pane in order to recognise if CTRL and the mouse wheel is used. This should create the zoom in and zoom out operations I need.

The problem is that the scrollable pane is not changing the bars according to the zoomed in or zoomed out group.

Here is the code snippet

Group group = new Group();

ScrollPane sp = new ScrollPane();
sp.setHbarPolicy(ScrollBarPolicy.ALWAYS);
sp.setVbarPolicy(ScrollBarPolicy.ALWAYS);
sp.setContent(group);

InputStream is = MaApplication.class.getResourceAsStream("test.jpg");
Image img = new Image(is);
ImageView viewer = new ImageView(img);
viewer.setFitWidth(600);
viewer.setPreserveRatio(true);
viewer.setDisable(true);
viewer.setCache(true);

group.getChildren().add(viewer);

DoubleProperty zoomProperty = new SimpleDoubleProperty(1);      

Scale scaleTransformation = new Scale();
scaleTransformation.xProperty().bind(zoomProperty);
scaleTransformation.yProperty().bind(zoomProperty);

group.getTransforms().add(scaleTransformation);

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

I don't want to use a StackPane instance as it is used in different examples. The should be a solution for this using Group instead. If you find this question to be a duplicate, please add a comment.

Upvotes: 0

Views: 981

Answers (1)

fabian
fabian

Reputation: 82461

ScrollPane uses the layoutBounds property to determine the size, not boundsInParent. layoutBounds does not include transformations. layoutBounds is just the size as determined by the Node's geometry before the transformations are applied. Therefore the ScrollPane still considers the size to be the size of the untransformed content.

To fix this you could either apply the transformation to the child of the Group (Group takes transformations of children into account when determining it's own size)

// group.getTransforms().add(scaleTransformation);
viewer.getTransforms().add(scaleTransformation);

or wrap the content in another Group

sp.setContent(new Group(group));

If you want to add multiple nodes to the Group, you should use the second approach.

Upvotes: 2

Related Questions