Search code examples
javafxscaling

JavaFX Scaling differently sized nodes to the same size


I am drawing differently sized maps on a pane. Some look decent, others are just presented as a small shape and you have to zoom in to get it to the right size. I want those maps to appear roughly the same size each time I initialize (so I don't have to manually scale each map). I've got Point2D points for the min and max values of x and y of the pane they're drawn on and same goes for the map (which is a Group of polygons). How do I set the distance between, say, the minPoint of Pane and the minPoint of Group? Or am I approaching this the wrong way?

edit:

 public void setDistance(Group map, Point2D paneSize, Point2D mapSize){
    //um diese distance verschieben, if distance > 10px (scale)
    double d = paneSize.distance(mapSize);
    double scale = ??
    map.setScaleX(scale);
    map.setScaleY(scale);
}

That's how I planned on doing it, not sure about that one line though.


Solution

  • To scale the node to the size of the parent node, the difference in the size is not important. What is important is the quotient of the sizes, more precisely the minimum of the quotients of the heights and the widths (assuming you want to fill the parent in one direction completely).

    Example:

    @Override
    public void start(Stage primaryStage) {
        Text text = new Text("Hello World!");
    
        Pane root = new Pane();
        root.getChildren().add(text);
        InvalidationListener listener = o -> {
            Bounds rootBounds = root.getLayoutBounds();
            Bounds elementBounds = text.getLayoutBounds();
    
            double scale = Math.min(rootBounds.getWidth() / elementBounds.getWidth(),
                    rootBounds.getHeight() / elementBounds.getHeight());
            text.setScaleX(scale);
            text.setScaleY(scale);
    
            // center the element
            elementBounds = text.getBoundsInParent();
            double cx = (elementBounds.getMinX() + elementBounds.getMaxX()) / 2;
            double cy = (elementBounds.getMinY() + elementBounds.getMaxY()) / 2;
            text.setTranslateX(rootBounds.getWidth() / 2 - cx + text.getTranslateX());
            text.setTranslateY(rootBounds.getHeight() / 2 - cy + text.getTranslateY());
        };
    
        root.layoutBoundsProperty().addListener(listener);
        text.layoutBoundsProperty().addListener(listener);
    
        Scene scene = new Scene(root);
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }