CSCI 201 Lab 9 -- Using Classes

Getting ready

If a directory called c:\files\lab09 presently exists on your computer, delete it.

We're going to give you a project to work on in this lab. Download a zipped copy of the lab09 project by right-clicking on this link, and storing the target file in the C:\files directory. Double-click on the lab09.zip icon in the C:\files directory to run the PowerZip program. On PowerZip's menu, hit the extract button, set the download directory to C:\files and then select ok to create: C:\files\lab09. Check to make sure that this folder exist before continuing.

This lab differs from the earlier 201 labs in several ways. You will be working with a package which contains eight Java classes. Those classes extends classes from a java package, the Abstract Windowing Toolkit, to create an on screen calculator which does 64 bit arithmetic in decimal, binary, and hexadecimal. This is a real program rather than one created for you to use in a lab. It was written by Nigel Gamble back in the mid 90's and released under the GNU General Public License. That is the same license used for Linux and a lot of other great public domain software. The GPL alows anyone to modify the code and reuse it, as long as they also release the source under the GPL. In the spirit of public domain software, you are going to be adding a new capability to this piece of software.

Understanding how it works

Start up JCreator by double-clicking on the ".jcw" file in the lab09 directory. Compile the program; you will get an warning message: "HexCalc.java uses or overrides a deprecated API." Ignore it. Execute the program and observe the output. As you can see, the program generates an on screen calculator which initially works as a base 16 or hex, calculator. Enter F + 6. It should equal 15. Then hit the dec button, and the display should change to 21. 15 base 16 equals 21 base 10. Then hit the bin button, and the display changes to 10101. 21 base 10 equals 10101(21 is the sum of 16+4+1) base 2. Look at the keypad on the calculator. Only the 0 and 1 keys are black on white. When you change the base that the calculator works in, the keypad grays out those keys that don't work in the current base. Your job is to add another base, base 4, to this calculator.

Before you can do this, you need to know a bit about positional notation. Positional notation is the method, developed in India about 2500 years ago, that we use to represent numbers. The position of a digit in the number, measured from the digit on the right end, is the power to which the radix, or base, is raised for that digit. Thus 2110 is 1 times 100, which is 1, plus two times 101, which is 2010. Similarly, 214 is 1 times 40, which is 1, plus two times 41 ,which is 810, which is 910

Here is the code in HexCalc.java that computes the value of a number, digit by digit as it is entered:

	if (firstdigit) {
		if (radix == 16)
			digitcount = 16 - 1;
		else if (radix == 2)
			digitcount = 64 - 1;
		else
			digitcount = -1;
		y = n;
		firstdigit = false;
	} else if (digitcount > 0
	|| (radix == 10 && y <= (Long.MAX_VALUE - n) / radix)) {
		y = y * radix + n;
		digitcount--;
	}

This code sets a digitcount when the first digit in a non-decimal number is entered. It uses digitcount to limit the number of digts that can be entered in a base 16 (16 digits in 64 bits) or base 2 (64 digits in 64 bits) number. Then it uses positional notation, y = y * radix + n, to convert the number entered to a number stored in the memory of the computer as each digit is entered. The code above is part of the Display class. Most of the guts of this program are in the methods of the Display class and the state of the calculator is held in the instance variables in this class. When the program is complied, eight classes are created. The HexCalc class contains main() and also extends the Applet class, so this program can be run as a stand alone program or from an html file. There is some fancy code in HexCalc, but the main thing main() does is to create a HexCalc object and initialize it.


	HexCalc hexcalc = new HexCalc();
	hexcalc.init();

and here is the init method:


public void
init()
{
	KeyPad keypad;
	Font f = new Font("Helvetica", Font.BOLD, 20);
	display = new Display();
	keypad = new KeyPad(display);

	display.setKeyPad(keypad);
	keypad.setFont(f);
	setLayout(new BorderLayout());

	add("North", display);
	add("Center", keypad);

	display.onScreen("0");
}

Notice how the hexcal.init method creates a new Display object and a new Keypad object. Then the keypad reference is passed to the setKeyPad method in the display object. display.setKeyPad copies that keypad reference to the instance variable named keypad in the display object. The this.keypad variable is the instance variable named keypad in the object where this code is executed. The other keypad variable is a local variable in the setKeyPad method.


