Freshman Honors Seminar

CS U231 Fall 2007 and CS U232 Spring 2008

http://www.ccs.neu.edu/jpt/fhs/

This site will contain materials from both semesters of the freshman honors seminar CS U231 and CS U232 in 2007-2008.

Materials from previous years are at:

Links to Course Materials

Introductory Links

The plan or syllabus for the CCIS Freshman Honors Seminar as a PDF document.

Access to the Sun Java site

Sun Java Downloads

Javadocs

Access to the Eclipse site for Eclipse 3.3

Eclipse Downloads

Access to Eclipse 3.2 for Windows (one version back)

eclipse-SDK-3.2-win32.zip

Access to the Java Power Tools.

The JPT 2.6.0 site

The JPT 2.6.0 javadocs

The JPT 2.6.0 annotated source and tutorial

The JPT 2.6.0 applets

The template methods class Methods.java for the Java Power Framework

Access to cascading style sheets

The main cascading style sheet for this web site: fhs.css.

The screen cascading style sheet for this web site: fhs_screen.css.

The applet cascading style sheet for this web site: applet.css.

Back to Top.

Down to Bottom.

Introductory Links

Links to Course Materials

9/6/07 Sample Methods Class #1
9/19/07 Playing Cards Demo
9/20/07 Tic Tac Toe
9/26/07 Concentration
9/27/07 Text Field Sample
9/28/07 Exercise 1
10/5/07 Sliders Demo
2/3/08 3D Explorations 1
2/14/08 3D Explorations 2
2/20/08 3D Explorations 3
3/13/08 3D Explorations 4
4/3/08 Simple Sketch

Back to Top.

Down to Bottom.

Course Materials

9/6/07: Sample Methods Class #1

In the first session of Freshman Honors Seminar, we presented the following Methods class that is based on the Java Power Framework (JPF) test/experiment environment.

The first sample class Methods.java

We did 4 experiments. Before the experiments, we uncommented some lines in the main method to increase the font size by 2 and to enable mouse actions in the graphics window. The main method is as follows:

public static void main(String[] args) { 
    LookAndFeelTools.adjustAllDefaultFontSizes(2);
    
    Methods methods = new Methods();
    
    methods.window.installSimpleMouseActions(true);
}

Experiment 1 uncomments and runs the sample Test method that is placed in Methods.java to enable a user to check that JPT is correctly installed. This method is:

public void Test() {
    Shape shape1 = new XRect(100, 100, 100, 50);
    
    Paintable paintable1 =
        new ShapePaintable
            (shape1, PaintMode.FILL_DRAW, Colors.red);
    
    Shape shape2 = new XOval(150, 125, 100, 50);
    
    Paintable paintable2 =
        new ShapePaintable
            (shape2, PaintMode.FILL_DRAW, Colors.yellow, Colors.blue);
    
    window.clearSequence();
    window.appendPaintable(paintable1);
    window.appendPaintable(paintable2);
    window.repaint();
}

This method is a public method with no parameters and no return value. This is an example of a method that will be implemented as a button in the Java Power Framework GUI when the program is run. Here is screen snapshot that shows the JPF GUI and the result of clicking on the Test button.

Test snapshot 1

As you can see, there is a red rectangle with black border placed on top of a yellow ellipse with blue border. Here is a second snapshot.

Test snapshot 2

Since we enabled mouse actions in the graphics window, we were able to drag both the rectangle and the ellipse and, furthermore, the ellipse is now the object on top.

Now let us comment on the code.

public void Test() {
    Shape shape1 = new XRect(100, 100, 100, 50);
    
    Paintable paintable1 =
        new ShapePaintable
            (shape1, PaintMode.FILL_DRAW, Colors.red);
    
    Shape shape2 = new XOval(150, 125, 100, 50);
    
    Paintable paintable2 =
        new ShapePaintable
            (shape2, PaintMode.FILL_DRAW, Colors.yellow, Colors.blue);
    
    window.clearSequence();
    window.appendPaintable(paintable1);
    window.appendPaintable(paintable2);
    window.repaint();
}

The rectangle and ellipse are constructed via the new operator using the JPT XRect and XOval classes which are among the basic geometric shapes supported by JPT. This is more concise than Java's corresponding classes Rectangle2D.Double and Ellipse2D.Double. Each Shape is then installed in a ShapePaintable which is an example of the general Paintable interface. A Paintable knows how to paint itself in a graphical situation. In this example, we tell each ShapePaintable to both fill itself and draw its border. For the rectangle, we supply the fill color of red but since we do not supply the border color that color defaults to black. For the oval we supply both the fill color of yellow and the border color of blue.

To actually display the Paintable’s, we clear the graphics window of any previously installed Paintable’s, we append the two new Paintable’s with the rectangle on top, and we instruct the window to repaint itself using its new contents. Repainting once at the end of a sequence of operations is more efficient than repainting after each step.

Experiments 2 and 3 deal with placing a single random point in the graphics window and with placing many such points at once. The methods are:

public void PaintOnePoint() {
    int x = MathUtilities.randomInt(0, 400);
    int y = MathUtilities.randomInt(0, 400);
    
    window.appendPaintable(new XPoint2D(x,y));
    window.repaint();
}


public void PaintManyPoints(int count) {
    for (int i = 0; i < count; i++) {
        int x = MathUtilities.randomInt(0, 400);
        int y = MathUtilities.randomInt(0, 400);
        
        window.appendPaintable(new XPoint2D(x,y));
    }
    
    window.repaint();
}

The methods are similar. In the PaintOnePoint method, a pair of random x,y coordinates are generated using a utility from the JPT class MathUtilities. The parameters are 0 and 400 since the graphics window is 400-by-400. Using the x,y coordinates, we then construct (using new) an XPoint2D which represents the geometric point, and we append this point as a Paintable to the graphics window.

There is important JPT magic going on here. An XPoint2D is not a Paintable since it is just pure geometry. However, whenever possible, JPT will automatically wrap what the programmer supplies into some object that will do what is required. Specifically, the XPoint2D is wrapped into a PointPaintable with the default settings that will then paint the point as a black square of side 6 centered at x,y. The details of this JPT magic are handled by the makePaintable method in ComponentFactory.

The PaintManyPoints method comes with a parameter or argument, namely, count to specify how many points to add. The inside of PaintManyPoints looks similar to PaintOnePoint except that the process of creating and appending a random point is wrapped within a for loop that accomplishes the repetition with count repeats. The syntax of a for loop is quite strange with the semicolons inside the parentheses but that is what was decided historically and no one can change it now. You must simply learn and memorize the pattern. Notice that the repaint operation is outside of the block of code executed by the loop (indicated by the braces { }) so that there is only one repaint for efficiency.

Because PaintManyPoints method comes with a parameter, there must be some way for the user to enter that parameter when the button in the JPF GUI corresponding to PaintManyPoints is clicked. The answer is that an auxiliary window opens up that allows that parameter to be entered.

Auxiliary GUI for PaintManyPoints

In the above snapshot, we entered 1000 to add 1000 points and then clicked. The result is shown in the snapshot below:

PaintManyPoints after 1000 points

Since this method does not clear the graphics window before adding new points, one can click multiple times. The snapshot below shows the result of clicking 5 times for 5000 points.

PaintManyPoints after 5000 points

Notice that the graphics window is almost filled. Why is this? First, the number of pixels in the window is 400x400 or 160,000. Each point is drawn using a square of side 6 which requires 36 pixels. Therefore, ignoring overlaps, 5000 points will require 5000x36 or 180,000 pixels. Of course, overlaps do occur which is why some small amount of white space is still visible.

Experiment 4 illustrates the automatic evaluation of mathematical expressions in JPT. The method is deceptively simple.

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

This method seems to do nothing much, namely, it just takes in an x and then returns that x. However, there is more JPT magic. The value of x will be entered from the user via an auxiliary GUI:

EvaluateDouble snapshot

As you can see, the user entered a mathematical expression:

(1 + sqrt(5)) / 2

and this expression was correctly read and evaluated to:

1.618033988749895

