2016-06-27 2 views
-2

У меня есть класс под названием MainStage, который распространяется на класс сцены javafx. Это часть этого класса.Создание этапов отдельного класса и создание для них уникальных методов

public void changeScene(){ 

    if(onLogin) 
     setScene(mainScene); 
    else{ 
    setScene(loginScene); 
    onLogin = false; 
} 
} 

Я использую этот метод внутри класса MainStage для изменения сцен. Я называю MainStage внутри контроллера для сцены

public class loginSceneController{ 

@FXML 
private Button submit; 
@FXML 
private TextField usernameField; 
@FXML 
private PasswordField passwordField; 

MainStage stage = (MainStage) submit.getScene().getWindow(); //This is where the nullpointer is thrown 


public void handle() { 
    submit.setOnAction(new EventHandler<ActionEvent>() { 

     @Override 
     public void handle(ActionEvent event) { 
      stage.changeScene(); 
      System.out.println("Stage changed sucessfully!!"); 
     } 
    }); 

} 

} 

Когда я пытаюсь запустить его, он бросает это:

Exception in thread "main" 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:745) 
Caused by: javafx.fxml.LoadException: /C:/Users/Max/workspace/CloudCCP/target/classes/Window/LoginScene.fxml:9 
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124) 
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104) 
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097) 
at Window.MainStage.<init>(MainStage.java:24) 
at Window.Window.start(Window.java:28) 
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 
Caused by: java.lang.NullPointerException 
at Window.loginSceneController.<init>(loginSceneController.java:30) 
+0

Как исправить это? –

+1

Объявление 'MainStage stage 'не является никаким методом, поэтому оно считается полем класса. Это означает, что он запускается до того, как экземпляр loginSceneController будет создан и доступен для другого кода. Поскольку ни один другой код не может видеть объект, все остальные поля (включая 'submit') по-прежнему равны нулю. – VGR

+0

Комментарий VGR отвечает на вопрос. Можете ли вы объяснить мне, что программа java запускает программы? –

ответ

1

MainStage stage линии должен быть перемещен внутри обработчика событий.

В настоящее время это объявление, которое не имеет никакого способа, поэтому считается полем класса. Это означает, что он запускается до того, как экземпляр loginSceneController будет создан и доступен для другого кода. Поскольку ни один другой код не может видеть объект, все остальные поля (включая submit) по-прежнему являются нулевыми.

Кроме того, вы не можете получить доступ к сцене кнопки, если кнопка еще не добавлена ​​в сцену. Вероятно, можно с уверенностью предположить, что если пользователю удалось вызвать действие кнопки отправки, кнопка должна быть в виде сцены в видимом окне, поэтому обработчик события является идеальным местом для доступа к родительскому сценарию и окну.

Поскольку вы спросили о порядке выполнения: каждый раз, когда объект создается с помощью new, объект должен сначала запустить все свои инициализаторы в порядке их появления в коде, а затем вызванном конструкторе. Пока это не произойдет, объект фактически не создается, и никакой другой код не может использовать его или ссылаться на него, *, включая FXMLLoader. Все поля изначально ноль, ноль или ложь, если они не инициализированы (например, private int x = 4;).

До тех пор, пока ваш объект не будет полностью построен, ни одно из полей, отмеченных звездочкой @FXML, будет не нулевым.


* Технически это возможно для конструктора «утечка» ссылка на новый объект перед конструктором является полной, но это считается плохой практикой, чтобы сделать это.

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