JavaFX getScene()在控制器的initialize方法中返回null [英] JavaFX getScene() returns null in initialize method of the controller

查看:1420
本文介绍了JavaFX getScene()在控制器的initialize方法中返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我昨天在JavaFX中构建了一个小应用程序。我想在Controller类中获取应用程序的场景。每次我尝试在控制器类中获取场景时都会出错。我可以在Controller类的Button上设置OnKeyPressed方法,工作正常。但是如果选择了Button,它的工作正常。我只能在Main-class方法replaceSceneContent中获取场景。我已经阅读了这个问题,但我在初始化中调用了getScene()方法 - 方法??感谢您的任何想法!

I built a small application in JavaFX yesterday. I wanted to get the Scene of the application in the Controller class. I got an error every time I tried to get the scene in the controller class. I could set the OnKeyPressed-method on a Button in the Controller class, works fine. But it works only fine if the Button is selected.. I can get the scene in the Main-class method replaceSceneContent only. I have read this question already, but I call the getScene()-method in the initialize-method?? Thanks for any ideas!

主要类别:

public class Main extends Application {

private Stage stage;

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

@Override
public void start(Stage primaryStage) throws Exception {
    stage = primaryStage;
    gotoMenu();
    primaryStage.show();
}

public void gotoMenu() {
    try {
        MenuController menu = new MenuController();
        menu = (MenuController) replaceSceneContent("Menu.fxml");
        menu.setApp(this);
    } catch (Exception ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private Node replaceSceneContent(String fxml) throws Exception {
    FXMLLoader loader = new FXMLLoader();
    @SuppressWarnings("resource")
    InputStream in = Main.class.getResourceAsStream(fxml);
    loader.setBuilderFactory(new JavaFXBuilderFactory());
    loader.setLocation(Main.class.getResource(fxml));
    BorderPane page;
    try {
        page = (BorderPane) loader.load(in);
    } finally {
        in.close();
    }
    page.setOnKeyPressed(event -> {
        switch (event.getCode()) {
        case F11:
            if (stage.isFullScreen()) {
                stage.setFullScreen(false);
            } else {
                stage.setFullScreen(true);
            }
            break;
        default:
            break;
        }
    });
    Scene scene = new Scene(page);
    page.prefWidthProperty().bind(scene.widthProperty());
    page.prefHeightProperty().bind(scene.heightProperty());
    stage.setScene(scene);
    return (Node) loader.getController();
}}

控制器类:

public class MenuController extends BorderPane implements Initializable {

Main application;

@FXML
private Button button;

public void setApp (Main application) {
    this.application = application;
}

@Override
public void initialize(URL location, ResourceBundle resources) {
    button.getScene().setOnKeyPressed(e -> {
        switch(e.getCode()) {
        case A:
            System.out.println("A pressed!");
            break;
        default:
            break;
        }
    });
}}}


推荐答案

你可以做

private Node replaceSceneContent(String fxml) throws Exception {
    FXMLLoader loader = new FXMLLoader();
    loader.setBuilderFactory(new JavaFXBuilderFactory());
    loader.setLocation(Main.class.getResource(fxml));

    BorderPane page = loader.load();
    MenuController controller = loader.getController();

    page.setOnKeyPressed(event -> {
        switch (event.getCode()) {
        case F11:
            if (stage.isFullScreen()) {
                stage.setFullScreen(false);
            } else {
                stage.setFullScreen(true);
            }
            break;
        default:
            break;
        }
    });
    Scene scene = new Scene(page);
    scene.setOnKeyPressed(event -> {
        if (event.getCode() == KeyCode.A) {
            controller.printA();
        }
    });


    page.prefWidthProperty().bind(scene.widthProperty());
    page.prefHeightProperty().bind(scene.heightProperty());
    stage.setScene(scene);
    return controller ;
}

public class MenuController extends BorderPane{

    // existing code...

    public void printA() {
        System.out.println("A!");
    }

}

只是评论:绝对是绝对的 MenuController 无法成为 BorderPane (或任何其他UI类)的子类。我把它留在了其他地方,但是它完全违反了MVC模式。

Just a comment: it makes absolutely no sense for MenuController to be a subclass of BorderPane (or any other UI class). I left that in, in case you need it elsewhere, but it completely violates the MVC pattern.

另外,我不确定你为什么要使用密钥处理程序要在场景中 A ,并且 F11 的键处理程序位于场景的根目录上。看来这些都应该在场景中注册。但是,我再次将其留在了问题中。

Additionally, I'm not really sure why you want the key handler for A to be on the scene, and the key handler for F11 to be on the root of the scene. It seems these should both be registered with the scene. But again, I left it as you had it in the question.

这篇关于JavaFX getScene()在控制器的initialize方法中返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