【问题标题】:Button returning null pointer in fxml按钮在 fxml 中返回空指针
【发布时间】:2019-11-17 14:03:26
【问题描述】:

我在尝试使用 JavaFX 时遇到了按钮问题。我正在尝试为按钮设置自定义字体。当我尝试更改按钮的字体时,程序崩溃了。

堆栈上的其他主题似乎没有帮助,因为它们似乎没有相同的问题。 如果还有其他主题,请原谅我,但由于我是 JavaFX 新手,所以我不明白该修复程序。 提前感谢您的帮助。

这是我的代码


import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.text.Font;
import javafx.stage.Stage;

import java.io.FileInputStream;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{

        FXMLLoader loader = new FXMLLoader();
        String fxmlDocPath = "C:\\Users\\Mihai\\Documents\\GitHub\\Kitchen3\\src\\sample\\sample.fxml";
        FileInputStream fxmlStream = new FileInputStream(fxmlDocPath);
        Parent root = loader.load(getClass().getResource("sample.fxml"));
        //Setting the stage and adding my custom style to it
        primaryStage.setTitle("Hello World");
        root.getStylesheets().add("sample/style.css");
        root.setId("pane");

        Controller controller = new Controller();
        loader.setController(controller);

        Font defaultFont = Font.loadFont(getClass().getResourceAsStream("/Aclonica.woff2"), 16);
        controller.homeButton.setFont(defaultFont);
        primaryStage.setScene(new Scene(root, 800 , 600));
        primaryStage.show();
    }


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

这是我的 fxml 文件:


<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <center>
      <Canvas height="560.0" width="800.0" BorderPane.alignment="CENTER" />
   </center>
   <top>
      <ButtonBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
        <buttons>
          <Button fx:id="homeButton" id="button" mnemonicParsing="false" text="Home" />
        </buttons>
      </ButtonBar>
   </top>
</BorderPane>

这是我的控制器


import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Font;

public class Controller {
    @FXML
    Button homeButton;
    @FXML
    BorderPane pane;

    public Controller(){

    }

    @FXML
    public void initialize(){
    //I have tried this to see if it would help.
        homeButton.setText("Home");
        Font default = Font.getDefault();
        homeButton.setFont(arial);
    }
    @FXML
    public Button getHomeButton() {
        return homeButton;
    }
    @FXML
    public void setHomeButton(Button homeButton) {
        this.homeButton = homeButton;
    }
}

堆栈跟踪:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at com.sun.javafx.scene.control.skin.Utils.computeTextHeight(Utils.java:130)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.computeMinLabeledPartHeight(LabeledSkinBase.java:707)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.computeMinHeight(LabeledSkinBase.java:689)
    at javafx.scene.control.Control.computeMinHeight(Control.java:489)
    at javafx.scene.Parent.minHeight(Parent.java:957)
    at javafx.scene.layout.Region.minHeight(Region.java:1401)
    at javafx.scene.layout.Region.computeChildMinAreaHeight(Region.java:1697)
    at javafx.scene.layout.Region.getMaxAreaHeight(Region.java:1978)
    at javafx.scene.layout.Region.computeMaxMinAreaHeight(Region.java:1847)
    at javafx.scene.layout.HBox.computeMinHeight(HBox.java:415)
    at javafx.scene.Parent.minHeight(Parent.java:957)
    at javafx.scene.layout.Region.minHeight(Region.java:1401)
    at javafx.scene.control.SkinBase.computeMinHeight(SkinBase.java:254)
    at javafx.scene.control.Control.computeMinHeight(Control.java:489)
    at javafx.scene.Parent.minHeight(Parent.java:957)
    at javafx.scene.layout.Region.minHeight(Region.java:1401)
    at javafx.scene.layout.Region.boundedNodeSizeWithBias(Region.java:1917)
    at javafx.scene.layout.BorderPane.layoutChildren(BorderPane.java:517)
    at javafx.scene.Parent.layout(Parent.java:1087)
    at javafx.scene.Scene.doLayoutPass(Scene.java:552)
    at javafx.scene.Scene.preferredSize(Scene.java:1646)
    at javafx.scene.Scene.impl_preferredSize(Scene.java:1720)
    at javafx.stage.Window$9.invalidated(Window.java:864)
    at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
    at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
    at javafx.stage.Window.setShowing(Window.java:940)
    at javafx.stage.Window.show(Window.java:955)
    at javafx.stage.Stage.show(Stage.java:259)
    at sample.Main.start(Main.java:25)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    ... 1 more
Exception running application sample.Main

Process finished with exit code 1 ```

【问题讨论】:

  • edit 你的问题并添加你得到的NullPointerException 的堆栈跟踪。
  • 听起来getClass().getResourceAsStream("/Aclonica.woff2") 正在返回空值。确认 Aclonica.woff2 是您程序的一部分。如果您从 .jar 文件运行,请确认 Aclonica.woff2 位于 .jar 文件的根目录中。
  • 这是我的问题,我也确定了这是问题所在。我发现另一个线程说有时如果没有加载字体,它会在其他地方显示错误。我也尝试从链接加载 Aclonica,它仍然无法正常工作

标签: java button javafx fxml


【解决方案1】:

即使您提供的代码甚至不应该编译,我想以下是您的问题:

您通过 fx:controller 分配了控制器,但也在代码中覆盖了它。 新实例是在加载后分配的,因此不知道控件的实例。

要么从你的 fxml 中删除 fx:controller 部分,然后在调用 loader.load(...) 之前设置控制器(!)

或者引用现有的Controller而不是设置一个新的

【讨论】:

  • 那么,如果我删除控制器,我如何访问其中的属性,因为我希望更改文本的字体。我还有另一种方法,从 fxml 文件中删除控制器。我得到同样的错误,这一行上的空指针controller.homeButton.setFont(defaultFont);
  • @fabian 我已经创建了控制器,这不是问题。在我的回复中,我问如果我删除控制器创建,如何访问控制器中的变量。
  • 是否将数据传递给控制器​​或检索数据对许多方法没有影响。但是,您基本上是根据问题将字体传递给控制器​​...您应该注意的另外一件事:使用static load 方法之一在加载程序的属性和场景之间没有建立联系任何。 FXMLLoader 的另一个实例是在这些用于加载 fxml 的 load 方法中创建的。此外,您不能同时执行这两种操作:指定 fx:contoller 并在加载之前设置控制器实例。
猜你喜欢
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多