TweetFollow Us on Twitter

Rapid Prototyping

Volume Number: 14 (1998)
Issue Number: 2
Column Tag: Programming Techniques

Rapid Prototyping

by John Schettino

An Object Oriented Approach to Using FaceSpan and AppleScript to Prototype Applications

Software Development 101

Just the other day I read a posting to a Macintosh programmers news group that asked a simple but powerful question. What design methodologies do most Macintosh programmers use? As I stared at the phosphors of my monitor, I recalled my years of formal study in Software Engineering. I learned all the state of the art (in the late 80s) software design methods when I was getting my Masters degree -- but what do I actually use in practice?

The answer is a bit surprising. It turns out that I usually use a technique called either incremental development or rapid prototyping. This approach relies on my own expertise in ad-hoc design and the fact that I'm usually working alone on a project. It doesn't hold up quite so well for large programmer teams. The basic idea is to quickly implement a subset of the application, use it -- or better yet let the customer use it, see what works and what doesn't, and then repeat the cycle. Each time through the cycle refine:

  • the requirements (what the application is supposed to do)
  • the interface (how the application looks)
  • the behavior (what the application does), and
  • the design (how the application is structured)

For this approach to succeed, using tools that support very fast implementation of successive versions of the prototype is critical. Discarding the prototype once it has served its purpose is also critical. This prevents overattachment to the initial version's implementation. It also keeps me from over-polishing the prototype! For these reasons I've selected AppleScript and FaceSpan as my Rapid Prototyping Environment.

The Tools

AppleScript is the Macintosh's bundled scripting language. It is a reasonable programming language for prototyping, since it includes basic block-programming constructs, subroutines, and several data types. It supports classes with data and member functions, and fairly complex data structures. There is also a wide array of scripting additions on the Internet that I use to round out the language. AppleScript is close enough to Java, C, or C++ to allow me to re-implement the prototype in any of those languages. It also reads a bit like psudocode so it can be used as a specification language for the final implementation. The big plus for AppleScript is that it can call on third-parties to perform complex tasks. That means databases, emailers, text editors, and even the Finder can be called on to perform major portions of a prototyped application. The big minus with AppleScript is that it completely lacks any capabilities for interface creation.

FaceSpan is a product from Digital Technology International that works as an interface tool with AppleScript or other OSA scripting languages, such as Frontier. Using FaceSpan I can create interfaces for AppleScript prototypes. The interface consists of several different styles of windows containing standard Macintosh interface elements. I then attach scripts to the windows and elements to process the events they generate. All the windows and scripts are contained in a single project file. I run the project within the FaceSpan environment while I'm developing it. Once it is working correctly, I save the project as a standard Macintosh executable file. In many ways it's simpler than it sounds.

The combination of AppleScript and FaceSpan is similar to HyperCard with several key advantages. Most important is the elimination of the Card/Background/Stack metaphor. In FaceSpan each window and it's window items behave as a unit, with their own message hierarchy. This yields "Mac-like" prototypes instead of "HyperCard-like" prototypes. FaceSpan also fully supports color, QuickTime, Drag and Drop, and other key Mac technologies. It has a rich set of interface elements to choose from. I've done pretty fancy interfaces with FaceSpan, creating and destroying window items on the fly, implementing direct manipulation interfaces, and so on. Some of the more interesting effects require a bit of script code, but at least that code is easily reused in other projects.

The Method

I like methods. A method is a little less formal than a procedure. It is a general description of the steps needed to get something done. If there is something in this method that doesn't work for you, then just work around it. The primary reason I develop a prototype is to refine my understanding of the application I'm creating. I also use it to get end-user feedback early in the design and implementation process while it is easy to make changes. The method I use to meet these goals with FaceSpan and AppleScript is quite simple:

  • First, create the static portions of the interface.
  • Second, add enough AppleScript to animate the interface at the most basic level.
  • Finally, add more AppleScript to implement as much of the application behavior as is needed for the prototype.

This three-step approach is not specific to FaceSpan and AppleScript. It's the same method I use in any language. When using these tools it is just a lot faster to complete each step. Depending on the goal of the prototype it is usually possible to stop before completing all three steps. For example, a UI designer might simply want to draw a possible interface and add a bit of AppleScript to animate it. The prototype could then be handed over to users and its usability could be assessed.

Drawing Interfaces in FaceSpan

