source: trunk/ccl/examples/cocoa/currency-converter/HOWTO_files/pages/building_ui_tiger.html @ 8013

Last change on this file since 8013 was 8013, checked in by mikel, 13 years ago

added final text and pictures to Tiger version of IB instructions for Currency Converter HOWTO

File size: 25.2 KB
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2          "">
3<html xmlns="">
4  <head>
5    <title>CurrencyConverter HOWTO</title>
6    <link rel="stylesheet" type="text/css" href="../stylesheets/styles.css" />
7  </head>
9  <body>
11    <div class="title">
12      <h1>Building the User Interface on "Tiger"</h1>
13    </div>
15    <div class="body-text">
16      <p>If you are using Mac OS X 10.4.x ("Tiger") to build your
17      application, then the Apple tutorial's section on building the
18      UI may be somewhat confusing. Apple's tutorial uses
19      InterfaceBuilder 3.x to show how to build an interface, and
20      there were many interface changes between versions 2.x and 3.x
21      of InterfaceBuilder. In this section we see how to build the UI
22      using InterfaceBuilder 2.x.</p>
24      <div class="section-head">
25        <h2>Launch InterfaceBuilder</h2>
26      </div>
28      <p>Start by locating Apple's InterfaceBuilder application. If
29        you installed Apple's Developer Tools, InterfaceBuilder should
30        be in the folder "/Developer/Applications/":</p>
32      <div class="inline-image">
33        <img src="../images/finder-win2.jpg"alt="" 
34             border='0'/>
35      </div>
37      <p class= "note"><strong><em>NOTE:</em></strong> If you have not
38        installed Apple's Developer Tools, you should do that now. You
39        will not be able to build the CurrencyConverter example
40        without them. The Developer Tools are distributed as an
41        optional install with Mac OS X 10.4 ("Tiger"). Look for the
42        "XCode Tools" package in the "Optional Installs" folder on the
43        Mac OS 10.4 install disk.</p>
45      <p>Once you have located InterfaceBuilder, double-click to launch
46        the application. InterfaceBuilder presents a window you can use
47        to choose a template for the nibfile you are going to create.</p>
49      <div class="inline-image">
50        <img src="../images/ibwin-tiger1.jpg"alt="" 
51             border='0'/>
52      </div>
54      <p>Make sure the "Application" option is selected in the "Cocoa"
55      section and click the "New" button to create a new
56      nibfile. InterfaceBuilder creates a new application nibfile, but
57      doesn't immediately save it. The Objective C objects that
58      represent the new application's interface appear in a new
59      untitled window:</p>
61      <div class="inline-image">
62        <img src="../images/ibwin-tiger2.jpg"alt="" 
63             border='0'/>
64      </div>
66      <p>The intial window and menubar also appear on the screen. The
67      new application's name appears in the menus as
68      "NewApplication". Save the new nibfile into the
69      "currency-converter" folder that you created earlier
70      (on <a href="making_project.html">this page</a>). Give the new
71      file the name "CurrencyConverter.nib"</p>
73      <div class="note">
74        <p><strong><em>NOTE:</em></strong> Most Objective C application projects use a main
75        nibfile called "MainMenu.nib", and if you use XCode to create
76        a new application project, it creates a nibfile with that
77        name. Apple's CurrencyConverter tutorial assumes that the
78        name of the main nibfile is "MainMenu.nib".</p>
80        <p>So, why do we tell you to use a different name? Clozure CL
81          has a main nibfile built into it, whose name is
82          "MainMenu.nib". Normally you don't see it, and don't even
83          need to know that it exists. But the Clozure CL
84          application-building tools create a new application by
85          copying resources from the Clozure CL application, so that
86          your new application has available to it all the built-in
87          Clozure CL tools. We ask you to name your nibfile
88          "CurrencyConverter.nib" so that it can coexist with the
89          Clozure CL main nibfile without causing any problems.</p>
91        <p>This difference between a Lisp project and an Objective C
92        project might be a little confusing at first. Just try to keep
93        in mind that whenever Apple's tutorial refers to the
94        "MainMenu.nib" file, it means the file we have just created
95        and named "CurrencyConverter.nib". In a Clozure CL project,
96        "MainMenu.nib" is the name of the main Lisp nibfile, not your
97        application's main nibfile.</p>
98      </div>
100      <div class="section-head">
101        <h2>Resize the Window</h2>
102      </div>
104      <p>Make the window smaller by dragging the bottom-right corner
105      of the window inward.</p>
107      <div class="inline-image">
108        <img src="../images/ibwin-tiger3.jpg"alt="" 
109             border='0'/>
110      </div>
112      <div class="section-head">
113        <h2>Change the Title of the Window</h2>
114      </div>
116      <p>InterfaceBuilder creates the initial window with the title
117      "Window". Change the title to the more appropriate "Currency
118      Converter":</p>
120      <ol>
121        <li><p>Click the Window object in the "Currency Converter"
122        window.</p>
123          <p><div class="inline-image">
124              <img src="../images/ibwin-tiger4.jpg"alt="" 
125                   border='0'/>
126            </div>
127        </p></li>
128        <li><p>Choose "Attributes" from the drop-down menu in the
129        Inspector window:</p>
130          <p><div class="inline-image">
131              <img src="../images/ibwin-tiger5.jpg"alt="" 
132                   border='0'/>
133            </div>
134        </p></li>
135        <li><p>Change the "Window Title" field to read "Currency Converter":</p>
136          <p><div class="inline-image">
137              <img src="../images/ibwin-tiger6.jpg"alt="" 
138                   border='0'/>
139            </div>
140        </p></li>
141      </ol>
143      <div class="section-head">
144        <h2>Add Text Fields</h2>
145      </div>
147      <p>In InterfaceBuilder's Palettes window, select the "Cocoa
148      Text" view, and find the NSTextView object:</p>
150      <div class="inline-image">
151        <img src="../images/ibwin-tiger7.jpg"alt="" 
152             border='0'/>
153      </div>
155      <p>Drag an NSTextView object and drop it into the "Currency
156      Converter" window:</p>
158      <div class="inline-image">
159        <img src="../images/ibwin-tiger8.jpg"alt="" 
160             border='0'/>
161      </div>
163      <p>If you drag a view near the edges of a window,
164      InterfaceBuilder displays blue guide lines that show the
165      standard placement of a view near the edge of the window. Drag
166      the text view to the right and upward until the guide lines
167      appear, and then let go. The text view is then positioned in
168      the standard way.</p>
170      <p>Now add two more text fields. You can drag them from the
171      palette as you did the first one, or you can duplicate the
172      first one. To duplicate, select the first text view and then
173      choose "Duplicate" from the "Edit" menu. Alternatively, you can
174      option-drag the text field to duplicate it.</p>
176      <div class="inline-image">
177        <img src="../images/ibwin-tiger9.jpg"alt="" 
178             border='0'/>
179      </div>
181      <div class="section-head">
182        <h2>Label the Text Fields</h2>
183      </div>
185      <p>Now add labels to the text fields, to idenitfy their
186      purposes for the user. For each text field, drag a Label object
187      from the palette and drop it next to the field. (Alternatively,
188      you can drop one Label and then duplicate it, just as you can
189      duplicate the text fields.)</p>
191      <div class="inline-image">
192        <img src="../images/ibwin-tiger10.jpg"alt="" 
193             border='0'/>
194      </div>
196      <p>Just as InterfaceBuilder displayed guidelines to help you
197      position the text field near the edge of the window, it also
198      displays guide lines to help you position the labels near the
199      text fields. Just drag each text field until the blue guide
200      lines appear, and release the label.</p>
202      <p>Now change the text of the labels. Click a label to select
203      it. Then show the Inspector by choosing the "Show Inspector"
204      item from the "Tools" menu. Select the "Attributes" item from
205      the pull-down menu at the top of the Inspector window, and type
206      the correct text into the Title field. For example, here is how
207      to enter the text for the top label:</p>
209      <div class="inline-image">
210        <img src="../images/ibwin-tiger11.jpg"alt="" 
211             border='0'/>
212      </div>
214      <p>Here's how the labels should look after you have entered the
215      text for all three:</p>
217      <div class="inline-image">
218        <img src="../images/ibwin-tiger12.jpg"alt="" 
219             border='0'/>
220      </div>
222      <p>When you first enter the text for a label, the label may not
223      be wide enough to show it all. In that case, you'll see only
224      part of the text in the label. You can resize the label to make
225      the full text visible. Click the label to select it. Notice the
226      small blue dots that surround it. Grab a dot on the left side
227      and drag it to the left to make the label wider, until you can
228      see the entire text.</p>
230      <div class="section-head">
231        <h2>Change Text Field Attributes</h2>
232      </div>
234      <p>The first two text fields accept user input; the last
235      displays the result of the conversion. We want the first to text
236      fields to be editable, so users can enter the values to use in
237      the conversion. We don't want the last field to be editable, but
238      we do want users to be able to copy text from it.</p>
240      <p>We can control all this behavior using text-field
241      attributes, configurable in the Inspector.</p>
243      <ol>
244        <li><p>Select the first text field</p></li>
245        <li><p>Choose "Show Inspector" from the "Tools" menu</p></li>
246        <li><p>Make sure "Attributes" is selected in the pull-down
247        menu at the top of the Inspector window</p></li>
248        <li><p>Ensure that the "Editable" and "Enabled" boxes are
249        checked in the "Attributes" display of the Inspector window</p></li>
250        <li><p>Repeat this process for the second text field</p></li>
251        <li><p>Finally, repeat it again for the last text field, but
252        this time make sure the "Editable" box is unchecked</p></li>
253      </ol>
255      <div class="section-head">
256        <h2>Add a Button</h2>
257      </div>
259      <p>Now we add a button that activates the currency conversion.</p>
261      <ol>
262        <li><p>Drag a Button object from the palette and drop it on
263            the window</p>
264          <p><div class="inline-image">
265              <img src="../images/ibwin-tiger13.jpg"alt="" 
266                   border='0'/>
267            </div>
268        </p></li>
269        <li><p>Double-click the button and change its title to "Convert"</p>
270          <p><div class="inline-image">
271              <img src="../images/ibwin-tiger14.jpg"alt="" 
272                   border='0'/>
273            </div>
274        </p></li>
275        <li><p>Select the button and then choose "Attributes" from
276        the pull-down menu at the top of the Inspector window. Almost
277        halfway down the "Attributes" view of the Inspector window,
278        find the "Key Equiv" field. Choose "Return" from the pulldown
279        menu in that field.</p>
280          <p><div class="inline-image">
281              <img src="../images/ibwin-tiger15.jpg"alt="" 
282                   border='0'/>
283            </div>
284        </p>
285        <p>When you choose "Return", InterfaceBuilder enters "\R" in
286        the text field for the Key Equivalent. Now when a user hits
287        the "Return" key, your application will behave as if they had
288        clicked the "Convert" button.</p></li>
289      </ol>
291      <div class="section-head">
292        <h2>Add a Separator</h2>
293      </div>
295      <p>Now add a separator line to visually group the text fields
296      together. Drag a separator line from the palette and drop it
297      above the button.</p>
299      <p><div class="inline-image">
300          <img src="../images/ibwin-tiger16.jpg"alt="" 
301               border='0'/>
302        </div>
303      </p>
305      <p>Drag the ends of the separator line until it spans a
306        visually pleasing width. As always, you can use the blue
307        guidelines that InterfaceBuilder displays to adjust the size
308        and position of the line and other elements to conform to
309        Apple's Human Interface Guidelines.</p>
311      <div class="section-head">
312        <h2>Set Up the Menus</h2>
313      </div>
315      <p>InterfaceBuilder creates the standard menus for a new
316      application, but it doesn't know the name of the
317      application. Consequently, the Application menu and several menu
318      items use the name "NewApplication" where they should use the
319      name of your application. Change the text of these items so that
320      they read "Currency Converter" instead of "NewApplication".</p>
322      <ol>
323        <li><p>Double-click the text "NewApplication" in the
324        application menu of your application's menubar. Change the
325        text to "Currency Converter".</p>
326          <p><div class="inline-image">
327              <img src="../images/ibwin-tiger17.jpg"alt="" 
328                   border='0'/>
329            </div>
330          </p>
331        <p><em>NOTE:</em> This change isn't really enough to get your
332        application to display the right name for the Application menu
333        when it's launched; the <a href="build_app.html">section</a>
334        on building the application explains how to make sure the
335        correct name appears.</p></li>
336        <li><p>Repeat this process for each menu item where the name
337        "NewApplication" appears. Using the same method you used to
338        change the name of the application menu, edit the "About
339        NewApplication" item, the "Hide NewApplication" item, and the
340        "Quit NewApplication" item in the application menu. Then edit
341        the "NewApplication Help" item in the "Help" menu.</p></li>
342      </ol>
344      <div class="section-head">
345        <h2>Tighten Up the Window Layout</h2>
346      </div>
348      <p>InterfaceBuilder provides layout tools with which you can
349      easily clean up the layout of a UI window and ensure it
350      conforms to Apple's user interface guidelines.</p>
352      <ol>
353        <li><p>Select the "Exchange Rate" text label. Then
354        Shift-click the other two labels to include them in the
355        selection (actually, it doesn't matter which label you select first).</p></li>
356        <li><p>Choose "Layout" > "Size to Fit" to shrink the labels
357        to the smallest sizes that still show all the text</p></li>
358        <li><p>Choose "Layout" > "Alignment" > "Align Right Edges" to
359        line up the right sides of the labels</p></li>
360        <li><p>With all three labels still selected, drag them up and
361        to the left. Release them when the blue guidelines show at
362        the top and left side of the window.</p></li>
363        <li><p>Now select all three text fields. You can click one of
364        them, then Shift-click to add the others to the
365        selection. Drag them up and left, toward the labels. Again,
366        release them when the blue guide line appears to show you the
367        proper distance from the labels. A guide line also appears to
368        show you when the fields are vertically aligned with the
369        center label.</p></li>
370        <li><p>Next, grab the separator line and move it up and to the
371        left. Release it when its left edge is aligned with the left
372        edge of the bottom label, and its top is the recommended
373        distance from the bottom label and its text field. Then drag
374        the right end of the separator line to resize it until its
375        right edge is aligned with the right edge of the bottom text
376        field.  Again, guide lines show when you have found the proper
377        distances.</p></li>
378        <li><p>Grab the button and move it up and left, again using
379        the guide lines to help you find a good position.</p></li>
380        <li><p>Finally, resize the window. When the blue guide lines
381        appear on the right and bottom of the window, it's the right
382        size for its contents.</p></li>
383      </ol>
385      <p>Now your application window should look something like the
386      one in the illustration:</p>
388      <p><div class="inline-image">
389          <img src="../images/ibwin-tiger18.jpg"alt="" 
390               border='0'/>
391        </div>
392      </p>
394      <div class="section-head">
395        <h2>Enable Tabbing Between Text Fields</h2>
396      </div>
398      <p>Users generally expect to be able to use the Tab key to move
399      from one text field to the next in a dialog
400      box. InterfaceBuilder enables you to specify the tanning order
401      in text fields.</p>
403      <ol>
404        <li><p>Choose "Layout" > "Keyboard Navigation" > "Show
405        Keyboard Check". InterfaceBuilder displays a set of small
406        icons that identify UI elements that can respond to key
407        events.</p></li>
408        <li><p>Select the "Exchange Rate" text field (the field, not
409        the label) and then choose "Layout" > "Keyboard Navigation" >
410        "Make Initial First Responder". A small "1" icon appears in
411        the text field to show that when the application launches,
412        that field receives keyboard events.</p></li>
413        <li><p>Control-drag from the "Exchange Rate" field to the
414        "Dollars" field. InterfaceBuilder shows the "Connections"
415        Inspector, and, because Keyboard Check is enabled,
416        automatically selects the "nextKeyView" outlet. Click the
417        "Connect" button in the Inspector window to confirm.</p></li>
418        <li><p>Repeat the previous steps to connect the "Dollars"
419        field back to the "Exchange Rate" field. That way, tabbing
420        moves the insertion point from the "Exchange Rate" field to
421        the "Dollars" field, and then back to the "Exchange Rate"
422        field. Control-drag from the "Dollars" field to the "Exchange
423        Rate" field, then click "Connect" to confirm.</p></li>
424      </ol>
426      <p>We don't enable tabbing into the "Amount" field because it's
427      not an editable field; it's used only to show the result of a
428      conversion.</p>
430      <div class="section-head">
431        <h2>Set Up the Classes Used In the User Interface</h2>
432      </div>
434      <p>The visual elements of your application's user interface are
435      all ready now. The last thing you must do is create descruptions
436      of any custom classes used by the application when users
437      interact with the interface.</p>
439      <p>When a user clicks the "Convert" button, it should send a
440      message to a custom class that causes the conversion to take
441      place, and the result to be displayed in the "Amount" field. In
442      order for the application to connect the user interface to
443      classes that perform these actions, you must add descriptions of
444      your classes to the nibfile. Fortunately, InterfaceBuilder can
445      create class descriptions and save them in the nibfile for
446      you.</p>
448      <div class="section-head">
449        <h3>ConverterController</h3>
450      </div>
452      <p>ConverterController is the <a href="">controller</a> class that the user
453      interface communicates with directly when the "Convert" button
454      is pressed. Create a description of the ConverterController
455      class, and then create an instance of it.</p>
457      <ol>
458        <li><p>In InterfaceBuilder's "CurrencyConverter.nib" window,
459        click the "Classes" tab. The window shows a browser view of
460        all available Objective-C classes:</p>
461        <p><div class="inline-image">
462          <img src="../images/ibwin-tiger19.jpg"alt="" 
463               border='0'/>
464        </div></p>
465        </li>
466        <li><p>Control-click the "NSObject" entry in the browser, and
467        choose "Subclass NSObject" from the popup
468        menu. InterfaceBuilder creates a new entry initially called
469        "MyObject". Change the name from "MyObject" to "ConverterController".</p></li>
470        <li><p>Select the "ConverterController" class in the browser,
471        then activate the Inspector window and choose "Attributes"
472        from the popup menu at the top of the Inspector. At the
473        bottom of the "Attributes" view is a list of actions or
474        outlets. Select "Outlets", and use the "Add" button to add
475        four fields:</p>
476        <p><div class="inline-image">
477          <img src="../images/ibwin-tiger20.jpg"alt="" 
478               border='0'/>
479        </div></p>
480        <p>Rename these four fields to: "amountField", "dollarField",
481        "rateField", and "converter":</p>
482        <p><div class="inline-image">
483            <img src="../images/ibwin-tiger21.jpg"alt="" 
484                 border='0'/>
485        </div></p></li>
486        <li><p>Now add the action that is triggered when the
487        "Convert" button is pressed: switch to the Actions view and
488        use the "Add" button to add a new action:</p>
489        <p><div class="inline-image">
490            <img src="../images/ibwin-tiger22.jpg"alt="" 
491                 border='0'/>
492        </div></p>
493        <p>Change the name of the action from "myAction:" to "convert:"</p></li>
494        <li><p>Now create an instance of the ConverterController
495        class. In the browser, Right-click the ConverterController
496        class and choose "Instantiate ConverterController". The
497        browser view automatically switches to the Instances view to
498        show you the newly-created instance of ConverterController as
499        a blue box icon. There is a small yellow flag next to the
500        ConverterController instances to show that it has outlets
501        that are not connected to anything. In our final step, we'll
502        create the correct connections for the instance's outlets,
503        which will enable the application to send messages correctly
504        to the objects that implement its behavior.</p></li>
505      </ol>
507      <div class="section-head">
508        <h3>Converter</h3>
509      </div>
511      <p>Converter is
512      the <a href="">model</a>
513      class that implements the actual conversion code. Create a
514      description of the Converter class, and then create an
515      instance of it. Repeat the steps you used to create the
516      ConverterController class and instance to create a Converter
517      class and instance:</p>
519      <ol>
520        <li><p>Switch to the browser view in the
521        "CurrencyConverter.nib" window.</p></li>
522        <li><p>Control-click NSObject and choose "Subclass NSObject"
523        from the resulting popup menu.</p></li>
524        <li><p>Change the name of the newly-created class from
525        "MyObject" to "Converter"</p></li>
526        <li><p>Control-click the "Converter" class and choose
527        "Instantiate Converter" to create an instance of the
528        Converter class.</p></li>
529      </ol>
531      <p>The model class, "Converter", has no outlets or actions, so
532      you don't need to add anything to it before instantiating
533      it. Your code will implement a conversion method, but
534      InterfaceBuilder doesn't need to know about it; the "convert:"
535      method in your code will know everything it needs to about the
536      "Converter" class. You just need to create the class
537      description and the instance so that your application will
538      start up with the correct objects created and connected.</p>
540      <div class="section-head">
541        <h3>Connecting the Outlets</h3>
542      </div>
544      <p>The final step in setting up the user interface is
545      establishing connections between the outlets and objects in the
546      interface, so that messages are sent from the user interface to
547      the correct objects.</p>
549      <ol>
550        <li><p>Connect the "Convert" button to the
551        "ConverterController" instance. Control-drag from the
552        "Convert" button to the "ConverterController" instance. Make
553        sure the "convert:" action is selected in the "Target/Action"
554        view of the Inspector window, then click the "connect" button
555        to confirm.</p></li>
556        <li><p>Connect the "ConverterController" instance to text
557        fields. Control-drag from the "ConverterController" instance
558        to the "Exchange Rate" field. Select "rateField" in the
559        "Outlets" view of the Inspector window and click "connect" to
560        confirm. Then repeat this process, connecting "dollarField"
561        to the "Dollars" text field, and "amountField" to the
562        "Amount" field.</p></li>
563        <li><p>Finally, connect the "ConverterController" to the
564        "Converter" instance. Control-drag from the
565        "ConverterController" instance to the "Converter"
566        instance. Select the "converter" outlet in the Inspector
567        window and click "connect" to confirm.</p></li>
568        <li><p></p></li>
569      </ol>
571      <p>The nibfile now contains descriptions of the custom classes
572      that your code will implement, including connections between
573      their outlets and the objects with which they must
574      communicate. You can save the nibfile and proceed to write the
575      code that implements their behavior.</p>
577      <p>You can continue now with the section on <a href="create_lisp.html">"Creating a Lisp File"</a>.</p>
581    </div>
583    <div class="nav">
584      <p><a href="../../HOWTO.html">start</a>|<a href="making_project.html">previous</a>|<a href="create_lisp.html">next</a></p>
585    </div>
586  </body>
Note: See TracBrowser for help on using the repository browser.