Subclassing GraphingApplet and ReportingSlate: A Math Applet Cookbook

To use these packages to make applets like the examples, you genrally need to write two .java files: One for a subclass of GraphingApplet, and one for a subclass of ReportingSlate.

Fully anotated templates are provided here for these two subclasses (See the links at the bottom of the Source Code page). On the same page you will find links to all of the source code for all of the sample applets. In some cases the commenting is more detailed than others, but for the most part, you will probably find them commented sufficiently well. If not, please let me know!

The present page details, pretty much step by step, what you need to do to use them.

Part One: Preliminaries and the Reporting Slate

Step One -- Defining Your Package

First, pick a package name for your applet, and make you classes part of this package. Be sure to include

import graphingApplet.*; import functionParser.*;

so that you can use the classes in these packages! This is done for you if you use the templates.

Step Two -- Setting up the Reporting Slate Subclass

Next, decide what buttons you want on the reportingSlate subclass, and what messages you wnat displayed there. The messages will probably involve reporting on data generated by the GraphingApplet subclass, so decide what data, name it, and register it with the MessageCenter using the ReportingSlate subclass's subscribe() method.

For example, in the TangentSlate.java example, we will have three buttons "clear", "in", and "out" -- for clearing the graph, and zooming in and out. These are defined right below the private sizing variables that are already specified in the template.

Next, we need to keep track of three doubles for reporting -- the coordinates of the clicked point, and the slope there -- as well as an integer "flag" to tell whether the user clicked or not (since what we paint depends on that) and no Strings. We name the slate "slopes", and do the subscribing as follows in the constructor. This is what follows the resize call. Since we have just one named integer to register, we create an IntDataArray of length one in our subscriber, and then we instantiate it by filling its single slot with a NamedIntData called "clicked, and carrying the initial value 0. Next we take care of the named double data. Since no named Strings are used in this example, we create a NamedStringDataArray of length zero for our subscriber.

Now that the subscribing is done, we create a ButtonPad of the right size for holding our three buttons the way we want, and ad the buttons to it. (See the BuutonPad documentation for your options here.) Finally, the template contains code for adding the ButtonPad itself, as well as the canvas on which the messages from the applet will be drawn.

In fact, next comes the paint(Graphics g) method that draws the strings to the canvas. Override this to paint the meesage you want. The message will typically depend on flags stored in the message center, and will report values from pieces of named integer and double data stored there. That is what happens in this example.

Finally, we add the code to make the buttons work. This is done here in the Java1.02 way here because many students here at Georgia Tech are using browsers that don't support Java1.1. So one overrides action() in the usual way -- except that if they are to make the graph do something standard, like zooing in or out, one should use the MessageCenter's runNamedParentMethod(String name, int x, int y) method, which is all set up to take care of such standard tasks. There is also cleanParentInput() which is likely to be called by a "clear" button.

That's about it. To summarize, the main interaction with the graphingApplet package here comes when you (1) subscribe named data, use ButtonPad to arrange buttons -- or text fields and such, and (3) use the runNamedMethod(String name, int i, int j) and such MessageCenter calls to make buttons do their thing.

Part Two -- Setting Up the Graphing Applet Subclass

Next you write your subclass of GraphingApplet. As explained in the introduction, your main work here is in overriding three methods:


(1) handleAllData()

(2) runNamedMethod(String name, int x, int y)

(3) doAllPainting()

But before we get to this, we need to take care of some routine instanitating, and setting up the init() method.

Step Three -- Creating the Instance Variables and Setting Up init()

We will continue with the TangentLine applet example, this time following the code for the GraphingApplet subclass, TangentLine.java. This code was created by filling in the template, replacing some of the comments there with code. In fact, the replaced comments just say what code they should be replaced with.

We need a bunch of instance varibles to keep track of user interaction (the boolean clicked), graphing calculations (like where the edges of the graph are) and computations. And we also need one FunctionEnteringPanel, and an associated Evaluator. See the code itself for clarifying comments on these.

Then we begin with init(), following the template, which has the obligatory immediate call to super.init() right at the beginning where it has to be.

Next, one adds the FunctionEnteringPanels. In this example there is only one, but it is put into an array fep of FunctionEnteringPanels. This array variable, fep, is a public variable of the super class. Even though there is only one FunctionEnteringPanel, it must still go in this array, since the super class will use the array to arrange however many FunctionEnteringPanels you have speicifed appropriately in the bottom BottomPanel of the applet. Dealing with an array at this stage is a small price to pay for hiding away all interaction with layout managers!

Next, this applet will have three cards in its CardBox. We now pick names for these cards, and labels to go by the radio buttons in the card selector. There is no really strong reason why one couldn't use the labels for the names, but some labels might look better with two words and spaces which isn't suitable for the names, so why not go for flexibility.

Once these arrays are ready, we construct the CardSelector.

This done, we construct the three objects that will be put on the cards. These must all be subclasses of Panel. Here we have a CursorReport, a GraphParameters and the ReportingSlate subclass that we worked on above.

Once these are ready, we instantiate the super class's cards variable. This is an array of Panels. We have three in this example. We then fill in the array with the cards constructed just above.

At this stage, we've got the CardBox in good shape. Now for the graph. We create the GraphCanvas and the two "badges" -- the CursorBadge and the GraphLocationBadge that go with and "label" it.

Next, add the copyright panel, constructed with your staement of authorship.

Finally, all of the pieces are ready to put in place. The template has code written in here for creating a top and bottom panel. The top panel holds the graph and the cardbox, sitting above the cardbox selector. The bottom panel contains all of the function enetering panels. These are now construced and added to the applet.

Now comes the "hooking up" stage of the initialization. We have everything in place, we just need to hook the pieces together. The fist step is to call mc.arrayConversion() which collects all the lists of named pieces of data from all of the MessageSubscribers and puts them in arrays for fast access. This too is done in the template, as is the first call to the GraphCanvas's updateParameters() method, which "harmonizes" it with the other components.

Finally, the instance variables must be instantiated, and the method ends with a call to handleAllData(), defined below, which does computations that are preliminary to graphing.

Step Four: Writing the Code For the Three Key Methods

Next, in the sample code you see the key methods written in:

(1) handleAllData()

(2) runNamedMethod(String name, int x, int y)

(3) doAllPainting()

in this order. The TangentLine applets does something pretty simple -- it draws tangent lines to a graph, so you can presumablr follow this step by reading the code. there aren't many mathematical details to worry about with this one, which is why it was picked for the example.

That is it. If you try to use this, and find that it is not clear about some point, please let me know.


Eric A. Carlen (send message)