Difference between revisions of "Flash Applets Tutorial"

From WeBWorK_wiki
Jump to navigation Jump to search
m
 
(24 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Flash Applets Tutorial ==
 
  +
== Introduction ==
 
In this tutorial it is discussed how to create a Flash applet with the interface necessary for inclusion in a WeBWork problem, as well as the construction of the corresponding PG file. We pay special attention to the problem of setting up the functions that define the interface between the applet and the WeBWork page that displays the problem.
 
In this tutorial it is discussed how to create a Flash applet with the interface necessary for inclusion in a WeBWork problem, as well as the construction of the corresponding PG file. We pay special attention to the problem of setting up the functions that define the interface between the applet and the WeBWork page that displays the problem.
   
Line 14: Line 14:
   
 
* [https://addons.mozilla.org/en-US/firefox/addon/firebug/ Firebug] and [https://addons.mozilla.org/en-us/firefox/addon/flashbug/ Flashbug] are [http://www.mozilla.com/en-US/firefox/new/ Firefox] plugins for debugging JavaScript and ActionScript. Flashbug allows, among other things, to see the output of the <code>trace()</code> function.
 
* [https://addons.mozilla.org/en-US/firefox/addon/firebug/ Firebug] and [https://addons.mozilla.org/en-us/firefox/addon/flashbug/ Flashbug] are [http://www.mozilla.com/en-US/firefox/new/ Firefox] plugins for debugging JavaScript and ActionScript. Flashbug allows, among other things, to see the output of the <code>trace()</code> function.
* The debug version of the Flash player is required to use Firebug/Flashbug. It can be [http://www.mozilla.com/en-US/firefox/new/ downloaded here].
+
* The debug version of the Flash player is required to use Firebug/Flashbug. It can be [http://www.adobe.com/support/flashplayer/downloads.html downloaded here].
* <code>DebugBox</code>, an ActionScript class that displays a box where debug messages can be displayed. '''''(Add downloading site)'''''.
+
* <code>DebugBox</code>, an ActionScript class that displays a box where debug messages can be displayed. '''''(Add downloading site)'''''. '''Important notice''': The <code>DebugBox</code> class uses the <code>TextArea</code> component to display messages. This requires that this component is present in the Library of the <code>.fla</code> file. To add the component to the Library, open the menu ''''Windows-Components'''' and drag <code>TextArea</code> to the Library.
 
* A <nowiki>"local tester"</nowiki> for the interface. This allows testing the interface whithout having to upload the applet to WeBWork. '''''(Add downloading site)'''''
 
* A <nowiki>"local tester"</nowiki> for the interface. This allows testing the interface whithout having to upload the applet to WeBWork. '''''(Add downloading site)'''''
   
 
'''Note''': Even for developers not using Firefox, it may be useful to use the debug version of the Flash player. At least exceptions thrown by ActionScript will cause a popup to be displayed. If using Chrome, it may be necessary to choose the correct plugin in the page <code>about:plugins</code>.
 
'''Note''': Even for developers not using Firefox, it may be useful to use the debug version of the Flash player. At least exceptions thrown by ActionScript will cause a popup to be displayed. If using Chrome, it may be necessary to choose the correct plugin in the page <code>about:plugins</code>.
  +
 
== Functions Expected by the Interface ==
 
== Functions Expected by the Interface ==
 
The communication between the applet and the JavaScript code in the WeBWork page uses the ActionScript class [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html <code>ExternalInterface</code>]. Using this class, the developer can define ''callbacks'' in the ActionScript code to be called by JavaScript, and also directly call JavaScript code from ActionScript.
 
The communication between the applet and the JavaScript code in the WeBWork page uses the ActionScript class [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html <code>ExternalInterface</code>]. Using this class, the developer can define ''callbacks'' in the ActionScript code to be called by JavaScript, and also directly call JavaScript code from ActionScript.
   
 
In this page we do not discuss the details of the <code>ExternalInterface</code> class, but describe the methods that WeBWork expects to be made available by the applet. For implementation details see the [[#Examples|examples]] section.
 
In this page we do not discuss the details of the <code>ExternalInterface</code> class, but describe the methods that WeBWork expects to be made available by the applet. For implementation details see the [[#Examples|examples]] section.
  +
  +
=== Telling JavaScript that the Applet is Ready ===
  +
The synchronization between the JavaScript code and the applet loading process is a crucial issue. The JavaScript code in the WeBWork page will try to verify by several means if communication with the applet has been established. It is, however, strongly recommended that the applet <nowiki>"tells"</nowiki> JavaScript that it is ready. This is done by calling the JavaScript function <code>applet_ready</code>, as in the example below:
  +
  +
<code>ExternalInterface.call("applet_loaded","appletName",1);</code>
  +
  +
Here, <code>appletName</code> is the name by which the applet is identified by JavaScript, as set up in the PG file.
  +
  +
For simple applets, it is recommended that this function call takes place in response to the <code>ADDED_TO_STAGE</code> event, not in the applet's constructor. More complex applets that need additional media or resources should use a more sophisticated loading method.
   
 
=== Functions Called by JavaScript ===
 
=== Functions Called by JavaScript ===
 
The JavaScript in the WeBWork page will call functions defined in the applet code to pass information containing problem data and to request the student's answer. The interface also makes it possible to record the ''state'' of the applet, reflecting the student's interaction with the applet. This is important, since students may work on a problem, log off, and then log on again, and the applet should be in a state consistent with the previous session. The following picture roughly displays the flow of the function calls:
 
The JavaScript in the WeBWork page will call functions defined in the applet code to pass information containing problem data and to request the student's answer. The interface also makes it possible to record the ''state'' of the applet, reflecting the student's interaction with the applet. This is important, since students may work on a problem, log off, and then log on again, and the applet should be in a state consistent with the previous session. The following picture roughly displays the flow of the function calls:
   
[[File:WW_Applet_Interface.jpg|640x215px]]
+
[[File:WW_Applet_Interface.jpg|660x300px]]
   
The names of the functions defined in the applet are ''not'' hard-coded by WeBWork. It is possible to configure them in the PG file. The following are the names that have been conventionally used, but developers are allowed to use names of their choice.
+
The names of the functions defined in the applet are ''not'' hard-coded by WeBWork. It is possible to configure them in the PG file. The following are the names shown have been conventionally used, but developers are allowed to change them.
   
 
#<code>isActive():uint</code>. JavaScript calls this function to check if the applet is ready to interact with the WeBWork page. The applet should return a nonzero value to indicate that it has loaded all the data it needs to function properly. JavaScript will repeatedly call this function, with a delay between calls, to give the applet several chances to load. The maximum number of calls is configured in the PG file.
 
#<code>isActive():uint</code>. JavaScript calls this function to check if the applet is ready to interact with the WeBWork page. The applet should return a nonzero value to indicate that it has loaded all the data it needs to function properly. JavaScript will repeatedly call this function, with a delay between calls, to give the applet several chances to load. The maximum number of calls is configured in the PG file.
#<code>setConfig(xmlString):uint</code>. This function is called to give the applet the opportunity to initialize problem data. Typically, a problem is generated in the PG file by randomization, and this information must be passed to the applet. The data must be encoded in a [http://en.wikipedia.org/wiki/XML XML] string. A deep understanding of XML is not required, since ActionScript makes it easy to read and write XML data. See the [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/XML.html documentation of the XML class] and the [http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ff5.html Working with XML] tutorial. Suppose, for example, that the problem generates the function <math>x+\sin(x)</math>. Then, <code>xmlString</code> could be <code><xml><function>x+sin(x)</function></xml></code> and, in the applet code, <code>xmlString.function</code> will refer to the string defining the function, <code>x+sin(x)</code>. The function should return a nonzero value if the configuration was successfully set, and 0 if not (for example, if <code>xmlString</code> does not contain valid XML data).
+
#<code>setConfig(xmlString):uint</code>. This function is called to give the applet the opportunity to initialize problem data. Typically, a problem is generated in the PG file by randomization, and this information must be passed to the applet. The data must be encoded in a [http://en.wikipedia.org/wiki/XML XML] string. A deep understanding of XML is not required, since ActionScript makes it easy to read and write XML data. See the [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/XML.html documentation of the XML class] and the [http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7ff5.html Working with XML] tutorial. Suppose, for example, that the problem generates the function <math>x+\sin(x)</math>. Then, <code>xmlString</code> could be <code><xml><function>x+sin(x)</function></xml></code> and, in the applet code, <code>xmlString.function</code> will refer to the string <code>x+sin(x)</code>. The function should return a nonzero value if the configuration was successfully set, and 0 if not (for example, if <code>xmlString</code> does not contain valid XML data).
  +
#<code>setXML(xmlString:String):uint</code> This function is called by JavaScript to request that the applet sets its state. Under normal circumstances, the parameter <code>xmlString</code> will be ''exactly'' the same string that was returned in a previous call to <code>getXML()</code>. The applet should use <code>xmlString</code> to put itself in the state it was right before the student was done interacting with the applet (for example, when the problem is submitted). The initial state of the applet can be configured in the PG file. ''This function should not be used to set problem data''. This should be done in <code>setConfig</code>.
  +
#<code>getXML():String</code>. JavaScript calls this function when it needs information about the applet state. This happens, for example, when the student presses the '''Submit''' button. This function must return a string with valid XML data, representing the result of the student's interaction with the applet. For example, if the student is required to enter the answer to the problem in the applet, this function should return information containing the current value the student has typed in.
  +
#<code>getAnswer():String</code>. JavaScript calls this function when the students clicks '''Submit''' in the problem page. The applet should return a <code>String</code> that represent's the student's answer. This string ''should not'' use XML, but a format compatible with WeBWork's answer checking macros.
  +
== Optional Functions ==
  +
The following functions can be optionally defined:
  +
 
#<code>getConfig():String</code>. This function is not actually used by the interface, but may be useful for debugging purposes. It should return a <code>String</code> containing valid XML, representing the configuration data that was passed to the applet by the <code>setConfig(xmlString)</code> function. The applet might simply keep <code>xmlString</code> in a variable and return it in this function.
 
#<code>getConfig():String</code>. This function is not actually used by the interface, but may be useful for debugging purposes. It should return a <code>String</code> containing valid XML, representing the configuration data that was passed to the applet by the <code>setConfig(xmlString)</code> function. The applet might simply keep <code>xmlString</code> in a variable and return it in this function.
#<code>getXML():xmlString</code>. JavaScript calls this function when it needs information about the applet state. This happens, for example, when the student presses the '''Submit''' button. This function must return a string with valid XML data, representing the result of the student's interaction with the applet. For example, if the student is required to enter the answer to the problem in the applet, this function should return information containing the current value the student has typed in.
 
  +
#<code>setDebug(uint:debugLevel):void</code>. It is convenient to have the applet generate different debug messages during development and after deployment. This function will be called to JavaScript to tell the applet what the debug level should be, according to a parameter set in the PG file. This way, the debug level can be changed without need to recompile the applet.
#<code>setXML(xmlString:String):uint</code> This function is called by JavaScript to request that the applet sets its state. Under normal circumstances, the parameter <code>xmlString</code> will be ''exactly'' the same string that was returned in a previous call to <code>getXML</code>. The applet should use <code>xmlString</code> to put itself in the state it was right before the student was done interacting with the applet (for example, when the problem is submitted). The initial state of the applet can be configured in the PG file. ''This function should not be used to set problem data''. This should be done in <code>setConfig</code>.
 
   
 
==Examples==
 
==Examples==
 
*[[The AdditionExample Applet]]
 
*[[The AdditionExample Applet]]
  +
  +
  +
[[Category:Applets]]
  +
[[Category:Flash Applets]]

Latest revision as of 19:39, 26 July 2011

Introduction

In this tutorial it is discussed how to create a Flash applet with the interface necessary for inclusion in a WeBWork problem, as well as the construction of the corresponding PG file. We pay special attention to the problem of setting up the functions that define the interface between the applet and the WeBWork page that displays the problem.

This interface relies on communication between ActionScript and JavaScript. Applet developers are responsible for writing the ActionScript code for the interface, while the JavaScript is provided by WeBWork, and is of no concern for problem authors. The JavaScript code, however, defines an interface that the applet is required to follow.

Applets included in WeBWork problems can come in several flavors: the applet may simply display a graph, perhaps with some interactivity, to aid students in visualizing the solution for a problem. It could be used to guide students in the process of finding a solution (in which case it has to "remember" the stage the student is in). Or, in more complex examples, it might require an answer to be entered in the applet, for example by typing it or by manipulating a graphic in certain way.

The complexity of the interface will depend on the purpose and complexity of the applet. In this tutorial, we will start with a very simple example that requires students to enter the answer in a simple problem. We will then proceed to more complex examples.

The examples require ActionScript 3 and have been tested in Flash CS5 (but should work in Flash CS4).

Debugging

Debugging is one of the most challenging aspects of developing Flash applets for WeBWork. The following tools are suggested:

  • Firebug and Flashbug are Firefox plugins for debugging JavaScript and ActionScript. Flashbug allows, among other things, to see the output of the trace() function.
  • The debug version of the Flash player is required to use Firebug/Flashbug. It can be downloaded here.
  • DebugBox, an ActionScript class that displays a box where debug messages can be displayed. (Add downloading site). Important notice: The DebugBox class uses the TextArea component to display messages. This requires that this component is present in the Library of the .fla file. To add the component to the Library, open the menu 'Windows-Components' and drag TextArea to the Library.
  • A "local tester" for the interface. This allows testing the interface whithout having to upload the applet to WeBWork. (Add downloading site)

Note: Even for developers not using Firefox, it may be useful to use the debug version of the Flash player. At least exceptions thrown by ActionScript will cause a popup to be displayed. If using Chrome, it may be necessary to choose the correct plugin in the page about:plugins.

Functions Expected by the Interface

The communication between the applet and the JavaScript code in the WeBWork page uses the ActionScript class ExternalInterface. Using this class, the developer can define callbacks in the ActionScript code to be called by JavaScript, and also directly call JavaScript code from ActionScript.

In this page we do not discuss the details of the ExternalInterface class, but describe the methods that WeBWork expects to be made available by the applet. For implementation details see the examples section.

Telling JavaScript that the Applet is Ready

The synchronization between the JavaScript code and the applet loading process is a crucial issue. The JavaScript code in the WeBWork page will try to verify by several means if communication with the applet has been established. It is, however, strongly recommended that the applet "tells" JavaScript that it is ready. This is done by calling the JavaScript function applet_ready, as in the example below:

ExternalInterface.call("applet_loaded","appletName",1);

Here, appletName is the name by which the applet is identified by JavaScript, as set up in the PG file.

For simple applets, it is recommended that this function call takes place in response to the ADDED_TO_STAGE event, not in the applet's constructor. More complex applets that need additional media or resources should use a more sophisticated loading method.

Functions Called by JavaScript

The JavaScript in the WeBWork page will call functions defined in the applet code to pass information containing problem data and to request the student's answer. The interface also makes it possible to record the state of the applet, reflecting the student's interaction with the applet. This is important, since students may work on a problem, log off, and then log on again, and the applet should be in a state consistent with the previous session. The following picture roughly displays the flow of the function calls:

WW Applet Interface.jpg

The names of the functions defined in the applet are not hard-coded by WeBWork. It is possible to configure them in the PG file. The following are the names shown have been conventionally used, but developers are allowed to change them.

  1. isActive():uint. JavaScript calls this function to check if the applet is ready to interact with the WeBWork page. The applet should return a nonzero value to indicate that it has loaded all the data it needs to function properly. JavaScript will repeatedly call this function, with a delay between calls, to give the applet several chances to load. The maximum number of calls is configured in the PG file.
  2. setConfig(xmlString):uint. This function is called to give the applet the opportunity to initialize problem data. Typically, a problem is generated in the PG file by randomization, and this information must be passed to the applet. The data must be encoded in a XML string. A deep understanding of XML is not required, since ActionScript makes it easy to read and write XML data. See the documentation of the XML class and the Working with XML tutorial. Suppose, for example, that the problem generates the function [math]x+\sin(x)[/math]. Then, xmlString could be <xml><function>x+sin(x)</function></xml> and, in the applet code, xmlString.function will refer to the string x+sin(x). The function should return a nonzero value if the configuration was successfully set, and 0 if not (for example, if xmlString does not contain valid XML data).
  3. setXML(xmlString:String):uint This function is called by JavaScript to request that the applet sets its state. Under normal circumstances, the parameter xmlString will be exactly the same string that was returned in a previous call to getXML(). The applet should use xmlString to put itself in the state it was right before the student was done interacting with the applet (for example, when the problem is submitted). The initial state of the applet can be configured in the PG file. This function should not be used to set problem data. This should be done in setConfig.
  4. getXML():String. JavaScript calls this function when it needs information about the applet state. This happens, for example, when the student presses the Submit button. This function must return a string with valid XML data, representing the result of the student's interaction with the applet. For example, if the student is required to enter the answer to the problem in the applet, this function should return information containing the current value the student has typed in.
  5. getAnswer():String. JavaScript calls this function when the students clicks Submit in the problem page. The applet should return a String that represent's the student's answer. This string should not use XML, but a format compatible with WeBWork's answer checking macros.

Optional Functions

The following functions can be optionally defined:

  1. getConfig():String. This function is not actually used by the interface, but may be useful for debugging purposes. It should return a String containing valid XML, representing the configuration data that was passed to the applet by the setConfig(xmlString) function. The applet might simply keep xmlString in a variable and return it in this function.
  2. setDebug(uint:debugLevel):void. It is convenient to have the applet generate different debug messages during development and after deployment. This function will be called to JavaScript to tell the applet what the debug level should be, according to a parameter set in the PG file. This way, the debug level can be changed without need to recompile the applet.

Examples