操作系统:RHEL 7.4
DE:KDE Plasma 4.11.19 和 GNOME 3.22.2
Java 版本:9 和 10
在调用 show() 后,我在尝试计算 Stage 的大小时遇到问题。之前在 Java 8/RHEL 6 中一切正常,我可以在 show() 之后一致地获得舞台的大小。我只会听宽度和高度属性,但看起来舞台本身有一个更新,然后另一个更新添加了装饰尺寸,但是如果装饰尺寸为 0 怎么办,如本例中装饰的宽度是 0,所以我不能只听对 width 和 height 属性的两个更改。
我做错了吗?是否有其他我可以听到的事件来保证舞台在 show() 之后已经完全初始化?我添加了一些示例代码来演示下面的问题。
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
编辑:看起来第二遍添加装饰也不能保证,偶尔会在第一遍中完成。