The JPT magic comes about because all input is processed through the implementations of the JPT Stringable interface which in turn rely on assorted parsing tools including the powerful package edu.neu.ccs.parser. Because of this built-in support, mathematical expression evaluation appears to “come for free”.

Back to Top.

Back to Links to Course Materials.

Back to Start of Sample Methods Class #1.

Down to Bottom.

9/19/07: Playing Cards Demo

The Playing Cards Demo displays a deck of 52 cards plus 2 card backs and 2 jokers. If a card is clicked with the mouse, it jumps to the top of the heap. If a card is dragged with the mouse, it moves. The demo can show the cards in sorted order or randomly placed as is illustrated by the two screen snapshots below:

Playing Cards Sorted Order       Playing Cards Random Order

Click on either snapshot above to go to the JPT 2.6.0 Applets Page where there is a more complete dicussion together with access to the Playing Cards Applet and the source code. When you reach that page, click on the snapshots there to launch the applet and to get to the source code.

Back to Top.

Back to Links to Course Materials.

Back to Start of Playing Cards Demo.

Down to Bottom.

9/20/07: Tic Tac Toe

The Tic Tac Toe game is elementary and so provides a simple setting in which to illustrate additional ideas in GUI building. Consider two screen snapshots from the Tic Tac Toe 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.

TicTacToe image with a winner       TicTacToe image with a tie

Click on either snapshot above to go to the JPT 2.6.0 Applets Page where there is a more complete dicussion together with access to the Tic Tac Toe Applet and the source code. When you reach that page, click on the snapshots there to launch the applet and to get to the source code.

Back to Top.

Back to Links to Course Materials.

Back to Start of Tic Tac Toe.

Down to Bottom.

9/26/07: Concentration

The Concentration game is a game that uses many of the techniques of the Tic Tac Toe game but has more sophisticated behavior. The game board consists of an even number of tiles whose content is initially hidden. The content is arranged in pairs, that is, each content item actually belongs to 2 tiles. When the user clicks a blank tile, its content item will be shown. Ditto, when the user clicks a second blank tile. If the 2 tiles show the same content, then this content will remain visible during subsequent clicks. If not, on the next click, the content of the 2 tiles will be hidden once again, and the process repeats. The goal of the game is to find all pairs so that ultimately all content is visible.

The Concentration game can use 4 kinds of content item: images, shapes, letters, and numbers. The snapshot below illustrates images.

Concentration images shapshot

Click on the snapshot above to go to the JPT 2.6.0 Applets Page where there is a more complete dicussion together with access to the Concentration Applet and the source code. When you reach that page, click on the snapshots there to launch the applet and to get to the source code.

Back to Top.

Back to Links to Course Materials.

Back to Start of Concentration.

Down to Bottom.

9/27/07: Text Field Sample

It is easy to do a single specific computation using a JPF class Methods.java. Here is an example that computes the square, the square root, and the inverse of a number using 3 public methods in the Methods class:

import edu.neu.ccs.jpf.*;

public class Methods extends JPF 
{
    
    public static void main(String[] args) { 
        Methods methods = new Methods();
    }
    
    public double Square(double x) { return x * x; }
    
    public double SquareRoot(double x) { return Math.sqrt(x); }
    
    public double Inverse(double x) { return 1 / x; }
    
}

To combine computations, it is necessary to create a class that instantiates its own graphical user interface (GUI). The following example, TextFieldSample.java, shows how to do this. The computations are intentionally trivial so the GUI building code will be as clean as possible.

Before getting into details, you may execute the applet version of the code by clicking one of the two images below:

TextFieldSample image with a positive number and access to applet       TextFieldSample image with a negative number and access to applet

Here is the complete source for TextFieldSample.java:

/* @(#)TextFieldSample.java   27 September 2007 */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;

import javax.swing.*;

