【问题标题】:How to reference Stage in controller class? [duplicate]如何在控制器类中引用 Stage? [复制]
【发布时间】:2016-10-28 15:00:22
【问题描述】:

主类

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/application/Main.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

MainController.class

    public class MainController implements Initializable {

    @FXML private MediaView mv;
    private MediaPlayer mp;
    private Media me;

    @FXML Slider volumeSlider;

    DoubleProperty width;
    DoubleProperty height;

    Stage stage;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // TODO Auto-generated method stub
        String path = new File("src/media/my.mp4").getAbsolutePath();
        me = new Media(new File(path).toURI().toString());
        mp = new MediaPlayer(me);
        mv.setMediaPlayer(mp);
        //mp.setAutoPlay(true);

        stage = (Stage) mv.getScene().getWindow();  // Error occured

        width = mv.fitWidthProperty();
        height = mv.fitHeightProperty();
        width.bind(Bindings.selectDouble(mv.sceneProperty(), "width"));
        height.bind(Bindings.selectDouble(mv.sceneProperty(), "height"));

        volumeSlider.setValue(mp.getVolume() * 100);
        volumeSlider.valueProperty().addListener(new InvalidationListener() {

            @Override
            public void invalidated(Observable observable) {
                // TODO Auto-generated method stub
                mp.setVolume(volumeSlider.getValue() / 100);
            }
        });
    }

    public void play(ActionEvent event){
        mp.play();
        mp.setRate(1);
    }
    public void pause(ActionEvent event){
        mp.pause();
    }
    public void fast(ActionEvent event){
        mp.setRate(2);
    }
    public void slow(ActionEvent event){
        mp.setRate(.5);
    }
    public void reload(ActionEvent event){
        mp.seek(mp.getStartTime());
        mp.play();
    }
    public void start(ActionEvent event){
        mp.seek(mp.getStartTime());
        mp.stop();
    }
    public void last(ActionEvent event){
        mp.seek(mp.getTotalDuration());
        mp.stop();
    }
    public void fullScreen(ActionEvent event){

    }
}

错误

javafx.fxml.LoadException: 
/C:/Users/SOONMYUN/workspace/MediaPlayer/bin/application/Main.fxml

    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 application.Main.start(Main.java:17)
    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)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at application.MainController.initialize(MainController.java:44)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    ... 17 more

我想将舞台从 Main 类获取到 Controller 类,但是失败了。

因为我应该在 Controller 类中使用 setFullScreen 函数。

【问题讨论】:

    标签: java javafx fullscreen


    【解决方案1】:

    我正在回答如何将舞台对象从主类传递到您的控制器类 在你的控制器类中创建一个函数

    public void setStage(Stage stage){
    this.stage=stage;
    }
    

    现在像这样在你的主类中调用这个函数

     FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/application/Main.fxml"));
                    Parent root = (Parent) fxmlLoader.load();
      ((MainController) fxmlLoader.getController()).setStage(primaryStage);
    

    如果你想获取舞台对象而不将它从主类传递到控制器类,你可以这样做

    1.给你的 AnchorPane 提供 id,例如fx:id="ap" 然后在你的 Controller 类中

    @FXML
    AnchorPane ap;
    

    2.你想要对象的地方

    Stage stage = (Stage) ap.getScene.getWindow();
    

    【讨论】:

    • 非常感谢!!它正在工作
    • 很高兴它有帮助。请投票并接受答案
    • 很抱歉我无法投票,因为我没有足够的声望..
    • @SoonmyunJang 不需要对不起哥们。快乐编码
    • 嗨。 setStage 函数成功运行,但是当我尝试在控制器类中使用 stage 时,stage.sizeToScene() 给了我一个空指针异常。我在同一控制器类中的单独函数authenticate(ActionEvent event) 中使用stage.sizeToScene()。我需要将stage 传递给这个authenticate(ActionEvent event) 函数吗?谢谢。
    【解决方案2】:

    从控制器访问阶段:

    • 在 Controller 类中为阶段变量创建一个 setter 方法
    • 在您的 Main.java 类

    • 中获取控制器实例
    • 通过Main.java中的setter方法设置控制器的stage变量

      插图:

      第 1 步:

          public class MainCOntroller {
      
           private Stage primaryStage;
      
              public void setPrimaryStage(Stage primaryStage){
                         this.primaryStage = primaryStage;
               }
                  .....
                 .....      
           }       
      

      第 2 步和第 3 步: 获取控制器实例并使用 setter 方法设置舞台

        public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
          try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/application/Main.fxml"));
           Parent root = (Parent)loader.load();
      
           MainController controller = (MainController) loader.getController(); 
      
            //set stage 
             controller.setPrimaryStage(primaryStage);
        } catch(Exception e) {
              e.printStackTrace();
          }
      }
      

    【讨论】:

    • 我很感激你。感谢您的回答,我解决了问题!
    • 不客气
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多