如何在同一场景中使用另一个控制器 class 加载新的 FXML
How to load new FXML with another controller class in the same scene
我尝试通过
加载新的 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 ""
如何解决?谢谢
您不能"override" FXML 中指定的控制器。如果您打算更改控制器(或有一个带有构造函数参数的控制器),那么您必须从 FXML 中删除 fx:controller
属性并在 FxmlLoader 中设置控制器:
fxmlLoader = new FXMLLoader(fxmlFileAsResource);
fxmlLoader.setController(yourControllerInstance);
Pane pane = fxmlLoader.load();
这是在同一帧中加载不同 FXML 帧的示例Scene
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")
);
}
}
我尝试通过
加载新的 FXMLURL 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 ""
如何解决?谢谢
您不能"override" FXML 中指定的控制器。如果您打算更改控制器(或有一个带有构造函数参数的控制器),那么您必须从 FXML 中删除 fx:controller
属性并在 FxmlLoader 中设置控制器:
fxmlLoader = new FXMLLoader(fxmlFileAsResource);
fxmlLoader.setController(yourControllerInstance);
Pane pane = fxmlLoader.load();
这是在同一帧中加载不同 FXML 帧的示例Scene
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")
);
}
}