The View component must contain sufficient logic to display the interface to the user. Depending upon the framework used, there can be quite a bit of code in the View. The important thing is to ensure business logic lies in the Presenter.
Regarding your secondary query, all Presenter methods will be invoked on the EDT when the View calls them (in the case of Swing). Unless the action required by the Presenter is trivial, I would immediately kick off a background thread to complete the work. That thread will update the View when completed using SwingUtilities.invokeLater()
.
In fact, to avoid being tied to Swing, I tend to pass my own EventDispatcher
class to each Presenter. This is an interface with the same methods as SwingUtilities
. I can then substitute in a different class if necessary.
Side note: this can make unit-testing the Presenter with JUnit difficult, because the Presenter method (and the unit test) will complete before the background thread does. I tend to construct each Presenter with an Executor
that is responsible for running the background threads. Then, in a unit test environment, I pass in a special Executor
implementation that immediately executes the run()
method on the same thread. This ensures the unit tests are single-threaded. Example:
public class SingleThreadExecutor implements Executor {
@Override
public void execute(Runnable command) {
command.run();
}
}