This is a very simple Java method that accepts one parameter,
limit, uses a for loop to sum up
the integers from 1 to limit, and then returns
the sum. As you can see, there is absolutely no code in the
method to create a graphical user interface.

Nevertheless, since the Methods class extends the
Java Power Framework class JPF, when the
program is run a button is created to execute this method and
after this button is clicked the following automatic GUI for
evaluating the method is shown:

You can see that the green arrow indicates where the argument
should be entered (we used 1000) and the red arrow indicates
where the result is returned (in this case 500500). The
order of argument(s) on the right and return on the left
mimics the structure of a method header.

The third method in the class named
DrawShapesAndText
illustrates both how to put shapes and text into a graphics
window and how to put the same kind of objects into panels.

The method creates 2 circles and 1 square and handles each
of these differently to illustrate the options. The first
circle is added directly as a Paintable to the
graphics window so it is entered as an object with default
settings, that is, its outline is shown in black and it has
no fill. The second circle is installed into a
ShapePaintable explicitly so one can set the
defaults. We choose a red fill and blue outline. Finally,
the square is painted in red on the background layer of the
graphics window and therefore is not represented as an
object in the window object. Rather some pixels have been
painted red and that is it.

The method also puts a simple text string into the window as
a Paintable object.

Since the method enables automatic mouse listening in the
graphics window, we can drag all of the items that were
entered into the window as objects, namely, the 2 circles
and the text string. We cannot drag the square since it
is painted on the background layer and is not represented
as an object floating above the background layer.

The situation is illustrated by the next two snapshots.

The initial drawing after clicking DrawShapesAndText

The drawing after dragging the 2 circles and the text string

Since we had already created the 2 circles, the square, and the
text string, we decided to show how easy it is to put such
objects into panels and then to show these panels. The screen
snapshots below illustrate this.

The panel named “Funky Panel” is built using a
VTable which is a class that specializes in
vertical panels.

The panel named “Extra Panel” is built using a
TablePanel which is a class that handles
1-dimensional or 2-dimensional tables.

The class is almost pure Java except that we have introduced the
JPT console object for writing the print
methods that will permit testing. The class is made aware of the
console object via the phrase
implements ConsoleAware in the class definition.

The class is elemental since it defines two simple instance
variables named x and y of type
int, two constructors both named Foo
which is exactly the name of the class, and two functions
or instance methods both named print. Things
could hardly be much simpler.

Even with such a simple class, you may still be puzzled about a
very fundamental question:

What exactly does a class definition do?

The simplest description might be to think of a class as an entity
that collects things such as variable definitions, function or
method definitions, and rules for construction. However this
view is somewhat simplistic since thinking of a class merely as a
collection box ignores the planning and intelligence that goes
into the design of a class and its subsequent usage.

A better description of a class is as a set of architectural plans
for the construction of one or more objects. Such plans specify
the elements of structure or data that the object should possess plus
the behavior that the object will exhibit. It is quite important
to distinguish a class, that is, a set of plans, from the objects
or instances constructed from these plans.

In the Foo, there are two structural elements defined,
namely, the instance variables x and y of
the primitive type int. These are initialized to a
default value of 0 but this value may be changed in a
constructor or later on since the instances are public.

In a class with more complexity, a class instance variable may be
of a type defined by a class. Thus, in general, a class may be
built by composition from primitive instance data and/or
instance data whose type is defined by one or more classes. In
fact, a class may include an instance variable that directly or
indirectly refers to another object of the same class. This
ability permits the definition of sophisticated data structures.

Class Foo provides two constructors. The first
constructor has no parameters and is called the
default constructor. In this example, the
default constructor does absolutely nothing so
the instances variables remain set to 0.

Let's look more closely at the second constructor:

public Foo(int x, int y) {
this.x = x;
this.y = y;
}

This constructor requires two parameters
int x, int y. These parameters are not
supplied by the Foo class itself but by whatever code
uses the Foo class. Generally, the code that uses a
class is referred to as a caller or client.

Notice that the parameter names x and y
are identical to those of the instance variables. Although this may
seem confusing, many programmers feel that it is also helpful since
it suggests how the parameters should relate to the instance
variables. Within the body of this constructor, we must of course
know how to distinguish the parameters from the instance variables.
We do this by writing this.x and this.y
to mean the x and y that belong to
this object. In Java, this acts as a name by
which an object can refer to itself just as, in English, people
can say “I” or “me” to refer to themselves.
The period is also important since it signifies access.
Thus, for example, the phrase this.x means
access this object’s x.

The parameter data gets stored into the instance data by means of
two assignment statements:

this.x = x;
this.y = y;

It is quite unfortunate that the mathematical symbol =
is used in Java to signify assignment. This notation
originated in the C programming language and has spread to many of
the successors to C. The problem is that = is a
symmetric operation in mathematics (a=b is the same as b=a) and is
used to perform a test for equality. In contrast, in programming,
assignment is absolutely not symmetric and furthermore the
effect of assignment is to change the left hand argument using
data from the right hand argument and not to simply perform a
test.

Let's try to describe simply but precisely what assignment does.
We may view assignment as a statement of the form:

LHS = RHS

In this statement, LHS must designate a storage location, that is,
it must name a variable that stands for a primitive type, a
variable that refers to an entire object, an instance variable
reference within an object, or an array cell reference.

RHS can be any of the kind of entities that LHS can be but RHS may
also be more general. RHS may also be an expression that performs
a computation or the return value of a method call.

In general, when the assignment is done, RHS is evaluated
and the value is transferred to LHS. How the value is transferred
depends on the type of LHS. If LHS is primitive, then the value
is copied directly into the storage associated with LHS. If LHS
is a reference to some form of object then only the minimal
information needed to store the new reference is copied but
not the entire object. This makes using objects quite efficient
since assignment avoids the overhead and drawbacks of a complete
copy of an object’s data.

Either way, LHS changes after an assignment. What was in
LHS before the assignment is obliterated. If your program needs
to remember what was in LHS before an assignment, you must use a
separate assignment to copy that data elsewhere prior to doing
the new assignment into LHS.

In contrast, if RHS is a variable, then it does not change under
an assignment. Thus, assigment is not at all symmetric and you
must be utterly careful in deciding what will be on the LHS (what
variable is to change) and what will be on the RHS (what variable,
expression, or function call will provide the new value for the LHS).

It is now possible to understand the two assignment statements in
the second constructor.

public Foo(int x, int y) {
this.x = x;
this.y = y;
}

The first statement says to take the constructor parameter
x and copy it into this object’sx. The second assignment says the same thing for
y.

We may now complete our discussion of the simple class
Foo by looking at the two print
methods.

Both methods use the JPT console object to print
to the JPT console. The JPT console is convenient since you
can easily change font sizes and also save the contents of
the console window to a file. If you wish to use the built-in
Java tools, replace console by System.
Note that println prints what you ask for and adds
a newline automatically. The out object also has
a print method that just prints what you ask for
and does not add the extra newline.

The first print method in Foo prints
3 lines consisting of the value of x, the value
of y, and a blank line. The expression

"x: " + x

takes the 3 character string x-colon-blank and appends the
value of the instance variable x converted from
its type int to a string. This expression syntax
is built into Java and is quite convenient.

The second print method in Foo prints
an optional 4th line with a header that identifies
which Foo object is being printed. The header is
passed in as a string. If the caller has made an error, the
header might be uninitialized, that is, null.
For safety, we check for this possibility and only print the
header if it is in fact not null.

Note that the test for “not equals” is !=.
If you are interested, the test for “equals” is
==. In other words, simple equality is tested using
a pair of equals signs whereas a single equals sign is used for
assignment. This peculiar set of conventions has been the bane
of students and programmers for 30 years so you must take care to
avoid the trap of using = when you want to test for
equality via ==.

When the header is taken care of in the second print
method, the method then calls the first print method
to take care of the printing of the data. This technique avoids
code duplication and is strongly recommended as a code style.

Since the Methods extends the test framework class
JPF, the test method TestFoo will
give rise to a button in the JPF graphical user interface that
then will execute the method. This automation makes testing
extremely rapid and convenient.

What does TestFoo do? As you can see, it appears
to both declare and construct 2 objects a and
b built using the Foo class. It
also prints these objects.

Let us examine the line
Foo a = new Foo(2, 3);
in detail.

The declaration part is Foo a. This states
that a will either be a reference to an object
of type Foo or will be null which
represents an uninitialized object. If we in fact ended
the statement here with a semicolon, a would be
declared as a Foo object but would be uninitialized.

