Freshman Honors Seminar

CS U231 Fall 2005 and CS U232 Spring 2006

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 2005-2006. Materials from last year are here.

Links

Introductory Links

September 18, 2005:

First Sample

September 23, 2005:

Finding Sums

Shape Editor

October 1, 2005:

Student Programs #1

October 6, 2005:

The JPT Book

October 12, 2005:

Student Programs #2

October 27, 2005:

Tic Tac Toe

Bit Display

October 30, 2005:

Student Programs #3

Integer List and Primes #1

November 1, 2005:

Integer List and Primes #2

November 2, 2005:

Listening for Keys in a GUI

November 10, 2005:

More on Listening for Keys in a GUI

November 18, 2005:

Even More on Listening for Keys in a GUI

Extended Tile Box

November 24, 2005:

Animate Sample

February 15, 2006:

Shape Tools for Intersections Etc

March 23, 2006:

Sudoku Version 1

Ken Eimer Gravity Simulation

Ken Eimer Pong Game ... The Road to Gravity

Down to the Bottom

Introductory Links

The plan or syllabus for the Freshman Honors Seminar in Computer & Information Science as a Word document or PDF document.

Access to the Java Power Tools.

The main JPT site: http://www.ccs.neu.edu/jpt/

The JPT 2.4.0 site: http://www.ccs.neu.edu/jpt/jpt_2_4/

The JPT 2.4.0 library file jpt.jar: http://www.ccs.neu.edu/jpt/jpt_2_4/lib/jpt.jar

The JPT 2.4.0 javadocs: http://www.ccs.neu.edu/jpt/jpt_2_4/docs/

The JPT 2.4.0 annotated source code: http://www.ccs.neu.edu/jpt/jpt_2_4/src/

The Methods.java file that may be used as a template for the Java Power Framework.

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

Back to the Top

Down to the Bottom

September 18, 2005

The First Sample Project

The methods file Sample1.java illustrates seven simple uses of JPT and the Java Power Framework. Please load this file into Eclipse with JPT installed and run the various methods. Then read the comments below on each method.

Our goal is for you to read the code and play detective. See how much of the code you can understand or at least guess as to the meaning. Look for patterns. Note whatever is puzzling. We will discuss such things in class.

In PrintThing, we illustrate how to print simple text output in the JPT console window.

In DemandSumInConsole and RequestSumInConsole, we compare the input-output patterns for the two paradigms supported by JPT.

In the demand paradigm, the user must supply valid data of the type expected or else exit the entire program. In the example, in which a sum of double precision numbers is being calculated, the user must supply a valid double or else the system will prompt for the input again. This requires deciding on a clean exit strategy. In the example, we choose to interpret the input of 0 as a summand as the user signal to cleanly exit the calculation.

In the request paradigm, the user must supply valid data of the type expected or else press return on an empty line to signal that the task is done. Thus, a clean exit strategy is built-in. The code uses a Cancelled Exception internally when the user presses return on a empty line and thus the code must look for this exception with a try-catch that handles the user's desire to exit.

Please compare the if-else structure in the demand code with the try-catch structure in the request code. You will see that the code is quite similar.

In EvalMathExpression, we illustrate two important features of JPT. First, if a simple public method in a JPF methods class has parameters and/or a return value, then JPF will build the GUI to obtain the parameters and display the return. Second, all text input in JPT that is to be converted into numerical data is automatically passed to a parser that reads and interprets mathematical expressions. These features are illustrated in the following screen snapshot that shows the evaluation of

sqrt(5) + pi + e

EvalMathExpression Snapshot

In RectangleAndCircle and FilledRectangleAndCircle, we illustrate how to install shapes into the graphics window of the automatic JPF graphical user interface.

In RectangleAndCircle, we construct two shapes and add them as Paintable objects to the window. These shapes are technically not yet Paintable so the addPaintable method wraps them in a suitable manner to display them with black strokes of thickness 2.

