Adding a Preferences Window to Your Application09/17/2001
Up to this point our applications have been single window applications (SimpleTextEditor was actually a multi-window application by virtue of it being document-based. In that situation, the machinery of the document-based application took care of handling multiple windows).
The focus of this article will be to add a Preferences window to the Address Book application, which is a staple of any application. This preferences window will allow the user of Address Book to select which columns he wishes to be displayed in the table.
We've got a lot of ground to cover in this column, so without further ado, we commence.
Interface Builder! Once again!
Before things get too busy here, we're going to get the essential task of building the preference window interface out of the way. Since we've built many interfaces already in this series of columns, I am going to give only a minimum of direction on constructing the Preferences panel, with particular emphasis on things that are new or different.
The Preferences window is just that, another window. Interface Builder makes the job of adding a window to an application painless by providing a palette of windows that we can add to our application. The palette actually has four objects on it; they are a standard window, a panel type window, a window with a drawer, and then a drawer, which can be added to a window.
Let's focus for a minute on the standard window and the panel. Window is just a window -- nothing special about it. Panels on the other hand are a special kind of window. The defining class of panel behavior,
NSPanel, is in fact a subclass of
NSPanel modifies the behavior of standard windows in several ways. Some of these may sound familiar from your day-to-day interaction with Mac OS X, so I won't go into a ton of detail. For example, when you are running an application with a panel open, and then you switch to another application, the panel will disappear, whereas windows don't. This helps to reduce screen clutter. You can see this in Interface Builder; when you click on the finder, the Palettes panel and Get Info panel will disappear. For more information about panels, see the
NSPanel class reference.
Most applications use
NSWindow as their preferences window, and we'll follow suit here. All you have to do to add a new window to your application is to drag it off the palette anywhere onto the screen. This will add the window instance to your
nib file under the "Instances" tab, and display the open window on screen. In the "Instances" tab it is possible to change the name of the window icons to whatever you like. To help distinguish between our two windows, rename Window (the one with the table) to
mainWindow, and Window1 (the one we just added) to
prefsWindow. Simply double-clicking on the name does this.
We will occupy our preferences window with six check boxes, where each check box corresponds to a potential table column. Check boxes can be found on the same Interface Builder palette as text fields and buttons carrying the name "Switch"; drag six of them onto the preferences window. Give the check boxes the following names, which incidentally are the names of our columns and the column identifiers (make sure that these names do indeed match your column titles and identifiers):
- First Name
- Last Name
- Home Phone
- Work Phone
- Mobile Phone
Yes, I realize we haven't had "Work Phone" and "Mobile Phone" up to this point. Enabling your application to handle these additional data fields should be trivial following the example of the article that first introduced us to table views. You should only need to add the appropriate interface elements and modify the method
createRecord. I leave the addition of these two data fields and the respective interface elements (i.e., input text fields) as an exercise for when you have the time or the inclination. Don't create the matching columns though. Leave those as they are.
One last control we're going to add is a "Close" button. Drag a regular button onto the preferences window and change the name to "Close".
Below is an image of my preferences window as I have laid it out.
To give our code access to these new controls, we have to add an outlet for each of the check boxes. Add to the
Controller class the following six outlets corresponding to the six check boxes, and make the appropriate connections:
For those of you working on this project, let's talk about how things are going.
We also have to add an action method to
Controller that is invoked whenever the user changes the state of any of the check boxes. We'll call this action method
setColumn because it will contain code that will add or remove columns from the table view in response to the user selecting or deselecting a check box.