【问题标题】:How to make javafx.scene.Scene resize while maintaining an aspect ratio?如何在保持纵横比的同时调整 javafx.scene.Scene 的大小?
【发布时间】:2021-03-21 21:44:55
【问题描述】:

我正在使用 JavaFX 2.2.7-b01 编写应用程序。

这是我目前拥有的代码示例。如何允许调整应用程序窗口的大小但保持最初配置的纵横比?换句话说,如果用户调整窗口大小,窗口宽度应始终保持为窗口高度的两倍。

  ...
  public void showScene(Stage stage, String fxmlPath) {
    try {
      FXMLLoader loader = new FXMLLoader();
      loader.setBuilderFactory(new JavaFXBuilderFactory());
      loader.setLocation(fxmlPath);
      Parent page;
      try (InputStream in = Main.class.getResourceAsStream(fxmlPath)) {
        page = (Parent) loader.load(in);
      }
      Scene scene = new Scene(page, 400, 200);
      stage.setScene(scene);
      stage.sizeToScene();
      stage.show();
    } catch (Exception ex) {
      ...
    }
  }
  ...

JavaFX 似乎允许用户在构造函数中指定场景的宽度和高度,但不允许通过编程访问来更新宽度或高度。没有 setWidth 或 setHeight 方法。我知道我可以添加属性侦听器以在调整场景大小时获取场景的 只读 宽度/高度,但我无法弄清楚如何动态更改场景尺寸,所以我可以强制保持纵横比。

我想如果我要对 Scene 对象进行子类化(如果我必须这样做的话),这将是可能的,但是还有其他简单的方法可以做到这一点吗?

【问题讨论】:

  • 我认为您不会使用 JavaFX 2.2 找到合适的解决方案。我建议针对 JavaFX issue tracker 记录功能请求。

标签: javafx


【解决方案1】:

> How to make javafx.scene.Scene resize while maintaining an aspect ratio?

通过操纵舞台大小而不是场景:

@Override
public void start(Stage primaryStage) {
    Button btn = new Button();
    btn.setText("Play by resizing the window");
    VBox root = new VBox();
    root.getChildren().add(btn);
    root.setStyle("-fx-background-color: gray");

    Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.minWidthProperty().bind(scene.heightProperty().multiply(2));
    primaryStage.minHeightProperty().bind(scene.widthProperty().divide(2));
    primaryStage.show();
}

【讨论】:

  • 我只是想指出这个解决方案并不完美,如果你放大窗口然后尝试缩小它,它不会让你一直对角线,你最终会得到从底部和侧面晃动它。
  • github.com/BITPlan/com.bitplan.javafx/blob/master/src/test/java/… 你会发现这个示例以及其他与调整大小相关的 stackoverflow 代码示例
  • 您可以通过将一个维度的最小值和最大值绑定到另一个维度来避免 MikaelF 指出的抖动问题,例如stage.setMinHeight(580); DoubleBinding w = stage.heightProperty().subtract(28).divide(2); stage.minWidthProperty().bind(w); stage.maxWidthProperty().bind(w);请注意,您只能在一个维度上调整窗口的大小,而其他维度的大小会自动调整。
【解决方案2】:

改变值时使用removeListener和addListener,防止监听器串连。

private ChangeListener<? super Number> widthChangeListener;
private ChangeListener<? super Number> heightChangeListener;

@Override
public void start(Stage stage) throws Exception {

    widthChangeListener = (observable, oldValue, newValue) -> {
        stage.heightProperty().removeListener(heightChangeListener);
        stage.setHeight(newValue.doubleValue() / 2.0);
        stage.heightProperty().addListener(heightChangeListener);
    };
    heightChangeListener = (observable, oldValue, newValue) -> {
        stage.widthProperty().removeListener(widthChangeListener);
        stage.setWidth(newValue.doubleValue() * 2.0);
        stage.widthProperty().addListener(widthChangeListener);
    };

    stage.widthProperty().addListener(widthChangeListener);
    stage.heightProperty().addListener(heightChangeListener);
}

【讨论】:

    【解决方案3】:

    在使用 Java Fx Scene Builder 的 netbeans 中,您可以使用 AnchorPane 约束来设置 调整舞台大小。

    【讨论】:

      猜你喜欢
      • 2011-09-10
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多