它表示标记fx:root
已添加到javafx 2.2中,但我不明白如何使用它,尽管使用此示例:http://docs.oracle.com/javafx/2/fxml_get_started/whats_new2.htm
main.xml中
<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
<fx:include fx:id="editorPane" source="editor.fxml"/>
</GridPane>
editor.fxml 没有fx:root
:
<?import javafx.scene.control.TextArea?>
<TextArea fx:id="editor" prefWidth="500" prefHeight="400"
fx:controller="sample.EditorController"
xmlns:fx="http://javafx.com/fxml"/>
editor.fxml 与fx:root
:
<fx:root type="javafx.scene.control.TextArea"
fx:id="editor" prefWidth="500" prefHeight="400"
fx:controller="sample.EditorController"
xmlns:fx="http://javafx.com/fxml"/>
实际上,我发现这两种代码没有任何区别。我错过了什么吗?
答案 0 :(得分:53)
<fx:root>
提供了使用FXML定义可重用组件的问题的解决方案。
例如,假设您要定义一个由TextField
中包含的Button
和HBox
组成的简单自定义组件。您需要使用Node
的子类来表示它,因此您可以编写类似
VBox vbox = new VBox();
vbox.getChildren().add(new MyComponent());
问题是你需要一个Java类,它是Node
的子类,以及FXML。在纯Java(无FXML)中,您可以使用:
public class MyComponent extends HBox {
private TextField textField ;
private Button button ;
public MyComponent() {
textField = new TextField();
button = new Button();
this.getChildren().addAll(textField, button);
}
}
使用FXML定义没有<fx:root>
元素的自定义组件会产生问题,因为您需要FXML作为某种节点,然后另一个节点实例来表示包装它的类:
<HBox>
<TextField fx:id="textField"/>
<Button fx:id="button" />
</HBox>
和
public class MyComponent extends HBox {
@FXML
private TextField textField ;
@FXML
private Button button ;
public MyComponent() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
loader.setController(this);
HBox hbox = loader.load();
this.getChildren().add(hbox);
} catch (IOException exc) {
// handle exception
}
}
}
这导致MyComponent由一个HBox包裹一个包裹TextField和Button的HBox组成。额外的冗余HBox是因为需要一个节点用于FXML根节点而一个节点代表该组件。
<fx:root>
提供了一种机制来创建Node作为组件(Java类),然后指示FXML文件将该节点用作其根:
<fx:root type="javafx.scene.layout.HBox">
<TextField fx:id="textField" />
<Button fx:id="button" />
</fx:root>
和
public class MyComponent extends HBox {
@FXML
private TextField textField ;
@FXML
private Button button ;
public MyComponent() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
loader.setController(this);
loader.setRoot(this);
loader.load();
} catch (IOException exc) {
// handle exception
}
}
}
现在MyComponent
具有与原始全Java版本相同的结构,HBox
包含TextField
和Button
。如果没有<fx:root>
元素,则无法使用FXML执行此操作。