当前位置: 首页 > 知识库问答 >
问题:

JavaFX舞台大小在表演后不可预测()

杨景山
2023-03-14

OS:RHEL 7.4
DE:KDE等离子4.11.19和GNOME 3.22.2
Java版本:9和10

在调用了show()之后,我在试图确定舞台的大小时遇到了问题。之前在Java8/RHEL6中一切都工作得很好,在一次show()之后,我可以一致地获得舞台的大小。我只想听width and height属性,但看起来舞台本身有一个更新,然后在装饰大小中添加另一个更新,但如果装饰大小是0,就像本例中装饰的宽度是0,所以我不能只听width and height属性的两个更改。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.stage.Stage;

public class JavaFXTest extends Application {

  public static void main(String[] args) {
      Application.launch(JavaFXTest.class);
  }

  @Override
  public void start(final Stage primaryStage) throws Exception {
    primaryStage.widthProperty().addListener(new ChangeListener<Number>() {
      @Override
      public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
       System.out.println("Width changed! Previous value = " + oldValue + ", new value = " + newValue);
      }
    });
    primaryStage.heightProperty().addListener(new ChangeListener<Number>() {
      @Override
      public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
       System.out.println("Height changed! Previous value = " + oldValue + ", new value = " + newValue);
      }
    });
    primaryStage.showingProperty().addListener(new ChangeListener<Boolean>() {
      @Override
      public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue, final Boolean newValue) {
        if(newValue) {
          Platform.runLater(() -> {
            final double width = primaryStage.getWidth();
            final double height = primaryStage.getHeight();
            System.out.println("Stage width and height after change to showing property (Platform.runLater): " + width + ", " + height);
          });
        }
      }
    });
    primaryStage.showingProperty().addListener(new ChangeListener<Boolean>() {
      @Override
      public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue, final Boolean newValue) {
        if(newValue) {
          final double width = primaryStage.getWidth();
          final double height = primaryStage.getHeight();
          System.out.println("Stage width and height after change to showing property: " + width + ", " + height);
        }
      }
    });
    primaryStage.show();
    Platform.runLater(() -> {
      final double width = primaryStage.getWidth();
      final double height = primaryStage.getHeight();
      System.out.println("Stage width and height immediately after show (Platform.runLater): " + width + ", " + height);
    });
    final double width = primaryStage.getWidth();
    final double height = primaryStage.getHeight();
    System.out.println("Stage width and height immediately after show:" + width + ", " + height);
  }
}

GNOME上的输出(和KDE,数字不同)
示例1:
更改显示属性后的舞台宽度和高度:NaN,NaN
显示后的舞台宽度和高度:NaN,NaN
更改显示属性后的舞台宽度和高度(platform.runlater):NaN,NaN
显示后的舞台宽度和高度(platform.runlater):NaN,NaN
宽度更改!前值=NaN,新值=318.0
高度改变!前值=NaN,新值=171.0
高度改变!前值=171.0,新值=208.0

示例2:
更改显示属性后的舞台宽度和高度:NaN,NaN
显示后的舞台宽度和高度:NaN,NaN
宽度更改!前值=NaN,新值=318.0
高度改变!以前的值=NaN,新值=171.0
更改到显示属性后的舞台宽度和高度(platform.runlater):318.0,171.0
显示后的舞台宽度和高度(platform.runlater):318.0,171.0
高度更改!前值=171.0,新值=208.0

编辑:它也看起来像是第二次通过添加装饰是不保证的,将在第一次通过偶尔做。

共有1个答案

鲁浩言
2023-03-14

我不能给出一个明确的答案,因为我对JavaFX不是很有经验。

窗户都装饰好了吗?如果没有,您可以先对stagestyle执行检查,并且只在装饰完成时响应。

如果所有窗口都装饰好了,等待应用更改是一个选项吗?如果不能选择等待,那么在应用可能的修饰后是否更新OutputScalexOuputScaley属性?如果没有,就用这些代替。

否则,作为最后的手段,您可以对这两个事件都做出响应。

 类似资料:
  • 我正在使用Javafx(没有使用FXML),我正在将阶段传递到a控制器中,以便在单击按钮时更改阶段上的场景。场景的变化是正确的,但是舞台和场景的尺寸增加了,它的尺寸增加了大约0.1(宽度),而高度有时也增加了(不是每次都增加)。 下面是正在使用的控制器。

  • 当我调整窗口大小时,舞台以及包含的场景会正确调整大小,但是当我单击最大化按钮时,只有舞台被最大化,而不是里面的场景。更糟糕的是,没有手动更改场景高度和宽度的方法(这些是只读的)。我还尝试创建新场景并将旧场景的根元素放在里面,但后来我得到了一个例外,即2个场景不能具有相同的根元素。谢谢! 最小可再现示例: 我标记了单击“最大化”的时刻。谢谢

  • 我想知道应该如何在javaFX舞台上设置图标。我已经找到了这个方法,但它没有正常工作。 stage是javafx.stage.stage的一个实例,我已经导入了javafx.scene.image.image。这是我们收到的例外: 无效URL:找不到无效URL或资源

  • 我在应用程序中有2个屏幕。第一个屏幕(MainController类)打开,从Eclipse运行应用程序。 第二屏幕(第二控制器类)位于第一屏幕的按钮打开。 如何在第二个屏幕上制作某种“后退”按钮,以显示第一个屏幕? 如果有必要,我将在JavaFX Scene Builder中创建应用程序的可视部分。

  • 问题内容: 我目前正在使用两个控制器类。 在Controller1中,它创建一个新的阶段,该阶段在主要阶段的顶部打开。 现在,一旦该阶段打开,我希望它在关闭之前保持打开状态约5秒钟。 在Controller2中,我尝试实现类似 但是我不知道在while循环中放入什么来关闭它。我已经尝试了各种方法,但没有任何效果。 问题答案: 使用:

  • 我一直试图从控制器打开一个新窗口以显示进度条: 请帮忙。没有例外,也没有错误。谢谢 编辑:我已经找到了它不显示的原因,这是因为在后面的代码中我有一个函数:阻止程序刷新我的场景和显示元素。是否有一种方法可以在后台或另一个线程中运行这一行(我以前从未使用过线程)再次感谢你的帮助。