In FilledRectangleAndCircle, we construct two shapes and then wrap them explicitly ourselves. This allows us more options. For the first shape, we specify FILL rather than the default DRAW and specify the fill color as green. For the second shape, we specify FILL_DRAW with the fill color as violet; since the draw color and stroke are omitted, these default to black strokes of thickness 2.

Here is a screen snapshot of FilledRectangleAndCircle.

FilledRectangleAndCircle Snapshot

In ShowRandomCards, we have a somewhat more sophisticated example so we do not expect you to understand everything immediately. Here you should try to read the code and do some detective work to see how much you can figure out from the information in the program.

The code begins by reading the images of cards in a card deck including two card backs and two jokers. Since there are 56 total images, you will notice a delay as the cards are read from the web. Below, we give the links to the directory of the images and the text file that controls the order in which the images are read. You may check out this data directly.

Here is a link to the JFitz card image directory on the JPT site.

Here is a link to the imagelist.txt file that lists the image files in the JFitz card image directory on the JPT site in the order in which the images will be read. You will see that the suits are read in the order Hearts, Diamonds, Spades, and Clubs and within each suit the order will be Ace, 2, ... 10, Jack, Queen, King. The 4 additional cards in the list are a black vertical card back, a red vertical card back, a black joker, and a red joker. You will notice that there are additional images in the directory that we choose not to put in imagelist.txt.

After reading the images, the code uses ProbStatTools to create a random permutation so that the cards will be displayed in random order. The code also uses MathUtilities to move each card to a random card location.

Here is a screen snapshot of ShowRandomCards.

ShowRandomCards Snapshot

You will notice that if you click ShowRandomCards multiple times, the later images will display quickly due to file-IO caching done by Java.

Back to the Top

Down to the Bottom

September 23, 2005

Finding Sums: TextFieldView, TablePanel, SimpleAction, Halo

The methods file Sample2.java

The vanilla sum panel file SumPanel.java

The sum panel file using the Halo wrapper SumPanelWithHalo.java

Before the detailed discussion, we will show screen snapshots of the two variations of the sum panel: vanilla and with halo.

Sum Panel Sum Panel With Halo
Vanilla Sum Panel Sum Panel With Halo

You can see immediately that the Sum Panel With Halo frame looks less crowded. We will discuss later why this is so.

Now let us discuss the code starting with SumPanel. The first block of code introduces the 5 text fields for the data x1, x2, x3, x4, and the total.

    private static int width = TextFieldView.getSampleWidth(20, '0');
    
    private TextFieldView view1 = new TextFieldView("0", width);
    
    private TextFieldView view2 = new TextFieldView("0", width);
    
    private TextFieldView view3 = new TextFieldView("0", width);
    
    private TextFieldView view4 = new TextFieldView("0", width);
    
    private TextFieldView total = new TextFieldView("0", width);

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.

    private SimpleAction sumAction =
        new SimpleAction("Sum Data") {
            public void perform() { sum(); }
        
    };

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.

    private Object[][] dataStuff =
        new Object[][] {
            { "x1", view1 },
            { "x2", view2 },
            { "x3", view3 },
            { "x4", view4 },
            { "total", total }
    };
    
    private TablePanel dataPanel =
        new TablePanel(
            dataStuff, 10, 10, WEST);
    
    private Object[] mainStuff =
        new Object[] { dataPanel, sumAction };
    
    private TablePanel mainPanel =
        new TablePanel(
            mainStuff, VERTICAL, 10, 10, CENTER);
 

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.

    public SumPanel() {
        add(mainPanel);
        addListeners();
        
        frame("Sum Panel");
    }

To understand this, let us also look at the class header.

    public class SumPanel extends TablePanel

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.

    private void sum() {
        double x1 = view1.demandDouble();
        double x2 = view2.demandDouble();
        double x3 = view3.demandDouble();
        double x4 = view4.demandDouble();
        
        double x = x1 + x2 + x3 + x4;
        
        total.setViewState(x + "");
    }

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.

    private void addListeners() {
        view1.addActionListener(sumAction);
        view2.addActionListener(sumAction);
        view3.addActionListener(sumAction);
        view4.addActionListener(sumAction);
    }

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.

    private Object[][] dataStuff =
        new Object[][] {
            { "x1", new Halo(view1) },
            { "x2", new Halo(view2) },
            { "x3", new Halo(view3) },
            { "x4", new Halo(view4) },
            { "total", new Halo(total) }
    };

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.

