views:

120

answers:

4

Hi,

I am new in swing, but managed to create a descend gui.
My problem though is that I was not able to apply the patterns suggested in references/tutorials, mainly the MVC pattern.

Is it me, or in JTree and using SwingWorker, it is not possible to have a clear separation of controller/view/model?
For example I use a Swingworker, but then I can not "fit" a controller in the design.

I.e. the action of the control essentially is in the doBackground method that is inside e.g the action perform of a button.
So no controller class.

The result of the action in swing worker is to update a Jtree, so I pass the result to a class I named model, but this class has to have access to the treeModel of the Jtree that is inside the JFrame i.e. the view, so no clear separation of view and model.

I looked at a lot of tutorials but all presenting the MVC had a trivial example, and in most cases the view (which was just a some labels!) updated everything. Am I completely confused, or it is not posible or at least easy to integrate an MVC pattern in a swing application that uses swingworkers and jtrees?

I am talking about the actual domain data and not the MVC that is implemented in the swing components.

Can someone help me (and spare me from this terrible headache) either with an overview of how this design could be approached or at least with a tutorial, that is useful, with a non-trivial example?

Thanks

+3  A: 

Swing is not stricly MVC, as the company previously known as Sun openly admits it:

(A traditional MVC separation) didn't work well in practical terms because the view and controller parts of a component required a tight coupling (for example, it was very difficult to write a generic controller that didn't know specifics about the view). So we collapsed these two entities into a single UI (user-interface) object.

For JTree you have TreeModel as, you guess it, model. Some simple components like JLabel don't even have a model.

As the link further explains, you do get certain level of separation with UI classes supplied by LAF. However Swing components themselves have to maintain and control a lot of UI related properties.

Geoffrey Zheng
A: 

Not sure if this will help, but try Swing Application Framework (SAF) (JSR 296). As far as I read or try this, it helps to separate view from event handling. But I'm not so in details with more complex examples (like with JTree)

http://java.sun.com/developer/technicalArticles/javase/swingappfr/

https://appframework.dev.java.net/

Good luck!

Jan Wegner
No, I don't think SAF will help with this particular topic; it doesn't force you into any GUI pattern such as MVC, MVP... In some instances it even encourages spaghetti programming... Moreover, SAF has been dead for a couple of years now...
jfpoilpret
+4  A: 

Still in many cases it is preferable and possible: Of course the controller needs to know about the component, which is responsible for the action, but still the view doesnt need any specific action implementation. You just dont implement the action in a view class, instead you use a controller (which knows about the view and model). So add the action listener there, updating some model details for example, even within a SwingWorker.

In almost every example I saw until know it was implementend like that, I dont see where this is anywhere different with any other component, like a jtree.

Maybe with having a look at the differences between MVC and MVP (which I prefer) its easier to understand: MVC or MVP

ymene
+1 for MVP reference, which I always forget to mention. :)
aperkins
+3  A: 

When I have build larger applications (person years of development), we often abstract the MVC architecture above the individual components to a top level controller/model and view, and accept that the individual components will be their own personalized MVC. GeoffreyZheng is absolutely correct in his assessment, and it is something I have actually loved about developing with the Swing environment. That being said, if you want true MVC, you will probably need to abstract away from individual components and talk about a view in a more abstract terminology.

aperkins
I understand what you are saying. But if I create a controller, model, in the case of JTree, I would have to keep info on where a result produced by an action should be placed in the tree. The controller can pass the result of an action, to my custom model, and the model can fire an event to the view that an update is available. But how can the tree know where to place the new node (or update the existing one)? I do not want to repaint the whole JTree. Only the part that has to change.But this means the model must know about the JTree structure. So this is not a clean separation. Right?
When I am using a JTree to represent something, I am usually storing the information on the back end as a tree as well. This means that I can pass along a few pieces of information - the location, depth, etc. Or, I can use the TreeModel on the back end as part of the model and have it fire the events itself. As long as the view is not directly modifying the model, I do not see a huge problem there. Hope that helps clarify.
aperkins
@perkins:Sorry I lost you in the last part. You store in the model the e.g. DefaultMutableTreeModel of the JTree, and update it using its methods (add,insertNodeInto etc) from the model? In the first part, what structure do you use to store info in the back-end as a tree?
Sorry if I wasn't clear - what I meant was that you can have a tree put into the JTree as a TreeModel (not mutable) but in the model itself it is mutable (same data structure). When the tree model itself changes in your application model, you would then have it send notifications to any TreeModelListeners it had so they would update their views. This way, the view does not ever directly modify the values in the model, but still gets notified in a rather clean way.
aperkins
@aperkins: When you say "you can have a tree put into the JTree as a TreeModel" you mean implement an extension of TreeModel and use that instead of the default tree model? I am sure you are clear. I am not experienced enough with swing to understand you answer. Can you please,if it is not too much effort for you, to explain in a more "analytical" or simple manner so that I fully grasp your answer?
Happy to explain further - you could use a default tree model, or a custom implementation - that is not what is important so much for the discussion. What I am trying to say (somewhat unsuccessfully) is that the JTree itself should not change the data in the tree model, but should fire events that are pushed into your application (or domain) model. Those events are then processed, eventually, to cause changes in the tree model (default or otherwise) that notifies the JTree through it's standard listening mechanism (TreeListener) of the changes.
aperkins
@aperkins: I got it. Thank you very much for your time!
No problem. Glad to help.
aperkins