You are on page 1of 7

Final Homework CSS 162: Programming Methodology Due Finals Week by Sunday at 11:30pm Winter 2014, Instructor Rob

Nash
Summary
In this assignment, well tie together multiple software techniques weve learned throughout the quarter. Well reuse our Shape classes and our data structures to build a fully functioning paint program similar in spirit to Microsoft Paint. If youre familiar with older versions MS Paint (before Windows Vista), then youll recognize this project.

The Paint Program

What to Submit
{Shape.java, ShapeSubclass1.java, ShapeSubClass2.java, Application.java (your main Driver here), ButtonPanel.java, DrawPanel.java}

Recursion?

Outcomes {Class Design, File IO, ArrayList(of Shapes), Stack(Undo), Recursive Sorting, Inheritance, Composition, Privacy Leaks, Interfaces, Exception Handling, Generics}
You will demonstrate multiple software techniques all wrapped up in one project that can be used to create pictures composed of shapes. Your software will read and write whole ArrayLists of Shapes (both of which must be Serializable) to disk to load and save pictures. Youll sort your pictures by area so that the largest shapes are rendered before the smaller shapes, rather than the smaller shapes being rendered first and then occluded by the rendering of the larger shapes later. Youll store each shape that is drawn in an ArrayList or Queue (that youve already built) and as the user clicks on the DrawPanel, youll add additional shapes to the list that represents your Picture. While well see a working demo of this code in class, its also worthwhile to return to the PolyDemo JFrame code that I provided this software maintains a list of Shapes in an ArrayList and draws them to the screen, which is exactly what your software must do as well. Your shapes can be drawn to the screen and then undone by offering undo and redo functionality. What if the user tries to undo when nothing has been done? Or tries to load a file that isnt a serialized set of shapes? Your program will throw an ApplicationException to describe the error that occurred.

Inheritance Hierarchies
Circle, Triangle extends Shape Application extends JFrame ButtonPanel, DrawPanel extends JPanel ApplicationException extends RuntimeException o Attempting to undo an empty set of shapes, or redo an empty undo stack.

Composited Classes
An Application has a ButtonPanel and a DrawPanel An Application has a set of shapes An Application has a current shape or brush that it is drawing or adding to the list of shapes o When the user left-clicks, clone (using a copy constructor) the current shape being drawn with and add it to the end of your list of shapes

A ButtonPanel has a set of JButtons o Buttons to change the shape were drawing o Buttons to change the color of the shape were drawing o Buttons to undo and redo drawn shapes o Buttons to save and load a file Use the JFileChooser or JOptionPane here to simplify this task o Other widgets A slider to control line width, for example. Three sliders to control custom RGB. A checkbox to determine whether to fill the shape being drawn g.drawRect() versus g.fillRect()

Requirements
(1) Use your Shape hierarchy to implement drawing shapes on a JPanel. Define a Shape instance variable called currentBrush and change this to point to a square, circle, etc. depending on which button is clicked in your button panel. a. Shapes should be Cloneable, so that you may copy the current users selected brush or shape and add that copy to the picture. b. Shapes should be Serializable, so we may easily read and write these objects to disk c. Shapes should be Comparable, so we may sort shapes from smallest to largest using compareTo(). i. Add your sort code where you store your set of shapes, which is most likely in the Application container class. (2) Inherit from a JPanel and make a ButtonPanel that will hold all of the buttons for your paint program. a. There should be buttons to choose the current shape being drawn. i. Your software must support at least three different shapes. b. There should be buttons to choose the current color. i. You may want to see JColorChooser for a free, premade color dialog. c. There should be a button for undo and a different button for redo. i. Use your linked list stack to implement an undo/redo feature. Shapes that are undrawn should be thrown onto a stack so that the user may undo and redo drawing operations.

d. There should be a button to rearrange the shapes in sorted order so that the largest shape is drawn first (element 0 in your ArrayList) and the smallest shape is drawn last (element size-1). i. Use any sort except the Bubble Sort to accomplish this. ii. Call the sort using the owner reference, discussed more below. e. Add a button to save your picture to a file. Do this by using an ObjectOutputStream and write the ArrayList of Shapes to disk. This can be done in 3-5 lines of code. f. Add a button to load a picture from a file. Do this by using an ObjectInputStream and read in a single object your ArrayList of Shapes. i. See JFileChooser for a premade file selection dialog you can use, if you like. (3) Build a DrawPanel that extends JPanel. A picture in our software is simply an ArrayList<Shape> that stores Shape objects; this will be implemented in in DrawPanel. So for each DrawPanel, define an ArrayList to hold the shapes drawn onto that panel. a. You can use PolyDemo as a starting point for the DrawPanel, since it already has a set of shapes and can draw them to the screen; this is most of what your DrawPanel should do, so reuse this class. (4) Use your ArrayList class to store Shapes a. All lists and stacks must be of your own implementation in this project; you may not use Javas ArrayList, Stack<T>, or other pre-built Java data structures. (5) Use your Stack to provide an undo/redo feature for your shape. a. The only thing well undo and redo is shape drawing operations, and not color changes, or any other operation. b. When the user undoes an operation, take that Shape off the end of the ArrayList that represents your picture and push it on your undo Stack. c. When the user redoes an operation, pop off any Shape from the undo stack and add it to the end of your ArrayList that represents your picture. (6)

