gpt4 book ai didi

java - FXML 按钮导致空指针,硬编码按钮则不会

转载 作者:行者123 更新时间:2023-11-30 06:56:12 27 4
gpt4 key购买 nike

请解释为什么会发生以下情况以及我需要更改哪些内容才能使 FXML 按钮表现得像硬编码按钮一样。

我正在尝试通过按下按钮来动态更改应用程序的 CSS。如果我对 Controller 中的按钮进行硬编码,一切都会按预期工作,但是当使用 FXML 时,相同的函数调用会导致空指针。

更新以显示完整代码(无论如何都是小测试程序)。请注意,我更改了一些名称以使其更易于阅读。没有更改任何功能,但添加的功能同时充当弱解决方法: Controller :

public class SoC extends Application
{
public Scene myScene;
Button btn = new Button();
@FXML
Button btnFXHack;
@FXML
Button btnFXFail;
boolean flipIt = false;

// basic function i want to use
public void changeCSS()
{
if (!flipIt)
{
myScene.getStylesheets().remove(0);
myScene.getStylesheets().add(getClass().getResource("styleTwo.css").toExternalForm());
}
else
{
myScene.getStylesheets().remove(0);
myScene.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());
}
flipIt = !flipIt;
}

// workaround that is fine unless there are more then one scene
public void changeCSSHack(Scene s)
{
if (!flipIt)
{
s.getStylesheets().remove(0);
s.getStylesheets().add(getClass().getResource("styleTwo.css").toExternalForm());
}
else
{
s.getStylesheets().remove(0);
s.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());
}
flipIt = !flipIt;
}

/**
* Button one changes CSS on his own scene only, which feels kinda hacked and lame.
*
* @param event
*/
@FXML
private void handleCSSHack(ActionEvent event)
{
// this button can access his own scene AND use it,....
changeCSSHack(btnFXHack.getScene());
}

/**
* Button two tries to change CSS with saved values in the mainController...
* ...and fails.
*
* @param event
*/
@FXML
private void handleCSSFail(ActionEvent event)
{
// ...yet this button tells me the SAME scene is null. Yes, the one he is on himself.
changeCSS();
}

@Override
public void start(Stage primaryStage)
{
try
{
BorderPane pane = (BorderPane) FXMLLoader.load(getClass().getResource("SoC.fxml"));
myScene = new Scene(pane);
myScene.getStylesheets().add(getClass().getResource("styleOne.css").toExternalForm());

btn = new Button("hardcoded");
btn.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
changeCSS();
}
});
pane.setCenter(btn);

primaryStage.setScene(myScene);
primaryStage.show();
System.out.println("Started");
}
catch (Exception e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
launch(args);
}
}

我的FXML的一部分(板子似乎不喜欢FXML,所以无法完整粘贴)

  <Button fx:id="btnFXHack" mnemonicParsing="false" onAction="#handleCSSHack" text="FX Button Hack" BorderPane.alignment="CENTER" />
<Button fx:id="btnFXFail" mnemonicParsing="false" onAction="#handleCSSFail" text="FX Button Fail" BorderPane.alignment="CENTER" />

作为旁注:如果我只是通过“children().add(btnFX)”将 FXML 按钮添加到我的 Pane 中,我现在有两次,但它也能正常工作。不过,我真的更喜欢将 GUI 内容保留在我的代码之外,所以我真的很想听听如何解决这个问题。

谢谢。

编辑以显示我的结构:

programmfolder
-src
--mainpackage
---controller.java
---.fxml-file
-themes folder
--default.css
--SciFi.css

所以是的,需要“/”才能到达 .css 文件。再说一次:changeCSS() 在被硬编码按钮调用时确实有效。所以我怀疑问题出在这一点上。

也可以按下 FXML 按钮来打印 println("stuff")。现在我感觉他只是没有看到我的场景,因此得到了空指针。即使是简单的 system.out.println(myScene.toString()) 也会导致 FXML 按钮出现空指针。问题是:为什么同一个对象会突然变为 null,具体取决于调用它的位置?

最佳答案

哦,天哪,现在我知道问题出在哪里了。你的 Controller 也是主应用程序类!!!

当您启动应用程序时,将创建“SoC”的实例并调用“start()”。因此,myScene 在此实例中被初始化。

当JavaFx为fxml文件创建 Controller 时,就会创建一个新实例!在这种情况下,myScene 为空。您应该从主应用程序类中创建一个单独的 Controller 类。或者,将 myScene 设置为静态。

关于java - FXML 按钮导致空指针,硬编码按钮则不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41757633/

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