When I bind an ImageView
to it's container:
imageView.fitWidthProperty().bind(widthProperty());
imageView.fitHeightProperty().bind(heightProperty());
It functions as intended when making the container bigger (the imageview
scales accordingly), but when I try to make the container smaller, neither the container or the imageview
becomes smaller. Strangely, when I set the imageview's image before the stage.show()
method, it does function as intended, but again faces the same issue when changing the image after the stage.show()
method.
Instead of bindings i've tried using listeners (both ChangeListener
and InvalidationListener
), changing the layoutChildren()
method in the container/parent class and making a wrapperclass for the imageview, but they didn't solve the issue.
My project doesn't use FXML, so I would like to find a solution that doesn't need it.
When you try to shrink it, the container is (probably) going to remain large enough to hold the ImageView
at its current size, and will be clipped by its container just to show the visible portion. Binding to dimensions is never a particularly good approach; to create custom layouts, subclass Region
and override layoutChildren()
.
Here is a quick example:
import javafx.scene.image.ImageView;
import javafx.scene.layout.Region;
public class ImageContainer extends Region {
private final ImageView imageView ;
public ImageContainer(ImageView imageView) {
this.imageView = imageView;
getChildren().add(imageView);
}
@Override
protected void layoutChildren() {
// usable width and height:
double width = getWidth() - snappedLeftInset() - snappedRightInset();
double height = getHeight() - snappedTopInset() - snappedBottomInset();
imageView.setFitWidth(Math.max(1, width));
imageView.setFitHeight(Math.max(1, height));
double imageWidth = imageView.getBoundsInLocal().getWidth();
double imageHeight = imageView.getBoundsInLocal().getHeight();
// center image (can also make this more complex and support alignment):
double x = snappedLeftInset() + (width - imageWidth) / 2;
double y = snappedTopInset() + (height - imageHeight) / 2;
imageView.relocate(x , y);
}
}
and
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
private final String ioColor = "https://images-assets.nasa.gov/image/PIA00738/PIA00738~orig.jpg";
private final String ioBW = "https://images-assets.nasa.gov/image/PIA01217/PIA01217~orig.jpg";
@Override
public void start(Stage stage) throws IOException {
ImageView leftImage = new ImageView(ioBW);
leftImage.setPreserveRatio(true);
ImageView rightImage = new ImageView(ioColor);
rightImage.setPreserveRatio(true);
SplitPane splitter = new SplitPane(new ImageContainer(leftImage), new ImageContainer(rightImage));
Scene scene = new Scene(splitter, 800, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}