
- Home
- Magazine
- Conference & Seminars
- News
- Archives
- Forums
- Store
- Directory
- Editorial
- Advertising
- User/Login
- Contact



Volume Number: 13 (1997)
Issue Number: 11
Column Tag: Getting Started
by Dave Mark , Copyright1997, All Rights Reserved
Three months ago, the August Getting Started column featured a program called VerySimpleText. We built this first version of VerySimpleText using ProjectBuilder and InterfaceBuilder. We started off by editing the nib file (the first version of VerySimpleText wrapped its entire user interface into a single nib file).
We added a Format submenu to the application's default menu, thus adding a series of powerful font, text, and page manipulation features to VerySimpleText. This was done by dragging a Format menu from the menu palette in the palette window.
We also added a scrollable text area (implemented by the NSScrollView class) to the default application window. We did this by dragging a scrollable text view from the DataViews portion of the palette window. We used the NSScrollView inspector to set the autosizing for this view so the scrollable text view grew and shrank along with its containing window. We used InterfaceBuilder's Test Interface feature to test out the window, making sure it looked and behaved as we wanted it to.
Next, we added an info panel (an about box) to VerySimpleText, along with a menu item to bring up the info panel. We edited an existing menu item (Info Panel...) to create our "About VerySimpleText..." item. We used the NSMenuItem inspector to enable the item (unchecking the disabled checkbox, actually). To create the panel itself, we used the Windows portion of the palette window and dragged out our new window, changing the name of the window instance in the nib window and the window's title in the inspector. We also used the palette window to drag some default text into the new info panel.
Once the about panel was built, we created an AboutPanelController class which brought up the about panel when the "About VerySimpleText..." item was selected. Working in the Classes tab within the nib window, we first subclassed NSObject, then created one outlet (abtWindow) and one action (show:). As a reminder, think of an outlet as a variable or object you want associated with your class. When InterfaceBuilder generates the source code for this class, outlets are declared in the header file as type id. An action is a method. In this case, the show: method will bring up the about panel.
Once we were done with our nib file, we told InterfaceBuilder to generate the source files for this project and to add them to the project.
Our next step was to link the "About VerySimpleText..." menu item to the AboutPanelController so when it was selected, the show: method would get called and the panel would appear. First, we instantiated our newly created AboutWindowController class. The instance appeared in the nib window's Instances tab. We then control-dragged from the "About VerySimpleText..." menu item (it's in the menu itself) to the AboutWindowController instance in the nib window. In the inspector window, we clicked the connect button to establish this link. Now, when the "About VerySimpleText..." item is selected, the AboutWindowController's show: method will be called.
Next, we control-dragged from the AboutWindowController instance to our AboutWindow instance. When the link appeared, we moved to the inspector window and clicked on the abtWindow outlet and clicked the Connect button to establish the link. This links the AboutWindowController's abtWindow variable to the AboutWindow. We added a line to the show: method to bring up the window:
- (void)show:(id)sender
{
[abtWindow makeKeyAndOrderFront:self];
}
Before we move on to this month's additions to VerySimpleText, I thought it might be useful to talk about the Model, View, Controller paradigm, described in Discovering OpenStep: A Developer Tutorial. The Model, View, Controller paradigm is also known as MVC. MVC originated with Smalltalk-80. It categorizes objects as either models, views, or controllers.
Models are objects that emulate some process or represent some knowledge-base. For example, an Employee object represents the knowledge or data associated with an employee. It is a model of an employee. A waterworks object might model the process of converting waste water to clean water and might include the data associated with that process. In general, a model object does not have a user interface. A model object may be distributable and persistent. A model class may be reusable and portable.
View objects are the user interface of your application. Anything displayed by your application is displayed in a view. For example, a window, editable, static, or scrolling text area, button, and scroll bar are all examples of view objects. View objects have no special knowledge of the data they display. In OpenStep, the Application Kit contains a complete set of view objects, all of them designed independent of any model objects. As is evidenced by the Application Kit, view objects are reusable.
Controller objects are the mediators between model objects and view objects. Typically, you'll have one controller object per window (or, possibly, a single controller for your entire application). Your controller object communicates between a model object and its representative view object. For example, an employeeController might use data from an employee object and use that data to create a visible representation of that employee within a view object. At the application level, a controller object would take care of tasks such as loading nib files and acting as a delegate for a window or application.
Delegates allow you to provide methods that get called by a class without actually having to subclass the class. Classes which allow delegates feature a set of delegation methods. For example, the NSWindow class features a delegation method called windowWillClose. In this month's sample program, we're going to create a class called Document which will act as an NSWindow delegate. When the NSWindow object gets ready to close, it first calls the delegate's windowWillClose method (assuming the delegate provides such a method). When we define the Document class, we'll provide a windowWillClose method so you can see how this works. You might want to take a look at the NSApplication and NSWindow classes. Their delegation methods are listed at the end of their respective files.
As you've already seen, every application comes with at least one nib file. The nib file is similar to a Macintosh resource file, though it has much more of an object orientation. In fact, one of the primary things stored in a nib file is a set of archived objects. The information in the nib file includes information about each object (like object size and location). It also reflects the position of each object in the overall object hierarchy as well as details about connections between objects in the hierarchy (connections such as the ones we created in the August version of VerySimpleText).
An important part of the object hierarchy is the File's Owner object. Figure 1 shows VerySimpleText's main nib file with the icon representing the File's Owner object in the upper left corner of the Instances tab. The File's Owner sits at the top of each nib file's archived object hierarchy and comes into play when you want to load a nib file other than the main nib file (which is loaded for you automatically).