Since we continue with =, we see that we are about
to do an assignment of the RHS into a. The RHS is
an explicit construction and all explicit constructions
must begin with the keyword new. After this, we
must specify new what. We choose to make a
Foo object which makes sense since a
is a variable declared to refer to a Foo object.
Since class Foo has two constructors, we have two
choices for how to build the Foo object.

Foo a = new Foo(); // default 0, 0
Foo a = new Foo(x, y); // x, y int

We choose the second format so we can set the instance variables
to 2 and 3 respectively.

After building a with values 2,3, we print it, then
we build b with values 5,7, and print it with the
header “b”. This is what appears in the console:

x: 2
y: 3
b
x: 5
y: 7

Notice that the test method TestFoo acts as the
caller or client that supplies the parameters to
use in the operations requested from class Foo.

A TextFieldView is a JPT class based on Java’s class
JTextField and its main purpose is to add robust I/O for
multiple data types. As you can see, each text field is initialized to
hold one character 0 and to have the same width. The
width is computed first by a method that returns the width of a string
with 20 zeroes. In other words, the text fields are designed to hold
20 digits.

The next block of code makes an object that encapsulates the behavior
we wish to perform, namely, to sum the text fields
x1, x2, x3, x4, and then place the result
into the text field total.

At first this code looks peculiar. It creates a SimpleAction
object that is given a string name Sum Data and is also given a
method definition, namely, the perform method is defined and
its definition is tantamount to calling the sum method defined
later in the class. Why this roundabout definition structure?

Our goal is to define the button Sum Data that you see in each of
the snapshots. A button must have a label and a behavior to perform when
it is clicked by the user. We know both of these. We want the label to
be Sum Data and the behavior to be the sum method. The
problem is that Java prohibits passing method names directly as arguments
to anything so there is no direct way to tell a button what it should do!
In some ways, this is an unfortunate restriction made by the designers of
Java but we must all live with it. The solution to this dilemma is that
we must construct an object that is expected to contain a method with a
standard name, in this case, perform, and we implement
perform by a one line call to the method sum that we really
want to use.

At this point, Java takes over since it has a standard way to construct a
button using an object of the general category of Action.
We will see in a moment that JPT automates the final step from action to
button.

The next blocks of code concern building the graphical user interface
or GUI. You will notice that the 5 text fields have 5 corresponding labels
and together these form a table with 5 rows and 2 columns. You can also
see that the button is centered below this 5-by-2 table. We build the GUI
in two steps. We make a 5-by-2 table object for the labels and text fields
and then we insert this table into a vertical table with the action/button
below. Here is the code.

The first step in making the 5-by-2 table is to create a 2-dimensional
array with 5 rows and 2 entries per row. Each row consists of a label
and its corresponding view. This is what is done in the definition of
dataStuff. This is the raw material for building the
5-by-2 table.

The next step is to create the table dataTable using the
data dataStuff. The constructor specifies the data,
a horizontal and vertical gap between cells of 10, and an alignment of
WEST which means that within cells objects are pushed
towards the west or left edge.

The next step is to combine the dataTable with the action
sumAction to make a second data array in preparation for
making the outer table. This is what is done in the definition of the
1-dimensional array mainStuff.

Finally, we create mainTable using mainStuff.
Since the array is 1-dimensional, we must specify a direction
HORIZONTAL or VERTICAL.
We choose VERTICAL in this case.
For alignment, we specify CENTER which is how
we get the button to be centered under the 5-by-2 table.

One powerful feature of TablePanel is that it can accept
general objects such as String (the labels) or
Action (sumAction) and figure out how to
make them into the appropriate GUI components. Thus
sumAction is used to automatically construct the button
that uses the action name for the button label and the perform
method for the button behavior.

The next step is the constructor for the SumPanel. The
constructor completes any initialization steps that cannot be
conveniently done in the earlier member data definition steps. Here
is the constructor.

This shows that SumPanel is also a TablePanel.
The first line of the constructor says to take mainPanel
and make it the single component within the SumPanel which
acts as a wrapper. This style of building all the pieces of the GUI in
the data definitions and then having one add statement to
wrap things up is a very common idiom in JPT code.

The second line of the constructor calls the addListeners()
method that we will describe below.

The third line of the constructor says to take the SumPanel
and place it in a frame, that is, a full-fledged window on the
screen that has Sum Panel as its title. This frame is
centered on the screen by default. We call the process of taking a
panel and putting it into a frame self actualization since it
avoids the traditional Java step of separately constructing the frame
and inserting the panel into its so-called content pane.

Let us finally look at the methods in this class of which there are only
two. The first method, sum(), does the algorithmic work of
the class since it implements the behavior in sumAction.

In the first four lines of sum(), we obtain the four values
to be summed. The method demandDouble() of the
TextFieldView class is used. This method insists that the user
provide valid numeric data and will use error dialog boxes until any
mistakes are fixed. This is an example of a method provided in
TextFieldView that is not available in Java base class
JTextField.

The next line does the mathematics of summation.

The final line converts the number x to a String
via the Java idiom x + "" and then places the
String into the total text field using the method
setViewState which is also defined in
TextFieldView.

The second and last method, addListeners(), is present for
the convenience of the user. A text field will listen for a
special event, namely, if the user presses the return-key while the
cursor is in the text field. If this event happens then any action
that has been specified via addActionListener will be done.
Thus, in this case, the summation action can also be triggered if the
user presses return in one of the first four text fields. This means
that the user does not actually have to click the Sum Data
button.

The method addActionListener is inherited by
TextFieldView from the Java base class JTextField.

We now explain what a Halo does and why it is used. A
Halo is a wrapper panel that surrounds another panel and
provides a small border. Its primary use in JPT is to provide focus
if a user makes an input error. By default, if an error occurs in a
TextFieldView, JPT will highlight the smallest panel that
surrounds the text field. This can sometimes be problematic. In the
case of the SumPanel, the smallest panel surrounding any
of the text fields is the 5-by-2 table panel. Thus, no matter where
the error occurs, the entire 5-by-2 panel is highlighted. This is not
so nice for the user.

The Halo class solves this problem by providing a small
panel to wrap around what is inside it so error highlighting will be
focused. Here is the change in the code to construct the array
dataStuff to add the necessary Halo
wrappers.

In this code, each Halo uses a default border size of
2 pixels all around each text field.

A Halo may also be used to provide an overall border
to a panel. Here is the change to the code that accomplishes this.

add(new Halo(mainPanel, 10, 10));

Here we use a larger border of 10 pixels all around the main panel.

With this, you have all of the changes between SumPanel
and SumPanelWithHalo.

Additional Comments

The code in the sum panel examples was written in 2005 and we decided
to leave the code as is. Let us comment here on the simplications
possible with the additions in JPT 2.5.0.

First, classes were added to JPT to deal with horizontal and vertical
table panels, namely, HTable and VTable.
Since, mainPanel is vertical, it may be defined as:

private VTable mainPanel =
new VTable(mainStuff, 10, 10, CENTER);

Next, a large number of methods have been added to
DisplayPanel to make it easy to add borders to panels.
Since most JPT panels extend DisplayPanel, these methods
are widely usable. This means that instead of wrapping
mainPanel in a Halo to get an outer border,
we can instead add the following line at the top of the constructor:

mainPanel.emptyBorder(10);

More complex borders may be added with equal ease. The real purpose
of the Halo class was to provide a small wrapper so that
error highlighting would be focused about the field with an IO error.
It was merely a trick to use a Halo for an empty border.
That trick is now unnecessary.

As you can see this class simply serves as a bridge to reach the
class FontSampler which is installed in JPT. The
main method of SampleFonts simply
executes the main method of FontSampler.
Therefore, to understand what is happening, you should look at
the file
FontSampler.java.
This program illustrates the following features of Java and JPT.

How to use the Java class GraphicsEnvironment
to obtain a string array that contains a list of all
“font family names” for all fonts installed on
the system.

How to initialize a JPT Dropdown list using
the list of font family names. This list will allow the
user to select a font family name for display of the font
sample.

How to set up a small text field for the font size and
two check boxes to enable the user to choose
“Bold” or “Italic” or both.
These use the JPT classes TextFieldView and
BooleanView.

How to define a BufferedPanel to serve as
the display area for a font sample.

How to combine the GUI elements to build the GUI.

How to define the method showFont() that
uses the user choices of font name and font size
together with the bold and italic settings to create a
sample of the font. This method makes use of the JPT
class TextPaintable.

How to encapsule the method showFont() in a
SimpleAction object that is also named
showFont.

How to attach the showFont behavior to the
dropdown list, the text field, and the check boxes so
that any changes will trigger a refresh of the sample.
This technique means that no “Show Font”
button is needed.

