I'm having some troubles designing the architecture of an application I'm trying to develop. I'm working on JAVA, and I started working on this application because I want to deepen my overall knowledge of JAVA, architectures and patterns. I want to follow the guidelines to make a reusable, low coupled application, like it should be. The application has only one JFrame, but inside it there are several JPanels, each one representing a module of the application.
The question is: in JAVA Swing, how to implement an appropriate MVC pattern?
I struggle on how to understand the way it should be done.
Should I have a main Controller class, that holds references to all the other Controllers?
(I have an image to demonstrate this, here: https://docs.google.com/file/d/0B7tBdn5slIFeY2FoSmxESTREQ1k/edit?usp=sharing)
And in this case, should all the events that require changing the module that is being presented redirect to the main Controller?
Or should I just couple the JFrame with the Controllers of the application, and communicate directly with them?
Basically, I would like to know if i need to have a class that 'manages' all the others.
I have already read several explanations, and different opinions, but I believe this is a little more specific.
Hope I have made myself clear (and hope as well that my explanation is better than my drawing :)).
EDIT:
a sample of the application usage:
- One (an only one) JFrame throughout all the lifecycle of the application;
- the menu will be on the left side, as in BorderLayout.WEST;
- the current module of the application will be in the center, as in BorderLayout.CENTER;
- when the user presses one button of the menu, the corresponding module is loaded into the BorderLayout.CENTER;
Should the menu (View) have it's own Controller, and this Controller communicate with the JFrame? And the JFrame load the new module into it's Layout? Or should the JFrame have its own Controller (or Model, as Gilbert Le Blanc said)?
I know this may seem to specific, or easy to understand, but everytime I think of an desktop application, I struggle to understand this.
When you have an application with a GUI, the GUI model becomes the application view. The application interacts with the GUI through the GUI model.
Or should I just couple the JFrame with the Controllers of the application, and communicate directly with them?
This is what I've done. I've packaged the controller classes together, but I've never created one main controller class.
I keep the GUI controller classes in a separate package from any other application controller classes, like the data access objects.
I usually put each JPanel in its own class, but I wouldn't call that a requirement. The JFrame has its own class, although the instance of the JFrame and the instance of the GUI model are passed to almost all of the GUI components. This makes menu actions possible.
This Traffic Signal GUI article goes over the basics of how to code a very simple GUI.
Edited to respond to the changes in the question.
The GUI controller is separate from the GUI model. The GUI model contains all of the data elements that make up your GUI. Strings for JTextFields, DefaultTableModels for JTables.
Based on your application design, I'd recommend that you create a Java class for every JPanel that you want to put in the center of your application. Your JFrame will control which JPanel is displayed, based on the menu. I'd also suggest that you look at the JTabbedPane which uses a different user interface to accomplish the task of choosing which panel to work with.
Assuming you're going with the menu on the left, each menu option (toggling JButton?) will have it's own controller method or class. These controllers have to have an instance of the JFrame so the controller can call the method in the JFrame class that puts the appropriate panel in the center of the display. The controller decides which method to call, but the methods themselves are a part of the JFrame class.
I've been talking about JFrame and JPanel classes. It's important that you use composition rather than inheritance to build these classes. The JFrame class contains a JFrame. It does not extend JFrame. The only time you extend a Swing component is when you want to override a component method.
As discussed here, Swing components use a separable model architecture with the model and view loosely coupled using the observer pattern. Not every GUI control has to be part of your application's controller. Using an ActionListener
, such as Action
, is particularly convenient for encapsulating application functionality.
Addendum: I'd use CardLayout
, illustrated here to switch panels. Note how the Action
handlers can be used with buttons, menus, combos, toolbars, etc. Each card's content can have it's own implementation of the MVC pattern, separate from the others. Use a PropertyChangeEvent
, seen here, for communication between components.
In general, Swing components, e.g. buttons and tables, already listen to their respective models, leaving you to focus on your application's data model and its listening views. Conveniently, a Swing model, e.g. ComboBoxModel
or Table
Model`, can have more than one listener.