public class TextFieldSample
    extends DisplayPanel
{
    /** The table panel gap. */
    protected int gap = 20;
    
    /** The text field view width. */
    protected int width =
        TextFieldView.getSampleWidth("0000000000000000000000");
    
    /** The text field view for x. */
    protected TextFieldView xTFV = new TextFieldView(width);
    
    /** The label for x. */
    protected Annotation xLabel = new Annotation("");
    
    /** The label for the square. */
    protected Annotation sLabel = new Annotation("");
    
    /** The label for the square root. */
    protected Annotation rLabel = new Annotation("");
    
    /** The label for the inverse. */
    protected Annotation iLabel = new Annotation("");
    
    
    /** The demand computation action. */
    protected SimpleAction demandAction =
        new SimpleAction("Demand Computation") {
            public void perform() { demand(); }
    };
    
    
    /** The request computation action. */
    protected SimpleAction requestAction =
        new SimpleAction("Request Computation") {
            public void perform() { request(); }
    };
    
    
    /** The constructor. */
    public TextFieldSample() {
        createGUI();
    }
    
    
    /** Create the GUI. */
    protected void createGUI() {
        // 2-dimension table of labels and text fields
        Object[][] stuff = {
            { "x",                new Halo(xTFV) },
            { "x",                xLabel },
            { "Square Of x",      sLabel },
            { "Square Root Of x", rLabel },
            { "Inverse Of x",     iLabel }
        };
        
        TablePanel panel =
            new TablePanel(stuff, gap, gap, WEST);
        
        // vertical table with 2-dimensional table and buttons
        Object[] mainStuff = { panel, demandAction, requestAction };
        
        VTable mainTable =
            new VTable(mainStuff, gap, gap, CENTER);
        
        // decorate
        mainTable.emptyBorder(gap);
        mainTable.setDeepBackground(Colors.white);
        mainTable.setDeepBackground(Colors.yellow, JButton.class);
        
        // add the main table to the enclosing GUI
        addObject(mainTable);
        
        // add the request action as the default action
        xTFV.addActionListener(requestAction);
    }
    
    
    /** The method to demand x for the computations. */
    protected void demand() {
        double x = xTFV.demandDouble();
        
        xLabel.setText("" + x);
        sLabel.setText("" + (x * x));
        rLabel.setText("" + (Math.sqrt(x)));
        iLabel.setText("" + (1 / x));
    }
    
    
    /** The method to request x for the computations. */
    protected void request() {
        try {
            double x = xTFV.requestDouble();
            
            xLabel.setText("" + x);
            sLabel.setText("" + (x * x));
            rLabel.setText("" + (Math.sqrt(x)));
            iLabel.setText("" + (1 / x));
        }
        catch (CancelledException ex) {
            xTFV.setText("");
            xLabel.setText("Cancelled");
            sLabel.setText("Cancelled");
            rLabel.setText("Cancelled");
            iLabel.setText("Cancelled");
        }
    }
    
    
    /** The main method. */
    public static void main(String[] args) {
        new TextFieldSample().frame("Text Field Sample");
    }
    
}

Now let us discuss the program.

By examining the shapshots of the GUI, you will see that there is a large table with 5 rows and 2 columns, and below that there are 2 buttons. In the left column of the table, there are 5 labels that remain constant throughout the program so these can be entered in the createGUI method as String data, In the right column of the table, there is 1 TextFieldView and 4 labels that show the output of computations and so cannot be entered as constants. These 4 labels use explicit Annotation objects. The first set of lines of code in the program define the TextFieldView and the 4 Annotation objects.

The 2 buttons will be defined from the 2 actions (behaviors) that they perform so you see next in the code the definitions of the corresponding SimpleAction objects. These definitions utilize the methods demand() and request() defined later in the code.

Next in the code is the public constructor. In this simple example, it has one task, namely, to create the GUI, and this is done by calling the createGUI method.

The createGUI method works as follows. First the stuff that will form the ingredients of the table that has 5 rows and 2 columns are collected in an array that has 5 rows and 2 columns. The left column has the constant String labels. The right column has the TextFieldView and the 4 Annotation objects. You will notice that the TextFieldView is wrapped within a Halo. The Halo is optional but the advantage of using the Halo is that if the user makes an input error then a small highlight wraps around the TextFieldView. The 5-by-2 table panel is created using the stuff and the class TablePanel.

