舞台在javafx中显示为null

时间:2018-05-19 18:03:39

标签: java javafx

在第一个场景中按下按钮时调用此方法(abc)。它的作用是将场景更改为waitingScreen并调用另一个方法waitscr()

 public void abc(ActionEvent event)throws Exception{
 stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    //for changing the scene.
    Parent administrator = 
    FXMLLoader.load(getClass().getResource("waitingScreen.fxml"));
    stage.setScene(new Scene(administrator));
    stage.show();
    conn.close();
     waiting_screen_Controller c = new waiting_screen_Controller();
     c.waitscr(event);

等待的是它启动计时器5秒钟和计时器结束时 它调用另一个方法setscr()(也许我只能在abc中启动计时器)

  public void waitscr(ActionEvent event)throws IOException{
    timetask = new TimerTask(){

        @Override
        public void run() {
            if(!timing){
                try{
                    timetask.cancel();
                    setscr(event);
                }
                catch(Exception ex){
                    ex.printStackTrace();
               }
            }
            else
                timing = updateTime();
        }
    };
     timer.scheduleAtFixedRate(timetask,1000,1000);
}

它更新时间

 public boolean updateTime(){
    System.out.println(s);
       if(s==0){
           return false;
        }
        s--;
        return true;
        }

setscr的作用是将场景改回第一个......

  public void setscr(ActionEvent event)throws IOException{ 
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("first.fxml"));
        Parent parent = loader.load();
        Scene s=new Scene(parent);
        stage = (Stage)((Node) event.getSource()).getScene().getWindow();
        System.out.print(event.getSource());
        stage.setScene(s);
        stage.show();

    } catch (SQLException ex) {
        System.out.println(ex.getMessage());
    }

    }

但问题是它给了npe阶段。

java.lang.NullPointerException
at sample.waiting_screen_Controller.setscr(waiting_screen_Controller.java:106)
at sample.waiting_screen_Controller$1.run(waiting_screen_Controller.java:45)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)

我认为这是因为ActionEvent因为npe处于阶段但是我打印了ActionEvent的源代码并且它不是null。

1 个答案:

答案 0 :(得分:0)

在调用waitscr之前,您正在替换场景。这样,当您致电Scene.getWindow时,该场景不再与窗口关联,结果为null

您不应该从非应用程序线程执行此操作。

通过仅检索一次窗口并使用Platform.runLater,您应该可以解决此问题:

public void abc(ActionEvent event)throws Exception{
    stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    ...
    c.waitscr(stage);
public void waitscr(final Stage stage) throws IOException {
    timetask = new TimerTask(){

        @Override
        public void run() {
            if(!timing){
                try{
                    timetask.cancel();
                    setscr(stage);
                } catch(Exception ex){
                    ex.printStackTrace();
                }
            }
            else
                timing = updateTime();
        }
    };
    timer.scheduleAtFixedRate(timetask,1000,1000);
}
public void setscr(Stage stage)throws IOException{
        // there seems to be a try missing somewhere
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("first.fxml"));
        Parent parent = loader.load();
        Scene s=new Scene(parent);

        Platform.runLater(() -> {
            // scene update on javafx application thread
            stage.setScene(s);
            stage.show();
        });

    } catch (SQLException ex) {
        System.out.println(ex.getMessage());
    }

}