The Shape Editor Demo

Here is the code for the Shape Editor demo which is on the JPT 2.4.0 site.

Back to the Top

Down to the Bottom

October 1, 2005

Student Programs #1

Most of the first student programs have been incorporated into the JPF Methods class. Two auxiliary classes were built by Jonathan Pelc and Michael Thomas. The most ambitious first program is by Michael Thomas.

The names of methods and classes have been modified to place the name of the student in front of the original name given by the student.

The methods file FHS_Methods_01.java

The file Pelc_FirstCode.java

The file Thomas_ListSearcher.java

Back to the Top

Down to the Bottom

October 6, 2005

The “JPT Book”

At the time that JPT 2.3.0 was released, a document was written that was intended to be the first chapter of a “JPT Book”. This project was not continued but that chapter is still useful as an introduction to JPT.

The code associated with the “JPT Book” can now be simplified further using the Paintable interface and the ShapePaintable class but I felt that it would still be useful for you to see the original sample code and first chapter document.

A copy of the “JPT Book” first chapter will be distributed in class.

Here is the link to the JPT Book and to all of the original sample code. You may download the files individually, in a zip file, or as a Windows self-extracting archive. Alternatively, you may wish to build the files yourself, one-by-one, and by typing the code, fixing mistakes, and doing experiments make the ideas more your own.

Below, I give links to a revised version of the Circle Samples that use the Paintable interface and the ShapePaintable class. There is no updated document that explains the changes in detail. If you compare these new files with the older versions, you will see that the structure that sets up the GUI is mostly the same but that there are changes in the geometric objects that define the circles and lines and in the code that paints the circles and lines onto the graphics window.

The methods file SampleCode01.java

The Circle Sample version 0 file CircleSample0.java

The Circle Sample version 1 file CircleSample1.java

The Circle Sample version 2 file CircleSample2.java

The Circle Sample version 3 file CircleSample3.java

The Circle Sample version 4 file CircleSample4.java

The Circle Sample version 5 file CircleSample5.java

The Circle Sample version 6 file CircleSample6.java

All files Circle_Samples_Revised.zip in a zip file.

All files Circle_Samples_Revised.exe in a Windows self-extracting archive.

Back to the Top

Down to the Bottom

October 12, 2005

Student Programs #2

The names of methods and/or classes may have been modified to place the name of the student in front of the original name given by the student.

The methods file FHS_Methods_02.java

The file McLaughlin_Encode.java

The file Morgano_StringAdder.java

The file Reed_Panel.java

The file Sawyer_Panel.java

The file Scullane_Panel.java

Back to the Top

Down to the Bottom

October 27, 2005

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.

TicTacToe image with a winner       TicTacToe image with a tie

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, a painted object, 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 thing 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 in a PaintableComponent which is an extension of the Java JComponent class designed to hold objects that are Paintable. A PaintableComponent is also set up to handle assorted mouse actions.

The mouse code that controls the game is quite simple. When the mouse is clicked, several checks are made. If the game is over or if the mouse has not hit a blank tile, then the 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 as a complex button that responds to mouse clicks in a subtle fashion depending on what particular tile is clicked. This illustrates how complex behavior can be coded in a rather simple fashion.

The file TicTacToe.java

Bit Display

There is a demo program that gives a visual display of the bits in an int versus a float (32 bits) and a long versus a double (64 bits). To try this demo program as an applet, go to:

Bit Display

This demo program may be helpful as you try to learn the material in the Discrete Structures course.

Back to the Top

Down to the Bottom

October 30, 2005

Student Programs #3

The names of methods and/or classes may have been modified to place the name of the student in front of the original name given by the student.

A main program has been added to each class that creates a frame in its constructor. Thus such classes can be launched as standalone programs. For convenience, we also include a Methods class to launch all programs from one place.

