简体   繁体   中英

Adding buttons to GridPane while using FXML

I started to use days ago JavaFX.

I'd like to make a 3x6 button matrix using GridPane. I made the GridPane on Scene Builder and I want to add dinamically all buttons like this:

@FXML
private GridPane gridPane;
private Parent root;
private Button gridButtons[][];

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

@Override
public void start(Stage stage) throws Exception{
    root = FXMLLoader.load(getClass().getResource("Main.fxml"));

    gridButtons = new Button[3][6];

    for(int x = 0; x < 3; x++) {
        for(int y = 0; y < 6; y++) {
            gridButtons[x][y] = new Button("n");
            gridPane.add(gridButtons[x][y], y, x);
        }
    }

    stage.setTitle("JavaFX 3x6 Matrix");
    stage.setScene(new Scene(root));
    stage.show();
}

But when I try to run this code I get some errors:

Exception in Application start method
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$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at view.Main.start(Main.java:43)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$148(WinApplication.java:191)
    ... 1 more
Exception running application view.Main

Why this happens?

EDIT:

When I went home I saw again my code and I noticed I made a big mistake. I forgot to write fx:id="gridPane" in the fxml.

Anyway I divided my code in Main and Controller. Thanks for the suggestion.

If you´re using your Main class as a controller too you´ll have to first get the Controller that was created on calling FXMLLoader.load as it creates a new instance of it I'm pretty sure (but in reality you´d never do that anyway, as James_D said you should make a seperate Controller class).

As a quick fix for that code, you can make a method called initialize() that will be called (if that exact method, called exactly that exists) when creating the Scene before it´s displayed. That one will be called in the correct instance of the controller for sure. To be able to pass parameters to the Scene´s Controller, you will have to get the Controller from the FXMLLoader and then call a method in that controller that takes the params as there is no predefined function like initialize for that.

What controller did you (or your SceneBuilder) specify in the FXML though? Can´t imagine that SceneBuilder would pick the Main class as it´s controller. Also, maybe it´s good to stop using SceneBuilder at the start, or else you´ll be lost if it breaks in some way or ends up not doing what you want it to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM