我对JavaFX比较陌生。我正在尝试测试每个fxml都有自己的带有加载器的控制器的设计模式。
示例:。
text.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<VBox>
<children>
<Label text="Hello world FXML"/>
</children>
</VBox>
MainController
public class MainController extends VBox {
public MainController() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/test.fxml"));
loader.setController(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
}
应用
public class App extends javafx.application.Application {
@Override
public void start(Stage primaryStage) {
MainController mainController = new MainController();
Stage stage = new Stage();
stage.setScene(new Scene(mainController));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
这不起作用,启动应用程序时出现一个空窗口:
如果对控制器和应用进行了某些更改:
控制器
private Parent root;
public MainController() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/test.fxml"));
loader.setController(this);
try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
public Parent getRoot() {
return root;
}
应用
stage.setScene(new Scene(mainController.getRoot()));
此后一切都按预期工作,可以在窗口中看到带有文本的标签。
如果我尝试在控制器中设置root:
loader.setRoot(this);
我得到一个错误:
javafx.fxml.LoadException: Root value already specified.
/C:/.../target/classes/fxml/test.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
...
问题:在JavaFX方面有更多经验的人可以就此建议我吗?我究竟做错了什么?有没有更好的方法可以做到这一点?
答案 0 :(得分:3)
由于要使用自定义组件方法,因此需要确保:
controller
设置root
和FXMLLoader
<fx:root>
作为fxml的根元素fx:controller
<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
<children>
<Label text="Hello world FXML"/>
</children>
</fx:root>
public class MainController extends VBox {
public MainController() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/test.fxml"));
loader.setController(this);
loader.setRoot(this);
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
答案 1 :(得分:-1)
在第一个示例中,您调用了'loader.load()',但没有使用该方法的返回值。您可以尝试this.getChildren().add(loader.load())
关于调用setRoot
时的异常,您可以显示所有相关代码吗?