Zz Programming with Adobe Flex

Creating Online Tests using Custom ActionScript Components

Learn how to create a Rich Internet Application consisting of an online test using Flex and custom ActionScript components.

Published:  zz
by Richard G. Baldwin

Flex Programming Notes # 0120


Preface

General

This tutorial lesson is part of a continuing series dedicated to programming with Adobe Flex.

An earlier lesson titled The Default Application Container provided information on how to get started programming with Adobe's Flex Builder 3.  (See Baldwin's Flex programming website.)

What you will learn

In an earlier lesson, titled Defining Custom ActionScript Components you learned how to define and use custom ActionScript components.  In this lesson, you will learn how to create a Rich Internet Application consisting of an online test using Flex and custom ActionScript components.

Disclaimer

My primary purpose in publishing this Flex application is to present and explain an example of a Rich Internet Application using Flex and ActionScript.  The online test capability embodied in this application is intended to be used for practice tests and self-assessment tests only.

Do not use this application in any scenario where the results of the tests may be used to compute a student's grade.  There are many issues, such as security and privacy that must be taken into account when using software that directly affects a student's grade.  Those issues were not taken into account in the development of this application.

If you elect to use this application in a scenario that directly affects a student's grade, you do so at your own risk and I won't be responsible for any damages that you or your student may incur.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

  • Figure 1. Project file structure for TestGenerator01.
  • Figure 2. Program output at startup.
  • Figure 3. Output after answering some questions.
  • Figure 4. Multiple-choice questions with three and four choices.
  • Figure 5. Multiple choice question with four choices and a reference.
  • Figure 6. Reference item opened in a new browser window.
  • Figure 7. Result of linking the Reference button to an image file.
  • Figure 8. Question with image before resizing.
  • Figure 9. Question with image after resizing.
  • Figure 10. Question style for multiple answers.

Listings

  • Listing 1. Beginning of TestGenerator01.mxml.
  • Listing 2. MXML template for a True/False question.
  • Listing 3. Beginning of the class file named TrueFalse01.
  • Listing 4. Beginning of the class definition for TrueFalse01.
  • Listing 5. Implicit setter methods for question and answer properties.
  • Listing 6. Beginning of the constructor.
  • Listing 7. Instantiate and configure two RadioButton objects.
  • Listing 8. Add and configure a Button object to check the answer.
  • Listing 9. Add the text area for reporting of results.
  • Listing 10. Beginning of the method named checkButtonHandler.
  • Listing 11. Compare with selected radio button and report.
  • Listing 12. Register a CREATION_COMPLETE listener on the VBox.
  • Listing 13. The completeHandler method of the TrueFalse01 class.
  • Listing 14. MXML templates for multiple-choice questions with three and four choices.
  • Listing 15. Beginning of the class named FourChoices01.
  • Listing 16. Implicit setter methods for FourChoices01.
  • Listing 17. The constructor for FourChoices01.
  • Listing 18. Beginning of the method named checkButtonHandler.
  • Listing 19. Compare with selected radio button and report.
  • Listing 20. The completeHandler method for FourChoices01.
  • Listing 21. The MXML template for the FourChoicesWithRef01 class.
  • Listing 22. Abbreviated class definition for FourChoicesWithRef01.
  • Listing 23. The MXML template for the FourChoicesWithImage01 class.
  • Listing 24. Abbreviated class definition for FourChoicesWithImage01.
  • Listing 25. The MXML template for the class named FourAnswers01.
  • Listing 26. Partial abbreviated class definition for FourAnswers01.
  • Listing 27. Event handler method named resetButtonHandler.
  • Listing 28. Event handler method named completeHandler.
  • Listing 29. Beginning of the event handler named checkButtonHandler.
  • Listing 30. Parse the value from the MXML answer attribute.
  • Listing 31. Construct a string containing the correct answer.
  • Listing 32. Compare student selection with the correct selection.
  • Listing 33. MXML code for TestGenerator01.
  • Listing 34. ActionScript code for TrueFalse01.as.
  • Listing 35. ActionScript code for ThreeChoices01.as.
  • Listing 36. ActionScript code for FourChoices01.as.
  • Listing 37. FourChoicesWithRef01.as
  • Listing 38. ActionScript code for FourChoicesWithImage01.as.
  • Listing 39. ActionScript code for FourAnswers01.as.

Supplemental material

I recommend that you also study the other lessons in my extensive collection of online programming tutorials.  You will find a consolidated index at www.DickBaldwin.com.

General background information

Project file structure

In this lesson, I will present and explain a Flex project named TestGeenerator01.  Figure 1 shows a screen shot of the project file structure that was captured from the Navigator panel in the Flex Builder 3 IDE.

Figure 1. Project file structure for TestGenerator01.

As you can see from Figure 1, this is a relatively complex project involving one MXML file, six ActionScript class files, and one image file.

Preview

Up to this point, most of the applications in this series of lessons have been somewhat trivial.  Those applications were designed to illustrate programming concepts as opposed to producing a useful application.

In this lesson, I will explain a fairly significant application.  In particular, I will show you how to define custom ActionScript components that can be used to create self-grading online tests.

I will also show you how to create an MXML file using MXML templates to create an online test that incorporates the custom ActionScript classes described above.

Running the flex application named TestGenerator01

