访问JavaFX控制器 - 来自不同控制器的加载器

时间:2016-10-02 11:10:54

标签: intellij-idea javafx

我有2套FXML / Controller   - 第一套是主窗口   - 第二组是一个带选项的窗口

当我从Main.java中调用它们时,两者都工作正常

我的文件夹结构是

src
|--- main
       |--- java
             |---- com
                     |--- main
                           |-  Main.java

                     |----controllers
                           |- MainWindowController.java
                           |- OptionsWindowController.java
        |---resources
                |- mainWindow.fxml
                |- optionsWindow.fxml

所以在Main.java

 public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/mainWindow.fxml"));
        Parent root = loader.load();
        MainWindowController mwController = loader.getController();
        mwController.init(primaryStage);
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

那部分工作正常,我称之为MainWindow,没关系。如果我切换名称并从这里调用OptionsWindow(使用它的控制器)也一样。

所以这两个都来自Main.java。

我希望从MainWindow调用OptionsWindow,因此在MainWindowController.java中我有一个方法(从菜单项调用):

public void loadOptionsWindow(){
    Stage modal = new Stage();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/optionsWindow.fxml"));
    OptionsWindowController opwCotroller = loader.getController();
    modal.initModality(Modality.APPLICATION_MODAL);
    Parent optionsRoot = null;
    try {
        optionsRoot = loader.load();
        Scene sceneOptions = new Scene(optionsRoot);
        modal.setScene(sceneOptions);
        opwCotroller.init(modal);
        modal.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是我收到以下错误:

java.lang.NullPointerException
    at com.controllers.MainWindowController.loadOptionsWindow(MainWindowController.java:190)

我已经检查过了FXML,我已经打印了loader.getLocation(),它应该是什么,但是loader.getController()返回null。

我试图将fxml移动到与控制器相同的文件夹,并使用

调用它
FXMLLoader loader = new FXMLLoader(getClass().getResource("/optionsWindow.fxml"));

由于找不到位置

,这不起作用
FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/controllers/optionsWindow.fxml"));

这不起作用,因为找不到位置。

所以...如果我在resoruce文件夹中有fxml并从Main调用它们,那么任何一个窗口都可以工作,但是当从不同文件夹中的类调用它们时它们不会。

我想将fxml放在与控制器相同的文件夹中,以使SceneBuilder了解方法及其所有内容。我使用Intellij,当控制器的类文件在fxml的文件夹之外时,SceneBuilder似乎并不知道方法。

以防fxml中的代码为:

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.controllers.OptionsWindowController">
   <children>
      <Label layoutX="300.0" layoutY="64.0" text="COSAS" />
      <Button fx:id="bAceptar" layoutX="388.0" layoutY="342.0" mnemonicParsing="false" text="Button" />
   </children>
</AnchorPane>

我迷失了,似乎什么都没有用,我只是不明白。

1 个答案:

答案 0 :(得分:0)

以防有人发现这有用。

当您第一次使用加载程序时(在我的情况下在Main.java中)似乎已经加载了加载程序&#34;。

所以当你打电话给一个新的装载机时,你需要&#34;加载&#34;它首先

像切换一样简单

来自:

的代码
public void loadOptionsWindow(){
    Stage modal = new Stage();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/optionsWindow.fxml"));
    OptionsWindowController opwCotroller = loader.getController();
    modal.initModality(Modality.APPLICATION_MODAL);
    Parent optionsRoot = null;
    try {
        optionsRoot = loader.load();
        Scene sceneOptions = new Scene(optionsRoot);
        modal.setScene(sceneOptions);
        opwCotroller.init(modal);
        modal.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

要:

public void loadOptionsWindow(){
    Stage modal = new Stage();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/optionsWindow.fxml"));

//removed the loader 

    modal.initModality(Modality.APPLICATION_MODAL);
    Parent optionsRoot = null;
    try {
        optionsRoot = loader.load();

//reinserted the loader AFTER the loader.load()
   OptionsWindowController opwCotroller = loader.getController();

        Scene sceneOptions = new Scene(optionsRoot);
        modal.setScene(sceneOptions);
        opwCotroller.init(modal);
        modal.showAndWait();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

现在就像一个魅力

感谢Patrik以及他在另一篇文章中的回答,尽管我搜索了几天,但我还是找不到更早找到的内容(https://stackoverflow.com/a/23461254/5483745