Begin with whatever you know about the desired application's look and behavior and start creating windows in FaceSpan. This is a good time to review the Macintosh Human Interface Guidelines, also known as the human-computer interface (HCI) guidelines. I'm a big fan of following these, because applications that follow the guidelines are easier for users to learn and use. The FaceSpan Window Editor is a great environment to experiment with different layouts, but even more so, it's a place where the developer can see first hand the effects of following (or ignoring) the HCI guidelines. Here's a simple example. There are detailed rules for laying out the elements of a modal dialog box. The first dialog box below follows these rules to the letter, the second does not.


Figure 1. Conforming and Non-conforming dialog boxes.

Although the two contain the same buttons, the first conforms to the HCI guidelines. The default push button is in the right location, there is a correct amount of white space between the window items and the window border, and the icon is placed correctly. The result is a dialog box that is instantly recognizable to a Mac user. FaceSpan encourages this type of consistency throughout the application, but it by no means enforces it.

FaceSpan's Window Editor creates three different types of windows. Document windows are used for main windows. They can be resizable, closeable, and zoomable. Their optional titles are distinct from their name, as used in scripts. Modal windows can be titled or untitled and, unlike Document windows, must be closed before any other windows can receive events. The last window type is floating Windoid. These are windows that float on top of all Document windows. They are usually used for tool palettes.

A window contains zero or more window items. The upper limit of window items is 330. There are 14 different types of window items, and these types are further customizable using Forms. For example, the Button window item can have either a standard or a 3-D visual representation.

The Window Editor consists of a pair of tool palettes. The window under construction is displayed almost exactly as it will appear. New window items can be dragged onto the window, or drawn on the window. Window items have several properties that control their behavior. For example the visible and enabled properties determine if a particular window item is visible, and usable. If its enable property is false, it displays in a grayed-out style.

Figure 2. The FaceSpan Window Editor.

Figure 2 shows a complex preferences Modal window in FaceSpan's window editor. This window uses several window items, including labels, textboxes, boxes, checkboxes, and buttons (called push buttons by FaceSpan.)

In addition to the window editor, an application has full control over the menu bar. Basic menu capabilities are supported, as well as limited (single level) hierarchical menus. The menu bar support is the weakest portion of FaceSpan. Applications can have only a single menu item in the Apple menu and have no access to the Help menu.

Animating the Interface

There are three basic forms of interface behavior: workflow control, feedback, and application specific behavior. The next step in prototyping is to implement the first two forms. By workflow control I mean the degree to which the application controls what the user can do at any given point in time. This includes simple things like push button and menu sensitivity, as well as window interactions. It also includes managing dependant window items. Feedback is the use of visual and auditory messages in the application. For example, feedback is displaying a confirmation dialog box when the user closes a window, or playing a beep when invalid data is entered into a text box.

The first step is to get the ball rolling at application startup. Let's assume I have a prototype that needs to open three windows when it is launched. I make a project in the FaceSpan environment, draw three windows in the Window Editor, and then save the project as an executable. When the user double clicks the appliction icon in the Finder, it launches just fine, but no windows are displayed. I need to add some AppleScript to the project to link the launching event to several actions. When the user launches a FaceSpan application a run event message is sent to the project script. If the user drops a file on the application icon, an open event message and a list of file references is sent to the project script instead. I want to open three windows when the user launches the application, so I add an on run handler in the project script:

on run
  -- get prefs
  set {p1, p2, p3} to storage item "positions"
  open window "Call Manager" 
    with properties {bounds:p1}
  open window "Status" -
    with properties {position:p2, zoomed:false}
  open window "Call Manager - driver" 
    with properties {position:p3, zoomed:false}
end run

Most Macintosh applications keep track of window positions for the user. I can do that for my prototype as well. This handler uses a storage item to keep track of user placement of the windows. Storage items are named containers where an application can store and recall any type of data. The actual data is kept in the resource fork of the application. Recall that this is the executable version of the project file.

When the user double clicks the application icon, the on run handler of the project script is called. I begin by recalling three positions (positions are a FaceSpan datatype that specifies the x, y, width, and height of a window) from storage. I use each position to place and size each window exactly where the user left them when they last quit the prototype. I open each window use the open window command. A Window is controlled by the settings of its properties, and I can set the values of window properties in the open window command using the with properties modifier. I use this to set the initial position of each window to the stored value. I need to create the initial values for the three positions and save them in the "positions" storage item within the FaceSpan environment. I also need to somehow capture the current location and size of each window and update the storage item when the user quits the prototype.

