committing everything FIRST POST

master
Sean Hickey 2012-07-15 00:48:06 -04:00
commit c60769b7a3
54 changed files with 1381 additions and 0 deletions

23
AndroidManifest.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.SimpleDrawingApp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".SimpleDrawingAppActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

1
README Normal file
View File

@ -0,0 +1 @@
This is a very simple drawing app that just displays a square everywhere you drag your finger. That's it.

BIN
bin/SimpleDrawingApp.apk Normal file

Binary file not shown.

BIN
bin/classes.dex Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
bin/jarlist.cache Normal file
View File

@ -0,0 +1,3 @@
# cache for current jar dependecy. DO NOT EDIT.
# format is <lastModified> <length> <SHA-1> <path>
# Encoding is UTF-8

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
bin/resources.ap_ Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
/** Automatically generated file. DO NOT MODIFY */
package com.SimpleDrawingApp;
public final class BuildConfig {
public final static boolean DEBUG = true;
}

View File

@ -0,0 +1,23 @@
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.SimpleDrawingApp;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int ic_launcher=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

20
proguard-project.txt Normal file
View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

14
project.properties Normal file
View File

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-7

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

12
res/layout/main.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>

7
res/values/strings.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, SimpleDrawingAppActivity!</string>
<string name="app_name">SimpleDrawingApp</string>
</resources>

View File

@ -0,0 +1,94 @@
package com.SimpleDrawingApp;
import android.app.Activity;
//import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
//import android.view.View;
import android.view.MotionEvent;
import android.opengl.GLSurfaceView;
//import android.widget.EditText;
public class SimpleDrawingAppActivity extends Activity {
/** Called when the activity is first created. */
public final static String EXTRA_MESSAGE = "firstApp.main.MESSAGE";
private GLSurfaceView mGLView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
mGLView = new FirstAppSurfaceView(this);
setContentView(mGLView);
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
/*public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}*/
}
class FirstAppSurfaceView extends GLSurfaceView {
private final float X_SCALE_FACTOR = 1f / (240); // determined through trial
// and error
private final float Y_SCALE_FACTOR = 1f / (240);
private SimpleDrawingAppRenderer mRenderer;
private float mPreviousX;
private float mPreviousY;
public FirstAppSurfaceView(Context context) {
super(context);
mRenderer = new SimpleDrawingAppRenderer();
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
float dx = 0;
float dy = 0;
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
dx = x - mPreviousX;
dx *= -1;
mRenderer.xPosition = x*X_SCALE_FACTOR*-1 + 1;
mRenderer.dx = dx*X_SCALE_FACTOR;
dy = y - mPreviousY;
dy *= -1;
mRenderer.yPosition = y*Y_SCALE_FACTOR*-1 + 1.6f;
mRenderer.dy = dy * Y_SCALE_FACTOR;
Square s = new Square(x*X_SCALE_FACTOR*-1 + .975f, y*Y_SCALE_FACTOR*-1 + 1.5f);
mRenderer.squareList.insertBack(s);
requestRender();
break;
}
mPreviousX = x;
mPreviousY = y;
return true;
}
}

View File

@ -0,0 +1,56 @@
package com.SimpleDrawingApp;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import com.SimpleDrawingApp.list.*;
public class SimpleDrawingAppRenderer implements GLSurfaceView.Renderer {
public DList squareList = new DList();
public float xPosition, dx;
public float yPosition, dy;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0f, 0f, 0f, 1.0f);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
try {
ListNode currentNode = squareList.front();
while(currentNode.isValidNode()) {
Square s = (Square)currentNode.item();
s.Draw(gl);
currentNode = currentNode.next();
}
}
catch (InvalidNodeException e) {
System.err.println(e + "in onDrawFrame");
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection
// matrix
initShapes();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
private void initShapes() {
}
}

View File

