Java – Cyclic dependency of two eclipse projects

architectureclasspatheclipsejava

I am trying to implement some sort of MVC in Java. Actually it's more of a MVP but this doesn't really matter to my problem.

Following situation:
I've got a GUI, made with Netbeans (because of the better GUIeditor) which is updated and changed frequently.

As my main project is easier to maintain in Eclipse I chose to import the Netbeans project into Eclipse as a separate project. So here I am with a project "App" containing the controller and the model package and a project "GUI" containing the view package.
The problem is that the pattern I am following along has a cyclic dependecy between the view and the controller. Whenever the view changes, the controller gets notified decides which data to get from the model and then makes the changes to the view.

When I add App to the build path of GUI and the other way round, I will end up with this error message "A cycle was detected in the build path of project 'GUI'". I mean that's true, this cycle is already in my design.

Currently at startup I register a view to its controller in the following way (this is no real code, I am trying to shorten it)

package view;
import controller.*;
class viewA{
   ...
   public viewA() {
       controllerA.register(this);
   }
   ...  
}

package controller;
import view.*;
class controllerA implements SomeListener{
   ...
   protected viewA[] registeredViews;
   public static register(viewA interestedView){
       arrayPush(registeredViews,interestedView);
       interestedView.addSomeListener(this)    
   }
   ...
}

So you see the connection is made by passing a reference to the controller and then registering a listener onto this view. The problem is: if I don't have the GUI project in App's buildpath the import can't be resolved, same happens for not having App in GUI's build path.

I'd like to keep this project structure and also stick to my MVC architecture. How can I work around it? What are your suggestions?

Best Solution

You have your listeners backwards from the usual way - normally, the controller has the initiative. It creates the view object and registers itself as a listener for view events.

Additionally, the listener type should be an interface defined in the View project. Then, the Contoller implements that interface and the view does not have to know about the concrete controller classes. Cycle resolved. You can do this in your "reverse" setup too, of course.