Introduction

The cox.jmatt.java.MathToolsapplication is a Java utility designed to assist in the development, formatting, and presentation of math questions for printed tests. It consists of ten packages: the core tools, seven packages of classes designed to support, demonstrate, and utilize them, and three specific implementations of the graphing.* package.

In a Nutshell

MathTools is...

* For some Java installations scripting or XML processing might require an external JAR.

MathTools is NOT...

MathTools Structure and Organization

cox.jmatt.java.MathTools.*

These are the core tools; the classes that do the work of presenting, manipulating, and generating test content.

cox.jmatt.java.MathTools.test.*

The .test.* package provides a container for things that might appear on a math test. Specifically, questions, answers, and additional text or notes.

cox.jmatt.java.MathTools.util.*

These are utility classes. They provide support services for the core tools or for applications using them.

cox.jmatt.java.MathTools.demo.*

The demo package contains classes designed to demonstrate the capabilities of the other MathTools classes. Every method of every class is not shown, but enough is presented to give a good idea of what's in the class and how it works. The demos are organized by class, and most are PizzaPanels. The star of the package is ScriptPanel and it is explained in more detail than the rest.

ScriptPanel provides a complete, if minimal, scripting environment. It uses the javax.script package. The GUI itself consists of four Panels plus a Forward and Back button to switch between them. The individual panels, and their functions, are:

By default, ScriptPanel uses JavaScript and instantiates an engine by name. To change this, point the URLLoaderPanel to the JAR containing the desired scripting language and enable it on the Config panel. Then enter or load a script, run it, and do unto the results!

The MathDBC & SQL demo runs SQL commands against any JDBC-compliant database. It can be used to build a database or manipulate an existing one, with SQL! SQL commands can be entered manually or loaded from a file. If the last command executed generates a ResultSet it can be formatted: there is a field for entering a row template. This plus the ResultSet are sent to MathTestFormatter and the result printed and optionally sent to the clipboard.

The MTFormatter demo provides access to the MathTestFormatter apart from the scripting environment. A template can be entered manually or loaded from a file. Template data can be loaded from a properties file, loaded from a properties panel, or both. Or a regular expression can be entered, applied to data from the RegEx data panel and its capture groups row-formatted.

The GPGenerator demo utility uses the SVG classes to generate graph paper. It has built-in generators for square-grid, polar, log and semilog, and a specialized chart usable for tracking blood pressure or blood sugar. There is also a generator for ledger-style sheets: multiple columns of differing widths and optional column headers. The class itself pre-defines a plethora of different pens (CSS styles) for rendering lines and text, and the generators themselves offer many configuration options. (The SVG output is sent to the clipboard where it can be pasted into a document and transcoded into a print- or graphic format.)

cox.jmatt.java.MathTools.graphing.*

The graphing base package consists of interfaces and concrete classes required for graphing implementations. They are:

The helper classes in the base package are:

cox.jmatt.java.MathTools.markup.*

The markup.* package provides the basic tools needed to build a fully scriptable CSS-styled XML markup language. It consists of two base classes, with one of them abstract, and two implementation classes. Two of these are designed around tag construction and manipulation and the others are for building CSS rules or 'style=' attributes.

cox.jmatt.java.MathTools.markup.svg.*

This markup.* subpackage implements the machinery to generate SVG markup. It consists of tag classes which correspond exactly with SVG tags, and pen classes which are used for the CSS styling germane to SVG. The MathDrawSVG class rounds out the package: it provides methods to generate instances of the others along with methods to set their default values.

Tag classes based on DrawableContainerTag are tags capable of containing other SVG tags: <g>, <symbol> and <svg> to name three. The 'drawable' means they also have methods to create, intialize and add other (drawing) tags directly, without requiring separate instantiation. This makes quick work of adding lots of drawing primitives (lines, circles, paths, etc.) without a lot of work.