Code additions or bug fixes have been noted in comments.

The methods file FHS_Methods_03.java

The file Costa_Panel.java

The file Costa_BlackJack.java

The file Goyne_Card.java

The file Goyne_Cardgame.java

The file Janulawicz_GCDLCM.java

The file Leinung_Quadratic_Dots.java

The file Leinung_QuadraticFormula.java

The file Pelc_Math_Maker.java

The file Sawyer_Checkers.java

The file Scullane_mod.java

The file Scullane_SumPanel.java

The file Thomas_CardTricks.java

A “List of Integer” Class and Prime Numbers Version #1

This set of sample files shows how to create:

The IntList class is based on the IntListNode class that creates a chain of nodes each with one int together with a reference to the next node in the chain. An IntList maintains 2 objects of type IntListNode: the head node points to the start of the chain of nodes and the tail node points to the last node of the chain. Append is simple because the operation is done using the tail node. Once the append operation is complete, the tail node reference is replaced by a reference to the newly appended node.

The IntListIterator class arranges to step through an IntList class item by item. Each iterator can be used precisely once. To iterate again, create a new IntListIterator object.

The Primes class has two public static methods that do the following operations:

Here are the files:

The file IntList.java

The file IntListNode.java

The file IntListIterator.java

The file Primes.java

The methods file Methods.java

A zip file with all of the above files Primes.zip

Below is a screen snapshot of a test of getPrimesUpTo(100):

Primes up to 100

Back to the Top

Down to the Bottom

November 1, 2005

A “List of Integer” Class and Prime Numbers Version #2

This set of demo programs solves the same “list of integer” problem as the previous demo but with more sophisticated coding. In this version, the node contains an array of integer of some fixed capacity that may be specified at construction. In this way, many int’s may be added to the node before it is necessary to construct an entirely new node. This reduces the time needed for “new” operations and the space overhead of many small node objects.

This code is rather more advanced than the previous demo and is placed here for those who may wish to investigate a “theme and variations”, that is, who enjoy seeing the same problem solved in two ways.

Here are the files:

The file IntArrayList.java

The file IntArrayListNode.java

The file IntArrayListIterator.java

The file Primes.java

The methods file Methods.java

A zip file with all of the above files Primes2.zip

Back to the Top

Down to the Bottom

November 2, 2005

Listening for Keys in a GUI

The demo program illustrates how to set up a key listener for a BufferedPanel window.

Key Play Panel

In the screen snapshot above, the red square was moved from its initial pixel position of (100,100) to the position shown (120,105) entirely using the keyboard. The arrow keys are enabled to move the square by 1 pixel in the corresponding direction. If the shift key is down when the arrow key is pressed then the square jumps by 10 pixels rather than by 1 pixel. Thus, the square was moved by doing the following operations. Press shift; click right arrow twice; release shift; click down arrow five times.

A BufferedPanel comes with a KeyActionAdapter installed on its inner panel just as it comes with a corresponding MouseActionAdapter. However, before the KeyActionAdapter can do its job as a KeyListener, additional steps must be taken. The issue is that Java must know what component should listen for the key events. This is not so obvious since a key does not point to a component directly in the way that a mouse click does. The way that Java handles this ambiguity is to give a key event to the current component that has “focus”, that is, the component that is the center of attention.

By default, JPT does not initialize the inner panel to have focus since normally a BufferedPanel does not respond to key events. So, this initialization must be done. Then, it is also necessary to make sure that the inner panel actually has focus. Here is how these steps are done.

First, it is helpful to name the inner panel of the BufferedPanel.

    public static int SIZE = 400;
    
    BufferedPanel window = new BufferedPanel(SIZE, SIZE);

    DisplayPanel inner = window.getInnerPanel();

Next, the following method must be called in the constructor before the GUI is instantiated in a frame.

    void initializeKeys() {
        // enable the inner panel to gain the focus of attention
        inner.setFocusable(true);
        
        // attach the pressed action object to the key adapter
        keyadapter.addKeyPressedAction(keyAction);
    }

