I needed to put <children>
tag in JavaFx2Menus.fxml
before MenuBar tag.
otherwise an Exception is raised:
javafx.fxml.LoadException: javafx.scene.layout.VBox does not have a default property.
I'm glad that Mihai posted this response for several reasons. First, it will help anyone else reading my post to be aware of that issue. Second, it has allowed me to speculate on the cause of this message in this blog post.
My first thought at reading Mihai's comment was that perhaps the difference was that I was using JavaFX 2.1 (still beta) when I ran the example and perhaps Mihai was using production-ready JavaFX 2.0. Assuming this is the case, the next question was, "What changed in JavaFX 2.1 to make this example work without the children
element? Feeling that I need to balance out recent cogitations on my blog with rampant speculation, I decided to do some of that speculation in this post. I speculate that JavaFX 2.1 has applied @DefaultProperty to more controls than in JavaFX 2.0 and that VBox was one of these which now has it applied.
The Javadoc description of the DefaultProperty annotation states, "Specifies a property to which child elements will be added or set when an explicit property is not given." The "Default Properties" section of the highly useful Introducing FXML adds:
A class may define a "default property" using the@DefaultProperty
annotation defined in thejavafx.fxml
package. If present, the sub-element representing the default property can be omitted from the markup. For example, if theGroup
class were to define a default property of "children", the<children>
element would no longer be required.
My speculation was that JavaFX 2.1 had added @DefaultProperty
annotation to the VBox
(among others) control. Although the Javadoc for JavaFX 2.1's VBox
does not show this annotation applied, the JavaFX 2.1 Javadoc documentation for its parent class, Pane, does indicate the presence of the annotation (and the @DefaultProperty
annotation is itself marked @Inherited). The next image shows Pane
JavaFX 2.0 and JavaFX 2.1 Javadoc versions side-by-side.
The circled portion of the JavaFX 2.1 API documentation for Pane
shows that this control (and controls inheriting from it such as VBox
) have children
as the component's default property. This explains why children
must be explicitly specified in JavaFX 2.0, but is optional for VBox
in JavaFX 2.1.
The @DefaultProperty
annotation has also been applied to the MenuBar control in JavaFX 2.1. Comparing Javadoc for MenuBar in JavaFX 2.0 to the Javadoc for MenuBar in 2.1 proves this. The next screen snapshot shows them side-by-side.
The circled portion of the JavaFX 2.1 API documentation shows that an annotation has been added in JavaFX 2.1 to the MenuBar
class to specify that the default sub-element for MenuBar
is now "menus" in JavaFX 2.1. Incidentally, Menu
also has a new @DefaultProperty
with "items" as its default property. With the @DefaultProperty
annotation of MenuBar
, I decided to try removing the <menus>
elements from my FXML and this appeared to work fine, removing a couple lines of XML from my source FXML and allowing many lines to be less indented. It worked and I had a little more concise of an FXML representation of the same menus application layout.
The more widespread use of the @DefaultProperty
annotation is a small, but very welcome addition to JavaFX 2.1. Although adding opening and closing "children" tags adds only two lines per use, it does increase the indentation as well for a well-formatted FXML file. FXML can be appealing because of its visual similarity to the presentation itself and having fewer "extra" lines for common cases can make it even more readable. Although the @DefaultProperty
annotation itself was available in JavaFX 2.0, it's much more widely applied and can be more widely used in FXML when using JavaFX 2.1.
No comments:
Post a Comment