6

I'm using FXML with JavaFX to develop graphical interfaces. I discovered this method for binding the width/height of a child node to the width/height of it's parent node:

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

But that feels inelegant. I'd rather not have to give an id to a node just so it's child can reference it's dimensions. Is there perahps some method for referenceing the parent of a node? Maybe something like prefWidth=${parent.width}?

NOTE: I know this can be done programmatically from Java, but that's not what I want here. I'm looking for a way to do this in the FXML.

J-bob
  • 8,380
  • 11
  • 52
  • 85
  • [Expression bindings](http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html#expression_binding) are resolved relative to the `FXMLLoader` namespace. Consequently you need to place some root of the expression into the namespace for this to work; the only way to do this in FXML is using an `fx:id`, as you do in the code snippet. So this is essentially as elegant as you can make this. Note that nodes have a `parent` property, so you should be able to do ``, but this is arguably no better, at best. – James_D Oct 21 '16 at 18:12
  • I guess it's also worth pointing out that you would typically accomplish this functionality without binding anything, but by using an appropriate layout pane with the correct configuration. E.g. if using a `VBox` for the parent, set `fillWidth="true"` and make sure the `maxWidth` is unbounded on the child, etc. – James_D Oct 21 '16 at 19:05
  • Oh, so you *can* refer to the parent of the node. That is much better, because then the code is portable. Is there an equivalent of `this` in FXML, so I can call something like `this.parent.width`? Or do I still need to give the inner node an ID? – J-bob Oct 21 '16 at 19:19
  • No, again, everything is relative to the [namespace](http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html#variable_resolution) of the `FXMLLoader`, so if `this` were valid (it's not) it would probably refer to the namespace, not the "current node". I haven't tested the `${node.parent.width}` idea, btw, but I think it should work. – James_D Oct 21 '16 at 19:28
  • If you want to place the info above into an answer I'll accept it. The fact that there is no concept of `this` due to the `FXMLLoader` namespace, but that you *can* use the `parent` keyword in the FXML. – J-bob Oct 25 '16 at 17:52

1 Answers1

14

Expression bindings work by referencing elements of the FXMLLoader's namespace. There is no concept of "this" to refer to "the current node" (that I am aware of). So the only way to access the parent of a node is for the node itself to be part of the namespace: you can achieve this by setting an fx:id on the node itself:

<Pane>
    <children>
        <Node fx:id="node" prefWidth="${node.parent.width}"></Node>
    <children>
</Pane>
James_D
  • 201,275
  • 16
  • 291
  • 322