Cocoa Programming for Mac OS X - Aaron Hillegass [65]
The objects on the Preferences panel will be connected to the preference controller. In particular, the preference controller will be the target of a color well and the check box. The Preferences panel will appear when the user clicks on the Preferences... menu item. When running, it will look like Figure 12.1.
Figure 12.1. Completed Application
Figure 12.2 presents a diagram of the objects that you will create and the NIB files in which they will reside.
Figure 12.2. Object/NIB Diagram
We will start by creating PreferenceController; this will allow us to take advantage of Xcode’s code completion later. Open the RaiseMan project, choose New -> New File... from the File menu, and create a new Objective-C class file that is a subclass of NSWindowController. Name the subclass PreferenceController. Edit PreferenceController.h to look like this:
#import @interface PreferenceController : NSWindowController { IBOutlet NSColorWell *colorWell; IBOutlet NSButton *checkbox; } - (IBAction)changeBackgroundColor:(id)sender; - (IBAction)changeNewEmptyDoc:(id)sender; @end Next, create a new subclass of NSObject called AppController. Edit AppController.h to look like this: #import @class PreferenceController; @interface AppController : NSObject { PreferenceController *preferenceController; } - (IBAction)showPreferencePanel:(id)sender; @end Note the Objective-C syntax: @class PreferenceController; This tells the compiler that there is a class PreferenceController. You can then make the following declaration without importing the header file for PreferenceController: PreferenceController *preferenceController; You could replace @class PreferenceController; with #import "PreferenceController.h". This statement would import the header, and the compiler would learn that PreferenceController was a class. Because the import command requires the compiler to parse more files, @class will often result in faster builds. Note that you must always import the superclass’s header file, because the compiler needs to know which instance variables are declared in the superclass. In this case, NSObject.h is imported by Foundation/Foundation.h. Setting Up the Menu Item Figure 12.3. Create an Instance of AppController Within the Interface Builder editor, click the application menu item RaiseMan. Control-drag from the Preferences... menu item to the AppController. Make it the target and set the action to showPreferencePanel: (Figure 12.4). Figure 12.4. Set the Target of the Menu Item AppController.m #import "AppController.h" #import "PreferenceController.h" @implementation AppController - (IBAction)showPreferencePanel:(id)sender { // Is preferenceController nil? if (!preferenceController) { preferenceController = [[PreferenceController alloc] init]; } NSLog(@"showing %@", preferenceController); [preferenceController showWindow:self]; } @end Note that this code creates the instance of PreferenceController only once. If the preferenceController variable is non-nil, it simply sends the message showWindow: to the existing instance. Note also that we import PreferenceController.h into the .m file that uses it. Preferences.xib Figure 12.5. Create an Empty XIB File Click on Preferences.xib to open it in the editor. Bring up the Identity Inspector, select File’s Owner, and set its class to PreferenceController (Figure 12.6). Figure 12.6. Set File’s Owner to Be a PreferenceController File’s Owner When a NIB file is loaded into an application that has been
Open MainMenu.xib. Drag an NSObject from the Library (under Objects & Controllers) to the dock. In the Identity Inspector, set its class to AppController (Figure 12.3).
Now you need to write the code for AppController. Make the contents of AppController.m look like this:
In Xcode, create a new empty XIB file named Preferences.xib (Figure 12.5).