Once a window is open the user can interact with it. They can click buttons, enter text into textboxes, check checkboxes and radio buttons, and so on. If there are no scripts attached to a window then these actions don't do anything specific to the prototype. The window behaves like a fill-in-the-blanks form. All the window items and the window itself will work, but unless the prototype does something with the information or actions the user takes, not much else will. FaceSpan does a lot of the hard work: the user can enter text into text fields, select radio buttons or checkmarks, tab between fields, scroll scrollable textboxes, and what not. What is missing is the application-specific actions that link the whole interface together.

For example, the modal dialog window in Figure 2 has a checkbox (displayed as a pull-down flag) labeled "Advanced Options." When the user toggles this checkbox "on" the window should expand to show the window items below it, and the OK push button should move down to the bottom. Clicking it again should collapse the window back to its original size and move the OK push button back to the original location. When I draw the dialog window in the FaceSpan Window Editor I set the OK push button growth property to move both. That tells FaceSpan to move it in both directions whenever the window size changes. In effect it becomes attached to the lower right corner of the window. What I want to do is resize the window between two fixed sizes, based on the setting of the "Advanced Options" checkbox. I add a handler to the script attached to the checkbox that resizes the window when the user changes the checkbox's value. That handler is very simple:

on hilited theObj
  if hilite then
    set height of my window to 555
  else
    set height of my window to 345
  end if
end hilited

When the user clicks to push a button, checkbox, or radio button window item the hilited event is sent to its attached script. The hilite property of the checkbox is true if it is checked and false otherwise. This little script changes the window size to one of two sizes, based on the hilite property value, each time the checkbox is clicked.

Figure 3.

I create lot of the animation of a prototype interface using similar techniques. Handlers for push button clicks (on hilited) or listbox selections (on selection made) usually enable or disable other window items, open or close other windows, or enable or disable menu items.

When the interface is fully animated the prototype is sufficient to answer a lot of questions about the final product. Does the interface work well? Is it easy to figure out how to accomplish a given task? Is feedback clear and consistent? The final step for a prototype is to add some or most of the application specific behavior. This is both a valuable and a dangerous step. Valuable because of what it can reveal about a potential design, and dangerous because if the prototype becomes "too functional" there is a real danger to ship it. By using FaceSpan and AppleScript, you are relieved of that danger, while still retaining the benefit of trying out a design before committing many hours to a C++ implementation. In other words, you're pretty much assured of having to throw away the prototype!

Adding Application-Specific Behavior

Adding application behavior is pretty much an exercise in AppleScript programming. The FaceSpan message hierarchy provides a lot of flexibility in the placement of handlers for FaceSpan event messages as well as application specific handlers. My job is to convert the various FaceSpan event messages into application-specific messages. FaceSpan event messages signal interface events (hilited, selection made, and so forth) while application-specific messages signal much higher-level events (produce a report, export to file, open database, and so on.) I then write handlers for those application-specific messages in AppleScript. This approach lets me reuse more of the design from the prototype because I'm able to separate the application-specific portions of each handler from the interface-specific portions. If I go on to implement the final application in C++ or Java, the interface code will be quite different than FaceSpan. The actual application specific behavior will also be coded differently, but the AppleScript code I write in the prototype can act as pseudocode.

A simple example is a push button in a window. When the user clicks the push button FaceSpan sends a hilited event message to its attached script, and then on to the window the button is in, and finally to the project script. The message flows along the message hierarchy until it is handled by a script, so I can place the on hilited handler wherever it makes the most sense. My rule is to place the handler in the script attached to the window or window item closest to the item generating the event message, unless a very similar action is performed regardless of which window item is generating it. For push buttons, I generally put the on hilited handler in the script attached to the push button. This handler converts the FaceSpan event message (hilited) into an application-specific function call. Function calls in AppleScript send a user-defined command message corresponding to the function name into the message hierarchy. Here's an example script that converts a FaceSpan event message to an application-specific user-defined command:

on hilited theObj set address to contents of textbox "digits" - as string sendCall(address) set contents of textbox "digits" to "" end hilited

