javafx java.lang.NullPointerException作为执行事件处理函数

时间:2013-09-16 22:42:07

标签: model-view-controller javafx

这些天我正在尝试学习一些JavaFx。我设置了一个简单的MVC,它运行良好,直到我点击按钮调用click envet。它抛出java.lang.NullPointerException。我认为问题是GUI启动后没有初始化实例变量“controller”。但我在main方法中初始化它。下面是视图类和我在main方法中所做的。

package javafxdemogui;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

/**
 *
 * @author Jason
 */
public class DemoView extends Application {

    private TextArea inputText;
    private TextArea outputText;
    private DemoController controller;

    @Override
    public void start(Stage primaryStage) {
        BorderPane borderPane = new BorderPane();

        this.inputText = new TextArea();
        this.outputText = new TextArea();
        this.inputText.setWrapText(true);
        this.outputText.setWrapText(true);
        this.outputText.setEditable(false);

        borderPane.setTop(inputText);

        HBox hbox = new HBox();
        hbox.setSpacing(10);
        Button resetBtn = new Button("reset");
        Button copyInputBtn = new Button("copyInput");
        hbox.getChildren().addAll(resetBtn, copyInputBtn);
        hbox.setAlignment(Pos.CENTER);
        borderPane.setCenter(hbox);

        borderPane.setBottom(outputText);


        resetBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                controller.processResetEvent();
            }
        });

        copyInputBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                controller.processCopyEvent(inputText.getText());
            }
        });

        Scene scene = new Scene(borderPane, 600, 400);
        primaryStage.setTitle("JavaFXDemoGUI");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public void registerObserver(DemoController controller) {
        this.controller = controller;
    }

    /**
     * Updates input display based on String provided as argument.
     *
     * @param input new value of input display
     */
    public void updateInputDisplay(String input) {
        this.inputText.setText(input);
    }

    /**
     * Updates output display based on String provided as argument.
     *
     * @param output new value of output display
     */
    public void updateOutputDisplay(String output) {
        this.outputText.setText(output);
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public void viewLaunch(String[] args) {
        launch(args);
    }
}

我在主要方法中做了什么......

public static void main(String[] args) {
    /*
     * Create instances of the model, view, and controller objects, and
     * initialize them; view needs to know about controller, and controller
     * needs to know about model and view
     */
    DemoModel model = new DemoModel();
    DemoView view = new DemoView();
    DemoController controller = new DemoController(model, view);

    view.registerObserver(controller);
    view.viewLaunch(args);
}

1 个答案:

答案 0 :(得分:1)

我建议将main()方法放在应用程序类中,而不是在main中执行任何操作,而是启动应用程序。

我还没有尝试过,但我愿意打赌,当调用Application.launch时,它会生成一个应用程序类的新实例,因此有效地将所有代码编写在main之前。启动被忽略。

我知道有一段时间,对于Java 8,Oracle团队正在考虑不在启动时调用main来启动JavaFX应用程序(不知道最终的结果是什么,也许他们仍然会调用main方法)。 / p>

您真正应该做的是处理init或启动应用程序方法中的所有初始化。还要注意(在JavaFX 2.2中)如果你在init中做了什么,那么对JavaFX对象有一些限制可以实例化(因为你还没有在JavaFX应用程序线程上),例如你不能创建工具提示或WebViews。 JavaFX应用程序线程。因此,您看到的大多数JavaFX应用程序最终都会在start方法前面的JavaFX应用程序线程上创建UI。

另外,一个好方法是将任何可以通过JavaFX应用程序线程完成的长时间运行任务(例如将数据库读入DemoModel之类的东西)搁置到JavaFX并发任务上,这样就可以获得进展反馈和来自该长时间运行任务的消息返回到您的UI以更新初始化状态(如果您的框架需要这种复杂程度)。