Then, the following method must be called in the constructor after the GUI is instantiated in a frame.

    void resetKeyFocus() {
        // reset the focus of attention to the inner panel
        // in case it has been set to some other component
        inner.requestFocusInWindow();
    }

The above method must also be called whenever the focus shifts to another component and the application wants the inner panel to again listen for key events. This is not needed in the demo program because the situation is so simple but in a more complicated program this method would need to be called at the end of any action that has shifted focus elsewhere.

In the code above, we mention the member data keyadapter and keyAction. You can see these definitions in the file.

In summary, there is additional complexity in listening for keys since it is not obvious when a key is pressed who should pay attention and Java has to resolve this ambiguity by the concept of “focus”.

The file KeyPlay.java

After the above file was posted, one student asked if it was possible to modify the program to handle pressing two cursor keys at once and thereby getting diagonal motion of the square. The program below accomplishes this goal.

The file MultiKeyPlay.java

Added November 10, 2005: Unfortunately, MultiKeyPlay does not work in all cases so it is buggy. The bug is that if one key is pressed, then a second key, then the second key is released, Java fails to generate an automatic key event for the first key that is still pressed.

Creation of these programs was greatly assisted by looking at a demo program from the Sun Java Tutorial site. This program tracks each key press and release and then gives feedback into a scrolling text pane. The program enables you to see what Java is capable of knowing about key events.

The Sun Java Tutorial file KeyEventDemo.java

This particular Sun Java Tutorial is at the site: How to Write a Key Listener

Back to the Top

Down to the Bottom

November 10, 2005

More on Listening for Keys in a GUI

The code here is another attempt to solve the multiple-key-press problem. The code in KeyTrackerDemo1 is better but not entirely satisfactory since movement of the test paintable square is not quite smooth and there are other small but annoying glitches.

The file StringInt.java

The above file is a simple data structure for a pair consisting of a String and an int. Its application in this code is to collect the name of a constant in a class and its value. This is used with the Java classes KeyEvent and InputEvent to explore what is the constant int data these classes supply.

The file StaticFields.java

The above file uses Java reflection to get lists of the public static fields in a particular class with a particular field type. The case where the field type is int is handled as a useful special case.

The file BooleanStateArray.java

The above file defines a data structure that can match an int from a specified list with a corresponding boolean value that is viewed as its state. The class is used to maintain the state of multiple key presses in a GUI.

The file Methods.java

The above file tests the data structure classes defined earlier.

The file KeyPressReleaseListener.java

The above file creates a KeyListener that can track the state of a given list of KeyEvent codes or of all KeyEvent codes if you wish this level of generality. This class utilizes BooleanStateArray.

The file KeyTrackerTest.java

The above file tests that multiple key presses can be tracked but does no other work. For this demo, the keys tracked are the 4 arrow keys and the shift key.

The file KeyTrackerDemo1.java

The above file tests that multiple key presses can be tracked and also moves a paintable square as in the KeyPlay example posted on November 2, 2005. For this demo, the keys tracked are the 4 arrow keys and the shift key. This demo sort of works but has some annoying glitches. If these glitches can be resolved then there will be future postings on this topic.

Back to the Top

Down to the Bottom

November 18, 2005

Even More on Listening for Keys in a GUI

The code posted here now provides a reasonably satisfactory solution to the problem of tracking multiple key presses. Two files are new. First let us post a screen snapshot.

Key Tracker 2 Snapshot

The file KeyTrackerDemo2.java

This version of the key tracker 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. This thread already existed in the first version of the key tracker demo and its purpose is the 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.

The file PaintableComponentLite.java

This class replaces the JPT PaintableComponent class with one that simply repaints if the internal paintable changes rather than do the much more agressive refresh that includes repacking the entire window. In hindsight, this is probably how PaintableComponent should behave by default so I plan to incorporate this change into JPT at semester break. Therefore, this class should be viewed as temporary.

The four files below are identical to those in the previous posting and continue to be essential for the solution.

The file StringInt.java

