source: branches/ia32/examples/cocoa/currency-converter/HOWTO_files/pages/building_ui_tiger.html

Last change on this file was 8372, checked in by R. Matthew Emerson, 17 years ago

Merged changes 7685:8261 from branches/1.1/ccl.

File size: 25.2 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 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>
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 text field until the blue guide
200 lines appear, and 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 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>
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><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>
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 tanning 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 descruptions
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, 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>
447
448 <div class="section-head">
449 <h3>ConverterController</h3>
450 </div>
451
452 <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
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>
456
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>
506
507 <div class="section-head">
508 <h3>Converter</h3>
509 </div>
510
511 <p>Converter is
512 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>
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>
518
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>
530
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>
539
540 <div class="section-head">
541 <h3>Connecting the Outlets</h3>
542 </div>
543
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>
548
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>
570
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>
576
577 <p>You can continue now with the section on <a href="create_lisp.html">"Creating a Lisp File"</a>.</p>
578
579
580
581 </div>
582
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>
587</html>
588
Note: See TracBrowser for help on using the repository browser.