如何在FXML中定义Stage?

Lep*_*aun 2 java javafx 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>
Run Code Online (Sandbox Code Playgroud)

直到我要更改的第一件事-设置窗口的名称之前,这似乎还可以。那时我意识到Scene不是Window(或JFrame类比),而Stage是。当我尝试将所有这些内容包装到元素中时,我无法将fx:controller属性设置为AnchorPane,因为它不再是根元素。我什至尝试通过fx:include在Stage文件中使用“外包”它,但这只是给了我一个“意外的结束标记:场景”错误。

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

Jam*_*s_D 5

FXML本质上只是定义了创建对象(通常通过无参数构造函数)并setXXX在这些对象上调用方法的方法。请参阅文档中的“类实例元素”“属性元素”。这样您就可以轻松实施

new Scene()
Run Code Online (Sandbox Code Playgroud)

new Scene()
Run Code Online (Sandbox Code Playgroud)

new Stage()
Run Code Online (Sandbox Code Playgroud)

<Scene>...</Scene>
Run Code Online (Sandbox Code Playgroud)

Stage stage = new Stage();
Scene scene = new Scene();
scene.setRoot(new AnchorPane(...));
stage.setScene(scene);
Run Code Online (Sandbox Code Playgroud)

new Stage()
Run Code Online (Sandbox Code Playgroud)

fx:controller属性必须位于根元素中,名称空间信息也应位于根元素中。

所以:

<Stage>...</Stage>
Run Code Online (Sandbox Code Playgroud)

然后用

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要让控制器专门应用于窗格,可以将一个FXML文件用于StageScene,然后将fx:include元素用于其他。这样,您可以将UI分成几个FXML-controller对。仅将FXML文件用于其中Stage(这当然可以用Java来完成),感觉有点多余,但是有可能:

Stage stage = new Stage();
Scene scene = new Scene();
scene.setRoot(new AnchorPane(...));
stage.setScene(scene);
Run Code Online (Sandbox Code Playgroud)

然后您的原始FXML文件是RootPane.fxmlfx:include如果需要,您可以使用其他标签将其分解。