source: tags/1.4/source/examples/cocoa/currency-converter/HOWTO_files/pages/building_ui_tiger.html

Last change on this file was 8441, checked in by mikel, 17 years ago

final edits to currency-converter examples

File size: 25.1 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>CurrencyConverter HOWTO</title>
6 <link rel="stylesheet" type="text/css" href="../stylesheets/styles.css" />
7 </head>
8
9 <body>
10
11 <div class="title">
12 <h1>Building the User Interface on "Tiger"</h1>
13 </div>
14
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>
23
24 <div class="section-head">
25 <h2>Launch InterfaceBuilder</h2>
26 </div>
27
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>
31
32 <div class="inline-image">
33 <img src="../images/finder-win2.jpg"alt=""
34 border='0'/>
35 </div>
36
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>
44
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>
48
49 <div class="inline-image">
50 <img src="../images/ibwin-tiger1.jpg"alt=""
51 border='0'/>
52 </div>
53
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>
60
61 <div class="inline-image">
62 <img src="../images/ibwin-tiger2.jpg"alt=""
63 border='0'/>
64 </div>
65
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>
72
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>
79
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>
90
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>
99
100 <div class="section-head">
101 <h2>Resize the Window</h2>
102 </div>
103
104 <p>Make the window smaller by dragging the bottom-right corner
105 of the window inward.</p>
106
107 <div class="inline-image">
108 <img src="../images/ibwin-tiger3.jpg"alt=""
109 border='0'/>
110 </div>
111
112 <div class="section-head">
113 <h2>Change the Title of the Window</h2>
114 </div>
115
116 <p>InterfaceBuilder creates the initial window with the title
117 "Window". Change the title to the more appropriate "Currency
118 Converter":</p>
119
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>
142
143 <div class="section-head">
144 <h2>Add Text Fields</h2>
145 </div>
146
147 <p>In InterfaceBuilder's Palettes window, select the "Cocoa
148 Text" view, and find the NSTextView object:</p>
149
150 <div class="inline-image">
151 <img src="../images/ibwin-tiger7.jpg"alt=""
152 border='0'/>
153 </div>
154
155 <p>Drag an NSTextView object and drop it into the "Currency
156 Converter" window:</p>
157
158 <div class="inline-image">
159 <img src="../images/ibwin-tiger8.jpg"alt=""
160 border='0'/>
161 </div>
162
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>
169
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>
175
176 <div class="inline-image">
177 <img src="../images/ibwin-tiger9.jpg"alt=""
178 border='0'/>
179 </div>
180
181 <div class="section-head">
182 <h2>Label the Text Fields</h2>
183 </div>
184
185 <p>Now add labels to the text fields, to identify 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>
190
191 <div class="inline-image">
192 <img src="../images/ibwin-tiger10.jpg"alt=""
193 border='0'/>
194 </div>
195
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 label until the blue guide lines
200 appear, then release the label.</p>
201
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>
208
209 <div class="inline-image">
210 <img src="../images/ibwin-tiger11.jpg"alt=""
211 border='0'/>
212 </div>
213
214 <p>Here's how the labels should look after you have entered the
215 text for all three:</p>
216
217 <div class="inline-image">
218 <img src="../images/ibwin-tiger12.jpg"alt=""
219 border='0'/>
220 </div>
221
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>
229
230 <div class="section-head">
231 <h2>Change Text Field Attributes</h2>
232 </div>
233
234 <p>The first two text fields accept user input; the last
235 displays the result of the conversion. We want the first two
236 text fields to be editable, so users can enter the values to use
237 in the conversion. We don't want the last field to be editable,
238 but we do want users to be able to copy text from it.</p>
239
240 <p>We can control all this behavior using text-field
241 attributes, configurable in the Inspector.</p>
242
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>
254
255 <div class="section-head">
256 <h2>Add a Button</h2>
257 </div>
258
259 <p>Now we add a button that activates the currency conversion.</p>
260
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>
290
291 <div class="section-head">
292 <h2>Add a Separator</h2>
293 </div>
294
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>
298
299 <p><div class="inline-image">
300 <img src="../images/ibwin-tiger16.jpg"alt=""
301 border='0'/>
302 </div>
303 </p>
304
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>
310
311 <div class="section-head">
312 <h2>Set Up the Menus</h2>
313 </div>
314
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>
321
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><strong>NOTE:</strong> 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>
343
344 <div class="section-head">
345 <h2>Tighten Up the Window Layout</h2>
346 </div>
347
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>
351
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>
384
385 <p>Now your application window should look something like the
386 one in the illustration:</p>
387
388 <p><div class="inline-image">
389 <img src="../images/ibwin-tiger18.jpg"alt=""
390 border='0'/>
391 </div>
392 </p>
393
394 <div class="section-head">
395 <h2>Enable Tabbing Between Text Fields</h2>
396 </div>
397
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 tabbing order
401 in text fields.</p>
402
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>
425
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>
429
430 <div class="section-head">
431 <h2>Set Up the Classes Used In the User Interface</h2>
432 </div>
433
434 <p>The visual elements of your application's user interface are
435 all ready now. The last thing you must do is create descriptions
436 of any custom classes used by the application when users
437 interact with the interface.</p>
438
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. In order for the application to connect the user
442 interface to classes that perform these actions, you must add
443 descriptions of your classes to the nibfile. Fortunately,
444 InterfaceBuilder can create class descriptions and save them in
445 the nibfile for you.</p>
446
447 <div class="section-head">
448 <h3>ConverterController</h3>
449 </div>
450
451 <p>ConverterController is the <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/02Essence/chapter_2_section_4.html#//apple_ref/doc/uid/TP40000863-CH3-SW4">controller</a> class that the user
452 interface communicates with directly when the "Convert" button
453 is pressed. Create a description of the ConverterController
454 class, and then create an instance of it.</p>
455
456 <ol>
457 <li><p>In InterfaceBuilder's "CurrencyConverter.nib" window,
458 click the "Classes" tab. The window shows a browser view of
459 all available Objective-C classes:</p>
460 <p><div class="inline-image">
461 <img src="../images/ibwin-tiger19.jpg"alt=""
462 border='0'/>
463 </div></p>
464 </li>
465 <li><p>Control-click the "NSObject" entry in the browser, and
466 choose "Subclass NSObject" from the popup
467 menu. InterfaceBuilder creates a new entry initially called
468 "MyObject". Change the name from "MyObject" to "ConverterController".</p></li>
469 <li><p>Select the "ConverterController" class in the browser,
470 then activate the Inspector window and choose "Attributes"
471 from the popup menu at the top of the Inspector. At the
472 bottom of the "Attributes" view is a list of actions or
473 outlets. Select "Outlets", and use the "Add" button to add
474 four fields:</p>
475 <p><div class="inline-image">
476 <img src="../images/ibwin-tiger20.jpg"alt=""
477 border='0'/>
478 </div></p>
479 <p>Rename these four fields to: "amountField", "dollarField",
480 "rateField", and "converter":</p>
481 <p><div class="inline-image">
482 <img src="../images/ibwin-tiger21.jpg"alt=""
483 border='0'/>
484 </div></p></li>
485 <li><p>Now add the action that is triggered when the
486 "Convert" button is pressed: switch to the Actions view and
487 use the "Add" button to add a new action:</p>
488 <p><div class="inline-image">
489 <img src="../images/ibwin-tiger22.jpg"alt=""
490 border='0'/>
491 </div></p>
492 <p>Change the name of the action from "myAction:" to "convert:"</p></li>
493 <li><p>Now create an instance of the ConverterController
494 class. In the browser, Right-click the ConverterController
495 class and choose "Instantiate ConverterController". The
496 browser view automatically switches to the Instances view to
497 show you the newly-created instance of ConverterController as
498 a blue box icon. There is a small yellow flag next to the
499 ConverterController instances to show that it has outlets
500 that are not connected to anything. In our final step, we'll
501 create the correct connections for the instance's outlets,
502 which will enable the application to send messages correctly
503 to the objects that implement its behavior.</p></li>
504 </ol>
505
506 <div class="section-head">
507 <h3>Converter</h3>
508 </div>
509
510 <p>Converter is
511 the <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/02Essence/chapter_2_section_4.html#//apple_ref/doc/uid/TP40000863-CH3-SW4">model</a>
512 class that implements the actual conversion code. Create a
513 description of the Converter class, and then create an
514 instance of it. Repeat the steps you used to create the
515 ConverterController class and instance to create a Converter
516 class and instance:</p>
517
518 <ol>
519 <li><p>Switch to the browser view in the
520 "CurrencyConverter.nib" window.</p></li>
521 <li><p>Control-click NSObject and choose "Subclass NSObject"
522 from the resulting popup menu.</p></li>
523 <li><p>Change the name of the newly-created class from
524 "MyObject" to "Converter"</p></li>
525 <li><p>Control-click the "Converter" class and choose
526 "Instantiate Converter" to create an instance of the
527 Converter class.</p></li>
528 </ol>
529
530 <p>The model class, "Converter", has no outlets or actions, so
531 you don't need to add anything to it before instantiating
532 it. Your code will implement a conversion method, but
533 InterfaceBuilder doesn't need to know about it; the "convert:"
534 method in your code will know everything it needs to about the
535 "Converter" class. You just need to create the class
536 description and the instance so that your application will
537 start up with the correct objects created and connected.</p>
538
539 <div class="section-head">
540 <h3>Connecting the Outlets</h3>
541 </div>
542
543 <p>The final step in setting up the user interface is
544 establishing connections between the outlets and objects in the
545 interface, so that messages are sent from the user interface to
546 the correct objects.</p>
547
548 <ol>
549 <li><p>Connect the "Convert" button to the
550 "ConverterController" instance. Control-drag from the
551 "Convert" button to the "ConverterController" instance. Make
552 sure the "convert:" action is selected in the "Target/Action"
553 view of the Inspector window, then click the "connect" button
554 to confirm.</p></li>
555 <li><p>Connect the "ConverterController" instance to the text
556 fields. Control-drag from the "ConverterController" instance
557 to the "Exchange Rate" field. Select "rateField" in the
558 "Outlets" view of the Inspector window and click "connect" to
559 confirm. Then repeat this process, connecting "dollarField" to
560 the "Dollars" text field, and "amountField" to the "Amount"
561 field.</p></li>
562 <li><p>Finally, connect the "ConverterController" to the
563 "Converter" instance. Control-drag from the
564 "ConverterController" instance to the "Converter"
565 instance. Select the "converter" outlet in the Inspector
566 window and click "connect" to confirm.</p></li>
567 </ol>
568
569 <p>The nibfile now contains descriptions of the custom classes
570 that your code will implement, including connections between
571 their outlets and the objects with which they must
572 communicate. You can save the nibfile and proceed to write the
573 code that implements their behavior.</p>
574
575 <p>You can continue now with the section on <a href="create_lisp.html">"Creating a Lisp File"</a>.</p>
576
577
578
579 </div>
580
581 <div class="nav">
582 <p><a href="../../HOWTO.html">start</a>|<a href="making_project.html">previous</a>|<a href="create_lisp.html">next</a></p>
583 </div>
584 </body>
585</html>
586
Note: See TracBrowser for help on using the repository browser.