The 5-by-2 table and the 2 actions (which will be used to create 2 buttons) are then placed in a vertical table using the class VTable.

Java Power Tools supports two policies regarding user input errors. The mandatory or demand policy requires that the user correct errors before the program proceeds. The relaxed or request policy permits a user to cancel an operation if an error has been detected. In that case, the code signals the situation by throwing a CancelledException. The program must prepare for this possibility by using a try-catch block as shown in the sample code for request(). In this case, the program chooses to clear the text field and to put the message “Cancelled” in the 4 annotations.

As you can see, the sample program illustrates the implementation of both error policies with the methods demand() and request() which are the implementation methods for the 2 SimpleAction objects. You may view this process of implementing an action by calling an associated method as an idiom for converting the method into an object. This idiom is needed in Java because Java does not view methods directly as “first class” entities on a par with objects.

In practice when an error occurs in reading data from a TextFieldView, the user will be presented with a dialog box in order to correct the error. With the demand policy, the error must be corrected. With the request policy, the error may be corrected or the user may choose to click the “Cancel” button to stop the processing. It is the code in the catch section that handles the alternative when the user chooses to cancel.

Back to Top.

Back to Links to Course Materials.

Back to Start of Text Field Sample.

Down to Bottom.

9/28/07: Exercise 1

Exercise 1 asks you to create a pictures using Paintable objects in a window that is launched in a Java application. For details, click here.

Back to Top.

Back to Links to Course Materials.

Down to Bottom.

10/5/07: Sliders Demo

The program SlidersDemo.java illustrates how to use horizontal and vertical sliders to control the x,y position of a circle in a window. For comparison, the circle position may also be controlled by clicking and/or dragging the mouse in the window. This permits you to compare and contrast the use of sliders versus the use of the mouse directly.

Sliders Demo snapshot and access to applet

Click on the above snapshot to execute SlidersDemo as a Java applet.

Back to Top.

Back to Links to Course Materials.

Back to Start of Sliders Demo.

Down to Bottom.

2/3/08: 3D Explorations 1

In class on January 31, 2008, I began some explorations of Java code for drawing “wire frame” renderings of 3D shapes. The ideas were intended as much as an exploration of how to design classes with a geometric flavor as of 3D graphics. My goal was to toss out this first draft and then elaborate and modify in subsequent lectures. Here are the files. I have added to each file an internal title and date but have otherwise left the code as is.

The Java file XPoint3D.java

The class extends the JPT class XPoint2D by adding a z coordinate to the existing x and y coordinates. As noted in the file, redefining the Stringable methods is left as a “To Do” item.

The Java file Shape3D.java

This class was at the heart of the presentation in lecture. After some discussion of alternatives, I argued that placing the shape vertex data in an array of point data would be very convenient since then edges could be represented by a pair of point indices and faces by a sequence of point indices. Other representations seemed to make it more difficult to represent edges and faces.

The Java file Transform3D.java

Transform3D is defined as in interface. The reason for this is that there are different kinds of transforms and different ways to maintain their data. Using an interface makes no irrevocable commitments. All options remain possible as ways to implement the interface.

The Java file Methods.java

Only one non-trivial method was introduced in this test class, namely, a method to define a simple cube. This method should be static because it is a factory method whose purpose is to construct some object. This method is also incorrect (my apologies). Can you figure out why?

Back to Top.

Back to Links to Course Materials.

Back to Start of 3D Explorations 1.

Down to Bottom.

2/14/08: 3D Explorations 2

In class on February 7, 2008, I continued the explorations of Java code for drawing “wire frame” renderings of 3D shapes. I fixed up some issues in the code and I discussed some subtle questions in how a “wire frame” might be rendered. I plan to continue the discussion tonight and hopefully reach the point where a cube can be drawn. ☺

The Java file XPoint3D.java

The Java file Shape3D.java

The Java file Transform3D.java

The Java file Methods.java

Back to Top.

Back to Links to Course Materials.

Back to Start of 3D Explorations 2.

Down to Bottom.

2/20/08: 3D Explorations 3