The handler is from a prototype Call Management application. In this prototype the main window consists of a graphical representation of a call, a textbox named "digits", and a push button labeled "Send". When the user clicks Send, I want to extract the current phone number from the textbox and place a telephone call to that number. I then want to clear the textbox. There are two different things happening here. Getting the phone number and clearing the textbox are both interface-specific actions, so I take care of them in this handler. The second action is placing a call to the entered number. That has nothing to do with the interface, and I'd like to separate the code out so I can at least have the option of reusing the design. I do this by calling a user-defined function. This in effect converts the FaceSpan hilited event message into an application-specific event message named sendCall(). Now all I have to do is implement the AppleScript handler for sendCall(). This handler is totally separate from the FaceSpan interface, and can be placed in a script anywhere along the message hierarchy (window item, window, and project). Where this is placed depends on several factors, including the ultimate target implementation language. For this prototype, I placed the handler in the project script:

on sendCall(phoneNum)
  if isConnected then
    tell window "Status"
      setMsg("Dial " & phoneNum)
      enableWaiting()
    end tell
    tcp write data "Dial " & phoneNum & LF -
      stream tcpDialogSocket
  end if
end sendCall

In the handler I send a protocol message through a TCP/IP socket to a host application. I also enable what amounts to a thread in another window (again using an application-specific message named enableWaiting()) that uses the FaceSpan idle handler to poll a TCP/IP socket for a reply. I'm taking advantage of the excellent shareware TCP/IP Scripting Addition by Mango Tree Software to perform the TCP/IP operations.

Don't get too hung up on the actual code, what's more important is to understand what it shows. When I implement the actual application it's pretty clear that the code must write a string to a TCP/IP socket to make a call, and once it's done this it must wait for a response. This design applies just as well to the final application as it does to this prototype.

Object Oriented Programming

I generally take an object-oriented approach to application design. FaceSpan and AppleScript fully support object-oriented implementations. For those not interested in or concerned with objects, a purely functional approach can also be used. If objects are important to the prototype, then there are several options available when using the FaceSpan/AppleScript combination. FaceSpan's windows and window items are themselves objects, while AppleScript includes its own script objects.

Objects in FaceSpan

In FaceSpan, every window is considered a window template. This means that FaceSpan considers every window, including all its window items and attached scripts, to be a class of sorts. An application can either use the template directly, or it can create several instances of the template. Each instance contains a complete copy of the window, including window properties and attached script properties. Each window instance is assigned a unique window id property. The open window command opens a window based on the template created in the Window Editor.

Window items also are objects. They contain properties as well as data, and can be created and destroyed dynamically. When a window is created in the Window Editor, the initial set of window items is specified and their property values are set. The application has complete control over these values, and can even override them when the window template is opened. The following code fragment dynamically creates several window items in a window.

on displayCall(calledNumber, calledNumberId, -
    isActive, isRadio, isInConf, -
    isConf, lineFrom, nodeX, nodeY)
  local xPos, ypos, iconArt, lineProps
  set ypos to (nodeY * 60) - top
  set xPos to nodeX * 80
  
  if isRadio then
    set radioItem to id of (make radio button -
      with properties {position:{4, ypos},width:16,-
      height:16, script:none, hilite:isActive, -
      cnum:calledNumber, cid:calledNumberId} -
      at end of window id theWindow)
    set index of window item id radioItem to 2
  end if
  
  set theIndex to -
    (index of graphic line "divLine") + 1
  if isConf then
    set iconArt to {class:resource info, -
      type:"cicn", name:"group", id:5001}
  else
    set iconArt to {class:resource info, -
      type:"ICON", name:"Big Off Tone", id:5002}
  end if
  
  set iconItem to id of (make icon with properties-
    {artwork:iconArt, position:{4 + xPos, -
    ypos - 10}, width:36, height:36, -
    draggable:true, droppable:true, script:none,-
    selection rule:as push button, -
    balloon:"ISP Id is: " & calledNumberId, -
    cnum:calledNumber, cid:calledNumberId, -
    conf:isInConf} at end of window id theWindow)
  set index of window item id iconItem to theIndex
  
  if (lineFrom = -1) then 
    set lineProps to {position:{18, ypos + 8}, -
      width:80, height:1, script:none}
  else if (lineFrom = 0) then 
    set lineProps to {position:{(80 * (nodeX - 1)) -
      + 22, ypos - 60}, width:1, height:68, -
      script:none}
  else
    set lineProps to {position:{(80 * lineFrom) + -
      14, ypos + 8}, width:80 * (nodeX - lineFrom),-
      height:1, script:none}
  end if
  
  set lineItem to id of (make graphic line -
    with properties lineProps -
    at end of window id theWindow)
  set index of window item id lineItem to theIndex
  
  if (lineFrom = 0) then
    set lineItem to id of (make graphic line -
      with properties {position:{(80 * (nodeX - 1))-
      + 22, ypos + 8}, width:72, height:1,-
      script:none} at end of window id theWindow)
    set index of window item id lineItem to theIndex
  end if
  
  set labelItem to id of (make label -
    with properties {position:{xPos + 10, ypos + -
    24}, width:80, height:16,contents:calledNumber,-
    script:none} at end of window id theWindow)
  set index of window item id labelItem to theIndex
  