This package also serves as an example of how the markup.* classes can be extended into a markup language implementation.

cox.jmatt.java.MathTools.markup.html.*

This package makes (X)HTML document generation scriptable just like the SVG package does for graphics. The BaseHTag is the superclass of all the tag classes in this package. It is a Tag sublcass so HTML-document scripting works much as does SVG.

cox.jmatt.java.MathTools.scrob.*

Not all scripting engines expose static methods to their scripts. All MathTools core classes have some static methods, and some classes have ALL static methods. SCROBs exist to alleviate this situation. A SCROB, or scriptable object is a class whose instance methods exactly duplicate and reflect to the same static method in the class SCROBbed. All-static MathTools classes do have ONE instance method: getSCROB(). If a script can't find a static method, call getSCROB() on that tool and use the SCROB in its place. SCROB Documentation: SCROBs don't have documentation. They duplicate static classes that DO.

Classes with fewer static methods have instance methods that 'shadow' them.

Logging and Communication

The MathTools logging and communication structure includes two components: CapCom and the MathPrinter interface. The MathTools classes report error and program flow information to CapCom. CapCom then relays this to the Global Printer, if one is set. Any class can be the Global Printer, as long as it implements the MathPrinter interface. The metaphor used is that the Global Printer has some method to display such logging information. Its processMathObject() method exists for subclass extension: none of the MathTools classes use it. It accepts an Object as a parameter and returns an Object; past that MathTools does not specify any aspect of it.

The MathConsole class exists to provide access to MathTools logging and communication. Though primarily meant for scripts, any class can make use of it. It and CapCom provide two logging methods for each level: Debug, Info and Error. One method accepts a String message and the other takes a String and a Throwable. Scripts needing to print a Debug-level message and Exception call Console.debug('Message', Exception) and Java applications using MathTools would call CapCom.debug('Message', Exception).

For non-logging messages MathPrinter defines mathPrintln() which accepts a String. CapCom and MathConsole both define mathPrintln() along with a plain println() method that aliases to it. MathPrinter is bi-directional via the processMathObject() method, which scripts can use to interact with user-defined MathPrinters.

Data Storage and Retrieval

CapCom makes provision for setting and retrieval of the Global Pizza. This is simply a java.util.Properties object. The application sets it before executing a script or using MathTools and it can be retrieved at need later. MathConsole provides read-only access to the Global Pizza and ScriptPanel sets it from the Script Pizza Panel before a script is executed.

The Shelf is the metaphor used for a java.util.Hashtable<String, Object>. Scripts or applications can store arbitrary things there. MathConsole allows scripts to store and retrieve things; applictions use CapCom.storeObject(), CapCom.getObject() or CapCom.removeObject().

Graphing

Graphing is an essential part of mathematics and no math package would be complete without at least a nod toward it. The graphing.* package is MathTools' nod. Since MathTools is primarily geared toward text output, its graphing package is designed with that in mind. It is meant to generate text capable of being consumed by some external application which will generate the actual graph.

The metaphor used here is of a student or teacher looking at (or creating) a problem that starts 'Graph the following...' with a blank sheet of graph paper and a pen. MathTools provides the graph paper (graphing.* package) and the pen (a script or application). It is up to the specific implementation to provide the actual machinery to change this math-problem-oriented data into a consumable format to generate the graph itself.

MathTools provides three implementations of the graphing package. The first, cox.jmatt.java.MathTools.java.graphing.xml is the XML implementation. The XML implementation is geared toward demonstrating how an implementation should behave and usable for persistent storage. It takes a script- or application-generated graph and turns it into simple XML markup that can be parsed and manipulated (DOM) or transformed (XSLT).

The cox.jmatt.java.MathTools.graphing.Graph implementation is built around the wonderful open-source Graph program. It can generate a basic .grf file which Graph can then load, edit, and convert to an image format.