Added 12/1/06: Font Sampler Applet

9/19/06: Visual Color List

For the purposes of information, JPT has a class named
VisualColorList that shows a scrollable list of
the named colors that are installed as static objects in the
JPT class Colors. Originally, we planned to
include the code of the VisualColorList class
in these samples.

Instead, we realized that the class VisualColorList
could be improved. We therefore provide the code for the
improved class
VCL.java.
This code will replace the code in VisualColorList
in the next release of JPT.

The scrollable color list in VCL shows a color swatch,
the color name, the color RGB values in decimal, and the color RGB
values in hexadecimal. The decimal values are separated by commas.
The hexadecimal values are preceded by the symbol #
and have no separators; this follows the convention for defining
colors on the web.

In addition to the scrollable color list, class VCL
provides a ColorView in which the user may enter a
color using either decimal or hexadecimal RGB values. This view
permits experiments in which a user can vary the parameters of a
named color and see what happens visually.

This program illustrates the following features of Java and JPT.

How to build the color table panel using an algorithm.
Specifically, there are far too many named colors to build
the color panel by hand. Therefore, color data is collected
in certain arrays and then the color panel is built using a
TableGenerator object that encapsulates the
algorithm for specifying all cells of the table.

How to put the color panel into a scroll pane and control
the size of its view port so that color swatches do not
visually fall across the view port boundary.

How to obtain the color name data from the Colors
class and how to build the decimal and hexadecimal RGB string
data.

Added 12/1/06: Color Applets

9/19/06: Functions and Plots

The class FunctionsAndPlots in the file
FunctionsAndPlots.java
is a Java Power Framework tester class that permits
the user to explore expression evaluation, definition
and evaluation of simple functions, and function plots.
It may be viewed as a collection of ingredients that
might be incorporated into a function plot program
to be constructed at some future time.

The initial JPF GUI that is presented when the class
FunctionsAndPlots is launched is shown
below.

The first GUI button “Evaluate” corresponds to
the method:

public double Evaluate(double x) {
return x;
}

When the “Evaluate” button is clicked, the GUI
shown below is automatically generated:

As an example, we have shown in this GUI the evaluation of
the famous mathematical constant known as the
“Golden Ratio”.
This automatic GUI is the fastest mechanism in JPT to make
a panel for evaluation of double precision expressions.

The next GUI button “EvaluateInConsole” launches
a method that performs a double precision evaluation loop
in the console window.

The next five GUI buttons bring up more sophisticated GUIs
to evaluate expressions and/or define simple functions.
The GUI button “EvaluateExpression” permits the
user to choose between three result types:
BigInteger, double, and
boolean. The next two buttons allow the user
to define simple functions that will then be recognized in
the expression parser. The final two buttons bring up GUIs
that permit both function definition and immediate testing
via expression evaluation. In the buttons with the phrase
“...WithIO”, the user can save function
definitions to disk. Here is the GUI created when the last
of the five buttons is clicked.

In the top pane of the window, the function definition for
cuberoot in terms of the built-in function
root is shown. In the bottom pane, the
result of testing cuberoot on
27 is shown. Note that, for visual purposes,
we have brought up the prior definition of cuberoot
to show both the definition and the test in one snapshot.
Normally, once a definition is made, the text fields are
cleared to prepare for additional definitions.

The “PlotFunctions” button launches an automatic
GUI in which the user may enter 4 items.

A comma-separated list of function names.

The left endpoint of the plot interval.

The right endpoint of the plot interval.

The number of subdivisions of the plot interval.

The function names can be either those of built-in functions,
simple functions added algorithmically, or simple functions
defined interactively by the user. In the screen snapshot
below, we show one built-in function sqrt and
two simple functions cuberoot and
fourthroot. The plot interval is from
-4 to 4 and the number of
subdivisions is 100.

In the screen snapshot below, you may see the plot results.

You will notice, in particular, that since sqrt
and fourthroot are not valid for negative
inputs, the plots simply skip these points for the
two functions.

The final two buttons bring up GUIs for plotting a polynomial
or a fourier series that is entered by giving coefficients.

The series of examples in this program deserves careful study
and may inspire you to build more elaborate programs. In
particular, I recommend that you check out how the data is
acquired from the functions and then how the plots are done
including scaling, grids, tick marks, and axes.

The KeyLabelData data structure class is almost 100%
pure Java. The main aspect of the class that relates to JPT is
that we require that the class implement Stringable
which is an interface that requires a method to save the object
data to a suitable string and a method to read the data back from
a correspondingly structured string. Internally, we use JPT to
make the coding of some of the methods faster and easier.

The purpose of the KeyLabelData is to associate a
“search key” string with a list of strings or
“labels”. The inspiration behind this class is a
class that would store the address label information for a
contact information program and would attach a search key to
each contact to make it easy to search for particular contacts.
The class is written in a more general way so that any kind of
string information may be associated with a search key. There
is one simplication, namely, that the number of labels that may
be associated with a particular search key is fixed at the time
of construction. This makes some code easier. A nice feature
of the search is that the search key is automatically broken
into individual words and one can search for any word by
giving a string of characters that start the word. It is not
necessary to type the full word.

Rather than discuss the KeyLabelData class line by
line, we are going to outline the class and tell you what to
look for in examining its code.

The class has 4 constructors that require varying amounts of
data.

The default constructor requires no data, sets no key or
labels, and results in a capacity of 6 labels.

A constructor that asks for the capacity and sets that
item but sets no key or labels.

A constructor that asks for a key and labels and sets
those items within a capacity of 6 labels.

A constructor that asks for the capacity, the key, and
the labels and sets all of those items.

The constructors are coded so that the first three make use of
the last constructor to minimize repeated code.

The capacity may not be changed after construction. On the other
hand, both the key and the labels may be changed and there are
assorted set methods to accomplish this. There is
also an append method to add a label to the list.

The class has get methods to retrieve information
about what is in the class.

The class implements “search recognition” by a method
with the following signature:

public boolean keyStartsWith(String string)

This methods returns true if the given string starts
any word in the search key. The search is case-insensitive so it
can find more matches.

The standard Java method toString() is implemented to
return a string that combines all labels each terminated with a
newline. Hence it may be viewed as the multi-line string of labels.

The Stringable method toStringData() makes
a string by combining the search key plus a newline with all labels
also terminated by a newline. It should be clear that this string
contains all of the critical information within the object.

The Stringable method fromStringData is
designed to reverse the effect of toStringData() to
set the key-label content of the data structure from a string.

Since we have chosen to make the capacity of this data structure fixed
at construction time, we do not include the capacity in the strings
returned by toString() and toStringData().
This is considered internal information.

Finally, the class implements a compareTo methods that
allows the class to implement the Comparable interface.
This in turns permits objects of the class to be sorted.

By Java convention, compareTo should normally be consistent
with the equals method and, in turn, this method should be
consistent with the hashCode method. This leads us to also
define the latter two methods.

From this summary, you can see that the class has facilities for building
objects in a flexible way and for setting, getting, searching, and sorting.
Thus, it is a simple but rather typical data structure class.

You may examine the tester class Methods for yourself. You
will see that the tests are reasonably simple. You will see that one
construtor and many methods are tested explicitly. In addition, since
object data is printed explicitly in the tests, you can see that other
behavior has also taken place correctly.

9/20/06: Tic Tac Toe

The Tic Tac Toe game is elementary and so provides a simple
setting in which to illustrate some additional ideas in GUI building.
Before further discussion, let us show two screen snapshots from the
demo program.

In the first screen snapshot, player X has won the game
and the winning sequence is highlighted in yellow.
In the second screen snapshot, the game has been played to a tie
since neither X nor O has won and no more moves are possible.

The game uses the concept of a tile that has a size,
an object that is painted, and a background color.
There are actually three kinds of tile:
the blank tile that just paints the background, the X tile,
and the O tile.
Notice that the same object may be painted on several tiles.
This distinction is important and is reflected in the code.
The three things that are painted (blank, X, O) are
Paintable objects that remain the same throughout
the program. The 9 tile objects that are visible in the GUI
are TileBox objects that can change their internal
Paintable object and so can change what they display.
In particular, as long as the game is not over, if a blank tile is
clicked then it will change to an X tile or an O tile depending on
what player has the next move. Technically, the tile does not
change its identity only its Paintable contents.

The tiles are arranged in a 3-by-3 grid using a
PaintableSequence.
The initialization code creates a 3-by-3 array of
TileBox objects each with a blank as its contents
and burlywood as its background color. Using the move command,
these tiles are geometrically positioned before being added to
the seqeunce.