end displayCall

This is a meaty handler that creates several window items. It shows several interesting things. First, the algorithm used to place the radio button, icon, label, and lines is reusable. I used virtually the same algorithm in a Java and a NewtonScript version of the final application. Second, the application has total control over the placement and property values for window items it creates. Third, I'm adding application-specific properties to the radio button and icon window items. I use these window items to hold information I need (caller number and conference information) to associate with the call, but don't want to store separately. Finally, notice that each window item has its script property set to none. This is one case where I take advantage of the FaceSpan message hierarchy for performance reasons. Whenever one of these window items generates an event message I can handle it in the window's attached script with a general handler. Here's the hilited event handler:

on hilited theObj
  try
    if class of theObj is radio button then
      set theCallId to cid of theObj
      switchCall(theCallId)
    end if
  on error
  end try
end hilited

I dynamically create radio buttons, icons, graphic lines, and labels as children of the window. Of these, only radio buttons and icons generate the hilited event message. In this prototype I don't want to perform any actions if the user clicks one of the dynamic icons, and there are no other radio buttons in the window except those I create dynamically. When I add the on hilited hander to the script attached to the window, it is called whenever the user clicks something (radio button, checkbox, push button, or icon) in the window, but only if that window item does not include its own on hilited hander in its attached script. In this case I need to verify only that the class of the sender of the message is radio button. If it is, then it must be one of my dynamically created ones.

I use the class of operator to determine if the object generating the message is a radio button. If it is, then I convert the FaceSpan event message into an application specific message named switchCall(). I retrieve the application specific property cid from the radio button, since that's the id that the server process knows about. This is an example of treating window items like objects, since each item contains its own unique data.

Objects in AppleScript

AppleScript also has its own little-used object/class system. Each script in AppleScript is considered a Script object that contains methods (called handlers) and data (called properties.) The script/end script command defines a script object within a script. The basic form is:

script className
  property parent: otherClassName

  property p1: value1

  on handlerName(params)
  end
end script

A script object can have zero or one parent script property, zero or more other properties, and zero or more handlers. This is more like Java than C++ since there is only single inheritance. There is also no private or protected data or methods. Everything is public. For prototyping, this is not a major hardship. Script objects are a little different than classes in most object-oriented languages in that the script/end script commands actually make a single instance. In the above example the commands make a single instance of the class named className. To make several instances of the class I'd have use the copy command to copy className. Instead of doing this, I can place the script/end script commands in a handler. Then the handler acts like a constructor. Every time I call the constructor a new instance of the class is created. Parameters to the hander can be used in the property statements of the script to provide initial values to newly created objects. This is an example of a simple constructor handler:

on makeMyObj(name)
  script myObj
    property myName: name
    on getName()
      return myName
    end getName
  end script

  return myObj
end

Calling makeMyObj("Fred") returns an instance of the myObj script object with its myName property initialized to "Fred".

Combining script objects with FaceSpan allows for encapsulating all of the handlers and data associated with a group of dynamic window items into one object. I use this technique to bind all the methods and data for a meeting in a meeting object in an example in by book, AppleScript Applications: Building Applications in FaceSpan and AppleScript, in the DateMinder application. This application implements a PIM that includes a Day view. The Day view is a window that displays a cluster of three window items for each meeting in a day. Here is a portion of the constructor and script object for a meeting:

on makeDayItem(itemclass, itemDetails, itemNote)
  local pos, startAt, meetingLength
  
  if itemclass = "Meeting" then
    set {pos, startAt, meetingLength} to itemDetails
    updateCalendarMeetMarks(startAt, true)
  else
    set startAt to 0
    set meetingLength to 0
    set pos to itemDetails
    updateCalendarOtherMarks(itemclass, true)
  end if
  
  script DayObject
    property theIndex : 0
    property barIndex : 0
    property iconIndex : 0
    property textIndex : 0
    property myPos : pos
    property myTime : startAt * 15 * minutes
    property myLength : meetingLength
    property myClass : itemclass
    property myNotes : itemNote
    

    on getItemInfo()
      if itemclass = "Meeting" then
        return {itemclass:myClass, xPos:myPos,-
          starttime:myTime, duration:myLength, -
          notes:myNotes}
      else
        return {itemclass:myClass, xPos:myPos, -
            notes:myNotes}
      end if
    end getItemInfo
    
    on resizeMeeting(theObj)
    end resizeMeeting

    on createImage()
    end createImage

    on updateMeeting(newTime, newDuration, newText)
    end updateMeeting

    on move (theInfo)
    end move

    on redraw()
    end redraw

    on openWindow()
    end openWindow

    on closeWindow()
    end closeWindow

    on windowName()
    end windowName

    on updateWindow()
    end updateWindow

    on adoptDetailWindow(oldWindowName)
    end adoptDetailWindow

    on updateItemText(newNote)
    end updateItemText

    on updateItemTextAndDisplay(newNote)
    end updateItemTextAndDisplay

    on remove()
    end remove
    
  end script
  
  return DayObject
  
end makeDayItem

I call the makeDayItem() handler to create a day item object. Once it is created I draw it's graphical representation in the Day window by calling the createImage() handler. An example of this is in the handler called when the user drags an icon onto the window to create a new meeting:

on newDayItem(theClass, theInfo)
  local theDayItem
  set theDayItem to -
    makeDayItem(theClass, theInfo, "")
  set end of theDayItems to theDayItem
  tell theDayItem to createImage()
end newDayItem

In this handler I create a new day item object by calling the day item constructor handler, and save the object in a list of all day items stored in a property. I then call the createImage() handler in the object to draw the object in the window. Any script needing to access data associated with the object, or to change its contents or location, need call only handlers in the object. I don't have to know how it is implemented, what window items are associated with it, or how to modify their properties. As I said, it's a powerful combination.

Moving From Prototype to Product

Once the prototype is completed and ready to retire, I don't just ignore it. Rather it can be mined for valuable information. The interface will have to be reimplemented in the target language (using PowerPlant, or the Constructor for Java, or by hand coding, depending on the implementation language). The prototype serves two roles here: it acts as a guide when laying out the interface and as a specification for naming the elements of the interface.

The same holds true for the AppleScript scripts. They act as a high-level specification language for the final code. Algorithms implemented in AppleScript are highly reusable, as are data structures and class hierarchies. I'm not suggesting that it's just a matter of "porting over" to C++ or Java, but at least I've already got a working solution to use when I'm doing the final implementation.

One Example of a Prototype That Worked

This is not just some abstract article - I've used these techniques many times when creating prototypes for GTE Laboratories. Here at the labs fast turn around times are critical when we're mocking up applications. By using this method and these tools, I've created many successful demos using AppleScript and FaceSpan. When we recreate a particular application in a production system, we first capture the design by dissecting the prototype.

One such example is a Call Management client application for an Internet telephony project. This application drives a server front end to allow the user to create and manage many telephone calls. Calls can be placed, merged into conferences, and dropped. Furthermore the user can have many calls active at the same time. The ultimate implementation target for the client application was Java, but much of the protocol used to communicate between the client and server was undefined and we needed a usable prototype in just two weeks. Using the method outlined in this article, and the TCP/IP osax from Mango Tree Software, I was able to create a professional prototype with a direct manipulation interface. This prototype carried us through the demo, and then was used for the final Java application over the next two months. The running application is shown below.

Figure 4.

As you can see, the application looks and behaves like any other Macintosh application. The icons on the scrolling display support drag & drop -- just drag a phone icon on top of another to merge the calls into a conference, or drag a phone icon out of a conference and onto the main window to split that call out of the conference.