The final implementation is the graphing.noop classes. These provide concrete classes implementing all Renderable interfaces but they do nothing! The no-op implementation is provided for extension by other implementations that don't need all the stuff the core interfaces mandate. (This is mostly because GraphHandler doesn't like GraphEngines that return null!)

MathTools & Scripting

Since the original posting of this page many things have changed. Foremost among them: MathTools now has a dedicated scripting tutorial!! Grab it from the download area and go to town with it. I'll leave the original stuff here, just because, but until whenever...

- - SNIP SNIP - -

The Basics

MathTools was designed for scripting. The tools themselves, even the all-static ones, have zero-argument constructors along with plenty of ways to generate more of themselves. All exposed tools also have SCROBs or shadow methods to ensure all methods are scriptable. Any scripting language can be used. All that is required is a javax.script.*-compliant API and a JAR file containing it.

ScriptPanel was designed to allow maximum flexibility and ease-of-use, right 'out of the JAR.' Everything required to get a script up and running can be configured from the Script Config panel. An URLClassLoader can be used to locate resources, both for MathTools and for any scripts. After the script ends, whatever Object it returns is displayed as a String and, if not-null, is copied to the clipboard. Thus, the MathTools JAR provides a complete scripting environment, capable of use with maximum flexibility and without the necessity of building a separate application just to access it.

Documentation

The best source of MathTools documentation is its javadoc. Every class and public method is documented and described there. Arguments, return values, possible errors, and even program flow is detailed. This document serves as a 'quick-start' guide and tutorial. Several sample scripts are included inside the MathTools JAR in the docs/SampleScripts folder. (This document is also there!)

The Scripting Language

By default MathTools uses JavaScript. Why? Because it is easy and it is included in most Java distributions. As stated above, though, this is NOT a requirement! The scripting language is easy to change, and ScriptPanel provides a ready-made environment for learning and exploring whatever scripting language is used.

While the MathTools are exposed to scripts, NOTHING says scripts must use them! One of ScriptPanel's greatest advantages is that it provides a place to experiment with a scripting language before even thinking about using MathTools! Albeit bare-bones and minimal, ScriptPanel offers a no-frills quick and easy place to actually learn a scripting language.

The MathClassLoader