The PaintableSequence is in turn placed into a
PaintableComponent which is an extension of the
Java JComponent class designed to hold objects
that are Paintable.
A PaintableComponent entity is also set up to
permit the easy definition of desired mouse actions.

The mouse code that controls the game is quite simple.
When the mouse is clicked on the PaintableComponent,
several checks are made.
If the game is over or if the mouse has not hit a blank tile,
then the mouse code does nothing.
On the other hand, if the mouse has hit a blank tile, then the
contents of that tile is changed to an X or O depending on what
player is next and then the next player is switched to its opposite.
After each click, a check is made to see if the game has been won
or if no more moves are possible.

In effect, one can think of the tile grid embedded within the
PaintableComponent as a complex button that
responds to mouse clicks in a subtle fashion that depends on what
particular tile is clicked. This contrasts with an ordinary button
that behaves in the same way no matter where the mouse is clicked
within the button. The mouse click code illustrates how complex
behavior may be coded in a rather simple fashion.

9/21/06: Fibonacci Variations

The Fibonacci numbers are a sequence of numbers starting with
1 1 and having the property that each subsequent number
is the sum of the preceding two numbers. Here are the first few
terms in the sequence:

1 1 2 3 5 8 13 21 34 55 89 144 233 ...

This example concerns generating the Fibonacci numbers in
a simple graphical user interface (GUI). The interface shows 3
successive terms in the sequence so you can see how the last term
is the sum of the previous 2 terms. Here are 4 screen snapshots
that show the start of the sequence and 3 successive executions
of the “Next Fibonacci” button.

After clicking “Next Fibonacci” a number of times,
we quickly realized that we wanted to be able to push forward
rapidly in the sequence without having to click for each step
individually. This led to the “Repeat Next ...”.
Suppose, we wish to go to the Fibonacci of index 50.
We click “Repeat Next ...”. Then the simple
dialog shown below appears, we enter 50, and click
“OK”.

What happens is that the next action is
repeated until index 50 is reached.
The result is shown in the screen snapshot below.

If you continue to higher values of the index, a problem eventually
occurs. The first time it occurs is at index 92. The
situation is shown in the screen snapshot below.

As you can see, the value of Fibonacci for 92 is
negative. What has happened? The answer is that we have used
data type long to do the arithmetic and this type
does not have enough space to store the actual result. Instead,
the value was computed but wrapped around to a negative number.
Ouch!

There is a way to fix this. Java supports a type
BigInteger that will maintain precision as long as
Java itself has enough memory for the required storage. Given
the amount of memory on modern systems, this is enough for some
rather large computations. Here is the screen snapshot taken
with the variation of Fibonacci that uses BigInteger.

Let us suggest some questions for you to consider as you examine
and compare both source files.

How are the 6 text fields and the table in which they are
contained constructed?

How are the 3 actions that define the 3 buttons built?

How are the 3 methods behind the 3 actions defined?

How do you get text out of a text field?

How do you get a number out of a text field?

How do you put text into a text field?

How do you put a number into a text field?

How do you put the result of a calculation into a text field?

How is the simple dialog that requests an index made to appear
on the screen?

What are the final steps in building the GUI?

In exactly what places do the programs
Fibonacci.java and FibonacciBI.java
differ?

Here are some suggestions that might inspire further projects. The
first two are simple and the last two require substantially more
thought and work.

What happens if the start numbers in the right column are
not 1 1 2 but some other three
numbers? Try experiments to find out some information.

Implement a version of Fibonacci in the console window that
asks for an index and prints all Fibonacci numbers from
index 0 up to that index.

Implement a version of Fibonacci in a GUI that asks for an
index (perhaps with a dialog or perhaps via a text field)
and then creates a scrollable panel that lists all of the
Fibonacci numbers from index 0 up to that index.

The Fibonacci numbers are based on a formula. If
a and b are two successive
Fibonacci numbers then the next number is mathematically
a+b. Instead of using this fixed formula,
can the formula be entered as a string by the user? Can
the JPT parser tools and the notion of SimpleFunction be
of use or is this the kind of problem that requires
starting from the beginning?

9/26/06: Ball Animation

The Ball Animation should be viewed as a demonstration program
that reveals the pattern for building animations using JPT. What is
animated is a simple ball that moves back and forth on a horizontal
track. There are slider controls that determine the step size,
that is how many pixels the ball moves in each step, and the
speed, that is, how many steps are executed per second. What
is animated is intentionally very simple so the pattern can be shown
in as clear a fashion as possible.

Here are two snapshots from the Ball Animation program:

The Ball Animation at Startup

The Ball Animation Running

The initial settings for the ball animation are a step size of 1 pixel
and a speed of 1 step per second. With these settings, the animation
will be very slow. At the opposite extreme, the step is 10 pixels and
the speed is 100 steps per second or as close to that as the processor
will permit. Visually, the ball will blur at that speed.

We will now discuss the design of the ball animation program
whose source may be obtained at
BallAnimation.java.
We will separate a discussion of the GUI aspects from the deeper issues
of how to program the animation using a separate “thread”.

GUI Design

The GUI consists of 3 levels: the animation track with the moving ball,
the slider controls for step size and speed with their labels, and the
buttons that run and stop the animation.

The ball is constructed as a ShapePaintable using an
XCircle object to define the circle shape and associated
settings to select red fill with blue boundary. This ball is inserted
into a PaintableSequence for two reasons. First, this is
the pattern that will needed to animate more than one object. Second,
we can set the default bounds of the sequence to be what we wish as
the size of the track along which the ball will move. Then, we insert
the sequence into a Tile object that sizes itself to the
bounds of the sequence and provides the light gray background that is
the visual representation of the track. When the tile is in turn
inserted into the GUI, it will automatically be placed within a
PaintableComponent object that will take care of the
repaint operations needed when the ball is moved.

The slider controls use the JPT class SliderView which is
a minimal extension of the Java class JSlider. The
extras in SliderView allow one to specify the actions to
be performed as the slider is sliding and when the slider is released.
The Java base class provides a method for defining the spacing of the
tick marks and a simple JPT method allows these marks to be labeled.
There is no provision in the slider classes for displaying the value
of the slider as text so this is done with the labels to the right of
each slider. Although the sliders appear to permit a slider value of
zero, methods in the class intervene to guarantee that the minimum
value of each slider is one. This avoids a division by zero.

The “Run Animation” button is constructed using a
ThreadedAction to guarantee that the animation is done
in a separate thread. What this means is discussed in a moment.
The “Stop Animation” button is built using a
SimpleAction in a manner familiar from earlier samples
on this site.

Animation and Threads

A thread of execution is a collection of program instructions
that conceptually appear to act as a unit that does work, looks at
or changes data, and interacts with the user, the file system, and
perhaps the network. All modern operating systems permit multiple
programs to run at once so a user can surf the web, read e-mail,
write a document, or manipulate an image all at once. Each program
conceptually runs in one or more threads of execution that are
distinct from those of all other programs currently running. It is
the responsibility of the operating system to split time between all
programs so each gets some slice of available processing time and
appears to have control of all system resources while it is actually
processing.

A simple program uses only a single thread of execution. For a program
with a GUI, this thread must pay attention to and respond to the user
actions such as typing keys and using the mouse. For this reason, this
first thread is often called the “GUI thread”. If the
program make few demands on the system then it can do all of its work,
that is, run all its algorithms, within the GUI thread. So little is
done that the user doesn't even notice any problems. However, if it
turns out that the algorithmic work is intensive, then that work will
consume all processor cycles allocated to the program and the program
will have no cycles to pay attention to the user. In effect, the GUI
will appear to freeze or die.

The solution to the problem of GUI freeze is to run intensive algorithms
in a second thread independent of the GUI thread. Then the operating
system will split time between the two threads provided that the busy
thread agrees to take periodic breaks or pauses. This will permit the
GUI thread to get needed processor time and therefore to remain alive.

Animation tends to be processor intensive so an animation program should
be planned in such a way that the animation is done in a second thread.
Java has a specific pattern for setting up a separate thread. Since the
lines of code are always the same, we introduced in JPT the class
ThreadedAction that incorporates this code. The key idea
is that a ThreadedAction encapsulates an ordinary action but guarantees
that each time it executes a new thread will be automatically created
to execute the ordinary action it references internally.

Let us see how simple this turns out to be.

Here is the code that sets up the ThreadedAction object that
will run the animation in a separate thread.

The ThreadedAction constructor must be provided with an
ordinary action that it will use to define the behavior that will be
executed on the separate thread. As you can see above, we provide
this ordinary action by creating a SimpleAction and
that action in turns calls the method runAnimation().
The fact that the behavior will run in a separate thread is now 100%
automatic.