If you have the Flash Player plug-in (version 9 or later) installed in your browser you should be able to click on TestGenerator01 and cause this application to run in your browser.  (Depending on how you have your browser configured, it should either run in a new tab or run in a new browser window.)

If you don’t have the proper Flash Player installed, you should be notified of that fact and given an opportunity to download and install the Flash Player plug-in program.

Program output at startup

Figure 2 shows the program output at startup.

Figure 2. Program output at startup.

The TestGenerator01 application

As the name of the application implies, this application is designed to make it relatively easy for teachers like myself to create self-grading online practice tests for our students.

Figure 2 shows the first two questions from a sample test.

Output after answering some questions

Figure 3 shows the results of a student having selected answers for the first two questions and having clicked the button after each selection to have the answer checked.

Figure 3. Output after answering some questions.

Did the student select the correct answer?

As you can see from the report in Figure 3, the student selected the correct answer for the first question and selected the wrong answer for the second question.  The correct answer is provided in the report in all cases.

MXML templates and class files

I will provide MXML templates and corresponding class files for six different styles of questions.  A brief description of each style follows along with the name of the file that contains the class definition for that style.  I will explain each template and each class definition in detail later in the lesson.

  • TestGenerator01.mxml - This is the main application file, which is used to launch the application, and which includes the six MXML templates.
  • TrueFalse01.as - This ActionScript file contains a class definition used to instantiate True/False question objects.  The first question in Figure 3 is an example of this style of question.
  • ThreeChoices01.as - This ActionScript file contains a class definition used to instantiate multiple-choice question objects for questions having three mutually-exclusive choices.  The second question in Figure 3 and the first question in Figure 4 are examples of this style of question.
  • FourChoices01.as - This ActionScript file contains a class definition used to instantiate multiple-choice question objects for questions having four mutually-exclusive choices.  The second question in Figure 4 is an example of this style of question.
  • FourChoicesWithRef01.as - This file contains a class definition used to instantiate multiple-choice question objects for questions having four mutually-exclusive choices and a reference to a web page containing information about the topic of the question.  Figure 5 shows an example of this style of question.
  • FourChoicesWithImage01.as - This file contains a class definition used to instantiate multiple-choice question objects for questions having four mutually-exclusive choices and an image.  Examples of this style of question are shown by question number 5 in Figure 8 and Figure 9.
  • FourAnswers01.as - This file contains a class definition used to instantiate multiple-choice question objects for questions having four non-mutually-exclusive choices where it is possible for a combination of none, one, or more of the choices to be the correct answer.  Figure 10 shows an example of this style of question.

These six styles are provided to illustrate the programming concepts involved in the design of the required custom classes.  Once you understand the concepts, you should be able to design classes for many other styles of questions.

Discussion and sample code

Will explain in fragments

I will explain the code in the MXML file and in each of the ActionScript files in fragments.  Complete listings of all the files are provided in Listing 33 through Listing 39 near the end of the lesson.

As I discuss this code, I will be switching back and forth between MXML code and ActionScript code.  In order to reduce the confusion, I will display the MXML code with this background color and will display the ActionScript code with this background color.

The application named TestGenerator01

This Flex application is driven by a file named TestGenerator01.mxml.

Beginning of the file named TestGenerator01.mxml

The main application file begins in Listing 1.  A complete listing of the application file is provided in Listing 33 near the end of the lesson.

Listing 1. Beginning of TestGenerator01.mxml.

The questionClasses namespace

The most interesting thing about Listing 1 is the definition of the questionClasses namespace, which points to the folder named QuestionClasses in Figure 1.

This namespace is applied to all of the class files from which the question objects shown in Figure 2 through Figure 10 are instantiated.

MXML template for a True/False question

Listing 2 shows the MXML template for a True/False question such as Question 1 in Figure 3.  (This is the template for Question 1.)

Listing 2. MXML template for a True/False question.

The template is highlighted in three different colors in Listing 2.  The remaining contents of Listing 2 are usage instructions provided in comment form.

The simplest template

This is the simplest of all the templates in this lesson and consists of the following parts:

  • User instructions in a comment at the beginning of the template.
  • Yellow - The element name (TrueFalse01) qualified by the namespace (questionClasses).  This is also the name of the class from which the question object will be constructed.
  • Cyan - The attribute named question and its value.
  • Magenta - The attribute named answer and its value.

Mapping from MXML to objects

An MXML element name corresponds to the name of a class from which an object will be instantiated and placed in the container.  In Listing 2, the container is the default Application container and the class is named TrueFalse01.

Am MXML attribute name correspond to the name of a property belonging to the object instantiated from the class identified by the element name.  In Listing 2, the properties are named question and answer.

MXML attribute values correspond to the values being assigned to the corresponding properties.  The values are enclosed in quotation marks in Listing 2.

The class named TrueFalse01

Beginning of the class file named TrueFalse01

The class file begins with the code fragment in Listing 3.  (A complete listing of the class file is provided in Listing 34 near the end of the lesson.)

Listing 3. Beginning of the class file named TrueFalse01.

Nothing new here

There is nothing in Listing 3 that is new to this lesson.  Listing 3 simply contains a package definition and a list of import directives that you have learned about in earlier lessons.

Beginning of the class definition for TrueFalse01

The class definition begins in earnest in Listing 4.

Listing 4. Beginning of the class definition for TrueFalse01.

Extends the VBox class

