英文:
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()
方法之后更改图像后仍然面临相同的问题。
除了绑定之外,我尝试过使用监听器(ChangeListener
和InvalidationListener
),更改容器/父类的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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论