所有类中对控制器的JavaFXML引用

所有类中对控制器的JavaFXML引用,java,javafx,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(Window

我有我的
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);
}
所以我的问题是,如何正确引用我的控制器,以便在所有类中使用它?我知道,在其他类中创建一个控制器实例只会给我一个
NullPointerException

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

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

}

您的问题非常不清楚,因为您引用了“其他类”,但绝对没有说明这些类是什么,或者在哪里实例化它们。无论如何,我都会尽力回答,包括所有的可能性

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

  • 在控制器本身中,
    initialize()
    方法或事件处理程序中
  • start()
    方法中
  • 从从1创建的对象。或2,或从这些对象创建的对象,等等
  • 如果要在控制器本身中创建这些其他对象,则只需传递对它们的引用,例如

    @FXML
    private void someHandlerMethod(ActionEvent event) {
        SomeOtherClass someObject = new SomeOtherClass();
        someObject.setController(this);
        // ...
    }
    
    如果在
    start()
    方法中创建这些其他对象,则可以从
    fxmloader
    获取控制器实例,并将其传递给其他对象:

    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");
    }
    
    在第三种情况下,你可以递归地做同样的事情;将控制器引用传递给一个对象,然后将其从该对象传递给需要它的人,等等


    更干净的方法可能是使用MVC方法,并与所有需要修改应用程序状态的控制器和其他对象共享一个模型实例。看,也许。对于中等复杂的应用程序,您可能需要考虑依赖注入框架,例如(JavaFX特定的)或Spring或Guice(这不是),以便更容易“注入”所需的模型。

    谢谢,我已经做到了,正如您告诉我的,我正在创建控制器类中的对象,因此,我按照您在eventhandler方法中向我展示的那样做了。我已经定义了您在另一个类(set控制器)中显示的setter方法。下一步是在控制器本身中创建一个getter方法来获取我的textarea,然后从我在其他类中创建的控制器实例中获取getter方法吗?@studentjavacoder No;在控制器外部公开UI元素是一种不好的做法。(假设您在几个月后决定对这些日志消息使用
    ListView
    而不是
    TextArea
    ,或者不管它们是什么…)只需在控制器中定义一个方法将文本附加到文本区域。然后,您可以从其他类调用该方法。如下所示:public void GUIprint(String s){GUIprint.appendText(s);}@studentjavacoder是的(但是您应该给该方法一个合理的名称)。
    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");
    }
    
    public class SomeOtherClass {
    
        private MyController controller ;
    
        public void setController(MyController controller) {
            this.controller = controller ;
        }
    
        // ...
    }