gpt4 book ai didi

javafx-8 - getScene() 返回 null,但 someChild.getScene() 不返回

转载 作者:行者123 更新时间:2023-12-01 13:28:34 25 4
gpt4 key购买 nike

我想做什么

加载样式表并在用户单击按钮时将其应用于场景

问题

调用 getScene() 返回 null。

函数所在的类是场景的 Controller 根节点,我使用的是Scenebuilder 2.0,并将类设置为场景的 Controller 加载的 fxml,它是一个 VBox

VBox guiRootNode = null; // inside this instance is where the `getScene() call is`

try {
FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("MainWindow.fxml"));
guiRootNode = (VBox) loader.load();
} catch (IOException e) {
e.printStackTrace();
}

if (guiRootNode == null) {
new Alert(Alert.AlertType.ERROR, "The GUI could not be loaded").showAndWait();
Platform.exit();
} else {
primaryStage.setScene(new Scene(guiRootNode));
}

问题代码是 MainWindow 类中的一个成员函数,@FXML 标签是这样我可以设置按钮调用它 onAction() 通过 MainWindow.fxml

@FXML
private void onDefaultCssClicked()
{
// getScene() returns null
getScene().getStylesheets().remove(getClass().getResource("dark.css").toExternalForm());
getScene().getStylesheets().add(getClass().getResource("default.css").toExternalForm());
}

完整代码可以在https://github.com/SebastianTroy/FactorioManufacturingPlanner找到然而,它并不代表一个远射的最小代码示例......

类似问题

JavaFX - getScene() returns null此 QA 假定 getScene() 调用是在 initialise 函数中或在实例化期间完成的。

JavaFX getScene() returns null in initialize method of the controller在此 QA 中,调用专门在 initialise 方法中进行,因此此处不适用。

我尝试过的事情

  • 我没有使用 fx:root 构造,检查 SceneBuilder 中的该选项会导致错误 javafx.fxml.LoadException: Root hasn't been set。在加载前使用方法 setRoot()。
  • 调用 button.getScene() 工作正常,所以我有技巧,但我还是想了解问题所在。

决议

我不再尝试让我的 Controller 成为根 gui 对象。

基本上我假设 FX gui 的 Controller 是根 GUI 节点,因此我让 Controller 扩展了根 gui 节点的类型。这当然不是这种情况, Controller 是并且应该是一个单独的类,其中注入(inject)了一些 gui 变量。

MCVE

主窗口.fxml

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.gui.MainWindow">
<children>
<Button onAction="#click" text="button" fx:id="button"/>
</children>
</VBox>

主窗口.java

public class MainWindow extends VBox {
@FXML
private Button button;

@FXML
private void click() {
System.out.println("Controller scene: "+ getScene());
System.out.println("Button scene: "+ button.getScene());
}

}

点击按钮输出

Controller scene: null
Button scene: javafx.scene.Scene@4d6ed40a

最佳答案

VBox为 fxml 的根加载的实例与用作 Controller 根的实例不同。您将加载的节点添加到场景中,但没有将 Controller 添加到场景中,所以 getScene()返回 null .

loader.getRoot() == loader.getController()

产量 false .

要使用与 Controller 和根相同的实例,请使用 <fx:root>元素并指定 MainWindow 的实例作为rootcontroller :

<fx:root type="application.gui.MainWindow" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button onAction="#click" text="button" fx:id="button"/>
</children>
</fx:root>
MainWindow mainWindow = new MainWindow();
FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("MainWindow.fxml"));
loader.setRoot(mainWindow);
loader.setController(mainWindow);
loader.load();

... new Scene(mainWindow) ...

MainWindow 的构造函数中执行此操作可能会很方便相反:

public MainWindow() {
FXMLLoader loader = new FXMLLoader(MainWindow.class.getResource("MainWindow.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException ex) {
throw new IllegalStateException("cannot load fxml", ex); // or use a different kind of exception / add throws IOException to the signature
}
}

这允许您初始化+加载 MainWindow使用 new MainWindow() .

关于javafx-8 - getScene() 返回 null,但 someChild.getScene() 不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47188913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com