@ -0,0 +1,54 @@
package com.SimpleDrawingApp;
import java.nio.*;
import javax.microedition.khronos.opengles.GL10;
class Square {
private FloatBuffer squareVB, squareVB2;
static float squareCoords[] = { -0.1f, 0.1f, 0.0f, // top left
-0.1f, -0.1f, 0.0f, // bottom left
0.1f, -0.1f, 0.0f}; // bottom right
static float square2Coords[] = { -0.1f, 0.1f, 0.0f, // top left
0.1f, -0.1f, 0.0f, // bottom right
0.1f, 0.1f, 0.0f }; // top right
private float x,y;
public Square() {
x = 0;
y = 0;
ByteBuffer vbb = ByteBuffer.allocateDirect(squareCoords.length * 4);
vbb.order(ByteOrder.nativeOrder());
squareVB = vbb.asFloatBuffer();
squareVB.put(squareCoords);
squareVB.position(0);
ByteBuffer vbb2 = ByteBuffer.allocateDirect(square2Coords.length * 4);
vbb2.order(ByteOrder.nativeOrder());
squareVB2 = vbb2.asFloatBuffer();
squareVB2.put(square2Coords);
squareVB2.position(0);
}
public Square(float x, float y) {
this();
this.x = x;
this.y = y;
}
public void Draw(GL10 gl) {
gl.glPushMatrix();
gl.glTranslatef(this.x,this.y,0);
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, squareVB);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, squareVB2);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glPopMatrix();
}
}

Binary file not shown.

View File

