In this lab you will implement a doubly linked list, and use it to construct a windows manager.The purpose of this lab is to:
If you'd like, you may work with one partner on this lab. If you choose to do so, you must both contribute equally to the work of this lab, and are both responsible for understanding its workings. You must hand in one submission between the two of you, with both your names clearly marked somewhere obvious to the graders.
I can offer groups a way to share their files using a "version control system" so that they can collaborate without just emailing files back and forth. Talk to me if you're interested.
On your monitor right now, you most likely have at least two open windows. Often, the windows on the screen get "stacked" one on top of the other, and depending on how they are arranged you may be able to see all the windows, or just parts of some. To bring a hidden window to the front, you just click on it, and all the other windows remain in the same order as before. For example,
|A stack of windows||After clicking on the fourth window from the top|
We are going to model this behaviour, using a linked list to store the stack of windows on your monitor. There is some starter code (for the GUI), which you should get from lab04.jar.
Before you get to the windows manager application, you may as well get your doubly-linked list up and running. Thus, your first task is to implement a doubly linked list called MyLinkedList and a corresponding ListIterator for your class.
Your MyLinkedList class is just a subset of LinkedList, and therefore should match its behaviour on this subset.
When you are finished your implementation, be sure to test your implementation thoroughly before continuing. In doubly linked lists, the removal of items can be especially tricky as you need to be sure to properly update the neighbour's next and previous pointers, as well as handle the special cases for removal from the front or tail.
You should not allow "null" pointers to be inserted into the list; if the user of your class attempts to do so, you should throw a NullPointerException.
You need two constructors. One is a 0-argument constructor that creates an empty list, and the other is a protected 3-argument constructor that initializes your head, tail, and size class members (and this second constructor may want to ensure that head.prev and tail.next are null, if the list is not empty.)
You will need to create a ListIterator which is returned by the factory listIterator() method. You can do this one of two ways:
In either case, you will need to implement all of the methods of a ListIterator: hasNext(), next(), hasPrevious(), previous(), nextIndex(), previousIndex(), remove(), set(x), and add(x). See the JavaDoc for details.
If you want to, you can use the protected variable modCount to check for and prevent the iterator being used after changes have been made. Note that you'll also need to update that variable for many of the methods listed below.
You should be able to re-use the tests you wrote in Lab 1 for MyArrayList. Just make changes similar to
MyLinkedList<String> x = new MyLinkedList<String>();
You'll want to test your ListIterator and be sure that it works properly. As a partial test, you should create a JUnit test that will perform the Sieve of Eratosthenes. In case you've not encountered this before, the "sieve" is used to determine prime numbers. The basic idea is that you initially list all of the integers in the range as potential prime numbers, then go through the possible factors one-by-one (starting from 2) and cross out any value on your list that is a multiple of it (but not the number itself).
So assuming you have the numbers from 2-10, you'd first go through and cross out the multiples of 2 other than itself (4,6,8,10) and then multiples of 3 other than itself (9, since the 6 is already gone), etc. You should stop when you reach the square root of the larger range end. What you're left with should be all the primes in the given range.
For example, the Sieve of [11,20] would return 11, 13, 17, and 19, and the Sieve of [1,20] would return 2, 3, 5, 7, 11, 13, 17, and 19.
For your JUnit test, create a few methods that perform the Sieve using the incorporated ListIterator, on a variety of ranges.
Now that you have your working doubly linked list (and associated iterator), we can start talking about the Windows manager and the starter files.
A WindowsManager object is a "monitor" that maintains a list of rectangular windows displayed within it. It may contain any number of windows, and they may overlap; overlapping windows form a sort of stack, stored in a WindowList object that you will write.
Windows respond to mouse clicks; the clicked-on window moves to the top of the "stack".
Each Window may contain coloured squares, stored in a SquareList object that you will write. One may draw a square in a window by clicking in the window somewhere that's not already occupied by a square. One may remove a square from a window by clicking on the square. Thus each window is associated with a list of squares to be drawn in the window. The squares in the window are drawn (in any order) when the window is drawn. All squares in a window are drawn in the same colour, a colour associated with the window (thus different windows may be associated with different colours.)
Each Square is a square of a given colour. It draws itself using a paint method, which is called when a window changes or is moved in the list.
Window.java -- This class represents a single window. You do not need to modify the Window class.
Square.java -- This class represents a single square that is drawn in a window. You do not need to modify the Square class.
Squares are normally 20 pixels wide and 20 pixels high. However, they may be smaller if near the border of a window, since they do not extend beyond the window that contains them. Thus when a square is created, its dimensions are reduced if necessary to make it fit within the window.
WindowsManager.java -- This class keeps track of all the windows, and takes care of displaying them. Its paint method is called when a window changes or when a window is exposed by moving another window from in front of it. It asks its WindowsList for windows, starting with the bottom window and ending with the top, and calls each window's paint method. Windows in turn call the paint method for its squares.
Clicking any of the mouse buttons in a window should do the following:
In either case, the window is redrawn.
You do not need to modify the WindowsManager class.
WindowsManagerTester.java -- This is a test file to run the program with a specific set of windows and colours. You will want to modify this file when you add more tests to your program.
Your job is to implement the following two classes:
This represents a list of windows on the monitor. Your class should store your list of windows as a (surprise, surprise) linked list -- your MyLinkedList, in fact. Implement the following public methods.
This represents a list of squares on a given window. Your class should store your list of squares as a linked list. Implement the following public methods.
You may add private data or methods to WindowList and SquareList, but you are not to change the public interface. Also make no changes to WindowsManager, Square, or Window.
Now you should be able to run the WindowsManagerTester class as a Java application, and click away. You should add more comprehensive tests to WindowsManagerTester; calls to the WindowsManager simulateClick method provide a way to automate the testing.
Include in your submission a file named README. The contents of the README file should include the following:
Look through your programs and make sure you've included your name at the top of all of them.
If you adhered to the honor code in this assignment, add the following statement to your README file:
I have adhered to the Honor Code in this assignment.
You now just need to electronically handin all your files. Assignment is 4.
Don't forget to run lshand and verify that things were submitted.