Resizing images to fit the parent node

2019-01-11 21:52发布

How do I get an image in an ImageView to automatically resize such that it always fits the parent node?

Here is a small code example:

@Override
public void start(Stage stage) throws Exception {
    BorderPane pane = new BorderPane();
    ImageView img = new ImageView("http://...");

    //didn't work for me:
    //img.fitWidthProperty().bind(new SimpleDoubleProperty(stage.getWidth())); 

    pane.setCenter(img);

    Scene scene = new Scene(pane);
    stage.setScene(scene);
    stage.show();
}

5条回答
ゆ 、 Hurt°
2楼-- · 2019-01-11 21:57

This is a better solution than binding the width property (better because often when binding a child to its container, it might not be possible to make the container smaller. At other ocasions the container might even automatically start growing).

The solution below relies on overriding an ImageView so that we can let it behave as 'resizable' and then providing implementations for the minimum ,preferred, and maximum width/heights. Also important is to actually implement the resize() call.

class WrappedImageView extends ImageView
{
    WrappedImageView()
    {
        setPreserveRatio(false);
    }

    @Override
    public double minWidth(double height)
    {
        return 40;
    }

    @Override
    public double prefWidth(double height)
    {
        Image I=getImage();
        if (I==null) return minWidth(height);
        return I.getWidth();
    }

    @Override
    public double maxWidth(double height)
    {
        return 16384;
    }

    @Override
    public double minHeight(double width)
    {
        return 40;
    }

    @Override
    public double prefHeight(double width)
    {
        Image I=getImage();
        if (I==null) return minHeight(width);
        return I.getHeight();
    }

    @Override
    public double maxHeight(double width)
    {
        return 16384;
    }

    @Override
    public boolean isResizable()
    {
        return true;
    }

    @Override
    public void resize(double width, double height)
    {
        setFitWidth(width);
        setFitHeight(height);
    }
}
查看更多
Juvenile、少年°
3楼-- · 2019-01-11 22:02

This is a calculated width method that removes the width of the scroll bar.

first:
myImageView.setPreserveRatio(true);

monitor scrollbar width changes:

scrollPane.widthProperty().addListener((observable, oldValue, newValue) -> {
            myImageView.setFitWidth(newValue.doubleValue() - (oldValue.doubleValue() - scrollPane.getViewportBounds().getWidth()));
        });

scrollBar width:
oldValue.doubleValue() - scrollPane.getViewportBounds().getWidth()

How do I set init width?
after primaryStage.show();

myImageView.setFitWidth(scrollPane.getViewportBounds().getWidth());

查看更多
Viruses.
4楼-- · 2019-01-11 22:06

Use ScrollPane or simply Pane to overcome this problem: Example:

 img_view1.fitWidthProperty().bind(scrollpane_imageview1.widthProperty()); 
 img_view1.fitHeightProperty().bind(scrollpane_imageview1.heightProperty());
查看更多
倾城 Initia
5楼-- · 2019-01-11 22:16

If you want the ImageView to fit inside a windows frame, use this line of code: imageView.fitWidthProperty().bind(scene.widthProperty()).

Note that I am using widthProperty of the scene not the stage. Example:

import java.io.FileNotFoundException;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

public class MapViewer extends Application {

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

    @Override
    public void start(Stage primaryStage) throws FileNotFoundException {
        String strTitle = "Titulo de la Ventana";
        int w_width = 800;
        int w_height = 412;
        primaryStage.setTitle(strTitle);
        primaryStage.setWidth(w_width);
        primaryStage.setHeight(w_height);

        Group root = new Group();
        Scene scene = new Scene(root);

        final ImageView imv = new ImageView("file:C:/Users/utp/Documents/1.2008.png");
        imv.fitWidthProperty().bind(scene.widthProperty());
        imv.setPreserveRatio(true);

        root.getChildren().add(imv);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

}

The aspect radio of the stage (primaryStage) should be similar to that of the image (1.2008.png)

查看更多
forever°为你锁心
6楼-- · 2019-01-11 22:18
@Override
public void start(Stage stage) throws Exception {
    BorderPane pane = new BorderPane();
    ImageView img = new ImageView("http://...");

    img.fitWidthProperty().bind(stage.widthProperty()); 

    pane.setCenter(img);

    Scene scene = new Scene(pane);
    stage.setScene(scene);
    stage.show();
}
查看更多
登录 后发表回答