aspose file tools*
The moose likes Java in General and the fly likes More Model-View-Controller advice needed Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "More Model-View-Controller advice needed" Watch "More Model-View-Controller advice needed" New topic
Author

More Model-View-Controller advice needed

Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Hello. I've been developing a guitar application for a while now. What's really slowing me down is that I still don't fully get the Model-View-Controller pattern. I've read so much on this subject and I think have a good understanding of what a Model or View or Controller is, but I just don't understand how they all get to know about each other when there are mutliple Models, Controllers and Views. I've looked at so many tutorials and each tutorial usually only has one model, view or controller.

Several of the examples I have seen so far have started the program off like this....



Which is what I did. But now my application is growing. I am now adding the ability for the user to edit and save chords. The user can click a button on the View class that opens up an EditChordView. There will also be an EditChordModel, and EditChordController.
The GuitarModel class currently has a ChordManager instance variable. The chordManager class loads the chords from a file stores them in groups by their name, and has a few other functions as well. But the problem is I need my EditChordModel class to have a copy of this as well. So it can load chords the user wants to edit and save them too.

So now I'm thinking I should pass the GuitarModel the ChordManager. But where or when should I pass it. I also need to pass it to the EditChordView but I'm not even sure which class I should create that in? It all has the potential to get very very messy. And it's something I can't just figure out by myself, because I know I could get something that works, but I have no one to tell me if it's considered good programming practice or not.

I'm about ready to beg for someone to help me through this because I can not find examples that deal with these problems.

Any adivce is appreciated.

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

When you need a class that takes care of certain responsibilities, you should ideally give them all the information they need and nothing more.

If your GuitarModel requires a ChordManager, then pass one to it in the constructor. The same goes for your EditChordModel. Maybe you can have a separate class that is responsible for maintaining the current ChordManagers, and you can select the one you want from it, and pass it to the GuitarModels or EditChordModels.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Stephan van Hulst wrote:When you need a class that takes care of certain responsibilities, you should ideally give them all the information they need and nothing more.

If your GuitarModel requires a ChordManager, then pass one to it in the constructor. The same goes for your EditChordModel.



Thank you Stephan for replying. I really do appreciate it. One of the things I'm not sure about because I can't find any examples, is where I should create the extra models and controllers. I would be greatful if you, or anyone, would take a look at this short example below and tell me if that is considered a good way of doing things, because I was thinking of doing something like this.



Obviously this code is just stripped down to the part I need advice on. What do you think of the way the Controller's editChordButton listener creates the editChordModel and editChordController? Also what do you think of the way the ChordManager is passed to the controller just so it can be passed to the EditChordModel? I need them both to have the same object as the class loads from text files and stores in a map. As there will only ever be one ChordManager would it be better practice to just make it's methods static, therefore eliminating all the passing of it from one contstructor to another?

Thank you for any help. Anyone who answers these questions would be really be helping me out a lot!
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
I've been searching all morning for an answer to the other thing about MVC that causes me to be confused. In an article about MVC someone actually asked the question more elegantly than I could so I've just copied and pasted the quote and his question underneath. Unforuntately no one answers his question so I still don't know the answer.



"In our example the model layer includes the Book class. In a real scenario, the model will include all the entities and the classes to persist data into the database, and the classes encapsulating the business logic."

Does this mean that each method that is being required from the Controller has to be implemented in one Model.