In class on February 14, 2008, I continued the explorations of Java code for drawing “wire frame” renderings of 3D shapes.

The Java file XPoint3D.java

Implemented public XPoint3D copy(). Also implemented a static method to copy arrays XPoint3D[]. This is used to define a copy method in Shape3D.

The Java file Shape3D.java

Settled on the strategy that get and set methods for this class would be implemented by assignment so that by default no copying is done. Then implemented a copy method so the caller may decide when a copy is required. This copy method used the tools in XPoint3D. In addition, tools were defined that copy arrays int[] and int[][]. These tools might at some point be refactored into a helper class.

The Java file Shape3DFactory.java

This class is intended to collect factory methods that create Shape3D objects. At the moment, it has one such method makeCube. This method was extracted from the Methods class and redesigned to place one corner at the origin and to make the edges of length 1.

The Java file Transform3D.java

This class defines the Transform3D interface which requires one method:

XPoint3D transform(XPoint3D p);

Although a Java interface file does not permit the definition of methods at top level, it does permit such a definition if the definition is within a static subclass. We take advantage of this feature to define a static class we name apply. Inside this class we define:

public static Shape3D transform(Transform3D t, Shape3D shape)

This method, in effect, extends the operation of a Transform3D from XPoint3D objects to Shape3D objects. Here is typical usage where t is a Transform3D and shape is a Shape3D:

Shape3D newshape = Transform3D.apply.transform(t, shape);

The Java file Transform3DFactory.java

This class is intended to collect factory methods that create Transform3D objects. At the moment, it has one such method:

public static Transform3D shadow(final XPoint3D candle)

This method constructs the shadow projection onto the x,y plane cast by a “candle” at the given position.

The Java file Methods.java

This file is now empty of interesting content but remains available for testing.

Back to Top.

Back to Links to Course Materials.

Back to Start of 3D Explorations 3.

Down to Bottom.

3/13/08: 3D Explorations 4

In class on February 21, 2008, I completed the explorations of Java code for drawing “wire frame” renderings of 3D shapes and was able to actually show the rendering of a cube. The first attempt to render produced bizarre results but one student quickly noticed the typo in my code and then the code ran perfectly. Given the fact that this code was produced live in class in 4 sessions, I am pleased that everything ran fine with one small correction.

I apologize for the delay in posting this code.

The Java file XPoint3D.java

This file is unchanged from 3D Explorations 3.

The Java file Shape3D.java

This file is unchanged from 3D Explorations 3.

The Java file Shape3DFactory.java

This file is unchanged from 3D Explorations 3.

The Java file Transform3D.java

This file is unchanged from 3D Explorations 3.

The Java file Transform3DFactory.java

This class is intended to collect factory methods that create Transform3D objects. In 3D Explorations 3, one method was defined:

public static Transform3D shadow(final XPoint3D candle)

This file adds an additional transform that deals with planar scaling of the image of a 3D shape:

public static Transform3D planeScale

(final double scale, final double x0, final double y0)

This method includes both a scale factor and translation components.

The Java file WireRender.java

This file contains one method:

public static PathList makePathList(Shape3D shape)

This method treats an XPoint3D as an XPoint2D and transforms each edge in a Shape3D into a pair of move and line commands that help to construct the PathList result.

The Java file Methods.java

This file now contains one test method that renders a cube. Here is a snapshot:

Cube Snapshot

Back to Top.

Back to Links to Course Materials.

Back to Start of 3D Explorations 4.

Down to Bottom.

3/13/08: 3D Explorations 4

4/3/08: Simple Sketch

The simple sketch program was generated in an hour’s conversation with a student who wanted a start on building an interactive program to draw shapes. It is intentionally posted “as is” with many possibilities for enhancement. At the moment, only the facilities for drawing points and lines are implemented. The buttons for rectangles and ovals do nothing. Below is a snapshot of the program in its current state and below that is a link to the source.

Sketch program snapshot

The Java file Sketch.java

Some possible enhancements after the first implementation of rectangles and ovals.

Back to Top.

Back to Links to Course Materials.

Back to Start of Simple Sketch.

Down to Bottom.