2013-09-16 4 views
1

В настоящее время я пытаюсь изучить некоторые JavaFx. Я создал простой MVC, и он работает хорошо, пока я не нажму кнопку, чтобы вызвать click envet. Он вызывает java.lang.NullPointerException. Я думаю, проблема заключается в том, что после запуска графического интерфейса переменная экземпляра «controller» не инициализируется. Но я инициализирую его в основном методе. Ниже представлен класс представления и то, что я сделал в основном методе.javafx java.lang.NullPointerException как выполнение функции обработчика событий

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

Советую размещая метод Main() в своем классе приложения и ничего не делать основной, но запуск приложения.

Я не пробовал, но я готов поспорить, что при вызове Application.launch он генерирует новый экземпляр вашего класса приложения, поэтому эффективно весь код, который вы написали в главном запуск игнорируется.

Я знаю, что на некоторое время для Java 8 команда Oracle рассматривала возможность не запускать main при запуске для запуска приложения JavaFX (не уверен, что конечный результат этого был, хотя, возможно, они все еще ссылаются на основной метод).

Что вы действительно должны делать, это обрабатывать всю вашу инициализацию в методах init или start вашего приложения. Также обратите внимание (в JavaFX 2.2), что если вы делаете что-то в init, есть некоторые ограничения на объекты JavaFX, которые могут быть созданы (поскольку вы еще не находитесь в потоке приложений JavaFX), например, вы не можете создавать всплывающие подсказки или WebViews с Прикладной поток JavaFX. По этой причине большинство приложений JavaFX, которые вы видите, создают свой пользовательский интерфейс в потоке приложений JavaFX в начале метода start.

Кроме того, хороший подход заключается в том, чтобы отложить любые длительные задачи, которые могут быть выполнены из потока приложений JavaFX (например, чтения базы данных в нечто вроде вашего DemoModel) на параллельную задачу JavaFX, таким образом вы можете получить обратную связь с результатами и сообщения из этой долговременной задачи обратно в пользовательский интерфейс, чтобы обновить статус инициализации (если ваша инфраструктура требует такого уровня сложности).

Смежные вопросы