The file StaticFields.java

The file BooleanStateArray.java

The file KeyPressReleaseListener.java

I should mention one remaining glitch that is truly puzzling. I test this code on a Toshiba laptop that is connected in my office to an external monitor with its own keyboard and mouse. If I press 3 or 4 arrow keys at once on the external keyboard then sometimes a key press is not detected. Using the laptop keyboard, this failure never happens. This seems to be a peculiar hardware problem involving the external keyboard and the USB ports through which the key data passes. Unfortunately, this shows that the detection of multiple key presses has a fragility that cannot entirely be overcome by software. Software cannot track state that is not delivered by the hardware.

Back to the Top

Down to the Bottom

Extended Tile Box

The file ExtendedTileBox.java

This class allows a tile to remember the row and column position that the tile occupies in a tile array structure. This means that it is not necessary to have code that searches for or recomputes this position. This functionality should probably be built into the JPT Tile base class so this is another change to JPT that should happen at semester break. Therefore, this class should be viewed as temporary.

Back to the Top

Down to the Bottom

November 24, 2005

Animate Sample

Animate Sample Snapshot

This demo program illustrates a timed animation that produces a succession of paintables that accumulate one on top of another in 6 stages:

  1. Red square
  2. Green circle
  3. Blue square
  4. Orange circle
  5. Black square
  6. Yellow circle

The animation timing delay is 1000 milliseconds = 1 second and the animation runs in a separate thread from the main “GUI thread”. It is essential to run processes with delays in a separate thread in order that the GUI remains responsive to the user actions.

Although this animation accumulates paintables, it would be equally easy to replace one paintable with another at each state to give the appearance of simple movement or more sophisticated transformations. We used accumulation in the demo simply so that all six stages would be visible in the final screen snapshot.

The file AnimateSample.java

Back to the Top

Down to the Bottom

February 15, 2006

Shape Tools for Intersections Etc

The 5 files posted today are:

The file ShapeTools.java

The file Shapes.java

The file Geometry.java

The file Methods.java

The file IntersectTest.java

The class ShapeTools contains static methods for computing the union, intersection, set difference, and symmetric set difference (exclusive or) of arbitrary shapes. There is also a static method to test if two shapes intersect. In addition, there are methods to deal with mutation, in particular, a method that returns the mutated outline of a Paintable object.

Unfortunately, although these methods are mathematically accurate, they are also computationally intensive. This means that they cannot be used interactively to test if one shape being dragged intersects another shape. For this reason, IntersectTest updates the array of signals that shows when shapes overlap only when mouse dragging is complete.

The class Shapes contains factory methods to draw regular shapes including regular polygons, wavygons, and stars. These shapes are useful in general but also play a specific role in the tests.

The class Geometry has a method that computes the intersection of two line segments by using linear equations. This method is used to compute the outline of a star shape in Shapes.

The class Methods is the main test class for the content classes.

The class IntersectTest shows a set of signals that display when any pair from among 7 shapes intersects. The last shape is the outline of a text string in a large font. Some of the small shapes will fit into the open regions of the text outline and this may be used to demonstrate that the intersection code is mathematically accurate. Indeed, if one of the small shapes is entirely within an open region of the text outline then no intersection will be signaled.

The class IntersectTest has a main method so it may be launched directly. It may also be launched by a button in Methods.

Back to the Top

Down to the Bottom

March 23, 2006 (Posting A)

Sudoku Version 1

This application provides an interactive venue in which a person can enter numbers into a Sudoku puzzle, experiment, remove numbers if needed, and save/restore a puzzle to a file (.sudoku). To enter or remove a number in a cell, click on the cell, press a key from 1 to 9 to enter a number or the keys 0 or blank to remove a number.

The puzzle will also supply hints if requested or clear such hints if the user wants to go back to working unaided. A trivial algorithm is run to initialize the hints. One or more of 3 sophisticated algorithms may be run to prune the hints. These algorithms may be run alone or in combination and may be run once or repeatedly. Often, if the algorithms are run repeatedly then the puzzle will be solved. If the hints in a cell become blank then the puzzle definitely cannot be solved. However, it is not known (to me) whether the algorithms are sufficient to solve any solvable puzzle with a unique solution.