public void
setKeyPad(KeyPad keypad)
{
	this.keypad = keypad;
}

The end result of all this is that display.keypad ends up referencing the keypad created in hexcalc. Now display has the state of the calculator


private TextField screen;
private int columns = 20;
private int curop = noop;
private boolean firstdigit = true;
private boolean after_unop = false;
private long x = 0;
private long y = 0;
private long memory = 0;
private int radix = 16;
private int digitcount;
private KeyPad keypad;

and the references it needs to use the keypad and hexcalc objects. This is very much as if we had assembled an electronic calculator by putting the logic circuit (display) and the keypad (keypad) into the case (hexcalc). Note that the 'case', hexcalc is composed of a group of objects, as is the keypad. This is very much like their physical counterparts in the electronic calculator. The keypad object uses three kinds of button objects; instances of the OperKey, NumKey, and NullKey classes. The display object also uses the public method ToString in the Ulong class to convert 64 bit unsigned numbers to strings. The hexcalc object uses other classes and objects to detect key pressed events and to build the on screen display.


Spend at least half an hour studying the HexCalc program to determine how its parts (objects, classes) are interconnected. Pay special attention to the handling of base 16 numbers since this is the code you'll need to copy, with small modifications, to add a base 4 mode. Search for the word radix and pay special attention to how radix 16. Ask your instructor for help if you have a hard time figuring out parts of the code.

Lab instructor check-off 1

Explain how, and where, the code handles base 16 numbers


You'll need to modify the code that computes the value of a number to limit the number of base 4 digits to 32. This is a 64 bit calculator and each base 4 digit takes two bits. Note that each base 16 digit takes takes four bits, so 64 bits is 16, base 16, digits. Here is that code again:

	if (firstdigit) {
		if (radix == 16)
			digitcount = 16 - 1;
		else if (radix == 2)
			digitcount = 64 - 1;
		else
			digitcount = -1;
		y = n;
		firstdigit = false;
	} else if (digitcount > 0
	|| (radix == 10 && y <= (Long.MAX_VALUE - n) / radix)) {
		y = y * radix + n;
		digitcount--;
	}

You'll need to copy the else if (radix==2) block and modify the new block for radix 4 with digitcount =32 -1 .

The other code you need to add to in display is located just below this. It is a case statement that handles the op's that come from key presses. Now we need to add a new case, quad, to both switch statements, with a new method, keypad.quadMode(), which we haven't created yet, associated with quad in the inner switch statement.

		case hex:
		case decimal:
		case binary:
			switch(op) {
			case hex:
				radix = 16;
				keypad.hexMode();
				break;
			case decimal:
				radix = 10;
				keypad.decMode();
				break;
			case binary:
				radix = 2;
				keypad.binMode();
				break;
			}

These cases are all integer constants which are defined at start of the display class, so you will need to add an integer constant called quad, with a value of 20, to the end of that list.


static final int decimal	= 12;
static final int hex		= 13;
static final int binary		= 14;
static final int neg		= 15;
static final int xor		= 16;
static final int ce		= 17;
static final int sto		= 18;
static final int rcl		= 19;

Now we need to add a quadMode method to the KeyPad class:


public void
quadMode()
{
 	int i;
 
 	for (i = 2; i < 4; i++)
 		key[i].enable();
 	for ( ; i < 16; i++)
		key[i].disable();
}

and a else if block in the Ulong class so it can handle base 4:

 
 	else if (radix == 4)
 		fieldlen = 16;

Add this just after the else if (radix == 16) block. You can simply cut and paste these code segments for this document to the Ulong class file.

Finally, change a blank key to one that activates quad mode by replacing the first


	add(new NullKey());

line in the KeyPad class with

  
	add(new OperKey(display, "qua", display.quad));

It took a total of 15 new or changed lines in the HexCalc program to make it work with base 4! Because Nigel Gamble used good object based Java when he created this program in 1995, a programmer who understands positional notation can easily extend it to work with a new base.


Lab instructor check-off 2

Show your instructor the enhanced calculator created by your new program.