JavaFXML reference to Controller from all classes

和自甴很熟 提交于 2019-12-24 20:14:49

问题


I have my MainView class, which is the one that starts up the whole program.

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);
}

}

This class loads my FXML and starts the program as you probably know. The controller is specified inside the FXML. Now what I want, is to be able to make a reference to this controller from any class in my program. That is because I want all my System.out.prints in every class to print out to my TextArea that is in my controller. This is the TextArea in my controller:

@FXML
private TextArea GUIprint;

So my question is, how do I make the right reference to my controller, so I can use it in all classes? I know that just making an instance of the controller in other classes would just give me a NullPointerException.

If you need to see my Initialize method in my controller, here it is, it just tells what pane to be visible at startup:

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

}

回答1:


You question is very unclear, because you refer to "other classes" but give absolutely no indication as to what those classes are, or where you instantiate them. I will try to answer anyway, covering all possibilities.

Since the start() method is the entry point to the entire application, the only places you can be creating any other objects are:

  1. In the controller itself, either in the initialize() method, or in an event handler
  2. In the start() method
  3. From objects you create from 1. or 2., or from objects you create from those, etc.

If you are creating those other objects in the controller itself, then you just pass a reference to them, e.g.

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

If you are creating those other objects in the start() method, you can get the controller instance from the FXMLLoader, and pass it to the other objects:

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");
}

In either case, just define the appropriate setter methods in the other class(es):

public class SomeOtherClass {

    private MyController controller ;

    public void setController(MyController controller) {
        this.controller = controller ;
    }

    // ...
}

In the third case, you can just recursively do the same thing; pass the controller reference to one object, and then pass it from that object to whoever needs it, etc.

A cleaner approach is probably to use a MVC approach, and share a model instance with all the controllers and other objects that need to modify the application state. See, perhaps, Applying MVC With JavaFx. For moderately complex applications, you might want to consider a dependency-injection framework such as afterburner.fx (which is JavaFX-specific) or Spring or Guice (which are not) to make it easier to "inject" the model where it is needed.



来源:https://stackoverflow.com/questions/46958457/javafxml-reference-to-controller-from-all-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!