This class extends the VBox class.  Therefore, an instance of this class is a VBox object and behaves according to the rules of a VBox object.  Among other things, this means that an object of the class is a container that will arrange the objects that it contains vertically with left justification.

Instance variable declarations

Listing 4 declares a large number of private instance variables.  Some of them will be used to store property values.  Others are working variables that need to be accessible by all of the methods belonging to the object.

Controlling the width of the VBox

I purposely forced the width of the VBox to be narrow enough to fit in this narrow publication format as shown in Figure 2.  If you use this class definition in an actual online test, you should probably increase the width of the VBox as described in Listing 4.

Implicit setter methods for question and answer properties

You learned about implicit setter methods that are used to set property values in earlier lessons in this series.  Listing 5 defines the implicit setter methods for the properties named question and answer.

Listing 5. Implicit setter methods for question and answer properties.

These two properties correspond to the two attributes having the same names in Listing 2.

Store incoming value in text of TextArea object

The setter method named question stores its incoming value in the text property of a standard TextArea object.  This object is referred to by the variable named theQuestion in Listing 4.

A white rectangular area

This TextArea object corresponds to the white rectangular area containing Question 1 in Figure 2.  As you can see, storing the incoming value in the text property of the object causes the text in the text area in Figure 2 to match the value of the question attribute in the MXML template in Listing 2.

The property named answer

The setter method named answer in Listing 5 stores its incoming value in one of the variables declared in Listing 4.  That value will be retrieved and used later to determine if the person taking the test has selected the correct answer to the question.

Beginning of the constructor

The constructor for the class named TrueFalse01 begins in Listing 6.

Listing 6. Beginning of the constructor.

Set the width of the VBox container

The constructor begins by setting one property and two styles belonging to the VBox container.  The width property is set using the value of vboxWidth defined in Listing 4, probably by way of an implicit setter named width belonging to the VBox object.

Set the styles

The two styles (borderStyle and backgroundColor) are set by calling explicit setter methods on the VBox object.  (Explicit setters, also called accessors, are methods having names that typically begin with the word set.  They represent a different way to set properties belonging to an object.)

Listing 6 causes the VBox container for the custom component to have a solid border and a yellow background color as shown in Figure 2.

A new TextArea object

After setting the width and two styles on the VBox object, Listing 6:

  • Instantiates a new TextArea object
  • Sets its editable property to false to prevent the text from being modified by the student
  • Sets its width property to two pixels less than the width of the VBox container, and
  • Adds the TextArea object to the container.

The first object added to the VBox

Because this text area is the first object added to the VBox container, it appears as the white rectangular area at the top of the first yellow object in Figure 2.  As mentioned earlier, the setter named question sets the text contents of the text area to the value of the question attribute in Listing 2.

Instantiate and configure two RadioButton objects

Listing 7 instantiates the True and False radio buttons shown in Figure 2.

Listing 7. Instantiate and configure two RadioButton objects.

Assigned to the same button group

The two radio buttons are assigned to the same group so that they will be mutually exclusive.  Putting them in the same group means that only one of them can be selected at any given time.

Listing 7 adds the two radio buttons to the container immediately below the white text area containing Question 1 in Figure 2.

Add and configure a Button object to check the answer

Listing 8 instantiates a Button object and adds it to the container immediately below the two radio buttons in Figure 2.  This is the button with the label Click to Check Answer.

Listing 8. Add and configure a Button object to check the answer.

Register an event handler

A click event handler method named checkButtonHandler is registered on this button.

As you will see later, this event handler determines if the student has selected a radio button that matches the correct answer to the question posed in the text area above the radio buttons.  Then the event handler posts the result of that determination in another text area below the button as shown in Figure 3.

Result area is initially hidden

The text area where the results are reported is initially hidden as shown in Figure 2 but becomes visible when the student clicks the button to check the answer.  If the student has selected the correct radio button, the report is presented in green as shown in Figure 3.  If the student has selected the wrong button, the report is presented in red (also shown in Figure 3).

Add the text area for reporting of results

The code in Listing 9 instantiates the TextArea object shown at the bottom of the object for Question 1 in Figure 3 and adds it to the VBox immediately below the Click to Check Answer button.

Listing 9. Add the text area for reporting of results.

As mentioned above, the visible property of this text area is set to false when it is instantiated causing it to be invisible until the student clicks the button to check the answer.

Put the constructor on hold

At this point, I am going to put the discussion of the constructor on hold and explain the method named checkButtonHandler, which is executed each time the student clicks the button labeled Click to Check Answer.

Beginning of the method named checkButtonHandler

The method named checkButtonHandler begins in Listing 10.

Listing 10. Beginning of the method named checkButtonHandler.

Make the text area visible

The method begins by setting the visible property of the text area at the bottom of the Question 1 object in Figure 3 to true.  This causes the text area to become visible as shown by the white rectangle at the bottom of that object in Figure 3.

Establish the correct answer

Then the method establishes the correct answer based on the value provided by the author of the question as the answer attribute in Listing 2.  If the value of the answer property is "0", the correct answer is False.  Otherwise, the correct answer is True.

Compare with selected radio button and report

Listing 11 compares the correct answer with the selected radio button to determine if the student has selected the correct radio button.

Listing 11. Compare with selected radio button and report.

If the correct radio button was selected before the check button was clicked, the results are reported in green text as shown in Figure 3.  Otherwise, the results are reported in red text.

Compute the required height for the VBox container.

One of our objectives is to cause the height of the VBox container to be automatically set to a height that will accommodate all of the components that are added to the container.  However, the code to accomplish that can't simply be put in the constructor.

If the code to compute the height is put in the constructor, that code might be executed before all of the child components have been fully constructed, at which point the heights of those components won't yet be known.  Instead, it is necessary to defer the computation of the height of the VBox until the VBox and all of its child components have been fully constructed.

Register a CREATION_COMPLETE listener on the VBox

Listing 12 registers an event handler on the VBox object that will be executed when this object "has finished its construction, property processing, measuring, layout, and drawing."

Listing 12. Register a CREATION_COMPLETE listener on the VBox.

The event handler method named completeHandler will compute and set the height of the VBox based on the sum of the heights of the child components.

The completeHandler method of the TrueFalse01 class

The completeHandler method is shown in its entirety in Listing 13.

Listing 13. The completeHandler method of the TrueFalse01 class.

This method computes and sets the height of the VBox container to the sum of the heights of its child components plus six pixels per component to account for the space between components.  The result of computing and applying this height is shown for Question 1 in Figure 3.

The end of the class

Listing 12 signals the end of the constructor and Listing 13 signals the end of the class named TrueFalse01.

Where do we go from here?

By now you should have a pretty good idea what this lesson is all about.  The previous paragraphs have explained the MXML template and the ActionScript class from which Question 1 in Figure 3 was constructed.

The remainder of the lesson will be dedicated to explaining the remaining five templates and classes from which the remaining five question styles are constructed.

As you may have guessed, there is a lot of similarity between templates and classes for the different styles of questions.  Therefore, I will concentrate on the differences and will highlight the code that is new to each new template and class.

The classes named ThreeChoices01 and FourChoices01

The next two classes that I will discuss are so similar that I will lump them together for discussion purposes.  I will explain the source code for the class named FourChoices01, which is simply an expanded version of the class named ThreeChoices01.  Complete listings of the two classes are provided in Listing 35 and Listing 36 near the end of the lesson.

Multiple-choice questions with three and four choice

The visual representations of objects instantiated from these two classes are shown in Figure 4.

Figure 4. Multiple-choice questions with three and four choices.

"Old-fashioned" multiple-choice questions

These are "old-fashioned" multiple-choice questions where the student is required to select only one of either three or four choices.  As before, when the student clicks the button labeled Click to Check Answer, the student's choice is evaluated and the result is shown in either red or green text below the button.

The MXML templates

MXML templates for these two question styles are shown in Listing 14.  The first template in listing 14, (highlighted in yellow), is for three choices.  The template highlighted in cyan is for four choices.

Listing 14. MXML templates for multiple-choice questions with three and four choices.

Very similar templates

As you can see, the template for four choices is like the template for three choices except that it contains information for four choices instead of just three.

A zero-based system

The instructions for these two templates should be pretty clear.  However, the one thing that may be worth pointing out is that the value of the answer attribute is specified in a zero-based counting system. 

For example, the value of the answer attribute for the first choice in Figure 4 (Dopey) is "0" and the value of the attribute for the fourth choice (Harold in Question 3, Figure 4) is "3".  This probably won't seem unusual to people with a programming background but it may seem strange to others.

Beginning of the class named FourChoices01

The class named FourChoices01 begins in Listing 15.  As usual, I will explain this class in fragments.  A complete listing of the class is provided in Listing 36 near the end of the lesson.

Listing 15. Beginning of the class named FourChoices01.

Very similar to the previous class

Even though this class declares a few more variables, this file begins in a way that is very similar to the ActionScript file for TrueFalse01.as discussed earlier.  (See Listing 3 and Listing 4.)

Implicit setter methods for FourChoices01

The implicit setter methods for this class are shown in Listing 16.

Listing 16. Implicit setter methods for FourChoices01.

More implicit setter methods than before

As you may have surmised from the template in Listing 14, more implicit setter methods are required for this class than for the class named TrueFalse01 (see Listing 5).  This is because the author of the test must provide a label for each of the four choices.  (Compare the setter method names in Listing 16 with the attribute names in Listing 14.)  However, there is nothing new or different about the implicit setter methods in Listing 16.

The constructor for FourChoices01

The constructor for this class is shown in its entirety in Listing 17.

Listing 17. The constructor for FourChoices01.

Differences relative to TrueFalse01

The main differences between this constructor and the constructor for the class named TrueFalse01 discussed earlier are:

  • This constructor instantiates four radio buttons instead of just two.
  • The labels on the radio buttons are set by the last four implicit setter methods in Listing 16 instead of being hard-coded as "True" and "False" in the constructor.

Otherwise, the two constructors are essentially the same, including the registration of a click event handler named checkButtonHandler on the button shown in Figure 4 and the registration of a CREATION_COMPLETE event handler named completeHandler on the VBox container.

Beginning of the method named checkButtonHandler

This event handler method begins in Listing 18.

Listing 18. Beginning of the method named checkButtonHandler.

The main purpose of the code in Listing 18 is to establish the correct answer and store it in the variable named correctAnswer declared in Listing 15.

Similar to previously-discussed code

The code in Listing 18 is essentially the same as the code in Listing 10 discussed earlier except that:

  • Listing 18 deals with four choices instead of just two as is the case in Listing 10.
  • Listing 18 extracts the correct answer from a label on a radio button instead of simply setting the correct answer to "True" or "False" as is the case in Listing 10.

