Comp 212 Project 2
Reverse Polish Notation Calculator
Due Friday, Nov. 17 at 23:59

For this project, you will write a Reverse Polish Notation (RPN) calculator that evaluates postfix expressions.  The calculator will be written in Java and will emphasize Java GUI construction, circular lists, and stream I/O in addition to the MVC and Adapter patterns.

The calculator will:

Milestones
This project is divided into two milestones.  In the first milestone you will write the GUI and Control, and for testing purposes we will give you .class files (but not source code) for the model.  Implement the model for the second milestone.

Milestone #1: due Wednesday, Nov. 8 at 23:59
Write a Java GUI and controller for the RPN calculator.   You can use the provided GUI as an example, but feel free to design your own layout as long as it is functionally equivalent to the example.   In any case, the GUI should support all of the features listed above.  Be aware that to implement this GUI you will need to use a combination of layout managers such as GridLayout, GridBagLayout, BorderLayout, and BoxLayout.  This Swing tutorial should help you learn about the various layouts and components (such as a FileChooser) that are used in this milestone.

We have graciously provided the .class files for the backend so that you can test your GUI and Control.  Use the provided UML diagram and documentation of the Model to help you write the control. Here is some stub code to help you get started. Try running CalcControl to familiarize yourself with the calculator.

Milestone #1 Updates: The following snippet of code should be helpful for evaluating a postfix expression. FormStream can be used to parse both strings and files. To make FormStream evaluate the expression in the file postfix_expr.txt, replace 'new StringReader(expr_str)' with 'new FileReader("postfix_expr.txt")'.

        try {
                FormStream fs = new FormStream(new StringReader(expr_str), _rpnEngine);
                fs.parse();
        } catch (Exception exc) {
                System.out.println(exc);
                System.out.println("caught FormStream exception");
        }

 



Milestone #2: due Friday, Nov. 17 at 23:59
 For milestone 2, you must write the backend using Circular Linked Lists and the object Adapter Pattern.  Write a class RPNEngine that implements IStack, ICalculator and has a private CLList field.  Implement IStack's methods pop, push, etc. using the appropriate methods for a CLList.  Here is some sample code to get you started.

The RPN calculator has both an expression mode and immediate mode. Think about how you could apply the state pattern to accomodate this functionality. For milestone 2, implement the state pattern as a part of the control.

Here are a few more things you have to do in order to get a working calculator:

Write a CLList visitor ToStringNthClockwise using RemNthVisitor as a guide. ToStringNthVisitor should return a string representation of the Nth element.  You should return "" if N is greater than the length of the list or if the list is empty.  Use this visitor to print the top three elements of the stack.

Make sure that clicking on "Save File" prints the expression in the entry box to a file.  There is an example file ExamplePrintToFile.java  that has all the basic elements.  Write a class PrintToFile (Singleton) with one lonely method printStrToFile(String file, String expression), that prints the given expression to the file.

Write a class FormStream, extending StreamTokenizer, that will evaluate an expression either from the entry box or from a file.  We have given the code for everything but the parse() function.  Evaluate runs in a loop, "parsing" all the "tokens" it encounters.  If the next token is a number, push it onto the RPNEngine; if it is an operator it pops two elements, performs the operation, and pushes the result onto the RPNEngine.

By the way, the order for subtraction/division goes like this:
a = pop();
b = pop();
c = b - a;

The constructor for FormStream takes in a Reader and a RPNEngine; the Reader should be a StringReader when evaluating the entry box and a FileReader when evaluating a file.  Both Readers take in a string for their constructor: for StringReader the string will be the actual expression, for FileReader the string will be the file name.  Here is an example of how this is going to work:

FormStream mySupaFlyStream = new FormStream(new StringReader(theStringFromEntryBox), _mySupaFlyRPNEngine);
mySupaFlyStream.parse();

Take a look at the Java API if you want to learn more about StreamTokenizer, StringReader, or FileReader.

To recap, here are the classes you need to write for Milestone #2:
ToStringNthClockwise
PrintToFile
FormStream
RPNEngine

and implement the state pattern for the control, if you didn't in milestone1.

Submission

Each milestone is to be submitted electronically.  The complete milestone set should contain the following: