Is this a proper implementation of MVC in Swing? - java

I have read about MVC but am having doubts on how to implement the concept in Java with Swing. Here's what I'm going for:
The model:
ListOfThings contains a Collection of Thing objects.
The controller:
Controller instanciates ListOfThings and populates it with a "add" method (internally creates a new Thing and adds it to the Collection)
The view:
A Swing interface with a ListOfThingsPanel which will contain ThingPanel components to represent the model. Both extend JPanel. ThingPanel contains various components meant to display the data of the Thing it's linked to.
It also has a button which adds a new (empty) thing to the list.
The click event calls the Controller's addThing() method which asks ListOfThings to add a new Thing to its list. ListOfThings has an event/listener system and ListOfThingsPanel listens to it to know when it should refresh the view.
Am I properly following the MVC concept by doing it like this?
Update:
I'm still learning Java but I have coding experience and would prefer to learn the theory and attempt it by my own means before using premade frameworks. While I'm aware Swing implements the MVC pattern, I have read it does it in a specific way (View and Controller combined) which might not be the best and not applicable in other circumstances. I'm a bit wary until I can make sure "Swing MVC" is not different from "MVC", or that the differences won't impact my understanding of the underlying ideas.
One thing of import to me is to learn to really separate the model from the view to allow me to ultimately create various views of various types (Swing but also console or update to JavaFX for example) This is why I'd like to avoid anything Swing specific outside of the view part itself.

While the Swing framework already implements a form of MVC (explicit models; JXyz & UI classes = controller & view), this strict separation is rarely used on application level and looks rather weird.
To start I suggest to follow the following design:
implement the client-side business logic with POJOs
wrap the POJOs with custom Swing models where needed (ListModel, TableModel)
Use a GUI builder to design the GUI
Use the Mediator pattern to listen for events (a custom subclass of JPanel listens for events of its children and updates other children or fires own custom events if needed)
If you want to go a step further, use a RCP such as the NetBeans Platform (very recommended).
Edit:
And here is the article explaining MVC in Swing:
http://www.oracle.com/technetwork/java/architecture-142923.html

Related

Combining MVC, DAO/Repository Pattern and Swing for Java GUI Applications

I am trying to create a graphical flashcards app from scratch. I have a few questions:
a. I have used Swing to build some apps in the past, calculator app. But I felt that was a trivial application so I want to ramp up my skills as a Java developer.
b. I have been told that a gold standard is to build a small application that uses one of these: MVC, MVM, MVVM and so on.And since I am learning design patterns, I was hoping to use it in the application.
c. My classes are such:
A model: Flashcard.java(It has a list of answers, a list of
pictures, a question), A FlashCard Manager(to perform CRUD)
Different view classes: GUI interface
Controller: All the event listeners
App: To initialize the app
d. I have tried to read online examples of such a combination and what was proposed in for the Manager or DAO, was to have it connect to JDBC for the database. I am trying to simulate that by using a HashMap> for the same purpose.Is that correct or do I have to use JDBC or SQLite?
e. Also am I supposed to have a controller-view pair, that is for every JComponent that uses an event listener or a controller for windows( startup window, main application window, child windows)?
f. Also should the controller class be an interface for all these controllers?
I do not have code because I am still developing it but I just wanted to get a general idea. Thanks for answering my questions.
b. I have been told that a gold standard is to build a small application that uses one of these: MVC, MVM, MVVM and so on.And since I am learning design patterns, I was hoping to use it in the application.
This both right and wrong. Some API's simply don't support the notion of a pure MVC (or variation). Swing for example implements a form of MVC of it's own which is more like M-VC, where the model is separate, but the view and controller are bound.
Think about a JButton. Do you ever apply a controller to it? You can add listeners to it, you can even add listeners directly to it's model, but it has it's own internal control mechanism, which generates events based on keyboard and mouse interaction.
You need to beware of when a MVC might not be suitable or where the amount of work to implement a pure MVC is not worth the effort.
Having said that, you can wrap Swing UI's in another MVC layer, but you need to think about it at a different level. Instead of each controller been considered a "view", you look at the container, which might contain multiple controls and see it as the "view", which a controller then manages.
d. I have tried to read online examples of such a combination and what was proposed in for the Manager or DAO, was to have it connect to JDBC for the database. I am trying to simulate that by using a HashMap> for the same purpose.Is that correct or do I have to use JDBC or SQLite?
This is not an unreasonable idea, however, you want to ensure that the public interface remains constant. This would allow you to change the implementation at a later date to use JDBC or a web service without having to rewrite the code that depends on it
e. Also am I supposed to have a controller-view pair, that is for every JComponent that uses an event listener or a controller for windows( startup window, main application window, child windows)?
This will depend. I tend to avoid exposing individual components, as this exposes them to unwanted modifications (you may not want a controller to be able to change the text of a button for example)
As a general rule of thumb, I try to make the relationship between the controller and the view as vanilla as possible, meaning that the controller shouldn't care about how the view is implemented, only that it upholds the contract between the it subscribes to.
This generally means I have a functional view, which is contracted to produce certain events/data and allows certain interaction (from the controller)
f. Also should the controller class be an interface for all these controllers?
IMHO, yes. This allows a view/controller/model to be implemented differently, but allows the rest of the code to continue working with it without the need to be modified.
The bottom line is, implementing a MVC over Swing is not as simple as people think it is. It takes some planning and consideration, but it is doable.
For a more detailed example, have a look at Java and GUI - Where do ActionListeners belong according to MVC pattern?

