oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

An Introduction to RubyCocoa, Part 1
Pages: 1, 2, 3

Creating the Controller Class

Just like a normal Objective-C controller class in a Cocoa application, our Ruby Controller class must inherit from the NSObject class. So, our first step is to subclass the NSObject class. Find the NSObject class in the "Classes" tab of the "MainMenu.nib" window.

Select this class in the list and press the "Return" button. This should create a new subclass of the NSObject class called MyObject. Highlight the new NSObject child class, if it is not already highlighted, and change its name from MyObject to Controller.

Once we've created and renamed our new Controller class, we need to add the necessary actions and outlets to it. Make sure the Controller class is highlighted and open the Info window (you can do so by selecting the "Show Info" item under the "Tools" menu, or by using a "Shift-Command-I" key combination) and select "Attributes" from the drop-down list.

First we'll add the outlets. So, click on the "Outlets" tab and add five new outlets to the list: 1) fileTableView, 2) archiveFile, 3) fileType, 4) fileTypeView, and 5) mainWindow.

After adding all of our outlets to our Controller class, we need to add the actions that it will be tasked with performing. To do this, we click on the Actions tab and add the following actions to the list: 1) addFile, 2) removeFile, 3) createArchive, 4) extractArchive, and 5) browseForArchive.

We now have our Controller class fleshed out enough to let us start making all of our connections between the nib file we've created and our Ruby application. Before we proceed, however, we must create an instance of our Controller class. We do this by selecting our Controller class from the list under the "Classes" tab in our "MainMenu.nib" window. Then, you can either control-click on it and select "Instantiate Controller" or you can select it through the "Classes" menu in the Interface Builder menu bar.

Once we have an instance of our Controller class, we can begin making all of our necessary connections. In the process we'll also find out what each of the outlets and actions do in our application. We'll begin with the outlets we created and then move on to the actions afterward.

The first three outlets are used to update and access the information the user shares with us through the interface. The latter two are needed only for using the NSOpenPanel and NSSavePanel classes. You'll need to connect each of the outlets to their respective interface elements. This is done by control-clicking on the newly created instance of our Controller class and dragging a line from it to the GUI element it represents.

The fileTableView outlet should be connected to the NSTableView object under the "Create" tab that displays the files we have selected for archiving. The archiveFile outlet should point to the NSTextField (text box, not label) under the "Extract" tab that will hold the name of the archive file we have chosen for extraction. The fileType needs to be connected to the NSPopUpButton that we placed in our custom view in order to allow us to access the file type chosen by the user when in the process of creating a new archive file. The fileTypeView outlet is a pointer to our custom view we created for the NSSavePanel, and finally, our mainWindow outlet is a pointer to the main window of our application.

You now have half of your Controller class' connections created. Next, we'll need to attach each of its actions to an element of the interface. Let's take a look at what each is supposed to do, and to which item each will be attached.

Connecting actions to the GUI elements that trigger them is done slightly differently than connecting outlets to their GUI elements. Rather than control-clicking the Controller object and dragging the line to the GUI element, we are going to go backwards, and control-click the GUI element that triggers the action and drag a line to the Controller object. Let's start with the actions for the '+' and '-' buttons.

The addFile action calls up an instance of the NSOpenPanel and allows the user to select one or more files that they want to include in their archive. The removeFile action simply deletes the currently selected file from the table. We need to connect both of these actions to the '+' and '-' buttons underneath the NSTableView object in our "Create" tab.

The createArchive and extractArchive actions are responsible for creating new archive files and extracting the contents of an already existing archive file to a chosen directory. The first action displays an NSSavePanel allowing the user to select a location for—and assign a name to—the archive file being created.

We should create a connection between it and the "Create Archive" button on the "Create" tab using the same method that we did for our add and remove file actions. The extractArchive action executes the tar program to extract the selected archive file to the directory chosen by the user through an instance of the NSOpenPanel class. The "Extract" button should be connected to the extractArchive method in the same way as the "Create Archive" button.

Finally, the browseForArchive action allows the user to select an archive file for extraction using an NSOpenPanel object. It is called whenever a user clicks on the "Browse" button under the "Extract" tab, and therefore, needs to be connected to that button following the same routine as described earlier.

That takes care of about everything that we can do using Interface Builder. The rest of our work will need to be done in Xcode. Normally, at this point we would select our Controller class and have Interface Builder create files with skeleton code for us to fill out in Xcode. However, it will only do this for Objective-C and Java, not Ruby. So, we'll have to do a little bit of work by hand here. So make sure you've saved your nib file before closing Interface Builder and Xcode.

The next installment will deal with creating the skeleton code that Interface Builder usually creates for us and finishing our project by adding in the rest of the Ruby code needed to give us a functioning application.

Until then, I hope this tutorial keeps you busy!

Christopher Roach recently graduated with a master's in computer science and currently works in Florida as a software engineer at a government communications corporation.

Return to