将子元素的宽度和高度绑定到父元素会导致在调整大小时无法变得更小。

huangapple go评论70阅读模式
英文:

Binding child width and height to parents makes it unable to become smaller when resizing

问题

当我将ImageView绑定到其容器时:

imageView.fitWidthProperty().bind(widthProperty());
imageView.fitHeightProperty().bind(heightProperty());

在扩大容器时,它按预期工作(imageview相应缩放),但当我尝试缩小容器时,容器和imageview都不会变小。奇怪的是,当我在stage.show()方法之前设置了imageview的图像时,它按预期工作,但在stage.show()方法之后更改图像后仍然面临相同的问题。

除了绑定之外,我尝试过使用监听器(ChangeListenerInvalidationListener),更改容器/父类的layoutChildren()方法以及创建一个ImageView的包装类,但它们没有解决问题。

我的项目不使用FXML,因此我希望找到一个不需要它的解决方案。

英文:

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.

答案1

得分: 2

当您尝试缩小它时,容器(可能)将保持足够大,以容纳ImageView以其当前大小,并将被其容器剪裁以仅显示可见部分。绑定到尺寸维度通常不是一个特别好的方法;要创建自定义布局,请子类化Region并覆盖layoutChildren()

以下是一个快速示例:

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() {
        // 可用宽度和高度:
        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();
        // 居中图像(也可以使这更复杂并支持对齐):
        double x = snappedLeftInset() + (width - imageWidth) / 2;
        double y = snappedTopInset() + (height - imageHeight) / 2;
        imageView.relocate(x, y);
    }
}

以及

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();
    }
}
英文:

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();
    }
}

huangapple
  • 本文由 发表于 2023年6月26日 22:38:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557706.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定