The action to stop the animation runs quickly so it does not need to
be run in a separate thread. It can be defined simply via a
SimpleAction.

To understand this, first keep in mind that the actions
runAction and stopAction will be used
to build the buttons “Run Animation” and
“Stop Animation” in the GUI. Clicking the buttons
will execute the actions. This will help us explain the pair
of helper methods. The method setRunState():

Disables the action runAction which in turn
disables the button “Run Animation”.

Enables the action stopAction which in turn
enables the button “Stop Animation”.

Sets the control parameter running to
true.

Symmetrically, the method setStopState():

Disables the action stopAction which in turn
disables the button “Stop Animation”.

Enables the action runAction which in turn
enables the button “Run Animation”.

Sets the control parameter running to
false.

The effect of this is that when the animation is running then the
“Run Animation” button is disabled so you cannot start
yet another thread in conflict with the already running thread.
At the same time the “Stop Animation” is enabled so it
is possible to stop the animation. When the animation is stopped,
then the state of the buttons is reversed. This is visible in the
two screen snapshots above.

The method setRunState() is run once and then the code
enters an infinite loop signaled by while(true). Hence,
unless something intervenes, this code will run forever. Notice,
however, there is an immediate test of the control variable named
running. If this variable is false, the
loop will exit.

You may ask, how can the variable running become
false if there is no code within the infinite loop to
change the variable? The answer is that the variable can become
false if the “Stop Animation” button is clicked. This
click is recognized in the GUI thread which is running in parallel
to the animation thread. The keyword volatile is
added in the declaration of the variable running to
alert the compiler that running may be altered by
different threads and to therefore avoid compiler optimizations
that would eliminate the test.

If running is true then the test fails
and the loop continues on to execute the animate()
method. The code has been written in this way to create a pattern
that you can follow if you want to do your own animation. All you
need to do is set up your own situation and write you own version
of animate().

Now comes a crucial step. The animation thread must pause to give
the GUI thread some life and to control the animation speed. The
following method call is made:

JPTUtilities.pauseThread(getDelay());

This code tells the current thread (which is in fact the animation
thread) to pause for the amount of milliseconds given by its parameter.
The delay time is computed by the method getDelay()
which uses information from the speed slider and simple arithmetic. It
might be computed quite differently in your animation program.

Finally, what about the phrase synchronized (animationLock)
that occurs in several places? This code resolves issues of conflict.
If more than one thread is working with certain data, then it is
possible to get that data into an inconsistant state by starting an
update to the data in one thread and then switching threads before the
update is complete. When a section of code is synchronized
relative to some “lock” object, then it can complete its work
before any other thread that synchronizes on the same object is allowed
to proceed with its work. This ensures that data is updated correctly.
It doesn't actually matter what the “lock” object is. What
is crucial is that sections of code that work on common data use the
same lock object for synchronization. One more point. The call to
pauseThread is not within the scope of synchronization.
If it were, the “Stop Animation” button could never actually
execute its code and the animation could never be stopped. Thus the
details of the pattern are very critical.

One additional technical point. If you close the Ball Animation window,
this will terminate the GUI thread. Look through the program to see how
the closing of the window also ensures that the animation thread comes to
a halt.

Hopefully, the Ball Animation can provide a pattern to follow
if you wish to explore animation.

For positive n, there is an “inductive formula”
that lets you compute n! from (n-1)!:

n! = n(n-1)!

This formula is the basis for the methods in the Java file given above.
It says that if you already have (n-1)! then you can
compute n! using a simple multiplication.

Since the factorial function grows quickly, we want to use so-called
“big integers” rather than int or
long to store the computations. There are two options:
the Java class BigInteger or
the JPT class XBigInteger. The Java file above shows
both variations so you can pick a style that you would prefer to use
in similar situations.

Since the Java file is heavily commented, we will simply let you read
it for yourself.

10/5/06: Classic Shapes

The JPF test file
ClassicShapes.java
illustrates how to constructs what we will call the 7 classic shapes:
rectangle, rounded rectangle, oval, square, rounded square, circle,
and line. These correspond to the following JPT and related Java
classes:

As you can see, the JPT class names are much more consise than the
Java names. The reason the Java names are so complex is that Java
wanted to provide both Double and Float
variations of the shapes. JPT simply uses double.

The constructors for XRect and XOval use
parameters x y w h where x and y
are the coordinates of the left-top corner of the bounding box and where
w and h are the width and height of that box.
The constructor for XRoundRect adds two extra parameters
that provide the rounding radii in the x and y directions respectively.

The constructor for XCircle uses x y r where
x and y are the coordinates of the center of
the circle and r is its radius. The classes
XSquare and XRoundSquare also use the center
rather than the left-top corner. For these classes, the radius means
the radius from the center of the square to its side so in fact is
one-half of the side. The XRoundSquare also adds to its
constructor the arc radius for rounding the corners.

The constructor for XLine2D uses x1 y1 x2 y2
which represent the coordinates of the endpoints of the line.

Note that it is sometimes convenient to define a rectangle, rounded
rectangle, or oval using the opposite corners of the bounding box.
The classes XRect, XRoundRect, and
XOval have a method setX1Y1X2Y2 that lets
you define the bounding box using any two opposite corners. On the
other hand, for squares and circles, this method and related methods
that use the bounding box to define the object are changed to do
nothing at all. This is because there is no valid way mathematically
to use a rectangular bounding box to uniquely define a square or circle.

The classes for squares and circles may be viewed a trivial convenience
classes since it is certainly possible to draw squares and circles with
the rectangle and oval classes.

Here is a screen snapshot with the execution of the
ShapeSample method in the file
ClassicShapes.java.

You should examine the file to see:

Exactly how each of the 7 shapes is constructed

How the shapes are placed into ShapePaintable
objects so that the desired fill and draw colors may be set
as well as the stroke thickness

How the corresponding 7 shape labels are created using
TextPaintable objects

10/5/06: GeneralPath Shapes

Java has a very powerful shape class named GeneralPath
that permits a user to build up a shape as a path consisting
of segments that may be added incrementally. JPT builds on this
foundation to provide several shape related classes that improve
convenience. First, let us describe GeneralPath.

The class GeneralPath has three constructors that are
the most useful.

GeneralPath() that creates an empty path
with the default winding rule WIND_EVEN_ODD.

GeneralPath(int windingrule)
that creates an empty path
with the specified winding rule.

GeneralPath(Shape shape)
that initializes the path using the data in the given shape.

What is the winding rule? This is a constant that specifies
the mathematical algorithm that will be used to fill the shape with
color or paint should that be desired. The even-odd rule is
the easiest to compute. For each horizontal line, you travel from
left to right and consider a point to be within the shape if you
have crossed the path an odd number of times. The more subtle rule
is based on the so-called winding number. A point is viewed
as within the path if the path winds around the point a non-zero
number of times. This rule is harder to compute but there do exist
reasonable methods to accomplish the task. Java prefers the easier
rule WIND_EVEN_ODD but as a mathematician I prefer the
rule WIND_NON_ZERO which may capture more points. If
the path does not cross itself, both rules give the same result.

Java specifies the winding rule to use via 2 integer constants that
are named as follows.

When a path is being constructed, the first call must be to the
method moveTo to initialize the start point of the path.
If one of the other 4 operations is called first, the class will throw
an exception.

A minor annoyance in Java is that the parameters must be
float rather than double. This decision
goes back to the early days of Java when programmers were quite
concerned about saving space and performance. Nowadays, with more
memory, space is not such a concern, and with mathematics chips it
is actually faster to compute in double than in float.

The main impact of using float occurs when you write
code and want a float constant. If you write, for
example, 2.397, this will be interpreted as
double. To inform Java that you want a
float, you must write 2.397f. The
extra f characters can be bothersome when you forget
them. There is no need for the f if the constant is
an integer.

We have created a sample file
PathShapes.java
that should help you to understand how to use the class
GeneralPath.

The first method in this class is ShowQuadShape that
creates a GeneralPath that moves to a start point
x0,y0 and then constructs a quadratic curve using the
4 parameters x1,y1,x2,y2.

Here is the screen snapshot of the quad curve corresponding to
these 6 input parameters.

Notice that the middle parameters x1,y1 correspond
to a control point that is not on the curve itself. The
control point together with the end points form a tent-like
structure and the curve falls within the tent. We plan to talk
about the algorithm that draws the curve in class since it is
much easier to explain the drawing process live.

