Java 如何在FXML中定义Stage?

Java 如何在FXML中定义Stage?,java,javafx,fxml,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 jav

我想完全用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>

这似乎还可以,直到我想改变的第一件事——设置窗口的名称。那个时我意识到场景不是窗口(或JFrame类比),而是舞台。 当我试图将所有这些都包装到一个元素中时,我无法将
fx:controller
属性设置为AnchorPane,因为它不再是根元素。我甚至试图通过在Stage文件中使用
fx:include
将其“外包”,但这只会给我一个“意外的结束标记:场景”错误

  • 如何在FXML中定义Stage
  • 舞台是JFX与JFrame的类比吗

  • FXML本质上只是定义了创建对象的方法(通常通过无参数构造函数)并在这些对象上调用
    setXXX
    方法。请参阅文档中的和。因此,您可以轻松地实现

    new Scene()
    

    。。。
    

    。。。
    

    
    另一件。这样,您就可以将UI拆分为几个FXML控制器对。仅为
    阶段使用FXML文件感觉有点多余(当然,您也可以用Java来完成这一部分),但这是可能的:

    
    

    然后您的原始FXML文件是
    RootPane.FXML
    。如果需要,您也可以使用进一步的
    fx:include
    标记对其进行类似的分解。

    “我无法将fx:controller属性设置为AnchorPane,因为它不再是根元素了。”为什么不将该属性移动到根元素?无法将其移动到根,因为根(阶段)没有控制器属性。您没有将其设置为元素的属性,它只是定义了
    FXMLLoader
    用于创建控制器的类
    AnchorPane
    也没有控制器属性。但是如果我想要一个包含2个或更多场景的舞台,每个场景都有自己的控制器,该怎么办?如果我在根元素(Stage)中设置了fx:controller,这不会迫使我在所有场景中使用该控制器吗?@Leprechaun您不能在单个
    Stage
    中设置多个
    场景
    ,并且不能仅用fxml替换
    Stage
    场景。忘记在fxml中“编程”任何东西。你正在定义那里的结构。对于更复杂的事情,您仍然必须使用java代码。@Leprechaun您可以将多个FXML文件与
    fx:include
    元素组合在一起。请参阅更新。但听起来似乎您还没有真正理解FXML和控制器的整个概念。我建议你多做一些研究和实验。@James\u D如果我想使用SceneBuilder,我还是需要使用fx:include thingy,因为它不能打开Stage。@Leprechaun那么为什么不做通常的事情,用Java定义你的
    Stage
    new Stage()
    
    Stage stage = new Stage();
    Scene scene = new Scene();
    scene.setRoot(new AnchorPane(...));
    stage.setScene(scene);
    
    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);
        }
    }