0

I have a problem with a button when trying to work with JavaFX. I am trying to set a custom font to a button. The moment I try to change the font of the button, the program crashes.

The other topics on stack do not seem to help as they do not seem to have the same problem. Excuse me if there is another topic but I did not understand the fix as I am new to JavaFX. Thank you for your help in advance.

Here is my code


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);
    }
}

This is my fxml file:


<?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>

And this is my Controller


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;
    }
}

Stacktrace:

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 ```
  • 1
    [edit] your question and add the stack trace of the `NullPointerException` you are getting. – Abra Nov 17 '19 at 14:07
  • It sounds like `getClass().getResourceAsStream("/Aclonica.woff2")` is returning null. Verify that Aclonica.woff2 is a part of your program. If you’re running from a .jar file, verify that Aclonica.woff2 is in the root of the .jar file. – VGR Nov 17 '19 at 16:26
  • That is my problem, I have also identified that this is the problem. I found another thread that says that sometimes if the font is not loaded it will show the error somewhere else. I have also tried to load Aclonica from a link, It still does not work – mihai tian Nov 17 '19 at 16:44

1 Answers1

1

Even though the Code you provided should not even compile I guess the following is your problem:

You assigned your Controller via fx:controller but also override it in your code. The new instance is assigned after load and therefore doesn't know instances of your Controls.

Either remove the fx:controller part from your fxml and set the Controller before(!) calling loader.load(...)

or refer to the existing Controller instead of setting a new one

Manuel Seiche
  • 231
  • 1
  • 5
  • Then if I remove the controller how do I access the properties within, because I wish to change the font of the text. I have also the other way, removing the controller from the fxml file. I get the same error, null pointer on this line ```controller.homeButton.setFont(defaultFont);``` – mihai tian Nov 17 '19 at 14:44
  • @mihaitian https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml – fabian Nov 17 '19 at 14:50
  • @fabian I have created the controller, that is not the issue. In my reply, I asked how do I access the variables in the controller if I delete the controller creation. – mihai tian Nov 17 '19 at 15:01
  • Whether you pass data to the controller or retrieving data doesn't make a difference of many of the approaches. However you're basically passing the font to the controller according to the question... Just one additional thing you should note: Using one of the `static` `load` methods no connection between the properties of your loader and the scene is established whatsoever. Another instance of `FXMLLoader` is created inside these kind of `load` methods that is used to load the fxml. Furthermore you cannot do both: specify `fx:contoller` and set the controller instance before loading. – fabian Nov 17 '19 at 15:17