If you examine the graphics code, you will see a call to the JPT
method Path.showShapeStructure. This method shows
a path, the data points on the path, the control points, and the
polygonal frame that connects the data and control points. The
path may also be filled but in the above example the fill color
was set to transparent. Behind the scenes, this method makes a
special Paintable object that displays all of the
features.

The next method in this class is ShowCubicShape that
creates a GeneralPath that moves to a start point
x0,y0 and then constructs a cubic curve using the
6 parameters x1,y1,x2,y2,x3,y3.

The portion of the code for this method that creates the cubic
curve is:

Here is the screen snapshot of the cubic curve corresponding to
these 8 input parameters.

Notice that the middle parameters x1,y1
and x2,y2 correspond to a pair of
control points that are not on the curve itself. The
control points together with the end points form a zig-zag
structure and the curve falls along this strructure. Again,
we plan to talk about the algorithm that draws the curve in
class since it is much easier to explain the drawing process
live.

Our discussion of the drawing algorithms will be assisted
by additional methods ShowQuadSubdivision and
ShowCubicSubdivision that we will explain in
class.

It is quite interesting to apply the above techniques to see
how Java draws a circle. In fact, its turns out that Java
uses 4 cubic segments to define a close approximation to a
circle that can be drawn much more quickly. Here is the code:

This snapshot clearly shows that the circle is in fact
approximated by 4 cubic segments.

It is interesting to “reverse engineer” the circle
shapes to discover the 4 cubics used. To help with this, there
is a method Path.shapeToString that will extract
the internals of the shape and put this data into a string that
may be printed. Here is the result of that process.

By naming the important parameters, we can take a more abstract view
of this circle data and come to a better understanding of how it is
structured. Let:

x be the x-coordinate of the circle center
(200 in the example)

y be the y-coordinate of the circle center
(200 in the example)

r be the radius of the circle
(100 in the example)

k = 0.5522847f be the cubic control constant for a circle

s = kr be the radius of the circle multiplied by
the constant k (55.22847f in the example)

We will now describe the 13 points that occur in the above specifications
for a circle in more abstract terms. By a vertex, we mean a point
that lies on the path. By a control, we mean a point that controls
the shape of a curve in the path but is not on the path.

x-coordinate

y-coordinate

type

location

x + r

y

vertex

east

x + r

y + s

control

ese

x + s

y + r

control

sse

x

y + r

vertex

south

x - s

y + r

control

ssw

x - r

y + s

control

wsw

x - r

y

vertex

west

x - r

y - s

control

wnw

x - s

y - r

control

nnw

x

y - r

vertex

north

x + s

y - r

control

nne

x + r

y - s

control

ene

x + r

y

vertex

east

The above table shows that there is a very systematic way in which
the coordinates of the vertices and control points are computed
based on the constant k. This constant has been
chosen so that the cubic segments will provide the best possible
approximation to the corresponding circular arcs.

We wish to pose a question that you may wish to puzzle about and
then follow up with experiments. An ellipse aligned along the
axes is characterized by two radii, the radius a
parallel to the x-axis and the radius b parallel to
the y-axis.
How would the above structural description of the
circle need to be generalized to provide a similar description
for the ellipse with radiiaandb?

We conclude this section with a final example that represents a
more complex path. Its code is:

10/23/06: Curve Mathematics

We are going to provide a summary of the mathematics behind the curves
provided in the Java class GeneralPath. We will focus on
cubic curves since quadratric curves follow the same pattern but are
simpler. Mathematically, the ideas generalize further, but Java
provides no built-in implementation.

A cubic curve segment is defined by
a start vertex point
P0,
two control points
P1 and P2,
and an end vertex point
P3.
In coordinates, we may view this as:

P0 = (x0, y0)
P1 = (x1, y1)
P2 = (x2, y2)
P3 = (x3, y3)

Java tends to work with the coordinates. Furthermore, when defining
a cubic segment, x0,y0 are taken to be the current point in
the path and the caller supplies just x1,y1,x2,y3,x3,y3
to the method curveTo. In most cases, we will try to use a
more mathematical notation in terms of points but you must recognize
that the formulas must be converted into pairs of formulas for the
x and y coordinates.

The 4 points P0,P1,P2,P3 define a cubic polynomial curve
P(t) in the parameter t as follows.

Here, following mathematical convention, we separate factors by a
space to indicate multiplication, and we let ^ stand
for the “exponent” operation. Note
that:

P(0) = P0 and P(1) = P3

so the above formula defines a cubic polynomial curve in t
that goes from point P0 to point P3
as t goes from 0 to 1.
Therefore, the points P0 and P3 are vertex
points of the curve.
Furthermore, since the points P1 and P2
influence the cubic curve path, these points may be viewed as control
points.

We will now describe the fundamental subdivision algorithm that
permits the curve to be divided into two segments which may once again
be defined by 4 points. This permits cubic curves to be recursively
constructed with extreme efficiency. We will first describe the
general case where the subdivision is based on a parameter
t and we will then specialize to
t = 1/2 which is what is used in practice.

Let 0 <= t <= 1.
The subdivision algorithm is based on repeated
linear interpolation. In general, if we are given two points
A and B and the parameter t,
then we can compute the point that is the fraction t of
the way from A to B by the formula:

(1 - t) A + t B

Notice that
when t = 0 this formula yields A
and
when t = 1 this formula yields B.
Since the formula is a linear function of t, the result
is called the linear interpolation.

The subdivision algorithm uses repeated linear interpolation. The
following 6 points are constructed. We leave you to check the
details of the algebra if you are so inclined.

Notice that S0 equals the point P(t) on
the cubic curve. Hence the subdivision algorithm can compute
points on the curve. I consider this a mathematical miracle.

The screen snapshot below illustrates this construction. In the
snapshot t = 1/2.

An even deeper mathematical miracle is what follows. Notice that
we have 2 sequences of points P0,Q0,R0,S0 and
S0,R1,Q2,P3 that may themselves be used to define
cubic curves. The mathematical miracle is that these curves
are precisely the left and right segments of the original curve
when subdivided at the point S0 = P(t).
This is why the process is called the subdivision algorithm.
This property of the subdivision algorithm leads the way to the
use of recursion.

For those of you who are interested, here is a more precise
statement of the mathematical facts. Let
Pa(u)
be the cubic that corresponds to P0,Q0,R0,S0 and
Pb(v)
be the cubic that corresponds to S0,R1,Q2,P3.

When the subdivision algorithm is used to draw a curve or to define
a curved region to fill, what happens is that subdivision is applied
recursively until it is determined that a segment has been reached
that is “flat enough” to be rendered as a straight line.
The curve is then rendered as a polygon with many small straight lines.

To play with this demo, use the mouse to drag the red points that
correspond to P0,P1,P2,P3. The structure drawing will
transform smoothly as you drag one of these points. If you wish to
see the numerical data, click to the “Cubic Data” pane.

As we were building this demo, we decided that it would be useful
to students to capture the stages we used in separate text files.
This would allow students to see how the demo was developed. We
will provide links to each such stage file and briefly comment on
what was done in that stage. The Java import
statements have been deleted from these text files.

Stage 1 sets up the basic structure of the GUI. Our goal was
to provide a pane to display the cubic structure and permit
mouse interaction and a pane to provide the data for all of
the points. Since we believed that there was not enough
screen real estate to show both panes at once, we decided to
use a Java JTabbedPane. At this stage, we only
set up the pane for the cubic structure. Our plan was to use
a PaintableSequence to hold the cubic, the 6 lines,
the 10 squares for the points, and the 10 labels.
To avoid problems
of graphics inconsistency, we planned to replace the paintable
sequence entirely rather than update it piecemeal and risk the
chance of a partial screen update. Therefore, this stage also
defined a Tile object that will serve as a wrapper
for the paintable sequence. By setting the bounds of the tile,
we can reserve the right amount of space in the GUI before the
paintable sequence is even built. At this stage, the bounds
were set to 600 by 600.

It turned out that there was an additional annoyance. The default
background for a JTabbedPane turned out to be a
shade of blue rather than simply white. For some reason, none
of the Java commands to change colors had an influence on this
blue background. We decided therefore to place the
Tile into a PaintableComponent whose
background we could set directly to white.

Stage 3 adds the mouse behavior. If the mouse is pressed close to one of
the 4 vertices P0, P1, P2, P3 then the particular vertex is
noted and dragging is enabled. As the mouse is dragged, all that needs
to be done is to update the position of the vertex and then call
paintStructure. This demonstrates that adding mouse actions
is easy if the underlying methods are already present.

Stage 4 adds the tabbed pane that shows the values of the 10 points
P0, P1, P2, P3, Q0, Q1, Q2, R0, R1, S0. Originally,
the plan was to use 4 rows for P’s,
Q’s,
R’s,
and S0.
However, this occupied too much horizontal width. Therefore, we
decided to use a vertical layout with 10 rows. The data definitions
show the traces of the earlier design but the new code is valid.