Building this prototype in FaceSpan and AppleScript let me focus on the important details including creating a layout algorithm for the call graph, finalizing and debugging the TCP/IP protocol between client and server, and creating an enjoyable and usable interface for call manipulation. I didn't need (or have time) to struggle with the details of coding the application in C++ or Java. Even so, I was still able leverage the time spent on the prototype when building the final version in Java. I also re-implemented it in a custom NewtonScript application. Even there the time spent on the prototype reaped large rewards when designing the GUI in the Newton Toolkit and implementing the application in NewtonScript.

Prototyping Can Work For You

There are at least three good reasons to create a prototype before building an application. A prototype can help answer tough questions about an interface: how usable is it, does it work better one way or another, what is the optimal placement of controls in a window. A prototype is usually ready to use in short order and can fill in for the final application while it is being written. A prototype also lets you play "what if" games with different algorithms and data structures. As long as you're willing to throw it away, it's almost always worth the investment in time.

FaceSpan and AppleScript provide a powerful and rich environment for rapid prototyping. FaceSpan interfaces can be designed such that they are full Macintosh interfaces. The tool provides a fast way to mock up interfaces, and those interfaces can be quickly modified as the prototype evolves. In a similar manner AppleScript is a wonderful prototyping language. The syntax is like psuedocode, so the resulting scripts act as documentation when moving to C++ or Java. It supports object-oriented programming, as well as a huge library of osax building blocks and access to scriptable applications. These tools and this method are valuable additions to any programmer's toolbox.

References


John Schettino is an author and Senior Member of the Technical Staff at GTE Laboratories, Inc. He is the co-author of the books BASIC for the Newton: Programming for the Newton with NS BASIC and AppleScript Applications: Building Applications with FaceSpan and AppleScript, both published by AP Professional. He is also a contributing editor for the Handheld Systems Journal and for the web eZine Mobilis, where he writes about Newton and WindowsCE. You can reach him via http://members.aol.com/pdcjohns.

 
AAPL
$111.78
Apple Inc.
-0.87
MSFT
$47.66
Microsoft Corpora
+0.14
GOOG
$516.35
Google Inc.
+5.25

MacTech Search:
Community Search:

Software Updates via MacUpdate

LibreOffice 4.3.5.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
CleanApp 5.0.0 Beta 5 - Application dein...
CleanApp is an application deinstaller and archiver.... Your hard drive gets fuller day by day, but do you know why? CleanApp 5 provides you with insights how to reclaim disk space. There are... Read more
Monolingual 1.6.2 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. It requires a 64-bit capable Intel-based Mac and at least... Read more
NetShade 6.1 - Browse privately using an...
NetShade is an Internet security tool that conceals your IP address on the web. NetShade routes your Web connection through either a public anonymous proxy server, or one of NetShade's own dedicated... Read more
calibre 2.13 - Complete e-library manage...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital librarian... Read more
Mellel 3.3.7 - Powerful word processor w...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
ScreenFlow 5.0.1 - Create screen recordi...
Save 10% with the exclusive MacUpdate coupon code: AFMacUpdate10 Buy now! ScreenFlow is powerful, easy-to-use screencasting software for the Mac. With ScreenFlow you can record the contents of your... Read more
Simon 4.0 - Monitor changes and crashes...
Simon monitors websites and alerts you of crashes and changes. Select pages to monitor, choose your alert options, and customize your settings. Simon does the rest. Keep a watchful eye on your... Read more
BBEdit 11.0.2 - Powerful text and HTML e...
BBEdit is the leading professional HTML and text editor for the Mac. Specifically crafted in response to the needs of Web authors and software developers, this award-winning product provides a... Read more
ExpanDrive 4.2.1 - Access cloud storage...
ExpanDrive builds cloud storage in every application, acts just like a USB drive plugged into your Mac. With ExpanDrive, you can securely access any remote file server directly from the Finder or... Read more

Latest Forum Discussions

See All

