Создание и привязка DoubleProperty в пользовательском элементе управления с FXML - PullRequest
0 голосов
/ 11 октября 2018

Я создаю пользовательский элемент управления, представляющий клавиатуру NumPad.Ширина и высота отдельных кнопок я хочу реализовать как DoubleProperty, чтобы их можно было настроить позже.

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу связать свойство с prefWidth иprefHeight столбцов и строк GridPane в файле FXML.Единственный способ сделать это - установить соединение в контроллере управления.Но я хочу избежать этого, если это возможно.

Это проблемный файл FXML.

<fx:root type="javafx.scene.layout.GridPane" xmlns="http://javafx.com/javafx/" xmlns:fx="http://javafx.com/fxml/1">
    <fx:define>
        <SimpleDoubleProperty fx:id="size">
            <value>
                <Double fx:value="50"/>
            </value>
        </SimpleDoubleProperty>
    </fx:define>

    <gridLinesVisible>false</gridLinesVisible>

    <hgap>5</hgap>
    <vgap>5</vgap>

    <Button text="C" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="0" focusTraversable="false"/>
    <Button text="Backspace" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="2" GridPane.rowIndex="0" GridPane.columnSpan="2" focusTraversable="false"/>

    <Button text="7" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="1" focusTraversable="false"/>
    <Button text="8" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="1" GridPane.rowIndex="1" focusTraversable="false"/>
    <Button text="9" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="2" GridPane.rowIndex="1" focusTraversable="false"/>

    <Button text="4" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="2" focusTraversable="false"/>
    <Button text="5" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="1" GridPane.rowIndex="2" focusTraversable="false"/>
    <Button text="6" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="2" GridPane.rowIndex="2" focusTraversable="false"/>

    <Button text="1" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="3" focusTraversable="false"/>
    <Button text="2" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="1" GridPane.rowIndex="3" focusTraversable="false"/>
    <Button text="3" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="2" GridPane.rowIndex="3" focusTraversable="false"/>

    <Button text="0" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="0" GridPane.rowIndex="4" GridPane.columnSpan="2" focusTraversable="false"/>
    <Button text="." maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="2" GridPane.rowIndex="4" focusTraversable="false"/>

    <Button text="E" onAction="#f" maxWidth="Infinity" maxHeight="Infinity" GridPane.columnIndex="3" GridPane.rowIndex="2" GridPane.rowSpan="3" focusTraversable="false"/>

    <columnConstraints>
        <ColumnConstraints fx:id="col1" prefWidth="${size.value}"/>
        <ColumnConstraints fx:id="col2" prefWidth="${size.value}"/>
        <ColumnConstraints fx:id="col3" prefWidth="${size.value}"/>
        <ColumnConstraints fx:id="col4" prefWidth="${size.value}"/>
    </columnConstraints>
    <rowConstraints>
        <RowConstraints fx:id="row1" prefHeight="${size.value}"/>
        <RowConstraints fx:id="row2" prefHeight="${size.value}"/>
        <RowConstraints fx:id="row3" prefHeight="${size.value}"/>
        <RowConstraints fx:id="row4" prefHeight="${size.value}"/>
        <RowConstraints fx:id="row5" prefHeight="${size.value}"/>
    </rowConstraints>
</fx:root>

${size.value} правильно инициализирует элемент управления, но нет связи между sizeи ColumnConstraints#prefWidthProperty / RowConstraints#prefHeightProperty.

Если я делаю привязку вручную, все работает.Но, как я уже сказал, я хочу избежать этого, если это возможно.

@FXML
private void initialize() {
    col1.prefWidthProperty().bind(size);
    // ...

    row1.prefHeightProperty().bind(size);
    // ...
}

, если я использую ${size}, я получаю NumberFormatException: для входной строки: "DoubleProperty [value: 50.0]"

1 Ответ

0 голосов
/ 11 октября 2018

Прямой доступ к свойствам не представляется возможным через привязку выражений.

Однако, если вы предоставляете доступ к свойству через контроллер, вы можете вместо этого использовать ${controller.size} для создания привязки:

@FXML
private DoubleProperty size;

public final double getSize() {
    return size.get();
}

public final void setSize(double value) {
    size.set(value);
}

public final DoubleProperty sizeProperty() {
    return size;
}
...
<columnConstraints>
    <ColumnConstraints fx:id="col1" prefWidth="${controller.size}"/>
    <ColumnConstraints fx:id="col2" prefWidth="${controller.size}"/>
    <ColumnConstraints fx:id="col3" prefWidth="${controller.size}"/>
    <ColumnConstraints fx:id="col4" prefWidth="${controller.size}"/>
</columnConstraints>
<rowConstraints>
    <RowConstraints fx:id="row1" prefHeight="${controller.size}"/>
    <RowConstraints fx:id="row2" prefHeight="${controller.size}"/>
    <RowConstraints fx:id="row3" prefHeight="${controller.size}"/>
    <RowConstraints fx:id="row4" prefHeight="${controller.size}"/>
    <RowConstraints fx:id="row5" prefHeight="${controller.size}"/>
</rowConstraints>
...
...