Compare correct answer with selected radio button and report

Listing 19 compares the selected radio button with the answer specified by the question's author in the MXML code in Listing 14 to determine if the student has selected the correct answer.

Listing 19. Compare with selected radio button and report.

Report the results of the comparison

Listing 19 also reports the results of the comparison in the text box below the button as shown in Figure 4.  If the student selected the correct radio button, the report is presented in green text.  Otherwise, it is presented in red text.

The completeHandler method for FourChoices01

The method named completeHandler is shown in its entirety in Listing 20.

Listing 20. The completeHandler method for FourChoices01.

Executed when the VBox has completed construction

As was the case for the class named TrueFalse01, this method is executed when the VBox that contains the user interface for the multiple-choice question "has finished its construction, property processing, measuring, layout, and drawing."

Set the height of the VBox container

The purpose of the method is to set the height of the VBox container based on the individual heights of the components contained in the container.

The code in Listing 20 is essentially the same as the previously discussed code in Listing 13 except that there are more components whose heights must be added to compute the required height of the VBox.

The end of the class

Listing 20 signals the end of the class named FourChoices01.

The class named FourChoicesWithRef01

The visual manifestation of an object instantiated from this class is shown in Figure 5.  An object of this class is a question style that provides a multiple-choice question with four mutually exclusive choices and a reference to a URL of the author's choice.

Figure 5. Multiple choice question with four choices and a reference.

Open the reference in another window

When the bottom button in Figure 5 is clicked, the reference that is linked to the button opens up in a new browser window as shown in Figure 6.

Figure 6. Reference item opened in a new browser window.

Can link to a variety of other media

The example that I will present in this lesson links the button at the bottom of Figure 5 to a web page on the Adobe help site as shown in Figure 6.  However, the button can be linked to any media that is acceptable as a URL by the parameterized constructor for the URLRequest class.  (Note that some security restrictions may apply.)

Could link to an image file

For example, the button could be linked to an image file causing the image to be opened in a new browser window when the button is clicked.  An example of linking to an image is shown in Figure 7.

Figure 7. Result of linking the Reference button to an image file.

Although I didn't show the code for doing this, Figure 7 was produced by linking the button at the bottom of Figure 5 to the image file named flex0120z.jpg located in the Images folder in Figure 1.  All that is required to accomplish this is to set the value of the referenceURL attribute in the template to "Images/flex0120z.jpg".

The MXML template for the FourChoicesWithRef01 class

Listing 21 shows the MXML template that can be used with the FourChoicesWithRef01 class to produce a question object like that shown in Figure 5.

Listing 21. The MXML template for the FourChoicesWithRef01 class.

Similar to previous template

If you compare the template in Listing 21 with the template highlighted in cyan in Listing 14, you will see that it differs only with respect to the addition of the referenceURL attribute at the bottom.

As I mentioned earlier, you can set the value of the referenceURL attribute to any string value that is acceptable as a URL by the parameterized constructor for the URLRequest class.  In this case, the specified value of the referenceURL attribute in Listing 21 links the button at the bottom of Figure 5 to a specific page on the Adobe website.

Very similar to the FourChoices01 class

The class definition for the class named FourChoicesWithRef01 is very similar to the previously-discussed class named FourChoices01.  Therefore, I am going to concentrate only on the differences between the two.

Abbreviated class definition for FourChoicesWithRef01

Listing 22 shows an ActionScript listing for this class where only the code that is different from FourChoices01 is shown.  The remaining code has been deleted for brevity.  You will find a complete listing of this class in Listing 37 near the end of the lesson.

Listing 22. Abbreviated class definition for FourChoicesWithRef01.

Material shown in Listing 22

Scanning Listing 22 from top to bottom, we see:

  • An import directive for the URLRequest class.
  • An import directive for the navigateToURL function.
  • A variable declaration for a variable named refButton that is used to store a reference to the button at the bottom of Figure 5.
  • A variable declaration for a variable named theReferenceURL that is used to store the URL that is linked to the button at the bottom of Figure 5.
  • An implicit setter method named referenceURL used to establish the property with the same name (see the template in Listing 21).
  • Instantiation of the button shown at the bottom of Figure 5.
  • Registration of a click event handler method named refButtonHandler on the button at the bottom of Figure 5.
  • Definition of the event handler method named refButtonHandler highlighted in yellow in Listing 22.

What is different here?

The only thing that is different in Listing 22 is some of the code in the method named refButtonHandler.

Connecting to the reference URL

As you can see in Listing 22, all that is necessary to connect to the referenced URL is to:

  • Instantiate a new URLRequest object passing the reference URL as a parameter to the constructor.
  • Call the navigateToURL function passing the URLRequest object's reference as a parameter to the method.

The navigateToURL function

Note that the navigateToURL function is a global (or at least quasi-global) function in the flash.net package.  Therefore, it was necessary for me to import the function in Listing 22.  According to the documentation, this function "Opens or replaces a window in the application that contains the Flash Player container (usually a browser)."

An exception handler

The remaining code in the refButtonHandler method is intended to alert the user if the connection attempt fails.  I will leave it as an exercise for the student to investigate the show method of the Alert class on her own.

The end of the class named FourChoicesWithRef01

Listing 22 signals the end of the class.

The class named FourChoicesWithImage01

The visual manifestation of an object instantiated from this class (when it first appears on the screen) is shown as Question 5 at the top of Figure 8.  An object of this class is a question style that provides a multiple-choice question with four mutually exclusive choices and an image embedded in the question.  (The image in Figure 8 is the Java source code inside the box.)

Figure 8. Question with image before resizing.

Image size is an issue

Embedding images into the presentation of the question presents some interesting challenges due to size considerations.  Two things are at play here.

  • First, the designer of the class can't possibly know the size of the image that will be used by the author of the test question.
  • Second, there may be significant time delays involved in the loading of images, which makes it difficult to use the size of the image to automatically set the size the VBox during the initial construction of the question object.

Automatic scroll bars

Note the scroll bars on Question 5 in Figure 8.  The vertical scroll bar was created automatically because the total height of all the components (including the image) was greater than the height of the VBox container.  When the vertical scroll bar appeared, it consumed part of the available width causing the remaining width to be less than the width of the text area containing the question.  This in turn caused a horizontal scroll bar to appear.

Scroll bars may not be the best solution

Obviously, the scroll bars can be used to view the entire question object, but that may not be the best approach for someone who is taking a test.  As a result, I elected to construct the question object with a default size and to provide a resize button by which the student can cause the question object to be resized to accommodate the image along with all of the other components.

Question with image after resizing

The resize button is shown at the top of Figure 8 with the label Click to Resize.  Figure 9 shows Question 5 and part of Question 6 after the student clicks the resize button and also clicks the button labeled Click to Check Answer.

Figure 9. Question with image after resizing.

Everything fits

As you can see in Figure 9, the height of the VBox container has been increased, the scroll bars are gone from the question object, and all of the components in the question object are clearly visible.

Also adjusts the width

Although it is not shown in Figure 9, if the width of the image is greater than the current width of the VBox container, the width of the container will also be increased to accommodate the width of the image.

The MXML template for the FourChoicesWithImage01 class

Listing 23 shows the MXML template that can be used with the FourChoicesWithImage01 class to produce a question object like that shown in Figure 8 and Figure 9.

Listing 23. The MXML template for the FourChoicesWithImage01 class.

Similar to previous template

As before, if you compare the template in Listing 23 with the template highlighted in cyan in Listing 14, you will see that it differs only with respect to the addition of the imageName attribute shown highlighted in cyan in Listing 23.

As indicated in the instructions in Listing 23, the image file of type JPEG (jpg),  PNG, or GIF should be placed in the folder named Images as shown in Figure 1.  Then the value of the imageName attribute should be set to the name of the image file without regard for the path to the file.  (The path to the Images folder is handled in the class definition.)

Very similar to the FourChoices01 class

The class definition for the class named FourChoicesWithImage01 is very similar to the previously-discussed class named FourChoices01.  Therefore, as I did before, I am going to discuss only the differences between the two classes.

Abbreviated class definition for FourChoicesWithImage01

Listing 24 shows an ActionScript listing for this class where only the code that is different from the FourChoices01 class is shown.  The remaining code has been deleted for brevity.  You will find a complete listing of the FourChoicesWithImage01 class in Listing 38 near the end of the lesson.

Listing 24. Abbreviated class definition for FourChoicesWithImage01.

Material shown in Listing 24

Scanning Listing 24 from top to bottom, we see:

  • An import directive to import the Image class.
  • Declaration of an instance variable named resizeButton.
  • Declaration of an instance variable named theImage.
  • Declaration of an instance variable named theImageName.
  • An implicit setter method named imageName that matches the attribute name shown in the template in Listing 23.
  • Instantiation and configuration of the resize button labeled Click to Resize.  A click event handler method named resizeButtonHandler is registered on the button and the button is added to the VBox immediately above the text area containing the question as shown in Figure 9.
  • Instantiation of a new Image object and the addition of the object to the VBox immediately below the text area containing the question as shown in Figure 9.  Note that the Image object is not connected to the image file at this point.  The reason will be explained later.
  • Registration of a CREATION_COMPLETE event handler on the VBox.  This was also done in the classes discussed earlier, but it has an additional purpose in this class.
  • The definition of the completeHandler method.
  • The definition of the resizeButtonHandler method.

What is new here?

All of what you see in Listing 24 is different from the class named FourChoices01 but much of it is not new to the discussion of this class.  I will explain only those things about Listing 24 that are new to the discussion of this class.  I have highlighted those items in the above list.

The implicit setter method named imageName

There is nothing really new about this implicit setter, but the circumstances surrounding its use are problematic.  The name of the image file is provided by the value of the attribute named imageName in the MXML template in Listing 23, causing it to be passed as a parameter to the implicit setter.  The setter stores the incoming name of the image file in the instance variable named theImageName.  This can lead to a timing problem.

A timing problem

The problem is that the name of the image file may not have been stored in the instance variable by the time the Image object is instantiated a little further down in the constructor.  In that case, the instance variable will contain null and an attempt to connect the Image object to the image file will fail.  Therefore, in this case, it is advisable to avoid connecting the Image object to the image file when the Image object is instantiated.  Instead, it is better to defer making that connection until the VBox object fires a CREATION_COMPLETE. event.

The completeHandler method

As you learned earlier, the completeHandler method is executed when the VBox container fires its CREATION_COMPLETE. event.  By this point in time, the attribute value from Listing 23 should have been stored in the instance variable named theImageName.

Set the source property of the Image object