Stage 4 also introduced a check box to control whether or not the
labels should be displayed. We found in experimentation that it
was sometimes hard to see the geometry due to the labels. Thus,
the ability to hide the labels was deemed essential.

Stage 5 was added to tidy up loose ends. After making the applet
file, we decided that the cubic structure pane should be 500 by 500
rather than 600 x 600. This required us to change the coordinates
of the some of the P’s. We also noticed a bug
in that the mouse would not always drag a P-square.
We realized that this was due to a difference in the size of a
square from the distance used to test mouse closeness. We made
both numbers equal.

10/26/06: Polygons and Cubic Curves

In the two previous sections, you have seen how to use the Java
class GeneralPath to make shapes consisting of lines,
quadratic curves, and cubic curves. Since you may also introduce
move and close operations, you can make shapes with multiple
sections. This is very powerful and general. However, there is
no simplification in Java for constructing a shape that consists
of a single section that is made up of only lines (a polygon) or
only of cubic curves segments. In this section, we will show you
how JPT makes these special cases easier.

Since a polygon consists of lines, there is no need for control
points. On the other hand, to define a cubic curve one must either
specify control points or employ an algorithm that will decide what
the control points should be based solely on the vertex points. If
such an algorithmically automated process provides control points
that are “good enough” then much effort can be saved by
the programmer and the user.

This section will focus on two JPT classes PolygonShape
and AutomaticCurve that are the most useful in
practice. JPT offers several other classes for more special needs.

Before we get into details, let us show a screen snapshot of the demo
program that will illustrate these ideas.

As you can see, the program will create a random shape that is either a
polygon or a cubic curve with between 3 and 18 vertices. If you have
selected one type of shape on construction you can switch to the
opposite type by clicking on the shape radio button choices. Using the
mouse, you can drag any of the vertex points to see how the shape
changes.

There are two choices that apply to both polygons and cubic curves,
namely, the decision about whether the shape is closed or open and the
decision about the winding rule that determines the filled region. In
this demo, you can flip these choices after the shape is built and see
visually exactly what happens. We have discussed the winding rule
above and the main thing to keep in mind is that
“wind-non-zero” potentially considers more points to be in
the shape region than the simpler rule “wind-even-odd”.

In the case of a cubic curve, you must also choose the algorithm that
automatically computes the control points from the vertex points. JPT
provides two such algorithms. The Bezier strategy chooses the control
points to achieve “smooth second derivatives”. Once you
learn calculus, this smoothness condition will make sense. The other
strategy is the chord strategy that computes the control points using
the chord joining the two adjacent vertices as a guide. This chord
vector is multiplied by a numerical factor that controls how tight the
curve is at each vertex. The smaller the factor the tighter the curve.
Factors between 0.25 and 0.333333 tend to
work best but you can experiment with other factors even negative ones.

The option to show labels lets you see where the polygon or curve starts.
This is useful when you switch from a closed to an open shape.

Rather than use integers to specify these choices as in Java, we follow
the modern practice of using classes with constant objects for each
choice. This means that if you accidentally reverse the order of the
choices in the above constructor, you will get a compiler error instead
of merrily going forward to discover the error at runtime.

The data points for the polygon are specified by a 2-dimensional array
of float that should have some number n of
rows and have exactly 2 columns.

The main point of the diamond example is that the diamond
data can be entered directly in the definition of the
float array. Thus, an array in Java can be
initialized quickly in manner somewhat like a list in
Scheme.

It is also possible to initialize a float array
algorithmically. This is illustrated by the following
example of a star.

In the star code, the method star() constructs the
float array that is used to make starShape.
You will also notice that I used a brief constructor fot the diamond
shape but the full PolygonShape constructor for the star.
The reason is that I needed to specify the winding rule
WindingRule.WIND_NON_ZERO since otherwise the star would
not fill properly.

Returning to the Polygons and Cubics demo, the code to construct
the shape is algorithmic. The data points are constructed randomly via
the following method:

As you can see, this method calls various helper methods that extract
the current user settings from the GUI. In the case of a cubic, the
AutomaticCurve constructor requires an extra parameter
that provides the tangent strategy. This strategy encapsulates the
algorithm that computes the control points from the vertex points.
The two strategies built into JPT are found in class
Tangent as is seen in the above code.

The main constructor for an AutomaticCurve is similar to
that for a PolygonShape except that it has two extra
parameters, an array to specify end tangents if the curve is open and
the tangent strategy parameter:

The endTangent parameter allows one to specify the end
tangents if the cubic curve is open via a float[2][2].
The usage of this parameter is more subtle and you may safely omit
it for now. Thus, the constructor we recommend is:

Here is a little puzzle related to the star. Can you make the star
shape by drawing only the outer outline? If you think about it, you
will need 10 data points not 5 since you need to explicitly know the
intersection points of the 5 star edges. You need some math to
actually figure out the coordinates of the intersection points. It
is also necessary to get the 10 points into a float
array in the correct order. See if you can do it!

11/13/06: Concentration Game

The Concentration Game was originally posted on the JPT 2.3.5 site about
two years ago. The code here has been carefully refactored to improve
its structure and readability.

In the Concentration Game, the user is presented with a square array of
hidden tiles. Upon clicking on a tile, its image is revealed. Upon
clicking on a second tile, its image is also revealed. If the two tiles
match, then they will continue to be visible. If they do not match, then,
on the next click, they will once again be hidden. By remembering the
location of tiles already shown, the user can make matches more easily
as the game proceeds. The goal is to match tiles with the fewest number
of guesses.

In this implementation of Concentration, the user is first presented with
a panel that allows a choice of settings.

Using the settings panel, the user may select the choice of images
(shapes, photos, letters of the alphabet, or numbers). The user is also
given 4 choices of grid size (3-by-3, 4-by-4, 5-by-5, or 6-by-6). The
limit of 6-by-6 is based primarily on limitations of screen real estate.

Here are screen snapshots (at 50% of full size) showing samples of the
shapes and samples of the photos.

When the images are letters or numbers, the game appears to be more
difficult since the memorization is more purely intellectual and has
less of a visual component.

The concentration game is available both as an application and as an
applet.

Most of the code for the Concentration Game is the same for the
application and the applet. A notable difference is the code for
obtaining the images. The application uses images in a directory
on the local disk whereas the applet uses web images. Since it is
possible that the images may fail to load, the program will revert
to shapes if images are not available. We now provide the Java code.

This class selects the images that will be shown in the tiles and
arranges that each image occurs an even number of times so that
matches are always possible. This class also creates the GUI for
the game.

Applet Specific Code

This class launches an applet with the ConcentrationSettings as
its GUI.

Notes

There are two files with the same name, GameImages.java,
one for the application and one for the applet. The class
ConcentrationSettings makes a static reference to the
class GameImages so by substituting a different file for
the application and for the applet we can easily arrange that the
photos come from different sources.

11/17/06: Random Shape Demos

In class, on November 16, 2006, in response to a student question, I
developed two versions of a program that add random circles to a
graphics pane each time a button is clicked. Each program installs
mouse actions that enable the circles to be dragged with the mouse.
When a circle is clicked it moves to the topmost position so it is
above all other circles. To the user, both programs appear to have
the same GUI and the same behavior.

We will provide a link to the source of each program and then describe
briefy the particular features.

This program uses BufferedPanel to create its graphics pane.
Since a BufferedPanel has a built-in
PaintableSequence is is easy to add individual circles as
ShapePaintable objects to the sequence. Furthermore, a
BufferedPanel has a built-in set of mouse actions that will
allow the user to drag the items in the sequence with the mouse. Thus,
to get this mouse behavior requires a single line of code. In total,
except for import statements, the entire program is one screen of code.

This program manually constructs a graphics pane using a
PaintableSequence that is placed in a Tile
that is in turn placed in a PaintableComponent. The default
bounds of the Tile are set at 500-by-500 so that it maintains its size
regardless of what is in the internal PaintableSequence. In
comparison with the first version of the program, there is only a tiny
change in the code to add a new circle. Where the work comes in is with
the mouse actions since these are not built-in. We must define methods
to implement the mouse press and drag behavior, mouse action objects to
encapsulate these methods as objects, and installation code to attach
the mouse actions to the paintable component wrapper. In total,
except for import statements, the entire program is two and a half screens
of code. You may view the extra code as revealing the kind of code that
is built into BufferedPanel and available automatically.

11/17/06: Dice in Java and Scheme

