Java 保持网格窗格具有相同的高度和宽度(纵横比)

Java 保持网格窗格具有相同的高度和宽度(纵横比),java,javafx,aspect-ratio,Java,Javafx,Aspect Ratio,我有一个JavaFXGridPane,当我调整阶段大小时,它会调整自身大小以适应阶段的尺寸。我希望gridpane的高度与gridpane的宽度相匹配,从而将大小调整到最大可能的大小,以保持此约束 我必须在GridPane的父级中添加更多元素。我发现添加的元素根本不正常,并且相互重叠 当然,当我删除覆盖方法时,它们就不再重叠了,但是当我重新调整stage的大小时,网格窗格并没有保持一个完美的正方形 我想尝试在背景中使用image/imageView,并为其应用setPreserveRatio(t

我有一个JavaFXGridPane,当我调整阶段大小时,它会调整自身大小以适应阶段的尺寸。我希望gridpane的高度与gridpane的宽度相匹配,从而将大小调整到最大可能的大小,以保持此约束

我必须在GridPane的父级中添加更多元素。我发现添加的元素根本不正常,并且相互重叠

当然,当我删除覆盖方法时,它们就不再重叠了,但是当我重新调整stage的大小时,网格窗格并没有保持一个完美的正方形

我想尝试在背景中使用image/imageView,并为其应用
setPreserveRatio(true)
。然后将此图像的heightProperty绑定到gridPane的prefHeightProperty,但由于某些原因,这也不会给我带来任何结果

这里是第二种方法的MCVE,它不起作用,但如果我能以某种方式使它起作用,它将非常好

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        StackPane stackPane = new StackPane();

        Image image = new Image("Square Image.png", 300, 300, true, true);
        ImageView imageView = new ImageView(image);
        // This makes the image resize while maintaining its square shape...
        imageView.fitHeightProperty().bind(stackPane.heightProperty());
        imageView.fitWidthProperty().bind(stackPane.widthProperty());
        imageView.setPreserveRatio(true);

        GridPane gridPane = new GridPane();
        for(int i=0; i<5; i++) {
            for (int j = 0; j < 5; j++) {
                Pane pane = new Pane();
                pane.setPrefSize(100, 100);
                gridPane.add(pane, i, j);
            }
        }
        // Does not work as intended... :(
        gridPane.prefWidthProperty().bind(imageView.fitWidthProperty());
        gridPane.prefHeightProperty().bind(imageView.fitHeightProperty());
        
        /*
        Tried this as well, also does not work.. :(
        gridPane.prefWidthProperty().bind(image.widthProperty());
        gridPane.prefHeightProperty().bind(image.heightProperty());
        */


        gridPane.setGridLinesVisible(true);

        stackPane.getChildren().addAll(imageView, gridPane);
        primaryStage.setScene(new Scene(stackPane));
        primaryStage.show();
    }
  
    public static void main(String[] args) {
        launch(args);
    }
}
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类主扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
StackPane StackPane=新的StackPane();
图像=新图像(“Square Image.png”,300,300,true,true);
ImageView ImageView=新的ImageView(图像);
//这会使图像在保持方形的同时调整大小。。。
imageView.fitHeightProperty().bind(stackPane.heightProperty());
imageView.fitWidthProperty().bind(stackPane.widthProperty());
imageView.setPreserveRatio(真);
GridPane GridPane=新建GridPane();

对于(int i=0;i将
GridPane
封装在
StackPane
中,并使用绑定动态更改
GridPane
子级首选大小,同时保持纵横比:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.stage.Stage;

    public class Main extends Application {

        private final int SIZE = 5;

        @Override
        public void start(Stage primaryStage) {

            GridPane gridPane = new GridPane();
            gridPane.setAlignment(Pos.CENTER);

            StackPane centerPane = new StackPane(gridPane);
            centerPane.setStyle("-fx-background-color:cyan");
            centerPane.setPrefSize(SIZE*50, SIZE*50);

            for(int i=0; i<SIZE; i++) {
                for (int j = 0; j < SIZE; j++) {
                    Pane pane = new Pane();
                    pane.setStyle("-fx-background-color:red");
                    gridPane.add(pane, i, j);
                    pane.prefWidthProperty().bind(Bindings.min(centerPane.widthProperty().divide(SIZE),
                                                                centerPane.heightProperty().divide(SIZE)));
                    pane.prefHeightProperty().bind(Bindings.min(centerPane.widthProperty().divide(SIZE),
                                                                centerPane.heightProperty().divide(SIZE)));
                }
            }
            gridPane.setGridLinesVisible(true);

            primaryStage.setScene(new Scene(centerPane));
            primaryStage.show();
        }

        public static void main(String[] args) {
            launch(args);
        }
    }
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.layout.*;
导入javafx.stage.stage;
公共类主扩展应用程序{
私有最终整数大小=5;
@凌驾
公共无效开始(阶段primaryStage){
GridPane GridPane=新建GridPane();
网格窗格。设置对齐(位置中心);
StackPane中心窗格=新的StackPane(gridPane);
centerPane.setStyle(“-fx背景色:青色”);
centerPane.setPrefSize(大小*50,大小*50);

对于(int i=0;iSo)您想让您的
GridPane
始终保持完美的1:1方形形状吗?如果我理解正确,只需将其宽度绑定到其高度:
GridPane.prefWidthProperty().bind(GridPane.prefHeightProperty());
@zephyr您没有像widthProperty()一样的只读可用bind()方法在GridPane中,bind()只能应用于prefWidthProperty()。并执行prefWidthProperty().bind(prefHeightProperty())也不起作用,只是检查了一下。是的,我更新了我的评论。这将处理
GridPane
,但如果您希望每个正方形也保持它们的比率,则需要计算类似的值。我尝试了
GridPane.prefWidthProperty().bind(GridPane.prefHeightProperty())
但它不起作用。我认为,因为它只是设置了prefWidth,而不是实际的宽度,javafx只是忽略了这句话,因为它不可能满足这样的要求。我想我不知道你当时想实现什么。你想要一个完全可扩展的盒子网格,保持它们的比例,并且始终显示问题是,这迫使
GridPane
的单元格保持1:1的比例,因此
GridPane
似乎也保持相同的比例。但实际上,
GridPane
仍在扩展后台的完整大小,留下单元格。如果y您为网格窗格设置背景要求是什么?保持
GripPane
正方形或其内容?您可以将绑定应用于
Gridpane
而不是其内容。这将使内容保持其首选大小。