ОС: RHEL 7.4
DE: KDE Plasma 4.11.19 и GNOME 3.22.2
Версия Java: 9 и 10
У меня возникают проблемы при попытке определить размер рабочей области после вызова show (). Раньше в Java 8 / RHEL 6 все работало нормально, и я смог получить размер рабочей области последовательно после show (). Я бы просто послушал свойство width и height, но похоже, что есть обновление для самой сцены, а затем еще одно обновление, добавляющее размер декорации, но что если размер декорации равен 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
РЕДАКТИРОВАТЬ: Похоже, что 2-й проход, чтобы добавить в декорации не гарантируется и будет выполняться на 1-м проходе время от времени.