如何在FXML中定义Stage?

时间:2016-08-05 14:40:25

标签: java javafx fxml

我想完全用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来“外包”它,但这只是给了我一个“意外的结束标记:场景”错误。

  1. 如何在FXML中定义舞台?
  2. 舞台是JFX的JFX比喻吗?

1 个答案:

答案 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);
    }
}

如果您希望控制器专门应用于窗格,您可以为StageScene使用一个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标记对其进行类似的分解。