Last evening, Tim Klopotoski sent me an interesting program in Scheme
that tosses dice. His words: “Very short. Very beautiful.”
Tim explained to me a fact that I considered astounding: Scheme can embed
image files into Scheme code. There is no need to reference images via
file names or web links. Tim's GUI building is a tour-de-force since he,
in effect, manually creates a button and tests for a mouse click. Bravo.

Class SpinningAnimation defines a panel that can
spin an arbitrary Paintable object. The class is
similar to
BallAnimation above
but is more general since it accepts an arbitrary paintable.
Furthermore, the rotation may be reversed instantly with the
click of a radio button.

Star Geometry and Trigonometry

Let us explain in detail the geometry and trigonometry that is
involved in the construction of the star shapes. Each star is
characterized by its center (x,y), its outer
radius r, the number of outer vertices,
and the jump between vertices that determines the
specific star shape. In the snapshot below, vertices equals
7 and jump equals 3 so this would be
described as a 7,3 star. Our goal is to draw the
star as an outline so you can see that we not only need the outer
vertices we also need an equal number of inner vertices. The
inner vertices are determined by where the lines joining the outer
vertices would cross. We have drawn a dashed line to suggest
one such line joining a pair of outer vertices separated by the
jump.

In the diagram, C is the center of the star,
A is the topmost outer vertex,
B is the next inner vertex clockwise from A,
and Z is the outer vertex jump steps from
A.
We are given the outer radius r.
We can compute B if we can compute the
inner radius s from C to B.
We will do this using geometry and trigonometry.

First, the total number of vertices (outer and inner) is
V where:

V = 2vertices

Then, the angle C, in the triangle CAB is
given by:

C = 360.0 / V = 180.0 / vertices

Next, consider the large isosceles triange CAZ. The
large angle at C in this triangle is given by:

C_Large = 360.0jump / vertices

Since CAZ is isosceles, we can compute the angle at
A as:

A = (180.0 - C_Large) / 2 = 90.0 - 180.0jump / vertices

Then, using triangle CAB, we can compute the angle
B as:

B = 180.0 - A - C

Now, using the “Law of Sines” from trigonometry, we have
the equation:

r / sindeg(B) = s / sindeg(A)

or

s = rsindeg(A) / sindeg(B)

This is the formula used to compute the star shape in the Java class
RegularShape.java.

Aside: This is yet another example of why students of computing
should know some mathematics. Mathematicians have spent thousands of
years discovering some nifty things that are quite useful in computing.

4/1/07: Keys, Animation, Threads

On November 18, 2005, we posted a demo that illustrated
the tracking of key press-release states and the use of
such tracking for animation. This demo utilized several
helper classes that were later introduced into JPT during
Summer 2006. Below we show a screen snapshot of the demo
and then give the slightly revised source code that uses
the JPT classes.

This demo uses two separate threads in addition to the
standard “GUI thread”.

The first thread examines the state of the five keys of interest
(up arrow, down arrow, left arrow, right arrow, and shift) and echoes this
state into a small paintable that is shaped as a large plus sign with 5 tiles.
When the shift key is pressed, the center tile is highlighted.
When an arrow key is pressed, the corresponding tile (N, S, W, E) is
highlighted. The purpose of this thread is to show whether or not
a key press or release has been detected by the software.

The second thread moves the paintable square if at least one arrow key is
pressed. The purpose of the second thread is to have a longer delay if
the paintable is being moved so that the movement delay is not forced to
be the same as the much smaller delay that is used to signal detection of
a key press or release. This design keeps the square from moving too
quickly.

This demo illustrates the fact that one may launch multiple threads besides
the default “GUI thread”.

In the demo above, the two threads run for the duration of the program.
The methods class below, illustrates a short-term thread that runs only
as long as is needed to animate a ball moving up and then moving down.

Of course, a stack trace is usually multiple lines of text,
some of which are quite wide. Hence it is convenient to
have additional utilities that will display a string in a
scroll pane that is in turn placed into a frame or into an
OK dialog box. These are provided in the class:

This is a model for how to set up an applet if you wish to catch
and display exceptions that occur as the GUI is being constructed.

Here is the access to the
BadGUIApplet.
You will see that an exception is thrown and that the message is
displayed in a dialog box.

Here is the heart of the html code for the BadGUIApplet
web page. It is parallel to the applet code for all other applets
on this site.

<h1>
Bad GUI Applet
</h1>
<h4>
The applet on this page intentionally throws an exception in
the course of building its GUI. The purpose is to demonstrate
the technique for viewing the exception stack trace in an OK
dialog box.
</h4>
<p class="centered">
<applet
codebase="./bin/"
code="BadGUIApplet.class"
archive="http://www.ccs.neu.edu/jpt/archive/2.5.0/lib/jpt.jar"
width="100"
height="100"
>
</applet>
</p>

4/12/07: Ball Animation with SimpleThreadedAction

In earlier examples with animation and threads, it was
necessary to build a SimpleAction and pass it
to a wrapper class ThreadedAction in order to
force the action to execute in a separate thread. As we
have seen, the separate thread is the key to running the
animation with appropriate pauses while the GUI remains
alive.

Recently, my mental light bulb went on and I realized that
it would be very convenient to build the action and make
it run in a separate thread all in one step. This was
easy to do and is available in the class below. The class
SimpleThreadedAction will become part of JPT
in the next release.

4/12/07: Ship: Graphics Composite

A key question in building graphics entities for more complex
programs such as games is how to build composites, that
is, entities that are made up two or more fragments that build
the entity. Here is a trivial example of what we mean, a space
ship with the rocket thrust coming from its rear.

Certainly, this is the world's most simple-minded space ship but it
is adequate to illustrate the idea of a composite of two or more
fragments, in this case, the silver triangle that represents the
space ship body and the red thrust rectangle that acts as a tail.

The natural JPT class to use to build a composite is
PaintableSequence since it can collect one or more
Paintable fragments that may be drawn in the order
specified during construction.
The class Ship1 given below is a derived class of
PaintableSequence. It uses the constructor to put
together the fragments that combine to make the space ship.

From the point of view of abstraction, however, the above solution
is a hack since we do not want to view a ship as a
PaintableSequence to which other random fragments may
be added.
We would prefer to build the ship internally and force the outside
world to see it simply as a Paintable entity. This
can be accomplished using the class
PaintableSequenceComposite.
This is done in the class Ship2 given below.

The key to this design is that the class Ship2 can
access an internal PaintableSequence via a protected
get method but callers in the outside world do not have access to
this sequence. This makes the Ship2 object an object
that uses parts in its construction but whose parts cannot be seen
from the outside.

Here is the test class. To distinguish the ships built from each
class, the Ship1 object is rotated 30 degrees
and the Ship2 object is rotated 60 degrees. In each
class, the turn method illustrates how to add simple
extra functionality.

5/2/07: LayeredComponent

A significant annoyance in classic Java is that the background of
a component or a panel as set via setBackground can
only be a Color. It would be much more convenient
if the background could consist of images, shapes, text, paints,
etc. This problem is solved via a new class
LayeredComponent that will be incorporated in the next
release of JPT.

A LayeredComponent takes the following ingredients:

A foreground object that is a
JComponent which contains the widgets that
constitute the foreground of the layered panel. Most
often the foreground will be a panel of some sort.

A background object that should either be a
Paintable or be convertible to a
Paintable via ComponentFactory.
The background object will form the main content of the
background of the layered panel.
If the background is null then it is ignored.

A paint object that will paint on the areas
of the background of the layered panel that are not
painted upon by the background object.
If the paint is null then it is ignored.

An opacity parameter that determines the
opacity of the background. Often it is desired to paint
a background with opacity less than 1 in order not to
overwhelm the foreground content. The opacity affects
both the background object and the paint.

A centered parameter that determines if the
background object should be centered relative to the
foreground component.

As you can see, LayeredComponent is general enough to
provide for both background objects, background paint, or both.
Below is the source:

The test code requires 2 images, one of apples in the foreground and one
of a tree in the background. You will notice 2 controls that allow you
to vary how the background is rendered. The slider allow the user to control
the opacity. The radio buttons allow the user to decide whether or not
to center the background object relative to the foreground. This allows
easy experimentation with the LayeredComponent widget.
In practice, of course, the designer would normally make these settings.

During testing, we experimented with placing the slider and radio buttons
within the layered component and setting their own backround to a
transparent color. However, when a user interacts with such controls,
Java makes subtle changes in rendering that produce strange artifacts
because Java assumes that that the control background is opaque and that
rendering shortcuts may be taken. This is therefore a limitation on the
usage of LayeredComponent.