FXML: элегантный способ привязать дочернюю ширину / высоту к родительской ширине / высоте

#javafx #fxml

#javafx #fxml

Вопрос:

Я использую FXML с JavaFX для разработки графических интерфейсов. Я обнаружил этот метод привязки ширины / высоты дочернего узла к ширине / высоте его родительского узла:

 <Node fx:id="parent">
    <children>
        <Node prefWidth=${parent.width}></Node>
    <children>
</Node>
  

Но это кажется неэлегантным. Я бы предпочел не указывать идентификатор узлу только для того, чтобы его дочерний элемент мог ссылаться на его размеры. Возможно ли использовать какой-либо метод для ссылки на parent узел? Может быть, что-то вроде prefWidth=${parent.width} ?

ПРИМЕЧАНИЕ: Я знаю, что это можно сделать программно из Java, но это не то, что я хочу здесь. Я ищу способ сделать это в FXML.

Комментарии:

1. Привязки выражений разрешаются относительно FXMLLoader пространства имен. Следовательно, вам нужно поместить некоторый корень выражения в пространство имен, чтобы это сработало; единственный способ сделать это в FXML — использовать fx:id , как вы делаете во фрагменте кода. По сути, это настолько элегантно, насколько вы можете это сделать. Обратите внимание, что узлы имеют parent свойство, поэтому вы должны быть в состоянии сделать <Node fx:id="node" prefWidth="${node.parent.width}"/> , но это, возможно, в лучшем случае не лучше.

2. Я думаю, также стоит отметить, что вы обычно выполняете эту функциональность, ничего не привязывая, но используя соответствующую панель макета с правильной конфигурацией. Например. если вы используете VBox для родительского элемента, установите fillWidth="true" и убедитесь, что maxWidth не ограничено для дочернего элемента и т.д.

3. О, значит, вы можете ссылаться на родительский узел. Это намного лучше, потому что тогда код переносим. Есть ли эквивалент this в FXML, чтобы я мог вызвать что-то вроде this.parent.width ? Или мне все еще нужно присвоить внутреннему узлу идентификатор?

4. Нет, опять же, все относительно пространства имен FXMLLoader , поэтому, если бы this это было допустимо (это не так), это, вероятно, относилось бы к пространству имен, а не к «текущему узлу». Кстати, я не тестировал ${node.parent.width} идею, но я думаю, что это должно сработать.

5. Если вы хотите поместить приведенную выше информацию в ответ, я приму это. Тот факт, что из-за this пространства имен не существует понятия, но вы FXMLLoader можете использовать ключевое слово в FXML. parent

Ответ №1:

Привязки выражений работают путем ссылки на элементы FXMLLoader пространства имен. Не существует понятия « this » для обозначения «текущего узла» (о котором я знаю). Таким образом, единственный способ получить доступ к родительскому узлу — это сделать сам узел частью пространства имен: вы можете добиться этого, установив fx:id на самом узле:

 <Pane>
    <children>
        <Node fx:id="node" prefWidth="${node.parent.width}"></Node>
    <children>
</Pane>