Getting Started
Find the code we built in previous labs and homeworks that relate to this assignment. Youll need your shape and shape subclasses, your linked list (to be used for undo), and an example JFrame to hold everything you will be designing (see the requirements above). Start by building a JFrame that holds only a single object; a DrawPanel (note that weve done this in lab). Be sure DrawPanel implements MouseListener like weve done in class, so you can capture Mouse Events and respond to them (mouseClicked(), mouseReleased(), etc.). When youve got a JFrame with a working DrawPanel, then add a new Panel to your JFrame (which will be the ButtonPanel). In order to see multiple items on your JFrame, youll need to set a layout manager in the JFrame constructor, before you add the DrawPanel and ButtonPanel. Id consider using a FlowLayout or a BorderLayout as your JFrame layout manager.

Class Shape implements Cloneable, Comparable, Serializable


Add to your existing Shape class the following interfaces: Cloneable (so we may add copies of the current brush to the set of shapes), Comparable (so we might sort shapes in order from largest to smallest), and Serializable (so we can write these objects to disk). Add the compareTo() and clone() methods as weve seen in class and lab.

Class Application extends (is a) JFrame Class


This class is the container for all other visual elements in our paint program. It is this JFrame that will track the current shape being drawn, and will host the drawing area (a DrawPanel) and a set of buttons (the ButtonPanel).

Data Members (has a) for Class Application


Shape currentBrush; o Use this reference to track the brush/shape the user is drawing with o Use currentBrush.clone() to add a copy of the current brush to your list of shapes private DrawPanel myDrawPanel; o When the user left-clicks on this panel, well add a clone of the currently selected shape to the DrawPanels list of shapes. private ButtonPanel myDrawPanel; o Use this to control the currently selected brush (i.e., the one were drawing with). o Use this to control the color (use setColor) for the currently selected shape (ie, our brush)

DrawPanel Class implements MouseListener


This class will hold a list of Shapes that should be drawn on every paint()/repaint() cycle. Declare the ArrayList of Shapes, and override the paint(Graphics g) method so that it iterates over the ArrayList of Shapes, calling draw(g) on each shape. First, create the JFrame class above, and in its constructor, build a DrawPanel class and attach it to the JFrame (note you may want to pass a this handle to the DrawPanel, so it can call functions on the owner JFrame such as getBrush()).

Data Members
Application owner; o In your Application class, provide a this reference to your DrawPanel constructor and save it in the owner reference above.

Now you can call methods defined in the Application class here owner.getBrush().clone() //example usage Stack<Shape> undoStack; o Use this to track changes to your picture and undo them ArrayList<Shape> picture; o Use this to store the set of Shapes that compose your picture

ButtonPanel Class Implements ActionListener


This class will hold a set of JButtons that will enable the user to select different shapes (or brushes), choose the color the user is drawing with, undo a shape being drawn, redo a shape being drawn, save shapes to a file, load shapes from a file and finally, sort shapes in ascending order with respect to area. Once youve built the JFrame class above, inside its constructor you should instantiate a ButtonPanel and attach it to the root JFrame. Consider passing a this reference to the ButtonPanel constructor, just as we did in the DrawPanel constructor. This is so when you change the current shape, color, etc., we can inform the JFrame, which manages a reference to the current shape being drawn (the artists brush).

Data Members
Application owner; o In your Application class (likely in the constructor), provide a this reference to your ButtonPanel constructor and save it in the owner reference above. o Now you can call methods defined in the Application class here owner.setCurrentBrush(new Square()) //an example owner.undo(); //more usage examples owner.redo();

Notes
Dont wait until the last minute to get help from your instructor this project is the longest well see in 162. Build your software in pieces o The containing JFrame, which holds a ButtonPanel and DrawPanel. o Test each piece as you progress, rather than waiting until the end Ie, put a main in each class and test them

For a ButtonPanel, simply wrap this in a JFrame for your test in main, as in: o JFrame foo = new JFrame(new ButtonPanel()); o foo.setSize(), setVisible(), setDefaultCloseOperation(), etc.

You might also like