Re: Clear as Mud
Re: Clear as Mud
- Subject: Re: Clear as Mud
- From: Charles Jolley <email@hidden>
- Date: Tue, 21 Aug 2001 00:22:00 -0500
>
When the program is launched only the Main Menu comes up, ala Project
>
Builder, which is to say there is no main window and therefor no main
>
window controller. Three custom menu items under "file" are "Open
>
Records," "Open Parameters," and "Run." In addition to the
>
MainMenu.nib, there are three other Nibs: "RecordController.nib,"
>
ParametersController.nib," and RunController.nib." RecordController
>
nib and related files take data from text fields and create a
>
MutableArray of records; ParametersController nib and related files
>
take data from a bunch of labeled sliders and keep the setting in a
>
Dictionary; RunController nib and related files display a window that
>
shows the progress of the "Run" when a Button is pushed. All sorts of
>
tricky logic stuff on the Model side, most of which I have figured out,
>
although much fine-tuning needs to be done over the coming months.
>
>
So, what is the best scheme for connecting these menu items so that the
>
respective windows get unarchived and opened up? Where are the
>
IBOutlets declared and implemented? Any other mojo needed?
>
Ok, I will not claim that the following method is the best or the most
official, but it is simple and extensible and those trump all for me.
There are many variations on what I will describe that will likely be
more efficient; I have chosen the means I am describing to make it
easier to understand. We can discuss efficiencies more one the basic
technique is understood.
To make things a little clearer, I am calling the windows you are trying
to create with your nib files "Editors". Thus, when I say record
editor, I an referring to your Record window along with the nib file and
controller classes that make that editor window dance.
1. Create Editor Controllers
The first thing you need to do is to create controller classes for each
nib file. The purpose of the controller class is to link all the user
interface work in your nib file to the logic in your application. Thus,
when the controller class is instantiated, it will load the nib file and
set everything up. You can (and probably should) also use this same
class to tie in the controls in your nib file. I will focus only on how
to get everything setup.
Let's take the RecordController as an example. Your RecordController
nib should have the controller class (let's call it MyRecordController)
as its File Owner. The initialization code of this controller should
include the lines to load the nib file. Since your class is the file's
owner, the -awakeFromNib method will be called once the nib file has
been initialized, where you can complete any setup you need to:
@implementation MyRecordController
- (id)init {
if (self = [super init]) {
... other init stuff ...
[NSBundle loadNibNamed: @"RecordController" owner: self] ;
...
}
return self ;
}
-(void)awakeFromNib
{
// objects in the nib are not unarchived and you can perform
further setup if you want to.
}
2. Create the Editor Manager
The next step is to create a controller class that will exist in your
MainMenu nib and will be responsible for instantiating all the other
controllers. There will only be one of these in your application, a
specialized role I typically call a manager in my code. So let's call
this class MyEditorManager, since it will manage the creation of your
editors. This class will have three action methods that each
instantiate one of your editors:
@interface MyEditorManager : NSObject
- (IBAction)newRecordEditor: (id)sender ;
- (IBAction)newParameterEditor: (id)sender ;
- (IBAction)newRunWindow: (id)sender ;
@end
The implementations all look similar, so I will show only one as an
example:
- (IBAction)newRecordEditor: (id)sender
{
[[MyRecordController alloc] init] ;
}
Now, of course, you would probably make your initialization a little bit
more sophisticated that this to tie your controller object to your model
objects. This is a separate topic for discussion.
3. Connect the Editor Manager to the Main Menu
Ok, last step. In your MainMenu nib create an instance of
MyEditorManager. This is the ONLY instance of this object that will
exist in your application. Create your menu items. Control-drag from
each menu item to the MyEditorManager instance and connect to the
appropriate action. For example, the "New Record" menu item would be
connected to the -newRecordEditor: action.
Viola. Run the program and here is what happens:
1. The MainMenu nib is loaded, creating an instance of MyEditorManager.
2. You select the "New Record" menu, which invokes MyEditorManager's
-newRecordEditor: action.
3. The -newRecordEditor: action creates a new instance of
MyRecordController.
4. During initialization, the MyRecordController instance loads the
RecordController nib.
----
When you are trying to connect this to your data model, the process is
fairly simple:
1. MyEditorManager should know about your data model (let's say it has a
reference it the data model object)
2. When MyEditorManager instantiates a controller, it should inform the
controller about the data model. For example, your initialization
method might be something like -initWithModel: (id)myModelObject.
3. The Controller object should handle the process of connecting the
user interface controls in your nib to your model.
-----
One last note, if you are using Cocoa's mutiple document architecture,
then the process I have described changed, but only slightly. If that
is relevant to your application design, let me know and I will go into
it. This e-mail is too long as it is!
I hope I have explained this process well enough for you to understand
it. It really is quite simple once it is understood; and it is very
powerful! With this approach, it is VERY easy to add new feature at a
later time, building them independently of one another. A program I am
currently working on has a dozen or more nibs for each document window
because the entire architecture is built on a plug-in system, using a
model similar to the one I just described, that will allow easy
expansion even after the application is released!
I hope this helps.
Cheers,
-Charles