This line of code:
[NSBundle loadNibNamed:@"NEXTSTEP_Document" owner:self]
loads a nib file named "NEXTSTEP_Document.nib" and sets the File's Owner of the loaded nib file to point to the specified File's Owner. For example, in this month's sample program, we'll define a Document class and we'll tell InterfaceBuilder that the Document class will act as the File's Owner in "NEXTSTEP_Document.nib". Before the nib file can be loaded, we instantiate a Document object. In the Document's init method, we'll call the method loadNibNamed, passing in the nib file name "NEXTSTEP_Document.nib", as well as the object reference self, which refers to the Document object. This second parameter is used as the newly opened nib file's owner.
Hopefully, the quick review above brought you back up to speed on the overall structure of the August version of VerySimpleText and gave you enough background to follow this month's changes. This month, we're going to add the ability to handle multiple documents to VerySimpleText. We'll tie this functionality to the Document menu's New item. You'll want to start off with a copy of the August version of VerySimpleText. Be sure to keep a copy of the original around just in case. I named my original folder VerySimpleText.01 and named the copy VerySimpleText.02. Once you've made your copy, open the ProjectBuilder project in the duplicate.
A new, untitled nib window will appear (See Figure 2). If you click on the Instances tab, you'll see two instances. One is the File's Owner. If you click on the File's Owner icon, the inspector window (attributes popup) will list a set of classes and the NSObject class will be selected. We'll revisit this a bit later in the column.

You'll name your new nib file as NEXTSTEP_Document.nib (you can leave off the .nib if you like). Be sure to save the new nib file in the same directory as the main nib file, NEXTSTEP_VerySimpleText.01.nib (Figure 3).

You will now be in ProjectBuilder.
Go back to InterfaceBuilder.
In the inspector window, the class NSObject will be selected.
Document will now be highlighted when you click on File's Owner.
The MyWindow icon should appear in the new nib window and the window itself should reappear.
You've just connect MyWindow to the File Owner's outlet (in this case, the Document classes' window variable).
You've just made Document MyWindow's delegate.
We are now done with this nib window.
The new Document menu will appear, just to the right of the nextstep menu.
We are now back in ProjectBuilder.
We have just marked AppDelegate as the NSApplication delegate. We won't implement any of the NSApplication delegate methods in our AppDelegate code, but we could. Take a look at NSApplication and take a few of the delegation methods for a spin.
We've just connected the new menu item to the AppDelegate's new: method.
OK. That's it for the nib files. Now all we need to do is add a bit of code and we are on our way.
Here's what the code looks like now:
#import "Document.h" @implementation Document @end
#import "Document.h"
@implementation Document
- init
{
//Find the nib and load it in. This instance will be the
//File's Owner object, so we pass ourself as owner
if (![NSBundle loadNibNamed:
@"NEXTSTEP_Document" owner:self])
{
//for whatever reason, we failed. Clean up and go
NSLog(@"Failed to load Document.nib");
[self release];
return nil;
}
return self;
}
//Since the Document is the Windows's delegate,
//it will get the following
//method called whenever the window closes.
- (void)windowWillClose:(NSNotification *)aNotification
{
//We remove ourself as the delegate as
//we are going to release ourselves
[window setDelegate:nil];
//Let garbage collection do the actual deletion
[self autorelease];
}
@end
Here's what the code looks like now:
#import "AppDelegate.h"
@implementation AppDelegate
- (void)new:(id)sender
{
}
@end
Edit the code so it looks like this:
#import "AppDelegate.h"
@implementation AppDelegate
- (void)new:(id)sender
{
}
@end
Change it to look like this:
#import "AppDelegate.h"
#import "Document.h"
@implementation AppDelegate
- (void)new:(id)sender
{
//Just instantiate a Document. It will know what to do.
[[Document alloc] init];
}
@end
When the application runs, select Document/New to create new windows.
Between delegates, File's Owner, and nib file loading, you've learned a lot this month. Be sure to spend some time looking at NSWindow and NSApplication to get a feel for the power of delegation. This will give you something to chew on until we have releases of Rhapsody and Rhapsody developer tools.




