我想完全用FXML定义我的GUI。我开始使用JavaFX模板,这些模板随处可见,从Oracle文档到Netbeans模板。 在这些模板中,FXML中没有定义Stage,只有实际的场景中有UI控件。类似的东西:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxskuska.FXMLDocumentController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
这似乎没问题,直到我想要改变的第一件事 - 设置窗口的名称。那是我意识到Scene不是一个Window(或JFrame类比),但舞台是。
当我尝试将所有这些包装在一个元素中时,我无法将fx:controller
属性设置为AnchorPane,因为它不再是根元素。我甚至尝试在Stage文件中使用fx:include
来“外包”它,但这只是给了我一个“意外的结束标记:场景”错误。
答案 0 :(得分:3)
FXML本质上只定义了创建对象的方法(通常通过无参数构造函数)并在这些对象上调用setXXX
方法。请参阅文档中的"Class instance elements"和"Property elements"。所以你可以轻松实现
new Scene()
带
<Scene>...</Scene>
和
new Stage()
与
<Stage>...</Stage>
和
Stage stage = new Stage();
Scene scene = new Scene();
scene.setRoot(new AnchorPane(...));
stage.setScene(scene);
与
<Stage>
<scene>
<Scene>
<root>
<AnchorPane ><!--...--></AnchorPane>
</root>
</Scene>
</scene>
<Stage>
fx:controller
属性必须进入根元素,名称空间信息也应如此。
所以:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.stage.Stage ?>
<Stage title="My Application" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="FXMLDocumentController">
<scene>
<Scene>
<root>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!"
onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69"
fx:id="label" />
</children>
</AnchorPane>
</root>
</Scene>
</scene>
</Stage>
然后你会用
加载它import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
public class FXMLStageTest extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Stage stage = FXMLLoader.load(getClass().getResource("Stage.fxml"));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
如果您希望控制器专门应用于窗格,您可以为Stage
和Scene
使用一个FXML文件,然后将fx:include
elements用于其他部分。这样您就可以将UI分成几个FXML控制器对。对于Stage
使用FXML文件感觉有点多余(你可以在Java中做这部分,当然),但有可能:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.stage.Stage ?>
<Stage title="My Application" xmlns:fx="http://javafx.com/fxml/1">
<scene>
<Scene>
<root>
<fx:include source="RootPane.fxml"/>
</root>
</Scene>
</scene>
</Stage>
然后您的原始FXML文件为RootPane.fxml
。如果需要,您可以使用更多fx:include
标记对其进行类似的分解。