2

I am working on a project where i want to display images with overlay.

My Idea was to create an AncorPane, put an ImageView in its background and then put several shapes above that. This does work.

Because the images are quite large they need to be scaled down according to the available space. Needless to say want to scale down all overlay-shapes that they stay in the same spot relative to the image. Visually this does work too by applying a Scale Transformation to the AncorPane, but here comes my problem.

The AncorPane gets its size from its children. But even though they are scaled down the AncorPane stays at the size of the untransformed image. This creates large amounts of whitespace. I assume it is a problem with the discrepancy between the layout bounds and the bounds in parent of non resizable nodes.

Does anybody have a suggestion on setting the actual size of the AncorPane ore another way of getting rid of this unwanted whitespace.

Example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;


public class test extends Application
{
    @Override
    public void start(final Stage stage) throws Exception
    {
        final ScrollPane scroll = new ScrollPane();
        final Scene scene = SceneBuilder.create().root(scroll).build();
        final VBox box = new VBox();

        final AnchorPane anchorPane = new AnchorPane();
        final ImageView imageView = new ImageView();
        final Shape overlayRectangle = new Rectangle(100, 100, 100, 100);

        scroll.setContent(box);
        box.getChildren().add(anchorPane);
        anchorPane.getChildren().addAll(imageView, overlayRectangle);
        overlayRectangle.toFront();

        imageView.setImage(new Image("http://cdn.sstatic.net/stackoverflow/img/sprites.png"));

        final Scale scale = new Scale(0.5, 0.5);
        anchorPane.getTransforms().add(scale);

        stage.setScene(scene);
        stage.show();
    }

    public static void main(final String[] args)
    {
        launch();
    }
}

When running the example you can see that the scroll bars only disappear when you extend the window size to two time the image size. I know i could just disable the scroll bars. This might work in the example code, but bear in mind that this example is shortened to a large degree. I even cut out dynamic resizing.

Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
l2p
  • 420
  • 3
  • 9
  • Do you mean something related to `sizeToScene()` method? try it out – joey rohan Jan 10 '13 at 08:45
  • Yes I would like to do something like `sizeToScene()` on the AnchorPane function wise. But panes do this automatically. Apparently they resize to the layout bounds instead of the actual visible bounds of the children. That's what I am trying to change. – l2p Jan 10 '13 at 09:42
  • Can u pls. post a [SSCCE](http://sscce.org/) – joey rohan Jan 10 '13 at 09:49

2 Answers2

1

I'm going to answer my own question with a quote from the ScrollPane documentation in case someone finds this.

ScrollPane layout calculations are based on the layoutBounds rather than the boundsInParent (visual bounds) of the scroll node. If an application wants the scrolling to be based on the visual bounds of the node (for scaled content etc.), they need to wrap the scroll node in a Group.

l2p
  • 420
  • 3
  • 9
0

The problem is beacuse of your

  final Scale scale = new Scale(0.5, 0.5);
  anchorPane.getTransforms().add(scale);

Remove the scale as it will be already sizeToScene, but you are re-defining it. Does it solve your problem?

Also vary the scale() method's arguments to increase or reduce (kind of zooming effect) the white space problem.

Or insted of removing, change it to:

 final Scale scale = new Scale(1,1);
 anchorPane.getTransforms().add(scale);
joey rohan
  • 3,505
  • 5
  • 33
  • 70
  • No that doesn't fix the problem. When nothing is scaled (which is happening when i remove the scale) the layout and the actual visible bounds are equal. Then the problem does not occur. But scaling down the images + overlay is the main reason why i am doing all this. You could remove the `sizeToScene()` since it doesn't actually do anything visible. – l2p Jan 10 '13 at 11:46
  • @l2p oh! you mean you have to scale to (0.5,0.5) and the white space shoudn't come? – joey rohan Jan 10 '13 at 11:48
  • @l2p try to use stage.setWidth(215); stage.setHeight(100); and image view's .setFitWidth(100); .setPreserveRatio(true); .setSmooth(true); .setCache(true); – joey rohan Jan 10 '13 at 12:16
  • Unfortunately that doesn't help. If i set the ImageView's dimensions with `setFitWidth()` the layout bounds get changed to the correct values but then I have the same problem with the overlay. Yes I could just set the dimensions of the rectangle with its respective methods but I want to support shapes in general as overlays which are generally not resizable. – l2p Jan 10 '13 at 12:45