For purposes of this discussion, the most important statement in the completeHandler method in Listing 24 is the statement highlighted in magenta.  This statement assigns the name of the image file (including the path to the Images folder) to the source property of the Image object.  This causes the actual image to be extracted from the file and displayed in the browser window.

Image size may not be available

However, some time may be required for the image to actually load and for its size to be established.  Therefore, some time must pass before the size of the image can be used to establish the required size for the VBox to contain the image and all of the other components.

II elected to set the height of the VBox to a default value that assumes an image height of 100 pixels and to allow the student to click the resize button to set the correct size of the VBox later.  The code near the end of the completeHandler method sets the default height of the VBox.

The resizeButtonHandler method

The resizeButtonHandler method in Listing 24 is executed when the student clicks the resize button at the top of Figure 8.  It is assumed that by the time the student clicks the resize button, the image will have been loaded and displayed.  Hence, the height and width properties of the Image object will contain the correct size.

The code in the resizeButtonHandler method uses the height of the image to adjust the height of the VBox so that it will accommodate the image and all of the other components.

Then the method checks to determine if the width of the image is greater than the current width of the VBox.  If so, it also adjusts the width of the VBox so that it will accommodate the width of the image.

The end of the class

Listing 24 also signals the end of the class named FourChoicesWithImage01.

The class named FourAnswers01

The visual manifestation of an object instantiated from this class is shown in Figure 10.  An object of this class is a question style that is completely different from all of the other question styles in this lesson.  In particular, all of the other question styles require the student to select one and only one answer.  This question style allows the student to select none, one, or more of the answers that apply to the question.

Figure 10. Question style for multiple answers.

The MXML template for the class named FourAnswers01

Listing 23 shows the MXML template that can be used with the FourAnswers01 class to produce a question object like that shown in Figure 10.

Listing 25. The MXML template for the class named FourAnswers01.

One major difference

Insofar as the MXML template is concerned, this question is no more complex than the others.  The one difference is that it may be necessary to provide multiple answers as a comma-separated list of answer numbers as the value of the answer attribute.