Make your own Tribez Figures (and More)...
Make your own Tribez Figures (and More) with Toyze Posted by Jessica Fisher on December 19th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
So Many Holiday iOS Sales Oh My Goodness...
The holiday season is in full-swing, which means a whole lot of iOS apps and games are going on sale. A bunch already have, in fact. Naturally this means we’re putting together a hand-picked list of the best discounts and sales we can find in order... | Read more »
It’s Bird vs. Bird in the New PvP Mode f...
It’s Bird vs. Bird in the New PvP Mode for Angry Birds Epic Posted by Jessica Fisher on December 19th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Telltale Games and Mojang Announce Minec...
Telltale Games and Mojang Announce Minecraft: Story Mode – A Telltale Games Series Posted by Jessica Fisher on December 19th, 2014 [ permalink ] | Read more »
WarChest and Splash Damage Annouce Their...
WarChest and Splash Damage Annouce Their New Game: Tempo Posted by Jessica Fisher on December 19th, 2014 [ permalink ] WarChest Ltd and Splash Damage Ltd are teaming up again to work | Read more »
BulkyPix Celebrates its 6th Anniversary...
BulkyPix Celebrates its 6th Anniversary with a Bunch of Free Games Posted by Jessica Fisher on December 19th, 2014 [ permalink ] BulkyPix has | Read more »
Indulge in Japanese cuisine in Cooking F...
Indulge in Japanese cuisine in Cooking Fever’s new sushi-themed update Posted by Simon Reed on December 19th, 2014 [ permalink ] Lithuanian developer Nordcurrent has yet again updated its restaurant simulat | Read more »
Badland Daydream Level Pack Arrives to C...
Badland Daydream Level Pack Arrives to Celebrate 20 Million Downloads Posted by Ellis Spice on December 19th, 2014 [ permalink ] | Read more »
Far Cry 4, Assassin’s Creed Unity, Desti...
Far Cry 4, Assassin’s Creed Unity, Destiny, and Beyond – AppSpy Takes a Look at AAA Companion Apps Posted by Rob Rich on December 19th, 2014 [ permalink ] These day | Read more »
A Bunch of Halfbrick Games Are Going Fre...
A Bunch of Halfbrick Games Are Going Free for the Holidays Posted by Ellis Spice on December 19th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »

Price Scanner via MacPrices.net

The Apple Store offering free next-day shippi...
The Apple Store is now offering free next-day shipping on all in stock items if ordered before 12/23/14 at 10:00am PT. Local store pickup is also available within an hour of ordering for any in stock... Read more
It’s 1992 Again At Sony Pictures, Except For...
Techcrunch’s John Biggs interviewed a Sony Pictures Entertainment (SPE) employee, who quite understandably wished to remain anonymous, regarding post-hack conditions in SPE’s L.A office, explaining “... Read more
Holiday sales this weekend: MacBook Pros for...
 B&H Photo has new MacBook Pros on sale for up to $300 off MSRP as part of their Holiday pricing. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1699... Read more
Holiday sales this weekend: MacBook Airs for...
B&H Photo has 2014 MacBook Airs on sale for up to $120 off MSRP, for a limited time, for the Thanksgiving/Christmas Holiday shopping season. Shipping is free, and B&H charges NY sales tax... Read more
Holiday sales this weekend: iMacs for up to $...
B&H Photo has 21″ and 27″ iMacs on sale for up to $200 off MSRP including free shipping plus NY sales tax only. B&H will also include a free copy of Parallels Desktop software: - 21″ 1.4GHz... Read more
Holiday sales this weekend: Mac minis availab...
B&H Photo has new 2014 Mac minis on sale for up to $80 off MSRP. Shipping is free, and B&H charges NY sales tax only: - 1.4GHz Mac mini: $459 $40 off MSRP - 2.6GHz Mac mini: $629 $70 off MSRP... Read more
Holiday sales this weekend: Mac Pros for up t...
B&H Photo has Mac Pros on sale for up to $500 off MSRP. Shipping is free, and B&H charges sales tax in NY only: - 3.7GHz 4-core Mac Pro: $2599, $400 off MSRP - 3.5GHz 6-core Mac Pro: $3499, $... Read more
Save up to $400 on MacBooks with Apple Certif...
The Apple Store has Apple Certified Refurbished 2014 MacBook Pros and MacBook Airs available for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Save up to $300 on Macs, $30 on iPads with Ap...
Purchase a new Mac or iPad at The Apple Store for Education and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free,... Read more
iOS and Android OS Targeted by Man-in-the-Mid...
Cloud services security provider Akamai Technologies, Inc. has released, through the company’s Prolexic Security Engineering & Research Team (PLXsert), a new cybersecurity threat advisory. The... Read more

Jobs Board

*Apple* Store Leader Program (US) - Apple, I...
…Summary Learn and grow as you explore the art of leadership at the Apple Store. You'll master our retail business inside and out through training, hands-on experience, Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Retail - Multiple Positions (US) - A...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.