Синтаксис ${}
используется для создания привязки выражения , которая, в свою очередь, используется для привязки Property
к результирующему ObservableValue
. Проблема с вашим кодом в Insets
не отображает его состояние как Property
экземпляров. Кроме того, класс Insets
является неизменным, что означает, что состояние устанавливается с помощью одного из конструкторов, и оба конструктора принимают только аргументы double
. Вы не можете передать результат привязки выражения, поскольку double
и FXMLLoader
не "ловко" извлекают текущее значение во время создания экземпляра Insets
.
Из того, что я понимаюВы хотите умножить каждую сторону Insets
на одно значение double
, и это должно произойти только один раз (т.е. вам не нужно обновлять значение с течением времени). В этом случае одним из решений является создание подкласса Insets
и «добавление параметра» в каждый конструктор для вашего скалярного аргумента.
package com.example;
import javafx.beans.NamedArg;
import javafx.geometry.Insets;
public class ScaledInsets extends Insets {
public ScaledInsets(@NamedArg(value = "scale", defaultValue = "1") double scale,
@NamedArg("top") double top, @NamedArg("right") right,
@NamedArg("bottom") double bottom, @NamedArg("left") double left) {
super(scale * top, scale * right, scale * bottom, scale * left);
}
public ScaledInsets(@NamedArg(value = "scale", defaultValue = "1") double scale,
@NamedArg("topRightBottomLeft") double topRightBottomLeft) {
super(scale * topRightBottomLeft);
}
}
Что позволит вам использовать следующее в файле FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import com.example.ScaledInsets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns="http://javafx.com/javafx/" xmlns:fx="http://javafx.com/fxml">
<fx:define>
<Sizer fx:id="SCALAR" fx:factory="getScaleFactor"/>
</fx:define>
<padding>
<ScaledInsets scale="$SCALAR" top="5" left="10" right="10"/>
</padding>
<Label text="Hello, World!"/>
</StackPane>
Обратите внимание, что FXML также поддерживает scripting :
Тег <fx:script>
позволяет вызывающей стороне импортировать код сценария в код JavaScript или встраивать его в FXMLфайл. Можно использовать любой язык сценариев JVM, включая JavaScript, Groovy и Clojure. Код сценария часто используется для определения обработчиков событий непосредственно в разметке или в связанном исходном файле, поскольку обработчики событий часто могут быть написаны более кратко на более свободно типизированных языках сценариев, чем на статически типизированном языке, таком как Java.
Я никогда раньше не использовал скрипты в FXML и не знаю, как использовать их в примере на данный момент. Достаточно сказать, что вы можете возиться с этим, но я не знаю, является ли сценарий жизнеспособным решением.
Не имеет отношения к вашей проблеме, но вы, похоже, используете классы AWT для того, чтобы получитьразмеры экрана. JavaFX предоставляет собственный API для этого: javafx.stage.Screen
. Вы можете использовать:
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
Чтобы получить размеры основного экрана. Чтобы получить размеры всего экрана, а не только визуальной области, используйте getBounds()
вместо getVisualBounds()
.