@ -0,0 +1,280 @@
/* DList.java */
package com.SimpleDrawingApp.list;
/**
* A DList is a mutable doubly-linked list ADT. Its implementation is
* circularly-linked and employs a sentinel node at the head of the list.
*
* DO NOT CHANGE ANY METHOD PROTOTYPES IN THIS FILE.
**/
public class DList extends List {
/**
* (inherited) size is the number of items in the list.
* head references the sentinel node.
* Note that the sentinel node does not store an item, and is not included
* in the count stored by the "size" field.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATION.
**/
protected DListNode head;
/* DList invariants:
* 1) head != null.
* 2) For every DListNode x in a DList, x.next != null.
* 3) For every DListNode x in a DList, x.prev != null.
* 4) For every DListNode x in a DList, if x.next == y, then y.prev == x.
* 5) For every DListNode x in a DList, if x.prev == y, then y.next == x.
* 6) For every DList l, l.head.myList = null. (Note that l.head is the
* sentinel.)
* 7) For every DListNode x in a DList l EXCEPT l.head (the sentinel),
* x.myList = l.
* 8) size is the number of DListNodes, NOT COUNTING the sentinel,
* that can be accessed from the sentinel (head) by a sequence of
* "next" references.
**/
/**
* newNode() calls the DListNode constructor. Use this method to allocate
* new DListNodes rather than calling the DListNode constructor directly.
* That way, only this method need be overridden if a subclass of DList
* wants to use a different kind of node.
*
* @param item the item to store in the node.
* @param list the list that owns this node. (null for sentinels.)
* @param prev the node previous to this node.
* @param next the node following this node.
**/
protected DListNode newNode(Object item, DList list,
DListNode prev, DListNode next) {
return new DListNode(item, list, prev, next);
}
/**
* DList() constructs for an empty DList.
**/
public DList() {
// Your solution here. Similar to Homework 4, but now you need to specify
// the `list' field (second parameter) as well.
head = newNode(null,this,null,null);
head.next = head;
head.prev = head;
head.myList = null; //not a valid node
size = 0;
}
/**
* insertFront() inserts an item at the front of this DList.
*
* @param item is the item to be inserted.
*
* Performance: runs in O(1) time.
**/
public void insertFront(Object item) {
// Your solution here. Similar to Homework 4, but now you need to specify
// the `list' field (second parameter) as well.
DListNode newNode = newNode(item,this,head,head.next);
head.next = newNode;
newNode.next.prev = newNode;
size++;
}
/**
* insertBack() inserts an item at the back of this DList.
*
* @param item is the item to be inserted.
*
* Performance: runs in O(1) time.
**/
public void insertBack(Object item) {
// Your solution here. Similar to Homework 4, but now you need to specify
// the `list' field (second parameter) as well.
DListNode newNode = newNode(item,this,head.prev,head);
head.prev = newNode;
newNode.prev.next = newNode;
size++;
}
/**
* front() returns the node at the front of this DList. If the DList is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception. (The sentinel is "invalid".)
*
* DO NOT CHANGE THIS METHOD.
*
* @return a ListNode at the front of this DList.
*
* Performance: runs in O(1) time.
*/
public ListNode front() {
return head.next;
}
/**
* back() returns the node at the back of this DList. If the DList is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception. (The sentinel is "invalid".)
*
* DO NOT CHANGE THIS METHOD.
*
* @return a ListNode at the back of this DList.
*
* Performance: runs in O(1) time.
*/
public ListNode back() {
return head.prev;
}
//added by me, not from class
public void concat(List s) {
ListNode currentNode = s.front();
try {
while(currentNode.isValidNode()) {
this.insertBack(currentNode.item());
currentNode = currentNode.next();
}
}
catch(InvalidNodeException e) {
System.err.println(e);
}
}
/**
* toString() returns a String representation of this DList.
*
* DO NOT CHANGE THIS METHOD.
*
* @return a String representation of this DList.
*
* Performance: runs in O(n) time, where n is the length of the list.
*/
public String toString() {
String result = "[ ";
DListNode current = head.next;
while (current != head) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
private static void testInvalidNode(ListNode p) {
System.out.println("p.isValidNode() should be false: " + p.isValidNode());
try {
p.item();
System.out.println("p.item() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.item() should throw an exception, and did.");
}
try {
p.setItem(new Integer(0));
System.out.println("p.setItem() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.setItem() should throw an exception, and did.");
}
try {
p.next();
System.out.println("p.next() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.next() should throw an exception, and did.");
}
try {
p.prev();
System.out.println("p.prev() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.prev() should throw an exception, and did.");
}
try {
p.insertBefore(new Integer(1));
System.out.println("p.insertBefore() should throw an exception, but " +
"didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.insertBefore() should throw an exception, and did."
);
}
try {
p.insertAfter(new Integer(1));
System.out.println("p.insertAfter() should throw an exception, but " +
"didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.insertAfter() should throw an exception, and did."
);
}
try {
p.remove();
System.out.println("p.remove() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.remove() should throw an exception, and did.");
}
}
private static void testEmpty() {
List l = new DList();
System.out.println("An empty list should be [ ]: " + l);
System.out.println("l.isEmpty() should be true: " + l.isEmpty());
System.out.println("l.length() should be 0: " + l.length());
System.out.println("Finding front node p of l.");
ListNode p = l.front();
testInvalidNode(p);
System.out.println("Finding back node p of l.");
p = l.back();
testInvalidNode(p);
l.insertFront(new Integer(10));
System.out.println("l after insertFront(10) should be [ 10 ]: " + l);
}
public static void main(String[] argv) {
testEmpty();
List l = new DList();
l.insertFront(new Integer(3));
l.insertFront(new Integer(2));
l.insertFront(new Integer(1));
System.out.println("l is a list of 3 elements: " + l);
try {
ListNode n;
int i = 1;
for (n = l.front(); n.isValidNode(); n = n.next()) {
System.out.println("n.item() should be " + i + ": " + n.item());
n.setItem(new Integer(((Integer) n.item()).intValue() * 2));
System.out.println("n.item() should be " + 2 * i + ": " + n.item());
i++;
}
System.out.println("After doubling all elements of l: " + l);
testInvalidNode(n);
i = 6;
for (n = l.back(); n.isValidNode(); n = n.prev()) {
System.out.println("n.item() should be " + i + ": " + n.item());
n.setItem(new Integer(((Integer) n.item()).intValue() * 2));
System.out.println("n.item() should be " + 2 * i + ": " + n.item());
i = i - 2;
}
System.out.println("After doubling all elements of l again: " + l);
testInvalidNode(n);
n = l.front().next();
System.out.println("Removing middle element (8) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
n = l.back();
System.out.println("Removing end element (12) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
n = l.front();
System.out.println("Removing first element (4) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
} catch (InvalidNodeException lbe) {
System.err.println ("Caught InvalidNodeException that should not happen."
);
System.err.println ("Aborting the testing code.");
}
}
}

Binary file not shown.

View File

@ -0,0 +1,160 @@
/* DListNode.java */
package com.SimpleDrawingApp.list;
/**
* A DListNode is a mutable node in a DList (doubly-linked list).
**/
public class DListNode extends ListNode {
/**
* (inherited) item references the item stored in the current node.
* (inherited) myList references the List that contains this node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
**/
protected DListNode prev;
protected DListNode next;
/**
* DListNode() constructor.
* @param i the item to store in the node.
* @param l the list this node is in.
* @param p the node previous to this node.
* @param n the node following this node.
*/
DListNode(Object i, DList l, DListNode p, DListNode n) {
item = i;
myList = l;
prev = p;
next = n;
}
/**
* isValidNode returns true if this node is valid; false otherwise.
* An invalid node is represented by a `myList' field with the value null.
* Sentinel nodes are invalid, and nodes that don't belong to a list are
* also invalid.
*
* @return true if this node is valid; false otherwise.
*
* Performance: runs in O(1) time.
*/
public boolean isValidNode() {
return myList != null;
}
/**
* next() returns the node following this node. If this node is invalid,
* throws an exception.
*
* @return the node following this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode next() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("next() called on invalid node");
}
return next;
}
/**
* prev() returns the node preceding this node. If this node is invalid,
* throws an exception.
*
* @param node the node whose predecessor is sought.
* @return the node preceding this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode prev() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("prev() called on invalid node");
}
return prev;
}
/**
* insertAfter() inserts an item immediately following this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertAfter(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertAfter() called on invalid node");
}
// Your solution here. Will look something like your Homework 4 solution,
// but changes are necessary. For instance, there is no need to check if
// "this" is null. Remember that this node's "myList" field tells you
// what DList it's in. You should use myList.newNode() to create the
// new node.
DListNode newNode = ((DList)myList).newNode(item,(DList)myList,this,this.next);
this.next.prev = newNode;
this.next = newNode;
myList.size++;
}
/**
* insertBefore() inserts an item immediately preceding this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertBefore(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertBefore() called on invalid node");
}
// Your solution here. Will look something like your Homework 4 solution,
// but changes are necessary. For instance, there is no need to check if
// "this" is null. Remember that this node's "myList" field tells you
// what DList it's in. You should use myList.newNode() to create the
// new node.
DListNode newNode = ((DList)myList).newNode(item,(DList)myList,this.prev,this);
this.prev.next = newNode;
this.prev = newNode;
myList.size++;
}
/**
* remove() removes this node from its DList. If this node is invalid,
* throws an exception.
*
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void remove() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("remove() called on invalid node");
}
// Your solution here. Will look something like your Homework 4 solution,
// but changes are necessary. For instance, there is no need to check if
// "this" is null. Remember that this node's "myList" field tells you
// what DList it's in.
this.prev.next = this.next;
this.next.prev = this.prev;
myList.size--;
// Make this node an invalid node, so it cannot be used to corrupt myList.
myList = null;
// Set other references to null to improve garbage collection.
next = null;
prev = null;
}
}

View File

@ -0,0 +1,19 @@
/* InvalidNodeException.java */
package com.SimpleDrawingApp.list;
/**
* Implements an Exception that signals an attempt to use an invalid ListNode.
*/
public class InvalidNodeException extends Exception {
private static final long serialVersionUID = 1L; //eclipse complained...
protected InvalidNodeException() {
super();
}
protected InvalidNodeException(String s) {
super(s);
}
}

Binary file not shown.

View File

@ -0,0 +1,80 @@
/* List.java */
package com.SimpleDrawingApp.list;
/**
* A List is a mutable list ADT. No implementation is provided.
*
* DO NOT CHANGE THIS FILE.
**/
public abstract class List {
/**
* size is the number of items in the list.
**/
protected int size;
/**
* isEmpty() returns true if this List is empty, false otherwise.
*
* @return true if this List is empty, false otherwise.
*
* Performance: runs in O(1) time.
**/
public boolean isEmpty() {
return size == 0;
}
/**
* length() returns the length of this List.
*
* @return the length of this List.
*
* Performance: runs in O(1) time.
**/
public int length() {
return size;
}
/**
* insertFront() inserts an item at the front of this List.
*
* @param item is the item to be inserted.
**/
public abstract void insertFront(Object item);
/**
* insertBack() inserts an item at the back of this List.
*
* @param item is the item to be inserted.
**/
public abstract void insertBack(Object item);
/**
* front() returns the node at the front of this List. If the List is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception.
*
* @return a ListNode at the front of this List.
*/
public abstract ListNode front();
/**
* back() returns the node at the back of this List. If the List is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception.
*
* @return a ListNode at the back of this List.
*/
public abstract ListNode back();
/**
* toString() returns a String representation of this List.
*
* @return a String representation of this List.
*/
public abstract String toString();
}

Binary file not shown.

View File

@ -0,0 +1,109 @@
/* ListNode.java */
package com.SimpleDrawingApp.list;
/**
* A ListNode is a mutable node in a list. No implementation is provided.
*
* DO NOT CHANGE THIS FILE.
**/
public abstract class ListNode {
/**
* item references the item stored in the current node.
* myList references the List that contains this node.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
protected Object item;
protected List myList;
/**
* isValidNode returns true if this node is valid; false otherwise.
* By default, an invalid node is one that doesn't belong to a list (myList
* is null), but subclasses can override this definition.
*
* @return true if this node is valid; false otherwise.
*
* Performance: runs in O(1) time.
*/
public boolean isValidNode() {
return myList != null;
}
/**
* item() returns this node's item. If this node is invalid,
* throws an exception.
*
* @return the item stored in this node.
*
* Performance: runs in O(1) time.
*/
public Object item() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException();
}
return item;
}
/**
* setItem() sets this node's item to "item". If this node is invalid,
* throws an exception.
*
* Performance: runs in O(1) time.
*/
public void setItem(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException();
}
this.item = item;
}
/**
* next() returns the node following this node. If this node is invalid,
* throws an exception.
*
* @return the node following this node.
* @exception InvalidNodeException if this node is not valid.
*/
public abstract ListNode next() throws InvalidNodeException;
/**
* prev() returns the node preceding this node. If this node is invalid,
* throws an exception.
*
* @param node the node whose predecessor is sought.
* @return the node preceding this node.
* @exception InvalidNodeException if this node is not valid.
*/
public abstract ListNode prev() throws InvalidNodeException;
/**
* insertAfter() inserts an item immediately following this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*/
public abstract void insertAfter(Object item) throws InvalidNodeException;
/**
* insertBefore() inserts an item immediately preceding this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*/
public abstract void insertBefore(Object item) throws InvalidNodeException;
/**
* remove() removes this node from its List. If this node is invalid,
* throws an exception.
*
* @exception InvalidNodeException if this node is not valid.
*/
public abstract void remove() throws InvalidNodeException;
}

Binary file not shown.

View File

@ -0,0 +1,261 @@
/* SList.java */
package com.SimpleDrawingApp.list;
/**
* A SList is a mutable singly-linked list ADT. Its implementation employs
* a tail reference.
*
* DO NOT CHANGE THIS FILE.
**/
public class SList extends List {
/**
* (inherited) size is the number of items in the list.
* head references the first node.
* tail references the last node.
**/
protected SListNode head;
protected SListNode tail;
/* SList invariants:
* 1) Either head == null and tail == null, or tail.next == null and the
* SListNode referenced by tail can be reached from the head by a
* sequence of zero or more "next" references. This implies that the
* list is not circularly linked.
* 2) The "size" field is the number of SListNodes that can be accessed
* from head (including head itself) by a sequence of "next" references.
* 3) For every SListNode x in an SList l, x.myList = l.
**/
/**
* newNode() calls the SListNode constructor. Use this method to allocate
* new SListNodes rather than calling the SListNode constructor directly.
* That way, only this method need be overridden if a subclass of SList
* wants to use a different kind of node.
*
* @param item the item to store in the node.
* @param next the node following this node.
**/
protected SListNode newNode(Object item, SListNode next) {
return new SListNode(item, this, next);
}
/**
* SList() constructs for an empty SList.
**/
public SList() {
head = null;
tail = null;
size = 0;
}
/**
* insertFront() inserts an item at the front of this SList.
*
* @param item is the item to be inserted.
*
* Performance: runs in O(1) time.
**/
public void insertFront(Object item) {
head = newNode(item, head);
if (size == 0) {
tail = head;
}
size++;
}
/**
* insertBack() inserts an item at the back of this SList.
*
* @param item is the item to be inserted.
*
* Performance: runs in O(1) time.
**/
public void insertBack(Object item) {
if (head == null) {
head = newNode(item, null);
tail = head;
} else {
tail.next = newNode(item, null);
tail = tail.next;
}
size++;
}
/**
* front() returns the node at the front of this SList. If the SList is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception.
*
* @return a ListNode at the front of this SList.
*
* Performance: runs in O(1) time.
*/
public ListNode front() {
if (head == null) {
// Create an invalid node.
SListNode node = newNode(null, null);
node.myList = null;
return node;
} else {
return head;
}
}
/**
* back() returns the node at the back of this SList. If the SList is
* empty, return an "invalid" node--a node with the property that any
* attempt to use it will cause an exception.
*
* @return a ListNode at the back of this SList.
*
* Performance: runs in O(1) time.
*/
public ListNode back() {
if (tail == null) {
// Create an invalid node.
SListNode node = newNode(null, null);
node.myList = null;
return node;
} else {
return tail;
}
}
/**
* toString() returns a String representation of this SList.
*
* @return a String representation of this SList.
*
* Performance: runs in O(n) time, where n is the length of the list.
*/
public String toString() {
String result = "[ ";
SListNode current = head;
while (current != null) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
private static void testInvalidNode(ListNode p) {
System.out.println("p.isValidNode() should be false: " + p.isValidNode());
try {
p.item();
System.out.println("p.item() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.item() should throw an exception, and did.");
}
try {
p.setItem(new Integer(0));
System.out.println("p.setItem() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.setItem() should throw an exception, and did.");
}
try {
p.next();
System.out.println("p.next() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.next() should throw an exception, and did.");
}
try {
p.prev();
System.out.println("p.prev() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.prev() should throw an exception, and did.");
}
try {
p.insertBefore(new Integer(1));
System.out.println("p.insertBefore() should throw an exception, but " +
"didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.insertBefore() should throw an exception, and did."
);
}
try {
p.insertAfter(new Integer(1));
System.out.println("p.insertAfter() should throw an exception, but " +
"didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.insertAfter() should throw an exception, and did."
);
}
try {
p.remove();
System.out.println("p.remove() should throw an exception, but didn't.");
} catch (InvalidNodeException lbe) {
System.out.println("p.remove() should throw an exception, and did.");
}
}
private static void testEmpty() {
List l = new SList();
System.out.println("An empty list should be [ ]: " + l);
System.out.println("l.isEmpty() should be true: " + l.isEmpty());
System.out.println("l.length() should be 0: " + l.length());
System.out.println("Finding front node p of l.");
ListNode p = l.front();
testInvalidNode(p);
System.out.println("Finding back node p of l.");
p = l.back();
testInvalidNode(p);
l.insertFront(new Integer(10));
System.out.println("l after insertFront(10) should be [ 10 ]: " + l);
}
public static void main(String[] argv) {
testEmpty();
List l = new SList();
l.insertFront(new Integer(3));
l.insertFront(new Integer(2));
l.insertFront(new Integer(1));
System.out.println("l is a list of 3 elements: " + l);
try {
ListNode n;
int i = 1;
for (n = l.front(); n.isValidNode(); n = n.next()) {
System.out.println("n.item() should be " + i + ": " + n.item());
n.setItem(new Integer(((Integer) n.item()).intValue() * 2));
System.out.println("n.item() should be " + 2 * i + ": " + n.item());
i++;
}
System.out.println("After doubling all elements of l: " + l);
testInvalidNode(n);
i = 6;
for (n = l.back(); n.isValidNode(); n = n.prev()) {
System.out.println("n.item() should be " + i + ": " + n.item());
n.setItem(new Integer(((Integer) n.item()).intValue() * 2));
System.out.println("n.item() should be " + 2 * i + ": " + n.item());
i = i - 2;
}
System.out.println("After doubling all elements of l again: " + l);
testInvalidNode(n);
n = l.front().next();
System.out.println("Removing middle element (8) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
n = l.back();
System.out.println("Removing end element (12) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
n = l.front();
System.out.println("Removing first element (4) of l: " + n.item());
n.remove();
System.out.println("l is now: " + l);
testInvalidNode(n);
} catch (InvalidNodeException lbe) {
System.err.println ("Caught InvalidNodeException that should not happen."
);
System.err.println ("Aborting the testing code.");
}
}
}

Binary file not shown.

View File

@ -0,0 +1,159 @@
/* SListNode.java */
package com.SimpleDrawingApp.list;
/**
* An SListNode is a mutable node in an SList (singly-linked list).
**/
public class SListNode extends ListNode {
/**
* (inherited) item references the item stored in the current node.
* (inherited) myList references the List that contains this node.
* next references the next node in the SList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
**/
protected SListNode next;
/**
* SListNode() constructor.
* @param i the item to store in the node.
* @param l the list this node is in.
* @param n the node following this node.
*/
SListNode(Object i, SList l, SListNode n) {
item = i;
myList = l;
next = n;
}
/**
* next() returns the node following this node. If this node is invalid,
* throws an exception.
*
* @return the node following this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode next() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("next() called on invalid node");
}
if (next == null) {
// Create an invalid node.
SListNode node = ((SList) myList).newNode(null, null);
node.myList = null;
return node;
} else {
return next;
}
}
/**
* prev() returns the node preceding this node. If this node is invalid,
* throws an exception.
*
* @param node the node whose predecessor is sought.
* @return the node preceding this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public ListNode prev() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("prev() called on invalid node");
}
SListNode prev = ((SList) myList).head;
if (prev == this) {
// Create an invalid node.
prev = ((SList) myList).newNode(null, null);
prev.myList = null;
} else {
while (prev.next != this) {
prev = prev.next;
}
}
return prev;
}
/**
* insertAfter() inserts an item immediately following this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertAfter(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertAfter() called on invalid node");
}
SListNode newNode = ((SList) myList).newNode(item, next);
if (next == null) {
((SList) myList).tail = newNode;
}
next = newNode;
myList.size++;
}
/**
* insertBefore() inserts an item immediately preceding this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public void insertBefore(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertBefore() called on invalid node");
}
SListNode newNode = ((SList) myList).newNode(item, this);
if (this == ((SList) myList).head) {
((SList) myList).head = newNode;
} else {
SListNode prev = (SListNode) prev();
prev.next = newNode;
}
myList.size++;
}
/**
* remove() removes this node from its SList. If this node is invalid,
* throws an exception.
*
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(this.size) time.
*/
public void remove() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("remove() called on invalid node");
}
if (this == ((SList) myList).head) {
((SList) myList).head = next;
if (next == null) {
((SList) myList).tail = null;
}
} else {
SListNode prev = (SListNode) prev();
prev.next = next;
if (next == null) {
((SList) myList).tail = prev;
}
}
myList.size--;
// Make this node an invalid node, so it cannot be used to corrupt myList.
myList = null;
// Set other reference to null to improve garbage collection.
next = null;
}
}