MVC - referring to "model-view-controller"?
Yeah. IIRC, it's an amalgam of the patterns first mentioned in the very first famous Patterns book...but it's been a long time since I looked!
To be brutally honest, MVC is just the most simple OO approach to building a GUI - it's the way a lazy OO programmer would do it (a more diligent OO programmer would have more than just three aspects). IIRC, the Listener pattern used very widely in Swing and AWT comes from the first source - certainly it works particularly well with MVC GUI's.
Essentially, you make classes whose purpose is:
- "to hold, manage, access: data" (models)
- "to view, format, beautify: data" (views)
- "to alter, manage the alteration of: data" (controllers).
In addition, complex features like skinnable GUI's are much easier to support in MVC. All you do is alter your views to be skinnable; NOTHING else needs to change. Another classic feature that often makes GUI code get horribly unclear and bug-infested is complex feedback on data-manipulation (e.g. verification that you typed in a phone number that ONLY contained digits, or perhaps a popup-dialog that appears when you set a font-size of less than 3 - i.e. unreadable) - these are easily implemented inside Controllers, and easy to maintain if they stay there.
I've always built my GUIs with a minimum required UI first - meaning the least fancy UI that I can get away with and still provide full functionality; then coming back to things when the game is fully working (as far as the engine is concerned) and completing the graphics and other UI components when the game is otherwise finished.
If you have a really good GUI API, then things like layout should be trivial - both to implement and to alter (note: Swing and AWT are not really good, they particularly suck at layout, and BOTH still have several
major bugs I'm aware of in their layout engines).
In this case, you should be able to make a great GUI from the start. Then at the end, when you have beta testers, you make small changes with ease.
So - if you don't do it this way...educate me. Give me the skinny on the MVC model.
IF you use Swing/AWT it doesn't quite work that way. If you use AWT, it works nothing like that way (note: my sole reason for not making any more apps and applets that are 1.1-compatible is that, inadequate as Swing is in many ways, it's also excellent in some fundamental areas, and MUCH better than the AWT).
IME, for most projects you need to create (or beg, borrow, or pay for) some fundamental extensions to Swing to make it "work properly". One of the excellent features of Swing is that it is very extensible (although I can off the top of my head think of two bugs in the Graphics class that have existed in 1.2, 1.3 and 1.4 that mean you have to re-implement some Graphics methods just to get a fully working JComponent class!).
For instance, NEVER use JTable. It is crap. There are actually companies that SELL alternatives to JTable, because it's so crap (and you could do so much better!). Try not to use the JTextXXX classes in java < 1.4, because there are really really major bugs that weren't fixed until 1.4. IIRC, the oldest one even has an API doc suggesting you don't use it - and use the newer alternative instead! (it's the one that tries to behave as similarly as possible to old AWT style TextXXX classes)
For my two most recent games, I "completed" the JLayeredComponent class, which is basically a half-arsed attempt at a GUI component that is missing most of the required functionality. I'm not sure if the programmer at Sun got bored, or if they never meant it to be publically accessed, and only built it to be used by their own internal-frames classes etc. It was about a week's work, all told, but now I have really effective easy-to-use JComponent that you can add additional JComponent's on top of, making it trivial to separate the different theoretical parts of your game into separate rendering classes. And for effectively no performance hit!
When doing this, I used the following main concepts:
- Always make each model an interface
- For each kind of view and controller you create, make an abstract class (normally called a "base class") that implements some or all of an interface (i.e. you might have NO abstract methods)
- Always make your abstract view or controller implement ALL the mouselistener, keyboardlistener etc methods with empty methods
- Put lots of useful methods into the base classes
- wherever you take an M V or C as an argument to a method, code the method to accept the base-class version of that M V or C
Now it's really easy to add new custom GUI components - they get all the benefits of the WindowAdapter, MouseAdapter etc just by extending ONE abstract class.
You can now also have GUI's where most components are instantly interchangeable, because they are supertype-identical, and all code was written to only use methods common to all your M V and Cs.
Finally, I suggest that things like your own "Popup DIalog Editor" are crucial - you write them once (Sun's ones are utter crap) and then you can use them forever more. If anyone would like one, I've got one that I'll giveaway - as long as someone volunteers to start a SourceForge project for it, and is prepared to maintain it. It allows you to create Dialog boxes on the fly with loads of features but is really easy to use, and can even load itself from an XML description - making it even FASTER to change your API.
EDIT: When I talk about making changes at the end of a project, I don't mean rewriting, for example, the rendering code used to represent the world. I mean instead the rearranging of components, or the adding of some extra GUI features (perhaps to make something more accessible). The rendering code I write changes little over the life of the project (so long as it works, that is).
Yeah. ALL the Layout Managers are broken in at least one way. The most commonly used (and most useful, in many ways) BorderLayout is (and always has been) f***ed beyond belief - due to a rather simplistic/lazy implementation that was never improved. I have great sympathy for anyone using them - they ought to be a delight, and instead are a curse. There are even JavaWorld articles dedicated to providing full source for a better layout manager that actually works AND is easy to use...this is pretty tragic. Shrug. If I had the time, I'd make my own Layout Manager, probably one that implemented most of the table-layout features of HTML (I haven't yet found a public domain one that does that). HTML tables do it SO well that Sun should really pull its pants up and just copy it!
All this is, of course, In My (Not So?) Humble Opinion...