CapCom maintains an URLClassLoader, the MathClassLoader, usable for non-JavaScript scripting languages (or JavaScript, if it's not included) and for other things as well. MTXPro and GraphEngineFactory both have the capacity to use it.

To change the scripting language simply put the JAR somewhere close to the MathTools JAR and put its URL into the URLLoaderPanel. Then enable the classloader and the scripting language will be available. This does require a javax.script.*-compliant package but those are many and more. The classloader set becomes CapCom's MathClassLoader, so custom XML parsers (SAX and DOM), XSLT transformers, and other graphing.* implementations can also be supplied there.

The Process

Step 1. Start MTDemo.

For operating systems that recognize executable JAR files, double-click the MathTools JAR file. The demo should fire up after a moment to initialize. If the operating system doesn't recognize executable JARs, open a command line, navigate to where the JAR file is and type the command:
java -jar MathTools_J6.jar
Once MathTools executes you will see the following:

From here all of the demos are available. The back and forward buttons ('[<|]' and '[|>]') can flip through the panels sequentially or a specific demo can be selected from the View menu. Select (or flip through to) the ScriptPanel demo.

Note that the Script demo also has forward and back buttons. Its individual panels are the Script Source panel (initially visible), the Script Pizza panel, the Script Config panel, and the URLLoader panel.

Step 2. Set up the environment.

To expose String properties to the script, select the Script Pizza panel. Enter any properties you want the script to know. They must be of the form:
PropertyName = Property value as a String
If the properties are to be available to multiple scripts, or multiple executions of the same script, consider saving them to a text file. This can then be loaded using the [Load] button.

The [Send to Global Pizza] button forces the properties to be parsed and set as the Global Pizza. ScriptPanel does this automatically, so that is not needed now. The button is there for applications that don't call ScriptPanel's deliverPizza() method.

Once the properties are set, select other options on the Script Configuration panel. The pre-configured options are at reasonable defaults for most scripting applications. The only thing that might need changing is the scripting language. ScriptPanel can instantiate an engine by name, by extension, or by its mimetype. Select the lookup option desired and change the 'Load engine...' TextField from javascript to whatever language/extension/mimetype is required. The '[]processMathObject(result)' checkbox is present for user-defined MathPrinters used with ScriptPanel. If checked, ScriptPanel calls CapCom.processMathObject() on the Object returned by the script's execution. BasicMathPrinter simply returns the object so checking this box has no result at all. Finally, if for some reason you do not want the return Object's toString() copied to the clipboard, uncheck that option here.

Step 3. Configure the ClassLoader

This step is optional unless you are using a scripting language other than JavaScript OR your script needs something from outside the MathTools JAR. If this is the case, flip to the URLLoader panel. File (or other) URLs can be typed into the TextArea directly, they can be selected individually via the [Add File URL] button, or a list can be loaded. As with the pizza configuration above, if multiple scripts need access, get the configuration perfect then copy/paste the perfect list into a text file!

Once the URLs are entered, click the [Check URLs] button. This checks the URLs. If all goes well an Info-level message appears reporting the number of URLs parsed. If this is less than the number entered, enable Error-level logging and click the button again. Any malformed URLs are reported at this level.

The [Set MTCL] button parses the URLs entered, builds an URLClassLoader around them and sets it as CapCom's MathClassLoader. Again, this button is there for custom classes using MathTools; ScriptPanel does this automatically. In fact, ScriptPanel sets the MathClassLoader regardless of whether or not it itself is using it.

IF your scripting language is different, make sure the URLLoader knows where it is and enable the '[]Enable URLClassLoader' box on the Script Config panel.

Step 4. Start scripting!

The easiest way to do this is to fire up your favorite text editor, enter and edit the script there, and load it into the script panel. Once it's there, click the [Run Script] button. If it doesn't work enable the Debug level and Stack Trace and try again. Work out the bugs (in the text editor, then re-load) and presto!

Don't be afraid to experiment! Fire up your web browser (Firefox, ideally!), load the javadoc and play with the tools. Then, once you're comfortable with the overall application you can start scripting in earnest. Good luck!


ScriptPanel after running a simple demo script.

The MathTools JAR also has a few sample scripts. They are in the docs/SampleScripts folder along with a copy of this web page. As a matter of interest, the version.txt file contains some version information. Specifically, the project name, the 'Stable Release' version number and the 'Build Code' number. These are displayed when MathTools is run from the JAR and the BasicMathPrinter's [Go!] button is clicked. Other than these, the rest of the content is MathTools!


Building from Source

Not a difficult process at all! Even simpler with the proper tools. I use jEdit to create/edit my program and script files. It's open-source, easy to use, written in Java, and does NOT impose a lot of 'overhead' common with other editors and IDEs. For managing the build process I use Ant from the Apache Software Foundation. The MathTools Ant script is build.xml located in the src directory of the download.

The steps for building MathTools are:

  1. Download the source file.
  2. Unzip the file into your project directory.
  3. Compile using whatever method you prefer.
Okay. Perhaps the last step needs more attention. Basic MathTools has NO external dependencies whatsoever. All of its source code is contained within Java itself. Most import statements start out java.something and the ones that don't are still included within Java! (Example: org.sax.stuff.) The only non-java dependencies are within the MathTools classes themselves, so no exotic includes are required.

Using Ant simplifies the process. If you don't have it but want to use it, download it and follow the installation instructions. After completing step #2 above you should have a folder in your (otherwise empty) project directory called src. Copy build.xml into the project directory itself. For the rest of the steps this will be the 'Project Directory' or 'Project Root Directory.'

Open a command prompt (Windows users) or equivalent (others) and navigate to the project root directory. Enter the command ant prepare and Ant will create the directory structure required for building and deployment. THIS IS IMPORTANT!! The MathTools build script expects a certain directory structure and this task creates it! Executing 'prepare' multiple times will NOT hurt anything, so don't worry if it happens.

Once the proper structure is in place, the two commands you'll use most often are ant compile and ant run. The former compiles any files that have changed and reports any errors it finds. The latter compiles and then executes the result. If there are no errors, MTDemo should pop open after a few seconds.

Other Ant Tasks

The command ant help displays a brief description of the defined tasks and what they do. The ant clean task erases ALL compiled classes and other residue from the build directory. If Ant gets confused over missing or changed items that SHOULD be found, run clean and re-compile. The ant javadoc task generates the MathTools javadoc; the folder appears in the project directory. Similarly, ant makejar creates the MathTools JAR file, again in the project root directory. The ant fulljar task does the same thing but includes the javadoc inside the MathTools JAR. The showpaths task displays all the relevant paths Ant uses in compiling MathTools.

This is where customization can begin! Part of the 'prepare' task is creating the include directory. This directory is for anything that should be included in the JAR file itself. Any classes or other resources that should be distributed within the JAR should be placed here. (Like the sample scripts and this document are!) This directory is also a part of the CLASSPATH used for compiling, so any JARs placed here will be used. To use a JAR during the compilation process without having it appear in the MathTools JAR, place it in the lib folder. Anything here is a part of the CLASSPATH when ant compiles and runs, but is NOT copied when making a JAR.

Speaking of JARs, the MathTools JAR must have a manifest. prepare 'touches' the file manifest.txt (yes, dot-TXT. Easier to edit that way and it still works!) but doesn't put anything there. To execute MathTools from its JAR, put this as the first line in the manifest file: Main-Class: cox.jmatt.java.MathTools.demo.MTDemo. (If you are customizing something, this may be different, but if that's the case you probably don't need to be reading this!)

The final task is an exercise in convenience (or pure laziness!). To compile the classes, turn them into a JAR, generate the javadoc, and copy the entire thing to a specific place: ant deploy. This task is useful but requires editing the build script. If this is desirable:

  1. Open build.xml in your favorite editor.
  2. Scroll down until you see the tag <property name='path.deploy.jar' location='${basedir}/deploy' />.
  3. Change the 'location=' attribute to the FULL PATHNAME to the directory where the JAR should appear.
  4. Locate the path.deploy.javadoc property; it should be right below the first one.
  5. Change the location of that property to the directory where the javadoc should go.
  6. Scroll to the bottom of the file, until you see <target name='deploy' depends='makejar, javadoc' />.
  7. Delete the comment tags (<!-- and -->) and, optionally, the <echo> tag.
Now, executing the command ant deploy will make a JAR and javadoc and copy it to a standard location. (This task was written as an easy way to copy JARs and documentation to a 'standard folder' containing lots of stuff to be burned onto a small CD-RW. Yes, I am lazy at times!)

Since we are discussiong customization, DO NOT be afraid to experiment with the Ant script! The original version, from which this one descended, was written to be a very broad 'standard' build script. For those reading between the lines, YES! Ant frustrated me greatly when I first began using it! It still does on occasion, but it mostly does what I want it to do now. So if you can benefit from my mistakes, PLEASE DO SO!

(For those of you reading this who have progressed far past this point, please show patience! When I first began programming Java, the words '... To build this from source...' frightened me into clicking the 'back' button immediately! Then, after I tried it a few times, I still ended up 'clicking the back button' by deleting the source code and just downloading the binaries. The reason: most of the writers of those instructions assumed that all who read them would be of a similar - and very high - level of expertise. I make no such assumption! And to those readers who may yet be afraid of 'compiling from source,' please do not hesitate to try it on MathTools!)