Java; Multiple MVC and Swing Relationships Best Practice?

I am attempting to develop a "Person database" Java Swing application, using MVC design paradigm with Observer/Observable. Here is a simplified abstract of M/V/Cs I am using:
App
AppModel
(Empty right now, possibly i'll store certain static application info such as version number here)
AppView
(Creates a JFrame and a few other Swing components)
AppController
(Instantiates AppModel, AppView and also a PersonController and a PersonListController)
Person
PersonModel
(Stores info for 1 person)
PersonView
(Displays a number of form fields inside a JPanel (i.e Name, Age, Phone number). Observes PersonModel.)
PersonController
(Instantiates PersonView. Observes PersonView. Instantiates PersonModel. Updates PersonModel.)
PersonList
PersonListModel
(Stores a list of Persons)
PersonListView
(Displays a list of persons with appropriate Add / Delete buttons. Observes PersonList.)
PersonListController
(Instantiates PersonListView. Observes PersonListView. Instantiates PersonListModel. Updates PersonListModel)
Also, a 'bootstrap', where the app starts. It creates a new AppController.
In the real application, there will be more (and different) Model/View/Controller objects but I want to keep this example simple.
I dont understand how I can go about 'merging' these seperate views into one UI while maintaining a good seperation of concerns.
Take for example the PersonListView. IMHO it doesn't need to care about the AppView (with the JFrame etc). PersonListView just needs to look at its own model and update itself accordingly. However, I cannot enforce that because the PersonListView's own Swing components need to be added to the Swing components of another view, the AppView.
So at the moment the AppController is instantiating its own View, plus indirectly a PersonView and PersonListView (via instantiation of their controllers). AppController then grabs the 'main' Jpanel for each view, grabs the 'parent' Swing components they should be added to on the AppView, and adds them.
This just doesnt seem the right way to do it to me. Im pulling Swing-related members from their hiding places and messing with them around inside a controller. In fact instantiating the model and view within the controller seems bad too, but I cant figure out a better way.
I've seen enough 'simple MVC' tutorials recently that I'm dreaming of the bloody things - but not one tutorial seems to go into the relationships of multiple models, views, controllers, especially where it concerns Swing. Maybe I am wrong and the App should have just one view? Maybe I need a 'Relationship' class that sort of takes every single Model/View/Controller and instantiates stuff appropriately?
Any advice would be most appreciated as Im completely at a loss!
This is where a strict MVC paradigm falls down (in Swing anyway, and it may explains why Swing is written the way it is).
Swing combines the view and control elements together, leaving the model separate. That means, you are free to add a view to any other view and the control follows (the model remains dynamic).
I have a developer who insists on using the strict approach to MVC and they still can't tell me the order of precedence. ie should the control know about the view or should the view know about the control - which one plugins into the other. Personally, I'm to lazy and simply follow the Swing implementation.
To my mind, if you want to follow a strict MVC, I'd basically allow for a public method in your controller that allows access to the overall view (say a JPanel with all the components on it that makes up the view for example).
Think about the JComboBox or JSpinner for example. They both have a number of components that make up the view (editors, buttons, etc), but you have single access point, the component itself...
Your next problem is going to be how to combine various views into a single over all view.
Personally, I would create a group controller of some kind that allowed you to supply the various, known, controllers together (setPersonList for example), as the "master" controller is going to need to know about these other controllers any way, as it needs to know how to layout them out.
IMHO

Passing objects between objects

I have a number of GUI classes that is accessing the same information object which is set from its constructor.
Each GUI class displays the gui information object in a different way.
Is it better to initialise the object each time in the constructor or just add the object to memory and use it each time a GUI class requires it ? Does either method fall into a design pattern ?
Before even reading up on specific object design patterns, a good starting place is to read up on the MVC (Model View Controller) pattern. It's probably the most commonly used architecture pattern out there, and a google search will bring up tons of good material (Wikipedia would even be a good place to start in this case)
It's used to address the problem you've hinted at, where your various display logic has to frequently access the same information holding logic. In an application which uses an MVC architecture, your code is (more or less) separated into three categories, code which displays information in a UI, code which holds (or models) information, and code which controls the flow of the application and application events. MVC applications commonly use listeners and other event design patterns, like the ones mentioned above.
Take look at dependency injection, listeners and event bus.
I would suggest dependency injection, there are a lot of frameworks out there. My favorite is guice but YMMV.
How about using a strategy pattern?. Basically just define a set of classes that inherit from the same interface such as
public interface GUIBehavior {
}
//Set of classes
public behavior1 implementse GUIBehavior...
//In the clases that display the information simply set an attribute for the behavior
private GUIBehavior myCurrentBehavior;

Swing with Guice

I'm already using Guice for the data model of my app, and so far I'm quite happy with it. However, the GUI part is about to become a Big Ball of Mud. I find it hard to use Guice here, because Swing components and models are tightly coupled, and often force a certain initialization order.
My application consists basically of a header with a lot of filters, a central and quite complex JTree component, and a lot of actions (e.g. from a JPopup), menus, dialogs, wizards etc. The main problem is that I have a lot of coupling between the components and actions (e.g. complicated validations, tree updates...). Could you give me some advice how to structure that GUI with Guice?
I'm aware of libs like GUTS, but the documentation is really thin, I'd rather avoid to add another dependency to my project and to learn another API (e.g. I don't know the Swing Application Framework).
I'd rather suggest a proper MVC, even better Presentation Model - View - Controller. Separate your code properly and Guice will fit in naturally. For example:
View classes should have a building part which draws the static content (labels, the tree, buttons, etc) and updating code which reacts to changes in the Presentation Model. All the action listeners should invoke some code on the controller. Both the Presentation Model and the controller should be injected by Guice, like all the other dependencies.
This organization would allow for easy testing with replacing the View with some testing code which will listen to changes in the Presentation Model and invoke actions on the controller.
I would advise to look at Guts-GUI.
It is a Swing UI framework based on Guice dependency injection model.
I think the problem is probably the overall architecture. You probably want to see if you can refactor the application to be simpler and more modular. Like Boris recommended, I would also suggest using the Presentation Model pattern - search for Martin Fowler and Karsten Lentzsch - and the JGoodies library.
For the problem with Actions, see how the Swing Application Framework and Netbeans Plaform handle them. For example, if an Action is used in both a view and a menu, you might want to make it available through a global map.
We have recently started on GUICE with swing. Here's what we have done which may be of help to you.
a. When you want to inject a model into a table/tree you could inject a model provider instead and do a provider.get() to get the model in the contructor.
for example
public class Mytable extends JTable {
public Mytable(Provider<MytableModel> modelProvider) {
this.setModel(modelProvider.get());
}
}
b. You could make a model generic and make use of the same model in different tables.
c. The model could have a handle to datasource which could be injected by a factory where necessary with assisted inject. Number of examples available in stack overflow.
d. Your model could be a flexible data structure which uses model to return the relevant cell/leaf/other value.
e. When you have actions, you inject actions in your component builders and attach them to relevant components.
f. Use #Singleton annotation where you have a shared object such as model injected in 2 different objects, such as action and the component.]
g. Use custom scope when you need to use number of instance sets of objects. Custom scopes are great for this as it keeps the code really clean.
Hope the above helps...

java / gwt UI coding - clean code

i've started on some basic java coding with gwt, and im getting a bit concerned about the heft of my main class.
For instance - how does one compartmentalize the keyhandlers, since they trigger a number of changes to the UI, how could i move this into a separate .class file and still be able to access all the various widgets in the main class, without having to pass everything to the handler (ie. all the widgets i manipulate after the click event).
i've googled but didnt come across any particularly good examples - know of any readily legible code-bases i could read to see how it should be done? (gwt's own tuts are pretty basic, and just kitchen-sink every thing into a single file)
thanks!
I hate to say something so unimaginative, but MVC works--it's not the ultimate, but it can start getting you organized.
EDIT: While searching on a semi-related topic, I came across this which has similar ideas to mine but goes into more detail.
What that means in terms of GWT is that you should think of just laying out your GUI components in one class, put all your event handling in a second and put your object model objects separate from the other two.
One way to accomplish this is to make most or all the controls on your GUI public members. This sounds kind of lame, but their usage is encapsulated inside the controller so it's not like you have uncontrollable access--in fact your access is clearer/better defined than if all your members were private but your view code was combined with the controller.
Specific tricks:
Have listeners be their own class. You can often reuse them-- in other words, avoid anonymous inner classes. I sometimes create a listener class and instantiate a new instance for each button/control that needs to have a similar effect when pressed. If I need it to act slightly differently for a given button, I'll pass something into the constructor of the "special" handlers so that they know to act a little differently. You can also create different handler sub-classes if necessary--I'm just saying don't forget that event handlers are classes, you can use inheritance and everything if need be.
One Very Old GUI Trick I learned a long time ago, try not to have various mini-handlers modifying the GUI in different ways, instead have all the "active" buttons and controls set a state within your GUI and then call a single method that applies that state to ALL the controls on your GUI. When you get beyond a trivial GUI this can be a life-saver. If I'm not being clear, leave a comment and I'll leave an example for you.
Property sheets:
There is a special case for GUIs--the property sheet style GUI. I've done a LOT of these and they are irritating as HELL. They tend to have dozens or hundreds of controls on them, each GUI control tends to be tied to a specific field in your model and there are just hundreds of lines of copy and paste boilerplate code connecting them, each group copied and pasted with a few items changed--at minimum it's like 3 lines of code per control (Create control, copy value in and copy value out).
I always write these with a "Smart" controller--one that can intelligently bind the control to some data without any unique code. This can get tricky and if this is your problem let me know in the comments and I can give you some general advice as to some tricks you might try. I've gone from a minimal reflective solution to a full-on XML based solution. Were I to do it again, I might consider annotation-based.
Example of MVC:
Note, this is just an example, there are a MILLION ways to do MVC.
In your MAIN:
Instantiate MyView
Instantiate MyModel
Instantiate MyController(myView, myModel)
myView.setVisible(true)
in MyView
probably extends Frame
Most components are public final (public final Button b=new Button())
If public members make you nervous, use getters--same EXACT effect as public final members with a little extra syntax.
Remember that you can set final members in your constructor.
May have general methods such as reset(), but MyController may be a better place for this.
in MyController
saves references to myView and myModel
adds listeners to myView where necessary (see advice on listeners above)
configures myView based on state of myModel
when "done" button pressed, copies state from myView to myModel
notifies myModel that it's data has been updated and destroys itself.
in MyModel:
This would be a typical model class, it would contain your business logic (mostly not used as part of the GUI, that's more like GUI logic in MyController. The controller would tend to set values in your business logic then call some method like updated() to cause some business logic to take control. It should know nothing of a GUI--this is your "pure" business class.
Sometimes the GUI might call an update() or some other method to trigger some data change and then reload the GUI controls from the Model--this is a fairly good way to integrate your business logic with your GUI without your model knowing about the GUI...
Also, as I said above, I would put more work into MyController if I was working with property sheets just due to the sheer number of lines of boilerplate that you end up with if you aren't smart about it.
Note that View and Controller are nearly always paired. You can't just replace a Swing view with a web view and expect the controller to remain unmolested--but the model should not ever change for the view or controller.
You should take a look at the best practices for GWT applications first:
http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
One of the concepts they talk about is that of MVP (not MVC) to structure your application. There's a sample project on Google Code that you can look at to understand how to structure a GWT application in this way:
http://code.google.com/p/gwt-mvp/

Categories

Resources