MVC - Organizing models and managing GUI windows
I'm having difficulty organizing my MVC models and basically controlling the whole application in general. My application works, but all the controlling logic is being dumped into the main class (Main.java). Here's a simple example of the problem I'm having:
Objectives
1) Display a list ofCompanies; i.e. Sun, Microsoft, Adobe, etc. (JFrame with a JList)
2) The user select aCompany and it pops up a new dialog with a list ofEmployees. (JDialog with a JList)
Here are the classes I came up with:
Models:
1) CompanyListModel
2) EmployeeListModel
Listeners:
1) CompanyListener
Views:
1) CompanyListFrame
2) EmployeeListDialog
Domain Objects:
1) Company
2) Employee
And then there's the main application class. To implement the above objective, I've been using my main class to control the GUI.
Here's an example of how I've implemented it.
publicclass Mainimplements CompanyListener{
/** Creates a new instance of Main */
public Main(){
CompanyListModel companyModel =new CompanyListModel();
companyModel.addCompanyListener(this);
CompanyListFrame gui =new CompanyListFrame(companyModel);
}
// A company was selected. Open a new dialog and display the employees
publicvoid companySelected(CompanyModel companyModel){
Company company = companyModel.getCompany();
EmployeeListModel employeeModel =new EmployeeListModel(company));
EmployeeListDialog =new EmployeeListDialog(employeeModel);
}
publicstaticvoid main(String[] args){
new Main();
}
}
My program is similiar design wise to the above, but contains many more classes. I'm still using my main class to control GUI logic (popping up new windows and creating models, etc). Thus, my main class implements like 5 different listeners. I'm sure this is a really poor design choice, I just don't know how else to implement it.
I should not nest models... correct? I was thinking about nesting the models, i.e. CompanyListModel contains an EmployeeListModel, but then the CompanyListModel will need to spawn the EmployeeListDialog when a Company is selected, right? Thus, I'd be mixing the view with the model.
Please provide some advice! :( Thanks!
[3151 byte] By [
Techniquea] at [2007-10-3 4:34:33]

> I'm having difficulty organizing my MVC models and
> basically controlling the whole application in
> general. My application works, but all the
> controlling logic is being dumped into the main class
> (Main.java).
Main? Why aren't you putting that into controller objects?
Don't you think of the Listeners for your Swing components as part of the controller?
> Here's a simple example of the problem
> I'm having:
>
> Objectives
>
> 1) Display a list of Companies; i.e. Sun,
> Microsoft, Adobe, etc. (JFrame with a JList)
>
> 2) The user select a Company and it pops up a
> new dialog with a list of Employees. (JDialog
> with a JList)
>
> Here are the classes I came up with:
>
> Models:
> 1) CompanyListModel
> 2) EmployeeListModel
>
> Listeners:
> 1) CompanyListener
I don't think you need a Listener for Company. You need Listeners for Swing UI events.
> Views:
> 1) CompanyListFrame
The Frame isn't the important, reusable thing here. I think it should be a JPanel. You can see how that would be reusable in other contexts. The JFrame that carries it is a commodity.
> 2) EmployeeListDialog
Same as above.
> Domain Objects:
> 1) Company
> 2) Employee
>
>
> And then there's the main application class. To
> implement the above objective, I've been using my
> main class to control the GUI.
That's all it should do. It should create the Controller. That's it. All the rest of the work is done by other classes.
>
> Here's an example of how I've implemented it.
>
> > public class Main implements CompanyListener {
>
> /** Creates a new instance of Main */
>public Main() {
> CompanyListModel companyModel = new
> CompanyListModel();
> companyModel.addCompanyListener(this);
> CompanyListFrame gui = new
> CompanyListFrame(companyModel);
>}
>
> // A company was selected. Open a new dialog and
> display the employees
> public void companySelected(CompanyModel
> companyModel) {
>Company company = companyModel.getCompany();
> EmployeeListModel employeeModel = new
> EmployeeListModel(company));
> EmployeeListDialog = new
> EmployeeListDialog(employeeModel);
>}
>
>public static void main(String[] args) {
>new Main();
>
> }
>
>
> My program is similiar design wise to the above, but
> contains many more classes. I'm still using my main
> class to control GUI logic (popping up new windows
> and creating models, etc). Thus, my main class
> implements like 5 different listeners. I'm sure this
> is a really poor design choice, I just don't know how
> else to implement it.
Is the number of listeners what's bothering you? Why? If you need that many, then create them. Just don't have Main doing it.
I see the Controller creating them when it creates the UI and passing them along. The UI now communicates with the Controller, which interacts with Model objects to accomplish tasks requested by the user.
> I should not nest models... correct?
Why not? If the problem calls for a HAS-A relationship (e.g., "Company HAS-A list of Employees") by all means build it into the object.
> I was thinking
> about nesting the models, i.e. CompanyListModel
> contains an EmployeeListModel, but then the
> CompanyListModel will need to spawn the
> EmployeeListDialog when a Company is selected, right?
Models don't create UIs. Controllers do. Models don't have to know anything about how they are displayed. Today it's a Swing UI, tomorrow it's a web browser - the Model doesn't change.
> Thus, I'd be mixing the view with the model.
> Please provide some advice! :( Thanks!
Take mine for what it's worth.
%
I'm sorry, I read your reply about 3 times and I've spent the last 20 minutes trying to implement it. I'm just not sure how the controllers are involved. Could you possibly provide source code for the controllers (and any part of the models / views that communicate with the controller)?
I feel like this is a wasted effort. I'm the sole entry level programmer at my company and I have only one year real wold experience . I work with about 10 other senior level (microsoft) programmers and none of them code in this fashion. All of our applications are desktop applications using C#, C/C++, or scripting languages.
I feel like if I worked on a project with one of them, they would criticize me for using MVC and "complicating" such a simple issue.
In trying to implement this solution, my workspace now has a huge load of classes for something so simple:
Company
CompanyFrame
CompanyListController
CompanyListListener
CompanyListModel
CompanyListPanel
Employee
EmployeeListDialog
EmployeeListModel
EmployeeListPanel
Main
11 classes and I left out the Emp Controller and Listener to simplify the example. The more classes that you have, the slower the application startup time. Moving the Views to JPanels as you suggested seemed smart but it wound up making it more difficult. I'm using NetBeans and Matisse and I don't believe you can use another JPanel class in the GUI editor unless you make it a bean.
Traditionally, I would have implemented as follows. I would have completed it in 5 minutes and it would be much easier to understand what's going on:
Company
CompanyFrame - contains a list of companies
Employee
EmployeeListDialog - contains a list of employees
Main
Of course doing it this way I'd be mixing data with the view, but is that always a bad thing or is it only bad for large scale applications? Should MVC not be used for small modules like this?
The reasons why I'm going away from my old "academic" programming practices is:
1) I want to become a better programmer of course!
2) There's alot of database queries in this application so I wanted to separate that from the GUI as much as possible. Thus, each model knows how to query the database and it's all done on separate threads.
I'd really like to do this right. If you could provide source that would be great. Also, are there any good books on desktop GUI development geared towards Java (or even C#)?
I already purchased the e-book Desktop Java Live, which is great but they don't go into detail about MVC and instead use Model-Presenter which has been retired (according to Fowlers website). I found that section fairly confusing so I figured I'd start with MVC since it's more widespread (?).
Thank you.
> I'm sorry, I read your reply about 3 times and I've
> spent the last 20 minutes trying to implement it.
> I'm just not sure how the controllers are involved.
> Could you possibly provide source code for the
> controllers (and any part of the models / views that
> communicate with the controller)?
No source code. Read about the MVC pattern.
> I feel like this is a wasted effort. I'm the sole
> entry level programmer at my company and I have only
> one year real wold experience . I work with about 10
> other senior level (microsoft) programmers and none
> of them code in this fashion. All of our
> applications are desktop applications using C#,
> C/C++, or scripting languages.
What's a wasted effort? You posting a question? Me posting a response? You writing Java? You trying to think about how to do this properly?
So why are you using Java if you're in a Microsoft shop? How's this working out with your co-workers?
> I feel like if I worked on a project with one of
> them, they would criticize me for using MVC and
> "complicating" such a simple issue.
That's usually because Microsoft likes tying a particular text box to a column in a table. If you change the textbox value you change the database. Nice and easy, right?
> In trying to implement this solution, my workspace
> now has a huge load of classes for something so
> simple:
>
> Company
> CompanyFrame
> CompanyListController
> CompanyListListener
> CompanyListModel
> CompanyListPanel
> Employee
> EmployeeListDialog
> EmployeeListModel
> EmployeeListPanel
> Main
>
> 11 classes and I left out the Emp Controller and
> Listener to simplify the example. The more classes
> that you have, the slower the application startup
> time. Moving the Views to JPanels as you suggested
> seemed smart but it wound up making it more
> difficult. I'm using NetBeans and Matisse and I
> don't believe you can use another JPanel class in the
> GUI editor unless you make it a bean.
>
> Traditionally, I would have implemented as follows.
> I would have completed it in 5 minutes and it would
> be much easier to understand what's going on:
>
> Company
> CompanyFrame - contains a list of companies
> Employee
> EmployeeListDialog - contains a list of employees
> Main
>
> Of course doing it this way I'd be mixing data with
> the view, but is that always a bad thing or is it
> only bad for large scale applications? Should MVC
> not be used for small modules like this?
For small modules that are nothing more the CRUD operations, it might be that a simpler approach is fine. (PS - CRUD stands for Create/Read/Update/Delete, standard relational operations on tables. I'm not commenting on you or your code.)
It only becomes a problem when that "simple" CRUD application decides to branch into something bigger. The approach of mingling view and data can become problematic then.
It's still possible to have a clean application for small apps. I think most Microsoft programmers do it that way because the wizards and stuff they're used only allow it to be done that way.
> The reasons why I'm going away from my old "academic"
> programming practices is:
> 1) I want to become a better programmer of course!
Kudos to you. At least you're still thinking about it.
> 2) There's alot of database queries in this
> application so I wanted to separate that from the GUI
> as much as possible. Thus, each model knows how to
> query the database and it's all done on separate
> threads.
That's good motivation, too.
> I'd really like to do this right. If you could
> provide source that would be great. Also, are there
> any good books on desktop GUI development geared
> towards Java (or even C#)?
I don't write for the desktop, so I'm not much help.
> I already purchased the e-book Desktop Java Live,
> which is great but they don't go into detail about
> MVC and instead use Model-Presenter which has been
> retired (according to Fowlers website). I found that
> section fairly confusing so I figured I'd start with
> MVC since it's more widespread (?).
If you're reading Martin Fowler you're doing well.
> Thank you.
I'm sorry that I'm not more helpful.
%
I've read about MVC of course, or I wouldn't have made it this far.
But most websites approach it very differently (i.e. some leave out the controller completely), others use a circular view M -> V -> C-> M, and then others describe interaction between the model and view soley through the controller.
I'm looking for something that goes beyond the simple "hello world" example where there's only one model with a few views.
>If you're reading Martin Fowler you're doing well.
Reading and learning are two different things. Fowler's website isn't very newbie friendly.
> But most websites approach it very differently (i.e.
> some leave out the controller completely),
I think you'll find the MVC idea more fully fleshed out for web apps. If you look at web MVC frameworks like Struts and Spring MVC, controller will be very easy to find.
It's less identifiable for desktop apps, which is what you're writing. It's still not hard to figure out. The model is your domain objects. The view are the panels in your Swing UI. What's left? The controller.
> others use
> a circular view M -> V -> C-> M, and then others
> describe interaction between the model and view soley
> through the controller.
Sometimes the view will know about model so it can display state, but it's read-only access.All requests to change model state must go through the controller.
> I'm looking for something that goes beyond the simple
> "hello world" example where there's only one model
> with a few views.
One excellent source for design ideas is Spring. I'm finding their view of the world to be very influential. There's a Spring rich client project that uses Swing. Maybe that would be worth a look.
> Reading and learning are two different things.
> Fowler's website isn't very newbie friendly.
Fowler is advanced. He's not writing for the beginner. You need some context to understand what he's getting at. But keep reading, coding and thinking - that's how you'll figure it out.
I'll give your model a look and see what inspires me.
%
I've been thinking about your question and the comments from your Microsoft co-workers: "Why is Java so complex?" It's a valid question. I think the rise of Ruby and such is a response to Java EE's complexity. People see how quickly developers in .NET and Ruby can pump out database-driven web apps and wonder why Java EE can't do the same.
My answer is that it can.
The thing that Microsoft .NET and Ruby have going for them is taking choices out of the hands of the developer. There are constraints, built-in helpers, and wizards for code generation that are tailored to hit the sweet spot for table-driven web apps. There's nothing preventing Java EE from doing as well.
You'll notice there are a lot of Java EE web MVC frameworks out there (e.g.,Struts, Java Server Faces, etc.) They all want to make it easier to pump out web apps. I think these are a good thing, but they aren't the whole story.
Enterprise systems using object-oriented techniques need to be about far more than just reaching into a table, pulling out data, manipulating it, and putting it back. When systems grow beyond the small prototype stage they have to worry about lots of other things. That's where the complexity really lies.
My experience is that writing code that's too tied to tables and going after columns in a very granular way isn't very scalable. It tends to turn into a lot of inelegant, procedural code that's hard to maintain as it grows.
Spending time on a good object model is likely to mean a larger number of fine-grained classes. If you layer it properly, you'll find that a lot of objects participate into doing something that on the face of it "should be simple". You'll hear people who like that procedural style objecting by saying, "Can't I just query for that column and get on with it? Why do I need all these objects?"
Don't confuse a small number of objects with simplicity. I think it's a more procedural coding style that won't scale with time.
If you know that the app will always be a CRUD-driven web app, by all means write in using the fastest, best techniques you can think of. But how often is it that the quick prototype turns into a long-lived enterprise app?
Just some rambling thoughts. Do with them what you wish.
%