If only one answer applies, no comma is required (but the inclusion of a comma in the list won't cause a problem).

If none of the answers apply, the value of the answer attribute should be set to a pair of quotation marks with nothing in between.

Grading criteria

The answer provided by the student will be deemed incorrect unless all of the answers in the list and only the answers in the list are selected by the student in the user interface of Figure 10.  (Note that the sample template shown in Listing 25 matches the user interface display shown in Figure 10.)

More complicated than the other classes

Many aspects of this class are similar to the class named FourChoices01.  However, in some respects, the programming logic for this class is more complicated than the programming logic for the other classes that I have discussed.

As I have done for the past several classes, I will present and explain an abbreviated version of the class definition.  In this case, however, I will break the event handler methods out into separate listings and explain them in somewhat more detail.

Partial abbreviated class definition for FourAnswers01

Listing 26 shows an abbreviated version of the class definition without the event handler methods.  (The event handler methods will begin in Listing 27.)  A complete listing of the source code for the class named FourAnswers01 is provided in Listing 39 near the end of the lesson.

Listing 26. Partial abbreviated class definition for FourAnswers01.

Material shown in Listing 26

Scanning Listing 26 from top to bottom, we see:

  • Declaration of an instance variable named resetButton.
  • Declaration of an instance variable named instruction.
  • Instantiation of a new Label object referred to by the variable named instruction.  This label is added to the VBox container and is shown in Figure 10 with the text "Select none or all that apply".
  • Instantiation of four radio buttons with different group names.  Giving them different group names makes it possible for the student to select more than one at a time.  They are added to the VBox and appear in Figure 10 with the labels "Dopey", "Harold", etc.
  • Instantiation of a Button object referred to by the variable named resetButton.  This button is added to the VBox container and appears in Figure 10 with the label "Click to Reset" immediately below the four radio buttons.  A click event handler method named resetButtonHandler is registered on this button.

Event handler method named resetButtonHandler

The event handler method named resetButtonHandler is registered on the button shown in Figure 10 with the label "Click to Reset".

Listing 27. Event handler method named resetButtonHandler.

The purpose of this event handler is to clear all four of the radio buttons to the unselected state in order to allow the student to change her mind and start over if she has already selected one or more radio buttons.  The code in Listing 27 is straightforward and simply sets the selected property of each radio button to false.

Event handler method named completeHandler

Although it isn't shown in Listing 26, the event handler method named completeHandler is executed when the VBox container fires a CREATION_COMPLETE event.  That event handler is shown in its entirety in Listing 28.

Listing 28. Event handler method named completeHandler.

Adjust the height of the VBox object

As has been the case in earlier classes, the code in Listing 28 computes and adjusts the overall height of the VBox container on the basis of the individual heights of the components contained in the VBox.  However, that is not new and is the not the reason that I am discussing the event handler here.

Need to set the instruction style

The MXML file shown in Listing 33 contains an mx:Style element (near the bottom) that sets the style of objects of type Label to bold and yellow with a font size of 18 point.  This is what causes the yellow text at the top of Figure 2 to be displayed in that style.  Because that style is set in the MXML file, it is applied to all Label objects in the entire application unless those Label objects provide style settings that override that style.

This class waits until the construction of the VBox is complete and then executes the two statements highlighted in yellow in Listing 28 to override the style that is specified in the MXML file.  This produces an instruction label with the style shown in Figure 10.

The event handler named checkButtonHandler

The event handler named checkButtonHandler is registered on the button shown in Figure 10 with the label "Click to Check Answer".  As has been the case in the other classes discussed in this lesson, the purpose of the event handler is to determine if the student has selected the radio button(s) that correctly answer the question.

More difficult than before

Accomplishing that task in this class is more difficult than has been the case in the previous classes.  In those classes, it was assumed that there was always one and only one correct answer.  That was fairly easy to deal with.  In this class, it is assumed that the correct answer may involve selecting none, one, or more of the four radio buttons shown in Figure 10.

Typographical errors

Another issue that arises in this class is the increased probability that the author of the question will make a typographical error when specifying the correct answer as the value of the answer attribute in Listing 25.

For example, the author may leave out a comma, may insert an extra comma, may insert a space, may specify the radio buttons in something other than ascending order, etc.  The code in this event handler attempts to guard against such typographical errors.

Interpreting the answer attribute value

The code is designed to properly interpret the value of the answer attribute so long as it contains some combination of none, some, or all of the characters "0", "1", "2", and "3" in any order, regardless of other extraneous characters (such as space characters) that may have been inserted.  (Since I can't test the code against all possible typographical errors, only time will tell if I was successful at achieving that goal.)

Several different approaches are available

There are a variety of ways to write the code to accomplish the task assigned to this event handler.  The approach that I elected may not be the most elegant, but hopefully it won't be too difficult to understand.

Beginning of the event handler named checkButtonHandler

The method named checkButtonHandler begins in Listing 29.

Listing 29. Beginning of the event handler named checkButtonHandler.

Create a pair of four-element arrays

Listing 29 creates a pair of four-element arrays capable of storing data of type Boolean.  The array referred to by buttonArray is populated with the current state of the four radio buttons shown in Figure 10.

The array referred to by answerArray will be populated based on the values provided by the author of the question for the answer attribute in Listing 25.

Compare the contents of the two arrays

Eventually, the contents of the two arrays will be tested for a match to determine if the student has selected the correct radio buttons. 

 Whether correct or not, the event handler will also construct and display a string containing the correct answer as shown in green at the bottom of Figure 10.

Parse the value from the MXML answer attribute

This class uses an implicit setter method to store the value of the answer attribute in Listing 25 in an instance variable of type String named theAnswer.  Listing 30 parses that string eliminating all characters other than "0", "1", "2", and "3".

Listing 30. Parse the value from the MXML answer attribute.

Discard unwanted characters

Listing 30 calls the charCodeAt method of the String class to get the Unicode value for each character in the string.  The numeric Unicode values for the characters "0" through "3" are 48 through 51.  This knowledge is used to discard all characters whose Unicode value is outside the range 48 through 51.

Set Boolean values in answerArray

Listing 30 uses the characters that are not discarded in the parsing process to set true Boolean values in the answerArray elements for those elements whose index matches the implied numeric value of the numeric characters.

The implied numeric value

The characters "0" through "3" are converted to the numeric values 0 through 3 by subtracting the constant 48 from the Unicode value of the character.  Those values are used as indices to store a true value in each element in the array referred to by answerArray whose index matches the implied value of one of the characters in the range from "0" through "3".

At this point, the array referred to by answerArray contains true and false values that match the value of the answer attribute in Listing 25.

Construct a string containing the correct answer

Listing 31 uses the information in the array referred to by answerArray to select labels from the radio buttons to construct a string containing the correct answer as shown in green at the bottom of Figure 10.

Listing 31. Construct a string containing the correct answer.

Compare student selections with the correct answer

Listing 32 compares the contents of the two arrays that were created in Listing 29 to determine if they match on an element by element basis.

Listing 32. Compare student selection with the correct selection.

If the array contents match...

If the contents of all four corresponding elements in the two arrays are equal, the color is set to green and a Correct message is displayed along with the correct answer in the text area at the bottom of Figure 10.

If they don't match...

Otherwise, the color is set to red and a Wrong message is displayed along with the correct answer in the same text area.

The end of the class

Listing 32 signals the end of the class named FourAnswers01, which is the final class to be discussed in this lesson.

Run the program

I encourage you to copy the code from Listing 33 through Listing 39.  Use that code to create a Flex project.  Compile and run the project.  Experiment with the code, making changes, and observing the results of your changes.  Make certain that you can explain why your changes behave as they do. 

Summary

In this lesson, you learned how to create a Rich Internet Application consisting of an online test using Flex and custom ActionScript components.

Resources

Complete program listing

Complete listings of the MXML code and the ActionScript code discussed in this lesson are provided in Listing 33 through Listing 39.

Listing 33. MXML code for TestGenerator01.

 

Listing 34. ActionScript code for TrueFalse01.as.

 

Listing 35. ActionScript code for ThreeChoices01.as.

 

Listing 36. ActionScript code for FourChoices01.as.

 

Listing 37. FourChoicesWithRef01.as

 

Listing 38. ActionScript code for FourChoicesWithImage01.as.

 

Listing 39. ActionScript code for FourAnswers01.as.

 


Copyright

Copyright 2009, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is object-oriented programming using Java and other OOP languages.

Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin’s Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP).  His first job after he earned his Bachelor’s degree was doing DSP in the Seismic Research Department of Texas Instruments.  (TI is still a world leader in DSP.)  In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com

-end-