I mean if I have a main big Model class it would end up with loads and loads of methods unrelated to each other that delegate to other model classes. For example (i've just wrote this out dead quick, I have not implemented anything that records yet but I do intead to have some kind of automation class.)



Is this something that programmers tend to do with big applications? I can't express in words how much I want this question answered. It's been driving me crazy for a very long time. So if you aren't replying because I haven't explained something very well or if I'm coming across as rude, please let me know and I'll fix it.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3611
    
  14

No absolutely not. MVC is a tool, not a goal.

I have a hard time answering your question, because I don't know what the responsibilities of your classes are.

I usually don't consider persistence part of the model. The model for me is a self-contained module of classes working together to represent the main problem only. Classes dealing with its results, like persistence or graphical user interfaces, should be completely separate.

Let's take a look at a chess game for example. The model would consist of ChessGame, ChessPiece (with Type and Color), Move and hell, maybe an AI (although I would tend to put the latter in its own package).

The view would mainly be taken care of by a ChessPanel class, which registers itself as a listener of a ChessGame, and updates itself when the game changes.

Persistence in this case is pretty simple. You can either create a class with a method that takes a ChessGame and stores it in some way, or let the ChessGame serialize itself. I'm not a fan of Java's serialization mechanism, so I usually take the former approach. A benefit is that instead of storing the game as a stream of raw bytes, you can also store it as a textual representation of the chess game's history, if the game keeps track of that (a separate History class maybe?)

Now, seeing as this is a small example, it's setup is way simpler than a bigger project. If you explain more about what you want your program to do, we can advise you on the buildup of it.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Stephan van Hulst wrote: If you explain more about what you want your program to do, we can advise you on the buildup of it.


Thank you!

ChordPlayer is a virtual guitar. There are strings drawn on the screen which the user can strum by holding down the left mouse button and dragging the mouse over the strings. There will be different modes how the user can play the guitar. In rythm guitar mode the user types in chord names on the keyboard. I have a ChordNameValidator class that kind of acts as predictive text so it finishes the chord name for the user as the user starts typing. There are two chord box diagrams. One is labeled next chord and one current chord. When the user types in a chord name the next chord box diagram displays a visual representation of the chord. When the user presses the space bar the next chord becomes the current chord and when the user drags the mouse over the strings the notes of that chord are sounded. The guitar and chord diagrams are all displayed on the same JPanel at the momement.

I have the above all pretty much working. Although I need to revisit java sound APIi because using Clips is causing problems. But that's not what i'm focusing on right now.

I also intend to have a lead mode where the user can play lead guitar by running the mouse over a string and using the numbers on the keyboard to represent the frets of that string. There will also be different guitars. A clean electric, an acoustic, and a distorted electric. I think this could all be represented in the GuitarModel class.

I also want there to be a transport bar at the bottom of the screen, with record and play buttons. There will different record modes. One record mode might just record the users strumming hand, so when it's played back the user can just concentrate on changing chords. Andother record mode might record the chord changes so the user can concentrate on struming. One might do both so the user can play lead over it. Then then user will be able to open a window to edit these recordings or each recording can be opened to have it's own window. They wont be wav files just data that the user can move about, kind of like how one manipulates midi when using recording software. This is in the future so I haven't thought it through too much. But I thought a Recording object could have a GuitarModel. The recording could fire events to play the notes. To the guitar model it will be the same as if the user was playing the notes.

Let me tell you some of the classes I have so far.

GuitarPlayer: This I already posted and just sets up the model view controller.

View: Draws the guitar strings (one day the gutiar) and draws the nextChordBox and currentChordBox views.

ChordBoxView: This is passed a Chord and draws it.

GuitarModel: So far this class has nextChord and currentChord variables and set and get methods for them. Other methods that deal with that. And play methods that makes sure the right notes are playing.

Cotroller: This contains code to work out how many strings the user has passed with the mouse using a Strum object to help out. It passes an array containing info on which strings were struck to the GuitarModel. It also takes the user input and passes it to ChordNameValidator to calculate the correct chordName. It then passes this name to the GuitarModel method setNextChord.

ChordNameValidator: checks the users text and performs various operations like making sure what the user types is always a chordName.

Chord: Contains chord information like which notes are played and by which fingers.

ChordGroup: Groups chords by name and is stored in a map in the ChordManager class. The reason for needing the group is the user can toggle through different inversions of the chords by pressing the arrow keys, and it remembers the users choice of chord version so the user doesn't have to keep hitting the arrows everytime.

ChordManager: Contains methods for creating chords from text files and adding them to ChordGroups and storing them in a map. Has methods to get the chords, and will later have methods to save new chords.

SoundManager: This loads the correct wav files for the notes. I need to learn how to manipulate sound at a lower level so it will contain a lot of low level sound manipulations.

ChordEditorView: Is a new window with tools to create a chord, and also has another ChordBoxView. The user, for example, clicks the button containing a circle with a number (representing a finger) and places it on the fret they want. This also contains text fields for changing the name or loading the name of an existing chord. It also has a Test button which makes the currentChord in GuitarModel this chord so the user can play it.

ChordEditorController: It takes the users actions and helps edit the chord.

ChordEditorModel: I haven't created this class yet but I should imagine it will help take the users requests for loading or saving chords and passes it to the ChordManager. It may store data like the value of the last button the user pushed so when they click the diagram it adds the correct component to the screen.

That's the basics. Sorry if that was too much info. I know it will be hard to know what the hell I'm talking about. I've tried to make it as clear as I can though.





Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

Neil Cartmell wrote:That's the basics. Sorry if that was too much info. I know it will be hard to know what the hell I'm talking about. I've tried to make it as clear as I can though.

I'm wondering if you're not taking on too much at once. Have you thought about isolating aspects of the problem and dealing with them one at a time?

From what I see, I think I'd be tempted to drop the GUI bit (and the business of recording) altogether for the moment, and simply work on the SoundManager part using text-based messages; maybe with a single Guitar to start with. Get that working and able to play notes and chords any way you want; and then perhaps add a new type of Guitar (electric as opposed to acoustical?). That way, you'll be starting out with 3 or 4 main classes as opposed to 20, and you can concentrate on the job at hand.

Build up the capabilities bit by bit, and make sure that everything is working exactly as you want before you go onto the next stage. Also, make sure you keep all the messages you use for testing, because they're likely to be invaluable when you come to builder your Controller (or Controllers).

Finally (and admittedly I'm biased because I hate GUI coding), plug in the visual side. Hopefully, by then, all the rest of the "plumbing" will be working, so it's simply likely to be a case of (a) getting it working, and (b) sending the right messages at the right time and responding to any replies.

My two-penn'orth, for what it's worth.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Thanks for the reply Winston and I apprecate the input. But I think I may have given the wrong impression. I do tend to work on one thing at a time and what I have so far works great. I do need to go back to learn more about sound API because I want more control then Clip gives me. But if I use the Clip interface I can now play chords and type in names and it all works just as I imagined. And also I agree I'm not bothering with the recording aspect yet, or different guitars. I just mentioned those because I have keep them in mind when I'm designing the structure.

The bit I struggle with is not knowing whether something is considered good programming practice. Mainly because I can't find any MVC examples that have more than one model or controller, (well there were a couple but they were too complicated for me to understand). So I went to add my ChordEditorModel class and I've no idea where convention would have me put it. I know I could get it working dead easy, but trying to find out if it's considered good programming practice is very hard.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

Neil Cartmell wrote:I know I could get it working dead easy, but trying to find out if it's considered good programming practice is very hard.

I think you may be reading too much into it. MVC is just a pattern, like any other, that aims to divide responsibility between the three main aspects of the application, so that they can be worked on independently, and so that changes to one are isolated from the others (that doesn't mean that some changes won't affect all of them, but these are likely to be changes to the requirements of the system as a whole).

The classic example is persistence (and while I'm generally with Stephan in not including it as part of the working design, it may well become important):
If you design it with no particular target in mind, you may still come up with some sort of Database interface. That doesn't mean that you have to save your data in a database, simply that all your 'save' operations go through a Database object. So:
database.save(Guitar);
might initially just serialize a Guitar object to a local file. Later, when you go public, you might want to change the method to one (or, maybe even better, add a whole new Database-compliant class) that saves the Guitar to a database table; but as far as your application is concerned, it's still database.save(Guitar).

It's called 'indirection' (and there's a very famous quote about it) and it works exactly the same with MVC. As long as you're thinking about all three things whenever you add a major new class or component - and for now I wouldn't worry about multiple occurrences of M, V or C (*Edit) - I doubt you'll go very far wrong.

Winston

(*Edit)
PS: It occurred to me that you might be confusing multiple 'Model' classes with multiple Models; they're not (or not generally, anyway). They're all regarded as part of the same Model, and are often in same package too. Major components (as, in your case, a Guitar) may well have a 'triad' of classes; one for each part of the system.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Winston Gutkowski wrote:
PS: It occurred to me that you might be confusing multiple 'Model' classes with multiple Models; they're not (or not generally, anyway). They're all regarded as part of the same Model, and are often in same package too. Major components (as, in your case, a Guitar) may well have a 'triad' of classes; one for each part of the system.


Yes I think this was part of the confusion. I see model written and it's always written as if there is some Model class that contains all the other models, and I was confused as how that should work. All the examples I am seeing set up the controller and view with one model class, and I'm left wondering is it ok to make the controller create the other model classes or do I pass multiple model classes into the controller.

Maybe I just need write it and see what happens. I've only been programming for less than two years and for six or seven months this year I didn't do an programming at all. I think I need to convince myself that It's ok to not write perfect code and just enjoy it. Plus by making mistakes I will learn from them and see the reasons people use certain design patterns will become clear.

Thanks for taking the time to help.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

Neil Cartmell wrote:Yes I think this was part of the confusion. I see model written and it's always written as if there is some Model class that contains all the other models, and I was confused as how that should work. All the examples I am seeing set up the controller and view with one model class, and I'm left wondering is it ok to make the controller create the other model classes or do I pass multiple model classes into the controller.

It's quite possible that you may have a single class for managing each part of the M, V and C; but trying to keep all the various components in a single class would be a nightmare.

As to having the Controller create Model classes directly: I'd advise against it. Far better that it sends a request to the Model (maybe 'Model Manager' is a better term) to say "give me a GuitarModel object" (division of responsibility again). However, going back to this 'triad' idea; it's quite possible that a Guitar may have a Controller class as well, that knows eg, what to do when it's asked to play a chord (ie, what messages to send to its Model class, what things to send back to the View, etc), and there's no reason why a Controller shouldn't be able to set up a GuitarControl class itself.
The general idea is that, after a bit of initialization, these component-related triads can actually do a lot of work between themselves without having to constantly go back to the "manager".

BTW, just a small point about naming. My preference is to call the Model class by its normal name - ie, 'Guitar', rather than 'GuitarModel' - because it's the "guts" of the component. Without it, the V and C portions wouldn't exist, so essentially they're just aspects of the Model class. However, this probably reflects my bias as an old DBA, and there may well be other naming conventions around for MVC, so don't just take my word for it.

Finally, as to passing bunches of objects around: it's quite common practise. Java has a raft of very useful collections you can use; or you may want to create your own named sets for specific tasks; I suspect you'll work this out for yourself as you get down to the "doing".

One thing you might want to consider, though, are marker interfaces for your classes (ModelObject, ControlObject and ViewObject?) that "classify" the type of object you're looking at.
These interfaces usually have no methods (although there's no reason why they shouldn't) and are simply used to 'mark' an object as belonging to a particular group. For example, your Guitar class (assuming its part of the Model), would have:
  public class Guitar implements ModelObject .... {

as part of its definition. The nice thing about this is that you can then check what type an object is, viz:
  if (thisObject instanceof ModelObject)...

and with generics you can write methods that take collections of ModelObjects:
  public someMethod(Collection<? extends ModelObject> modelStuff) { ...

Just be careful that you don't start writing a lot of "dispatch" code around them; because that would be bad practise .

That's about all I can think of at the moment. Best of luck with your project.

Winston
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
Neil Cartmell wrote:All the examples I am seeing set up the controller and view with one model class, and I'm left wondering is it ok to make the controller create the other model classes or do I pass multiple model classes into the controller.

Better to pass the view and model into the controller's constructor, and better still to pass them as Interfaces. That gives you clean separation between the design elements. There's nothing wrong with multiple models, just be sure they are truly performing different functions.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Thanks. A lot of useful information but I'm still not quite getting it. Well, I still feel like I'm missing a piece of knowledge that I need to know. Sorry to be a pain. I've searched all day looking for well written code that uses MVC that hasn't just got one class for it's model and I have had no luck. It's kind of like trying to write a song without ever having heard a piece of music before; what you would end up with is not something that obays conventional pop song rules!

How about this:

Say there was a program similar to mine but as well as being able to play the guitar, there was also a metronome. So there was a JFrame with a JPanel that drew the guitar strings that the user could interact with the guitar and still use the keyboard to interact with the guitar. And there was a JPanel at the bottom of the JFrame that had the metronome buttons like, start, stop , speed up. Imagine both these hade a lot of different capabilities so their classes would be pretty huge.

Although in the same program, would the metronome model be separate from the guitar model? Would there be a controller just for the guitar, and one for the metronome? What if there was another view which allowed the user to edit chords, would that need another controller? Would someone please be kind of enough to write out in code how you would instantiate all these objects so the appropriate objects new about each other and show me how the program would start up. In the most conventional way possible? Just the basic constructor calls and classes. Even if it's just pseudocode. I feel if somone did this I that would be all I need to know and I could finally move on. Also I think an examle like that would help other people searching MVC here.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

Neil Cartmell wrote:Thanks. A lot of useful information but I'm still not quite getting it...

You know what? I'd say, for the moment, forget it. Trying to assimilate all this new knowledge while also trying to design a system is likely to do your head in; and it'll probably lead to a well-known phenomenon called "development paralysis".

Go back to basics: what is this system supposed to do? Why are you writing it? What are the components? For example: What is a Guitar? What does it have? (Strings? Fret? Tuning knobs? Wow-handle (I have no idea of my terminology here )) What does it do?...or, more specifically, what do you need to be able to tell it to do. And Dennis is quite right: think about making it an interface - or at least making an interface for it as soon as you've written the class - and have your methods pass the interface around.

If you get that right, the refactoring for MVC should be fairly straighforward. Just remember that a Guitar is NOT what you see on the screen (although there's nothing wrong with thinking about how it might look). You could almost certainly make one that works from the command line, or from a basic tester class; and if I was doing it, that's probably the way I'd start (but then I hate GUI programming). The other nice thing about doing it that way is that you're already separating the View from the Model.

And like I said before: to start with, keep your requirements simple. Do it, get it working, and then move on to the next stage.

HIH

Winston

BTW, an MVC example that's anything more than trivial is likely to take up lots of space, so I wouldn't hold your breath.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Well after hours and hours of trying to find out what object is supposed to create what other object in MVC I saw this posted in a comment.

"I think the controller is supposed to choose the correct model and give it to the view. "

"I agree with Yogler, the controller sets up the models needed then passes them onto the view regardless of how many there are. "

That's good enough for me; the word Model that ends with 's'. My application controller will now set up the various models. That's all I needed, or wanted to know. And if someone comes along and says "no no no you should never do that" I will likely walk away from design patterns forever because there seems to be some rule that stops any object from creating another or knowing about another but never a straight forward answer to what should be done instead.

I already have the GUI up and running and it works great. It doesn't make sense to me to go back to the command prompt. The GUI was such a big part of the program, the very first thing I did was draw 6 lines on the screen to represent strings and to make sure it could tell when the mouse passed over them. And then I made sure that when I changed chord with the keyboard the guitar knew what string with what fret had been hit, therefore determining the note. Now my applicaton draws the chords nicely. You can edit the chords. You can link up the edited chord with the current chord of the guitar so you can play it. I just need to add lead guitar functions and automation and I'm done. (for version 1 anyway) With automation the user will be able to strum and then play back the strum so they can concentrate on just the chords, therefore people with only one arm or have lost fingers will be able to write songs for guitar, which was why I originally wanted to write this program in the first place.

I appreciate all the help and hope I don't comes across as ungrateful but the answers I was looking for seem so simple. I just needed a starting point, a basic example on how to set up a program with multiple vies, controllers or models. Trying to learn from forums never seems to work out for me. Maybe it's the way I ask the questions. But that's me done with posting topics asking for help. Hopefully I will be at a stage where I can help others one day but until then...

Rant over.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

Neil Cartmell wrote:"I think the controller is supposed to choose the correct model and give it to the view. "

What did I say before? Translator/Butler.

I appreciate all the help and hope I don't comes across as ungrateful but the answers I was looking for seem so simple. I just needed a starting point, a basic example on how to set up a program with multiple vies, controllers or models...

Glad you found it; and best of luck.

Winston
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
Neil Cartmell wrote:Well after hours and hours of trying to find out what object is supposed to create what other object in MVC I saw this posted in a comment.

"I think the controller is supposed to choose the correct model and give it to the view. "

"I agree with Yogler, the controller sets up the models needed then passes them onto the view regardless of how many there are. "

That's good enough for me; the word Model that ends with 's'. My application controller will now set up the various models. That's all I needed, or wanted to know. And if someone comes along and says "no no no you should never do that" I will likely walk away from design patterns forever because there seems to be some rule that stops any object from creating another or knowing about another but never a straight forward answer to what should be done instead.


Well look: no one is forcing you to use MVC or any other design pattern. You can get things done without them. Design patterns aren't rules, they are simply solutions that have been found to be useful over and over. If you decide to use a design pattern, it should be because you recognize in it a solution to a problem you face in your application.

Your first few posts seem to show a grasp of the pattern. I don't understand why you got so frustrated so quickly. It's less than 3 days since then.

There are a lot of different ways of accomplishing something. So I try not be the one to say "no no no you should never do that". Instead I try to simply say what I would do in a similar situation, and try to articulate why. The goal with MVC is to try to prevent our program's logic from being dependent on the UI code, and vice versa. So we have a view piece and a model piece, and we try not to give them knowledge of each other. We put the controller between them to make things happen. My preferred way to think of a controller is as a switchboard operator. She'll patch through communications between the view and the model. Can our switchboard operator handle multiple calls between multiple sources? Sure. She just needs to know where to patch the connection. When some user action happened in the EditChordView, the controller would know to patch that to the EditChordModel and not some other model. When some user action happened in the GuitarView, the controller would know to patch that to the GuitarModel and not some other model.

Well after hours and hours of trying to find out what object is supposed to create what other object in MVC I saw this posted in a comment.

I thought your first couple of examples were just fine. What worried you about them? Whenever I have used MVC, some higher-level class created the Model and the View and then passed them into the constructor of the Controller.

Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Dennis Deems wrote:
I thought your first couple of examples were just fine. What worried you about them? Whenever I have used MVC, some higher-level class created the Model and the View and then passed them into the constructor of the Controller.



That worked fine when there was just the one model class. But when I had the EditChord class I started thinking how do I set that up, and I wondered if I should pass the controller the guitarModel, AND the editChord class, or does the controller make the EditChord class. Then I got to thinking about all the things I want my program to eventually do. It will have a class that's in charge of recording/ automation, and probably a metronome class as well. I wasn't sure if it was considered ok for the controller to make all these objects or do I have to pass them all into the Controller constructor from the main method. The main method would get pretty busy with all of the creating each other and I wasn't sure if that would be considered unprofessional.

I've got the editChord class working. I create it in the controller and it doesn't look like spaghetti code to my untrained eye, but I'm just trying to make sure I do things right.

I'm sorry for getting frustrated. I never get frustrated over bugs or creating methods; so far those are easy to figure out myself because I know I've got it right or it wouldn't work. Whether creatings severeal models and passing them to the controller is right, I have no way of finding out exept by google or forums.
Neil Cartmell
Ranch Hand

Joined: Feb 13, 2010
Posts: 150
Oh and thanks Dennis, that really did make things seem a little clearer.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: More Model-View-Controller advice needed