如何在 FXML 中定义 Stage?

How to define Stage in FXML?

我想完全用 FXML 定义我的 GUI。我从 JavaFX 模板开始,这些模板从 Oracle 文档到 Netbeans 模板无处不在。 在这些模板中,没有以 FXML 定义的舞台,只有包含 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>

这似乎没问题,直到我想更改的第一件事 - 设置 window 的名称。那时我意识到 Scene 不是 Window(或 JFrame 类比),但 Stage 是。 当我试图将所有这些包装在一个元素中时,我无法将 fx:controller 属性设置为 AnchorPane,因为它不再是根元素。我什至尝试通过在 Stage 文件中使用 fx:include 来 "outsource" 它,但这只是给了我一个 "Unexpected closing tag:scene" 错误。

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

FXML 本质上只是定义了创建对象的方法(通常通过无参数构造函数)并在这些对象上调用 setXXX 方法。请参阅文档中的 "Class instance elements" and "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);
    }
}

如果你想让控制器专门应用到pane,你可以对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 标签类似地分解它。