JavaFXML对所有类的Controller的引用

时间:2017-10-26 15:39:03

标签: java javafx

我有MainView课程,这是启动整个课程的课程。

public class MainView extends Application {
@Override
public void start(Stage stage) throws IOException {
    stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
        @Override
        public void handle(WindowEvent t) {
            Platform.exit();
            System.exit(0);
        }
    });

    FXMLLoader loader = new FXMLLoader(getClass().getResource("NavigationView.fxml"));
    Parent root = loader.load();
    Scene scene = new Scene(root);
    stage.setResizable(false);
    stage.setScene(scene);
    stage.show();
    stage.setTitle("Greenhouse");
}

/**
 * @param args the command line arguments
 * @throws java.sql.SQLException
 */
public static void main(String[] args) throws SQLException {
    launch(args);
}

}

这个类加载我的FXML并启动你可能知道的程序。控制器在FXML内指定。现在我想要的是能够从我的程序中的任何类引用这个控制器。那是因为我希望每个班级中的所有System.out.prints都打印到我控制器中的TextArea。这是我的控制器中的TextArea

@FXML
private TextArea GUIprint;

所以我的问题是,如何正确引用我的控制器,所以我可以在所有类中使用它?我知道只是在其他类中创建控制器的实例只会给我一个NullPointerException

如果你需要在我的控制器中看到我的Initialize方法,就在这里,它只是告诉启动时可见的窗格:

@Override
public void initialize(URL url, ResourceBundle rb) {
    loginPane.setVisible(true);

}

1 个答案:

答案 0 :(得分:1)

你的问题很不清楚,因为你提到了&#34;其他课程&#34;但绝对没有迹象表明这些类是什么,或者你实例化它们的位置。无论如何,我会尽力回答,涵盖所有可能性。

由于start()方法是整个应用程序的入口点,因此您可以创建任何其他对象的唯一位置是:

  1. 在控制器本身中,可以是initialize()方法,也可以是事件处理程序
  2. start()方法
  3. 从您创建的对象1.或2.,或从您创建的对象等
  4. 如果您在控制器本身中创建其他对象,那么您只需传递对它们的引用,例如

    @FXML
    private void someHandlerMethod(ActionEvent event) {
        SomeOtherClass someObject = new SomeOtherClass();
        someObject.setController(this);
        // ...
    }
    

    如果要在start()方法中创建其他对象,可以从FXMLLoader获取控制器实例,并将其传递给其他对象:

    public void start(Stage stage) throws IOException {
        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Platform.exit();
                System.exit(0);
            }
        });
    
        FXMLLoader loader = new FXMLLoader(getClass().getResource("NavigationView.fxml"));
        Parent root = loader.load();
    
        MyController controller = loader.getController();
        SomeOtherClass someOtherObject = new SomeOtherClass();
        someOtherObject.setController(controller);
    
        Scene scene = new Scene(root);
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
        stage.setTitle("Greenhouse");
    }
    

    在任何一种情况下,只需在其他类中定义适当的setter方法:

    public class SomeOtherClass {
    
        private MyController controller ;
    
        public void setController(MyController controller) {
            this.controller = controller ;
        }
    
        // ...
    }
    

    在第三种情况下,你可以递归地做同样的事情;将控制器引用传递给一个对象,然后将其从该对象传递给任何需要它的人,等等。

    更简洁的方法可能是使用MVC方法,并与需要修改应用程序状态的所有控制器和其他对象共享模型实例。或许,见Applying MVC With JavaFx。对于中等复杂的应用程序,您可能需要考虑依赖注入框架,例如afterburner.fx(特定于JavaFX)或Spring或Guice(不是),以便更容易注入&#34;注入&#34 ;需要它的模型。