Controller Instantiation

Controllers are instantiated as needed by their views so in order to manage these references in some way you need to utilize Initializable interface that controllers support. When adding that interface the class gains the Initialize function:

public interface Initializable {

    public void initialize(URL location, ResourceBundle resources);

}

You can use this function to register the controller instance with a mechanic for instance management or a message bus.

Direct Function Calls

To get a controller reference in another controller to be able to call functions on it you need a central index that can give you that reference. The Google Guava library provides the ideal collection for this: ClassToInstanceMap. This map can be used to resolve Class names to references.

For this workflow you create a static ClassToInstanceMap in your Application.java:

public class Application {

    // We use the mutable ClassToInstanceMap as controllers are added as they are
    // initialized.
    public static final ClassToInstanceMap controllers = MutableClassToInstanceMap.create();

    [...]
}

And in the initializer of your controller you add the controller instance to that map:

public class ControllerA implements Initializable {

    public void initialize(URL location, ResourceBundle resources) {
        Application.controllers.putInstance(ControllerA.class, this);
    }

    /** This is the function we wish to call from another controller
     */
    public void workIt() {
        System.out.println("Working it!");
    }
}

Another controller can then resolve the instance for ControllerA and use it:

public class ControllerB {
    [...]

    public void handlingSomeUserInput() {
        Application.getInstance(ControllerA.class).workIt();
    }
}

Of course this is completely unsafe as the instance may be null when the controller has not yet been initialized.

Message Passing

When you wish to send events between