Here are some screen snapshots at 67%. To see a full size image, click on the snapshot.

Puzzle 1

Puzzle 1

Puzzle 1 Solved

Puzzle 1 Solved

Here are the classes for Sudoku version 1.

The file SudokuModel.java

This class maintains the data structure with the numbers already filled into the Sudoku puzzle cells and the related data structure for the hints computed for the empty cells. The class is also the center for the algorithms that prune the hints to remove those hints that may logically be proved to be impossible in the current situation. There are currently 3 pruning algorithms installed that may be executed individually or in combination either for a single cycle or repeatedly. An initial trivial algorithm is always run automatically when any puzzle cell changes. Here is an outline of the algorithms.

Algorithm 0 (Trivial).

For each cell that has a number entered by the user, eliminate that number as a hint from all cells in the same rol, column, or 3x3 block. This algorithm is always run once automatically.

Algorithm 1 (Triplet)

Suppose you have a triplet of 3 rows or 3 columns that all pass through a row of blocks or a column of blocks. Then under certain circumstances, you can argue that some hints may be eliminated. For example, if a triplet of 3 rows passes through a row of blocks then one can reason as follows. If one can show that a certain number must occur in one row of one of the blocks then that number may be eliminated as a hint in the same row of the other two blocks.

Algorithm 2 (Hint Sets)

Consider the set of hints for a row, a column, or a block that correspond to cells that are still empty. Suppose there exists a hint set of size k such that there exist (k-1) other hint sets that are subsets of this hint set (a subset may be equal). Then, all k hints may be removed from any other hint set for the same row, column, or block.

Algorithm 3 (Uniqueness)

Suppose for some value d, d turns out to occur in a given row, or a given column, or a given block in just one cell. Then that cell must have value d even if there are currently other hint values for that cell. Therefore, we can remove all other hints from that cell and we can remove d from all other cells in the same row, or same column, or same block as the cell in question.

The file SudokuHint.java

This class encapsulates a data structure for the hint for a single cell in the puzzle. A hint is effectively a set of numbers from the Sudoku values of 1 to 9. Internally, a hint is represented as a boolean array of size 10 where only the index values from 1 to 9 are used. Externally a hint is represented in two ways. The first way is via the boolean function getHint that returns true if a number d is a member of the hint set and false if d is not a member of the hint set. The second way is as a bit sequence that is returned in an int via the hashCode function. Thus the hashCode is performing double duty both as a set representation and as the usual hash code value. One can use either external representation to deal with the hint as a set.

The file SudokuBlock.java

This class encapsulates the GUI for one Sudoku cell.

The file SudokuTable.java

This class encapsulates the GUI for the 9-by-9 table of Sudoku cells.

The file Sudoku.java

This class encapsulates the GUI for the 9-by-9 table of Sudoku cells together with the assorted controls. This is the main program.

The file StringableFileIO.java

This class manages file IO for a Sudoku puzzle. It is quite general and will be inserted into Java Power Tools in the next release.

Back to the Top

Down to the Bottom

March 23, 2006 (Posting B)

Ken Eimer Gravity Simulation

Gravity Simulation

Gravity Simulation

The file GravSim.java

This class instantiates the Gravity Simulation GUI and launches the animation directed by the Mover object.

The file Controls.java

This class provides interactive controls for the gravity simulation. These controls are in a separate window.

The file Mover.java

This class manages the animation and is the heart of the algorithmics.

The file Ball.java

This class instantiates the ball object that is animated.

Back to the Top

Down to the Bottom

March 23, 2006 (Posting C)

Ken Eimer Pong Game ... The Road to Gravity

Pong Game

Pong Game

The file Pong.java

This class instantiates the Pong GUI and launches the animation directed by the Mover object.

The file Mover.java

This class manages the animation and is the heart of the algorithmics.

The file Ball.java

This class instantiates the ball object that is animated.

Back to the Top