【问题标题】:How to load new FXML with another controller class in the same scene如何在同一场景中使用另一个控制器类加载新的 FXML
【发布时间】:2017-11-23 10:51:47
【问题描述】:

我尝试通过

加载新的 FXML
URL url = this.getClass().getClassLoader().getResource("pknn/fxml/CreateCharacter.fxml");if (url == null) return;
AnchorPane pane = FXMLLoader.load(url);
startPanel.getChildren().setAll(pane);

这适用于带有 StartController 的 CreateCharacter.fxml

<AnchorPane fx:id="createCharacterPanel" onMouseEntered="#paneEventHandler" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pknn.StartController">

但是当我尝试将另一个 FXML 加载到同一场景时

URL url = this.getClass().getClassLoader().getResource("pknn/fxml/LockerRoom.fxml");
if (url == null) return;
AnchorPane pane = FXMLLoader.load(url);
createCharacterPanel.getChildren().setAll(pane);

它不起作用,即使我将其更改为

startPanel.getChildren().setAll(pane);

但是还是不行。 这是我要加载的fxml。

<AnchorPane fx:id="lockerRoomPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pknn.LockerRoomController">

它有很多例外,比如

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
...
Caused by: javafx.fxml.LoadException: 
/Users/pknn/Study/ComPro/MonsterBattle/out/production/MonsterBattle/pknn/fxml/LockerRoom.fxml:10

at pknn.StartController.createCharacter(StartController.java:132)
Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.ReflectUtil can not access a member of class pknn.LockerRoomController with modifiers ""

如何解决?谢谢

【问题讨论】:

  • 普通场景加载FXML文件没有问题。你搞砸了别的东西,但是因为你没有显示一个工作代码而不能说什么。

标签: java javafx javafx-8 fxml fxmlloader


【解决方案1】:

您不能“覆盖” FXML 中指定的控制器。如果您打算更改控制器(或具有带有构造函数参数的控制器),则必须从 FXML 中删除 fx:controller 属性并在 FxmlLoader 中设置控制器:

        fxmlLoader = new FXMLLoader(fxmlFileAsResource);
        fxmlLoader.setController(yourControllerInstance);
        Pane pane = fxmlLoader.load();

【讨论】:

  • 我有一个 LockerRoomController.java 来做我的控制器,我可以使用 fxmlLoader.setController(LockerRoomController.class); ?
  • @PakanonPantisawat 不,它必须是 fxmlLoader.setController(new LockerRoomController());
【解决方案2】:

这是一个在同一个Scene中加载不同FXML帧的例子

create_character.fxml

<AnchorPane fx:id="createCharacterPanel" fx:controller="sample.StartController" xmlns:fx="http://javafx.com/fxml" >
    <children>
        <Button text="Load" onAction="#handleLoadFXML" AnchorPane.topAnchor="0" AnchorPane.leftAnchor="0" />
        <ScrollPane AnchorPane.topAnchor="30" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" AnchorPane.bottomAnchor="0">
            <content>
                <VBox fx:id="child"/>
            </content>
        </ScrollPane>
    </children>
</AnchorPane>

pane_a.fxml 和 pane_b.fxml

<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.SecondController">
    <children>
        <Label text="Pane A"/>
    </children>
</AnchorPane>

<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="sample.SecondController">
    <children>
        <Label text="Pane B"/>
    </children>
</AnchorPane>

加载文件的控制器

public class StartController {
    @FXML
    private AnchorPane createCharacterPanel;

    @FXML
    private VBox child;

    private Parent loadFXML(String name) {
        try {
            return FXMLLoader.load(getClass().getResource(name));
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @FXML
    private void handleLoadFXML(ActionEvent event) {
        child.getChildren().addAll(
            loadFXML("pane_a.fxml"),
            loadFXML("pane_b.fxml")
        );
    }
}

【讨论】:

    猜你喜欢
    • 2013-09-08
    • 2019-07-14
    • 2018-09-27
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多