使用FXML时向GridPane添加按钮

时间:2018-05-26 12:51:11

标签: java javafx

我几天前开始使用JavaFX。

我想使用GridPane创建一个3x6按钮矩阵。 我在Scene Builder上创建了GridPane,我想在所有按钮上添加这样的按钮:

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

但是当我尝试运行此代码时,我遇到了一些错误:

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

为什么会这样?

编辑:

当我回家时,我再次看到了我的代码,我注意到我犯了一个大错误。我忘了写fx:id =&#34; gridPane&#34;在fxml中。

无论如何,我将我的代码分为Main和Controller。谢谢你的建议。

1 个答案:

答案 0 :(得分:0)

如果你使用Main类作为控制器,你必须首先获得在调用FXMLLoader.load时创建的Controller,因为它创建了它的新实例我很确定(但实际上你不管怎么说,从来没有这样做,因为James_D说你应该制作一个单独的Controller类。

作为该代码的快速修复,您可以创建一个名为initialize()的方法,在显示之前创建场景时将调用该方法(如果确切的方法,则称为完全存在)。那个将在控制器的正确实例中被调用。为了能够将参数传递给Scene的Controller,你必须从FXMLLoader获取Controller,然后在该控制器中调用一个方法来获取参数,因为没有预定义的函数,比如初始化。

你(或你的SceneBuilder)在FXML中指定了哪个控制器?无法想象SceneBuilder会选择Main类作为它的控制器。另外,也许最好在开始时停止使用SceneBuilder,否则如果它以某种方式中断或最终没有按照你想要它做的那样你将会丢失。