Просмотр исходного кода

Merge branch 'a2_submission' into 'master'

A2 submission 1

See merge request !4

Tareef Saleem Dedhar 6 лет назад
Родитель
Сommit
102d753dbf
75 измененных файлов с 1203 добавлено и 0 удалено
  1. BIN
      assignments/a2/.gradle/4.7-rc-2/fileChanges/last-build.bin
  2. BIN
      assignments/a2/.gradle/4.7-rc-2/fileHashes/fileHashes.bin
  3. BIN
      assignments/a2/.gradle/4.7-rc-2/fileHashes/fileHashes.lock
  4. BIN
      assignments/a2/.gradle/4.7/fileChanges/last-build.bin
  5. BIN
      assignments/a2/.gradle/4.7/fileContent/fileContent.lock
  6. BIN
      assignments/a2/.gradle/4.7/fileHashes/fileHashes.bin
  7. BIN
      assignments/a2/.gradle/4.7/fileHashes/fileHashes.lock
  8. BIN
      assignments/a2/.gradle/4.7/taskHistory/taskHistory.bin
  9. BIN
      assignments/a2/.gradle/4.7/taskHistory/taskHistory.lock
  10. BIN
      assignments/a2/.gradle/buildOutputCleanup/buildOutputCleanup.lock
  11. 2 0
      assignments/a2/.gradle/buildOutputCleanup/cache.properties
  12. BIN
      assignments/a2/.gradle/buildOutputCleanup/outputFiles.bin
  13. 0 0
      assignments/a2/.gradle/vcsWorkingDirs/gc.properties
  14. 9 0
      assignments/a2/.idea/compiler.xml
  15. 17 0
      assignments/a2/.idea/gradle.xml
  16. 6 0
      assignments/a2/.idea/misc.xml
  17. 10 0
      assignments/a2/.idea/modules.xml
  18. 12 0
      assignments/a2/.idea/modules/a2_main.iml
  19. 12 0
      assignments/a2/.idea/modules/a2_test.iml
  20. 55 0
      assignments/a2/.idea/workspace.xml
  21. 27 0
      assignments/a2/README.md
  22. 13 0
      assignments/a2/a2.iml
  23. 15 0
      assignments/a2/build.gradle
  24. BIN
      assignments/a2/build/classes/java/main/.gradle/4.7/taskHistory/taskHistory.bin
  25. BIN
      assignments/a2/build/classes/java/main/.gradle/4.7/taskHistory/taskHistory.lock
  26. BIN
      assignments/a2/build/classes/java/main/.gradle/buildOutputCleanup/buildOutputCleanup.lock
  27. 2 0
      assignments/a2/build/classes/java/main/.gradle/buildOutputCleanup/cache.properties
  28. BIN
      assignments/a2/build/classes/java/main/Colours$1.class
  29. BIN
      assignments/a2/build/classes/java/main/Colours$2.class
  30. BIN
      assignments/a2/build/classes/java/main/Colours$3.class
  31. BIN
      assignments/a2/build/classes/java/main/Colours.class
  32. BIN
      assignments/a2/build/classes/java/main/Controls$1.class
  33. BIN
      assignments/a2/build/classes/java/main/Controls$2.class
  34. BIN
      assignments/a2/build/classes/java/main/Controls$3.class
  35. BIN
      assignments/a2/build/classes/java/main/Controls$4.class
  36. BIN
      assignments/a2/build/classes/java/main/Controls$5.class
  37. BIN
      assignments/a2/build/classes/java/main/Controls.class
  38. BIN
      assignments/a2/build/classes/java/main/Handler.class
  39. BIN
      assignments/a2/build/classes/java/main/Main.class
  40. BIN
      assignments/a2/build/classes/java/main/Menubar.class
  41. BIN
      assignments/a2/build/classes/java/main/Model.class
  42. BIN
      assignments/a2/build/classes/java/main/Observer.class
  43. BIN
      assignments/a2/build/classes/java/main/Sidepane.class
  44. BIN
      assignments/a2/build/classes/java/main/Thingy.class
  45. BIN
      assignments/a2/build/classes/java/main/View.class
  46. BIN
      assignments/a2/build/classes/java/main/colourButton.class
  47. BIN
      assignments/a2/build/classes/java/main/playSlider.class
  48. BIN
      assignments/a2/build/classes/java/main/previewLine.class
  49. BIN
      assignments/a2/build/classes/java/main/previewPanel$1.class
  50. BIN
      assignments/a2/build/classes/java/main/previewPanel.class
  51. BIN
      assignments/a2/build/libs/a2-1.0-SNAPSHOT.jar
  52. BIN
      assignments/a2/build/resources/main/backbutton.png
  53. BIN
      assignments/a2/build/resources/main/backwardsplaybutton.jpg
  54. BIN
      assignments/a2/build/resources/main/forwardsbutton.png
  55. BIN
      assignments/a2/build/resources/main/playbutton.jpg
  56. 1 0
      assignments/a2/build/resources/main/rainbowicon.svg
  57. 2 0
      assignments/a2/build/tmp/jar/MANIFEST.MF
  58. BIN
      assignments/a2/gradle/wrapper/gradle-wrapper.jar
  59. 6 0
      assignments/a2/gradle/wrapper/gradle-wrapper.properties
  60. 172 0
      assignments/a2/gradlew
  61. 84 0
      assignments/a2/gradlew.bat
  62. 2 0
      assignments/a2/settings.gradle
  63. 117 0
      assignments/a2/src/main/java/Controls.java
  64. 35 0
      assignments/a2/src/main/java/Handler.java
  65. 34 0
      assignments/a2/src/main/java/Main.java
  66. 30 0
      assignments/a2/src/main/java/Menubar.java
  67. 272 0
      assignments/a2/src/main/java/Model.java
  68. 9 0
      assignments/a2/src/main/java/Observer.java
  69. 202 0
      assignments/a2/src/main/java/Sidepane.java
  70. 56 0
      assignments/a2/src/main/java/View.java
  71. BIN
      assignments/a2/src/main/resources/backbutton.png
  72. BIN
      assignments/a2/src/main/resources/backwardsplaybutton.jpg
  73. BIN
      assignments/a2/src/main/resources/forwardsbutton.png
  74. BIN
      assignments/a2/src/main/resources/playbutton.jpg
  75. 1 0
      assignments/a2/src/main/resources/rainbowicon.svg

BIN
assignments/a2/.gradle/4.7-rc-2/fileChanges/last-build.bin


BIN
assignments/a2/.gradle/4.7-rc-2/fileHashes/fileHashes.bin


BIN
assignments/a2/.gradle/4.7-rc-2/fileHashes/fileHashes.lock


BIN
assignments/a2/.gradle/4.7/fileChanges/last-build.bin


BIN
assignments/a2/.gradle/4.7/fileContent/fileContent.lock


BIN
assignments/a2/.gradle/4.7/fileHashes/fileHashes.bin


BIN
assignments/a2/.gradle/4.7/fileHashes/fileHashes.lock


BIN
assignments/a2/.gradle/4.7/taskHistory/taskHistory.bin


BIN
assignments/a2/.gradle/4.7/taskHistory/taskHistory.lock


BIN
assignments/a2/.gradle/buildOutputCleanup/buildOutputCleanup.lock


+ 2 - 0
assignments/a2/.gradle/buildOutputCleanup/cache.properties

@@ -0,0 +1,2 @@
+#Thu Jun 14 20:06:54 EDT 2018
+gradle.version=4.7

BIN
assignments/a2/.gradle/buildOutputCleanup/outputFiles.bin


+ 0 - 0
assignments/a2/.gradle/vcsWorkingDirs/gc.properties


+ 9 - 0
assignments/a2/.idea/compiler.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <bytecodeTargetLevel>
+      <module name="a2_main" target="1.8" />
+      <module name="a2_test" target="1.8" />
+    </bytecodeTargetLevel>
+  </component>
+</project>

+ 17 - 0
assignments/a2/.idea/gradle.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+        <option name="useAutoImport" value="true" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 6 - 0
assignments/a2/.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_10" project-jdk-name="10" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/classes" />
+  </component>
+</project>

+ 10 - 0
assignments/a2/.idea/modules.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/a2.iml" filepath="$PROJECT_DIR$/a2.iml" />
+      <module fileurl="file://$PROJECT_DIR$/.idea/modules/a2_main.iml" filepath="$PROJECT_DIR$/.idea/modules/a2_main.iml" group="a2" />
+      <module fileurl="file://$PROJECT_DIR$/.idea/modules/a2_test.iml" filepath="$PROJECT_DIR$/.idea/modules/a2_test.iml" group="a2" />
+    </modules>
+  </component>
+</project>

+ 12 - 0
assignments/a2/.idea/modules/a2_main.iml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="a2:main" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.type="sourceSet" external.system.module.version="1.0-SNAPSHOT" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/../../out/production/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$/../../src/main">
+      <sourceFolder url="file://$MODULE_DIR$/../../src/main/java" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 12 - 0
assignments/a2/.idea/modules/a2_test.iml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="a2:test" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.type="sourceSet" external.system.module.version="1.0-SNAPSHOT" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output-test url="file://$MODULE_DIR$/../../out/test/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$/../../src/test" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="a2_main" />
+  </component>
+  <component name="TestModuleProperties" production-module="a2_main" />
+</module>

+ 55 - 0
assignments/a2/.idea/workspace.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectFrameBounds" extendedState="6">
+    <option name="x" value="936" />
+    <option name="y" value="24" />
+    <option name="width" value="926" />
+    <option name="height" value="1056" />
+  </component>
+  <component name="PropertiesComponent">
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+  </component>
+  <component name="RunManager">
+    <configuration default="true" type="Application" factoryName="Application">
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit">
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <patterns />
+    </configuration>
+    <configuration default="true" type="TestNG" factoryName="TestNG">
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="SUITE_NAME" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="GROUP_NAME" />
+      <option name="TEST_OBJECT" value="CLASS" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
+      <option name="OUTPUT_DIRECTORY" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="singleModule" />
+      </option>
+      <option name="USE_DEFAULT_REPORTERS" value="false" />
+      <option name="PROPERTIES_FILE" />
+      <properties />
+      <listeners />
+    </configuration>
+  </component>
+</project>

+ 27 - 0
assignments/a2/README.md

@@ -0,0 +1,27 @@
+
+# CS 349 A2 - Worse Paint
+
+This is a drawing app akin to Microsoft Paint. You can draw lines of any given colour and thickness in the panel, rewind to see your history, press start to go to the start (empty), or end to go back to the latest changes and continue working.
+
+## Getting Started
+**Controls**
+
+ - Painting: Click and drag the mouse over the canvas to draw a line
+ - Selection of thiccness: Drag the slider on the left panel to increase/decrease thiccness of your line.
+ - Colour selection: Click the "custom" colour to open a chooser with full options, or simply click on one of the default colour options to use them.
+ - History: Drag the slider on the bottom back to watch your history undo itself. 
+ - Start/End: Click start to reset the canvas, click end to jump back to the latest changes in your drawing.
+
+## Deployment
+
+Run "java Main" in build/classes/java/main, or "./gradlew run" in the root directory if you do not have gradle installed, and if you do "gradle run" should suffice.
+
+## Enhancements
+
+The first enhancement done is to rewind (fast forward is broken) not by "strokes", but rather by length. So, short lines are "erased" very quickly, and long lines the opposite. This seemed like a more intuitive design than time-based, so I chose to go this direction instead
+
+The second enhancement was the live preview of your line if you were to draw it right now. This makes visualizing your thickness and colour combination very easy.
+
+## Authors
+
+* **Tareef Dedhar** - *All work* 

+ 13 - 0
assignments/a2/a2.iml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="a2" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="1.0-SNAPSHOT" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+      <excludeFolder url="file://$MODULE_DIR$/build" />
+      <excludeFolder url="file://$MODULE_DIR$/out" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 15 - 0
assignments/a2/build.gradle

@@ -0,0 +1,15 @@
+version '1.0-SNAPSHOT'
+
+apply plugin: 'java'
+
+sourceCompatibility = 1.8
+
+task run(type:JavaExec) {
+    classpath = sourceSets.main.runtimeClasspath
+    main = 'Main'
+}
+
+repositories
+{
+  jcenter()
+}

BIN
assignments/a2/build/classes/java/main/.gradle/4.7/taskHistory/taskHistory.bin


BIN
assignments/a2/build/classes/java/main/.gradle/4.7/taskHistory/taskHistory.lock


BIN
assignments/a2/build/classes/java/main/.gradle/buildOutputCleanup/buildOutputCleanup.lock


+ 2 - 0
assignments/a2/build/classes/java/main/.gradle/buildOutputCleanup/cache.properties

@@ -0,0 +1,2 @@
+#Mon Jun 18 23:44:10 EDT 2018
+gradle.version=4.7

BIN
assignments/a2/build/classes/java/main/Colours$1.class


BIN
assignments/a2/build/classes/java/main/Colours$2.class


BIN
assignments/a2/build/classes/java/main/Colours$3.class


BIN
assignments/a2/build/classes/java/main/Colours.class


BIN
assignments/a2/build/classes/java/main/Controls$1.class


BIN
assignments/a2/build/classes/java/main/Controls$2.class


BIN
assignments/a2/build/classes/java/main/Controls$3.class


BIN
assignments/a2/build/classes/java/main/Controls$4.class


BIN
assignments/a2/build/classes/java/main/Controls$5.class


BIN
assignments/a2/build/classes/java/main/Controls.class


BIN
assignments/a2/build/classes/java/main/Handler.class


BIN
assignments/a2/build/classes/java/main/Main.class


BIN
assignments/a2/build/classes/java/main/Menubar.class


BIN
assignments/a2/build/classes/java/main/Model.class


BIN
assignments/a2/build/classes/java/main/Observer.class


BIN
assignments/a2/build/classes/java/main/Sidepane.class


BIN
assignments/a2/build/classes/java/main/Thingy.class


BIN
assignments/a2/build/classes/java/main/View.class


BIN
assignments/a2/build/classes/java/main/colourButton.class


BIN
assignments/a2/build/classes/java/main/playSlider.class


BIN
assignments/a2/build/classes/java/main/previewLine.class


BIN
assignments/a2/build/classes/java/main/previewPanel$1.class


BIN
assignments/a2/build/classes/java/main/previewPanel.class


BIN
assignments/a2/build/libs/a2-1.0-SNAPSHOT.jar


BIN
assignments/a2/build/resources/main/backbutton.png


BIN
assignments/a2/build/resources/main/backwardsplaybutton.jpg


BIN
assignments/a2/build/resources/main/forwardsbutton.png


BIN
assignments/a2/build/resources/main/playbutton.jpg


+ 1 - 0
assignments/a2/build/resources/main/rainbowicon.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;" xml:space="preserve" version="1.1" id="svg2"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs6"><clipPath id="clipPath16" clipPathUnits="userSpaceOnUse"><path id="path18" d="M 4,31 C 1.791,31 0,29.209 0,27 L 0,27 0,9 C 0,6.791 1.791,5 4,5 l 0,0 28,0 c 2.209,0 4,1.791 4,4 l 0,0 0,18 c 0,2.209 -1.791,4 -4,4 l 0,0 -28,0 z"/></clipPath></defs><g transform="matrix(1.25,0,0,-1.25,0,45)" id="g10"><g id="g12"><g clip-path="url(#clipPath16)" id="g14"><path id="path20" style="fill:#880082;fill-opacity:1;fill-rule:nonzero;stroke:none" d="M 36,9.5 0,9.5 0,5 36,5 36,9.5 Z"/><path id="path22" style="fill:#3558a0;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,13.93 -36,0 0,-4.6 36,0 0,4.6 z"/><path id="path24" style="fill:#138f3e;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,18.17 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path26" style="fill:#fad220;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,22.5 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path28" style="fill:#ff5000;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,26.83 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path30" style="fill:#ff000e;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,31 -36,0 0,-4.33 36,0 0,4.33 z"/></g></g></g></svg>

+ 2 - 0
assignments/a2/build/tmp/jar/MANIFEST.MF

@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+

BIN
assignments/a2/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
assignments/a2/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Tue May 29 15:31:30 EDT 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-rc-2-all.zip

+ 172 - 0
assignments/a2/gradlew

@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save ( ) {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"

+ 84 - 0
assignments/a2/gradlew.bat

@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 2 - 0
assignments/a2/settings.gradle

@@ -0,0 +1,2 @@
+rootProject.name = 'a2'
+

+ 117 - 0
assignments/a2/src/main/java/Controls.java

@@ -0,0 +1,117 @@
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import javax.swing.ImageIcon;
+
+public class Controls extends JPanel implements Observer
+{
+  private Model model;
+  private playSlider playback;
+  private JButton play;
+  private JButton rewind;
+  private JButton reset;
+  private JButton clear;
+
+  // Bob the Builder this shit
+  public Controls(Model model, Handler handler)
+  {
+    // Hook up this observer so that it will be notified when the model
+    // changes.
+    this.model = model;
+    this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+    this.setPreferredSize(new Dimension(1280,75));
+    this.setMinimumSize(new Dimension(320, 75));
+    //ImageIcon icon1 = new ImageIcon("/src/main/resources/playbutton.jpg");
+    this.play = new JButton("Play");
+    play.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        
+      }
+    });
+    this.rewind = new JButton("Rewind");
+    rewind.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        
+      }
+    });
+    this.playback = new playSlider(0, 0, 0);
+    playback.addChangeListener(new ChangeListener()
+    {
+      public void stateChanged(ChangeEvent e)
+      {
+        if (!playback.getSettingLen() && playback.getValue() != model.getTotalVisibleLen())
+        {
+          model.changeThingy(playback.getValue());
+        }
+      }
+    });
+    this.playback.setPreferredSize(new Dimension(280, 75));
+    this.reset = new JButton("End");
+    reset.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        model.ffwd();
+        //playback.setValue(playback.getMaximum());
+      }
+    });
+    this.clear = new JButton("Start");
+    clear.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        model.rewind();
+        //playback.setValue(playback.getMinimum());
+      }
+    });
+    this.add(play);
+    this.add(rewind);
+    this.add(playback);
+    this.add(clear);
+    this.add(reset);
+    model.addObserver(this);
+  }
+
+  public void update(Object observable)
+  {
+    int len = model.getTotalLen();
+    if (len > 0)
+    {
+      playback.toggleSettingLen();
+      playback.setMaximum(len);
+      playback.toggleSettingLen();
+      playback.setValue(model.getTotalVisibleLen());
+    }
+    this.setBackground(model.controlColour);
+    revalidate();
+    repaint();
+  }
+}
+
+class playSlider extends JSlider
+{
+  private boolean settingLen;
+  
+  public playSlider(int min, int max, int val)
+  {
+    super(min, max, val);
+    this.settingLen = false;
+  }
+  
+  public void toggleSettingLen()
+  {
+    this.settingLen = !settingLen;
+  }
+
+  public boolean getSettingLen()
+  {
+    return settingLen;
+  }
+}

+ 35 - 0
assignments/a2/src/main/java/Handler.java

@@ -0,0 +1,35 @@
+import java.io.*;
+import java.awt.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+
+public class Handler extends MouseInputAdapter implements ActionListener, ChangeListener
+{
+  private Model m;
+
+  // Bob the Builder this shit
+  public Handler(Model model)
+  {
+    m = model;
+  }
+  
+  public void mousePressed(MouseEvent e)
+  {
+    m.newThingy(e.getX(), e.getY());
+  }
+  
+  public void mouseDragged(MouseEvent e)
+  {
+    m.addPoint(e.getX(), e.getY());
+  }
+
+  public void actionPerformed(ActionEvent e)
+  {
+    
+  }
+
+  public void stateChanged(ChangeEvent e)
+  {
+    
+  }
+}

+ 34 - 0
assignments/a2/src/main/java/Main.java

@@ -0,0 +1,34 @@
+import javax.swing.*;
+import java.awt.*;
+
+public class Main
+{
+  public static void main(String[] args)
+  {
+    JFrame window = new JFrame("Paint, but worse");
+    Model model = new Model();
+    Handler handler = new Handler(model);
+    View view = new View(model, handler);
+    Menubar menubar = new Menubar(model, handler);
+    Sidepane sidepane = new Sidepane(model, handler);
+    Controls controls = new Controls(model, handler);
+    model.notifyObservers();
+    
+    // create a layout panel to hold the views
+    JPanel mainpanel = new JPanel(new BorderLayout(0, 0));
+    window.getContentPane().add(mainpanel);
+    mainpanel.add(view, BorderLayout.CENTER);
+    mainpanel.add(menubar, BorderLayout.PAGE_START);
+    mainpanel.add(sidepane, BorderLayout.LINE_START);
+    mainpanel.add(controls, BorderLayout.PAGE_END);
+    model.setSideColour(Color.cyan);
+    model.setControlColour(Color.gray);
+
+    // Setup the frame to do frame things
+    window.setPreferredSize(new Dimension(1280,720));
+    window.setMinimumSize(new Dimension(320, 180));
+    window.pack();
+    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    window.setVisible(true);
+  }
+}

+ 30 - 0
assignments/a2/src/main/java/Menubar.java

@@ -0,0 +1,30 @@
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+
+public class Menubar extends JMenuBar implements Observer
+{
+  private Model model;
+
+  // Bob the Builder this shit
+  public Menubar(Model model, Handler handler)
+  {
+    // Hook up this observer so that it will be notified when the model
+    // changes.
+    this.model = model;
+    this.setPreferredSize(new Dimension(1280, 50));
+    this.setMinimumSize(new Dimension(320, 50));
+    this.add(new JMenu("File"));
+    model.addObserver(this);
+  }
+  
+  /**
+  * Update with data from the model.
+  */
+  public void update(Object observable)
+  {
+    revalidate();
+    repaint();
+  }
+}

+ 272 - 0
assignments/a2/src/main/java/Model.java

@@ -0,0 +1,272 @@
+import java.util.Observable;
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import java.io.*;
+
+public class Model extends Observable
+{
+   /** The observers that are watching this model for changes. */
+  private ArrayList<Observer> observers;
+  private ArrayList<Thingy> thingies;
+  private Thingy curThingy;
+  private Color curColour;
+  private int curThiccness;
+  private int totalLen;
+  private int totalVisibleLen;
+  public Color sideColour;
+  public Color controlColour;
+
+  // Constructor
+  public Model()
+  {
+    this.observers = new ArrayList();
+    this.thingies = new ArrayList();
+    this.curColour = Color.black;
+    this.curThiccness = 5;
+    this.totalLen = 0;
+    this.totalVisibleLen = 0;
+    setChanged();
+  }
+  
+  public void newThingy(int x, int y)
+  {
+    if (totalLen != totalVisibleLen)
+    {
+      // resize curthingy to it's visible length
+      ArrayList<Point> temp = new ArrayList();
+      for (int i = 0; i < curThingy.getVisibleLen(); i++)
+      {
+        temp.add(curThingy.getPoints().get(i));
+      }
+      curThingy.setPoints(temp);
+      // reset total length to total visible length
+      totalLen = totalVisibleLen;
+      // delete extra nodes in thingies
+      int start = thingies.indexOf(curThingy);
+      for (int i = start + 1; i < thingies.size(); i++)
+      {
+        thingies.remove(i);
+      }
+    }
+
+    curThingy = new Thingy(curColour, curThiccness);
+    thingies.add(curThingy);
+    curThingy.addPoint(x, y);
+    totalLen++;
+    totalVisibleLen++;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public void addPoint(int x, int y)
+  {
+    curThingy.addPoint(x, y);
+    totalLen++;
+    totalVisibleLen++;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public int getTotalLen()
+  {
+    return totalLen;
+  }
+  
+  public int getTotalVisibleLen()
+  {
+    return totalVisibleLen;
+  }
+  
+  public ArrayList<Thingy> getThingies()
+  {
+    return thingies;
+  }
+  
+  public void changeThingy(int x) // int x is the position in the slider we are at
+  {
+    int tempLen = 0;
+    int index = 0;
+    
+    for (int i = 0; i < thingies.size() && tempLen <= x; i++)
+    {
+      tempLen += thingies.get(i).getVisibleLen();
+      index = i;
+    }
+    
+    //if (Math.abs(index - thingies.indexOf(curThingy)) > 1 && index != (thingies.size() - 1)) index = thingies.indexOf(curThingy);
+    curThingy = thingies.get(index);
+    // off by one adjustments if we're at the end of a thingy
+    if (index > 0 && curThingy.getVisibleLen() == 0 && tempLen > x) curThingy = thingies.get(index - 1);
+    if (curThingy.getVisibleLen() == curThingy.getPoints().size() && tempLen < x) curThingy = thingies.get(index + 1);
+    
+    // now modify tempThingy
+    // if we want to go back in time
+    if (tempLen > x)
+    {
+      curThingy.reduceLen();
+      totalVisibleLen--;
+    }
+    else // go forwards
+    {
+      curThingy.increaseLen();
+      totalVisibleLen++;
+    }
+
+    setChanged();
+    notifyObservers();
+  }
+
+  public void ffwd()
+  {
+    for (Thingy t: thingies)
+    {
+      t.setVisibleLen(t.getPoints().size());
+    }
+
+    if (thingies.size() >= 1)
+    {
+      curThingy = thingies.get(thingies.size() - 1);
+    }
+
+    setChanged();
+    notifyObservers();
+  }
+  
+  public void rewind()
+  {
+    for (Thingy t: thingies)
+    {
+      t.setVisibleLen(0);
+    }
+
+    if (thingies.size() >= 1)
+    {
+      curThingy = thingies.get(0);
+    }
+
+    setChanged();
+    notifyObservers();
+  }
+
+  public void setSideColour(Color c)
+  {
+    sideColour = c;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public void setControlColour(Color c)
+  {
+    controlColour = c;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public void changeThiccness(int x)
+  {
+    curThiccness = x;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public void changeColour(Color c)
+  {
+    curColour = c;
+    setChanged();
+    notifyObservers();
+  }
+  
+  public int getThiccness()
+  {
+    return curThiccness;
+  }
+  
+  public Color getColour()
+  {
+    return curColour;
+  }
+
+  // Add observer to be notified on change
+  public void addObserver(Observer observer)
+  {
+    this.observers.add(observer);
+  }
+
+  // Remove an observer from opdate list
+  public void removeObserver(Observer observer)
+  {
+    this.observers.remove(observer);
+  }
+
+   // Notify all observers shit went down
+  public void notifyObservers()
+  {
+    for (Observer observer: this.observers)
+    {
+      observer.update(this);
+    }
+  }
+}
+
+class Thingy
+{
+  private ArrayList<Point> points;
+  private Color colour;
+  private int thiccness;
+  private int visibleLen;
+  
+  public Thingy(Color c, int x)
+  {
+    points = new ArrayList();
+    this.colour = c;
+    this.thiccness = x;
+    this.visibleLen = 0;
+  }
+  
+  public void addPoint(int x, int y)
+  {
+    points.add(new Point(x, y));
+    visibleLen++;
+  }
+  
+  public ArrayList<Point> getPoints()
+  {
+    return points;
+  }
+
+  public void setPoints(ArrayList a)
+  {
+    points = a;
+  }
+  
+  public Color getColour()
+  {
+    return colour;
+  }
+  
+  public int getThiccness()
+  {
+    return thiccness;
+  }
+  
+  public int getVisibleLen()
+  {
+    return visibleLen;
+  }
+  
+  public void reduceLen()
+  {
+    visibleLen--;
+  }
+  
+  public void increaseLen()
+  {
+    visibleLen++;
+  }
+
+  public void setVisibleLen(int x)
+  {
+    visibleLen = x;
+  }
+}

+ 9 - 0
assignments/a2/src/main/java/Observer.java

@@ -0,0 +1,9 @@
+
+/**
+ * An interface that allows an object to receive updates from the object
+ * they listen to.
+ */
+interface Observer {
+    void update(Object observable);
+}
+

+ 202 - 0
assignments/a2/src/main/java/Sidepane.java

@@ -0,0 +1,202 @@
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+import java.awt.event.*;
+import javax.swing.event.*;
+
+public class Sidepane extends JPanel implements Observer
+{
+  private Model model;
+  private Colours colours;
+  private JPanel thiccness;
+  private previewPanel preview;
+
+  // Bob the Builder this shit
+  public Sidepane(Model model, Handler handler)
+  {
+    // Hook up this observer so that it will be notified when the model
+    // changes.
+    this.model = model;
+    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+    this.setPreferredSize(new Dimension(280, 720));
+    colours = new Colours(model);
+    preview = new previewPanel(model);
+    this.add(colours);
+    this.add(preview);
+    model.addObserver(this);
+  }
+
+  /**
+  * Update with data from the model.
+  */
+  public void update(Object observable)
+  {
+    this.setBackground(model.sideColour);
+    revalidate();
+    repaint();
+  }
+}
+
+class Colours extends JPanel
+{
+  private Model model;
+  private ArrayList<colourButton> colours;
+  private JButton chooserButton;
+  private JFrame chooserFrame;
+  private JPanel chooserPanel;
+  private JButton changeButton;
+  private JButton confirmButton;
+  private JColorChooser colourChooser;
+
+  public Colours(Model m)
+  {
+    this.model = m;
+    this.setLayout(new GridLayout(0, 2));
+    this.setPreferredSize(new Dimension(280, 480));
+    this.colours = new ArrayList();
+    colourButton.model = m;
+    colours.add(new colourButton(Color.red));
+    colours.add(new colourButton(Color.green));
+    colours.add(new colourButton(Color.blue));
+    colours.add(new colourButton(Color.yellow));
+    colours.add(new colourButton(Color.magenta));
+    colours.add(new colourButton(Color.orange));
+    colours.add(new colourButton(Color.cyan));
+    //colours.add(new colourButton(Color.gray));
+
+    this.changeButton = new JButton("Custom");
+    changeButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        chooserFrame.pack();
+	chooserFrame.setVisible(true);
+      }
+    });
+    this.chooserFrame = new JFrame("Chooser Window");
+    this.colourChooser = new JColorChooser();
+    this.confirmButton = new JButton("Select this colour?");
+    confirmButton.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        changeButton.setBackground(colourChooser.getColor());
+        model.changeColour(colourChooser.getColor());
+      }
+    });
+    this.chooserPanel = new JPanel(new FlowLayout());
+    chooserFrame.getContentPane().add(chooserPanel);
+    chooserPanel.add(colourChooser);
+    chooserPanel.add(confirmButton);
+    this.add(changeButton);
+    
+    for(colourButton b: colours)
+    {
+      this.add(b);
+      b.addActionListener(new ActionListener()
+      {
+        public void actionPerformed(ActionEvent e)
+        {
+          colourButton.model.changeColour(b.getBackground());
+        }
+      });
+    }
+  }
+}
+
+class colourButton extends JButton
+{
+  public static Model model;
+
+  public colourButton(Color c)
+  {
+    this.setBackground(c);
+    this.setOpaque(true);
+  }
+  
+  public String toString()
+  {
+    return this.getBackground().toString();
+  }
+}
+
+class previewPanel extends JPanel
+{
+  private Model model;
+  private JSlider slider;
+  //private JLabel label;
+  private previewLine preview;
+  
+  public previewPanel(Model m)
+  {
+    this.model = m;
+    //this.label = new JLabel("Thiccness");
+    this.slider = new JSlider(1, 50, model.getThiccness());
+    this.slider.addChangeListener(new ChangeListener()
+      {
+        public void stateChanged(ChangeEvent e)
+        {
+          model.changeThiccness(slider.getValue());
+        }
+      });
+    this.slider.setPreferredSize(new Dimension(280, 75));
+    this.preview = new previewLine(m);
+    this.setPreferredSize(new Dimension(280, 240));
+    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+    this.add(preview);
+    //this.add(label);
+    this.add(slider);
+  }
+}
+
+class previewLine extends JPanel implements Observer
+{
+  private Model model;
+  private previewPanel parent;
+  
+  public previewLine(Model m)
+  {
+    this.model = m;
+    model.addObserver(this);
+  }
+
+  public void update(Object observable)
+  {
+    newBackground();
+    revalidate();
+    repaint();
+  }
+
+  public void newBackground()
+  {
+    Color temp = model.getColour();
+    int r = temp.getRed();
+    int g = temp.getGreen();
+    int b = temp.getBlue();
+
+    if (r == g && g == b)
+    {
+      if (r > 125) r = g = b = 0;
+      else r = g = b = 255;
+    }
+    else
+    {
+      r = 255 - r;
+      g = 255 - g;
+      b = 255 - b;
+    }
+
+    this.setBackground(new Color(r, g, b));
+  }
+  
+  public void paintComponent(Graphics g)
+  {
+    super.paintComponent(g);
+    Graphics2D gtemp = (Graphics2D) g;
+    gtemp.setColor(model.getColour());
+    gtemp.setStroke(new BasicStroke(model.getThiccness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+    gtemp.drawLine((int)(this.getSize().width*.25), (this.getSize().height/2), (int)(this.getSize().width*.75), (this.getSize().height/2));
+  }
+}
+

+ 56 - 0
assignments/a2/src/main/java/View.java

@@ -0,0 +1,56 @@
+import java.util.*;
+import java.awt.*;
+import javax.swing.*;
+
+public class View extends JPanel implements Observer
+{
+  private Model model;
+
+  // Bob the Builder this shit
+  public View(Model model, Handler handler)
+  {
+    // Hook up this observer so that it will be notified when the model
+    // changes.
+    this.model = model;
+    this.setBackground(Color.white);
+    model.addObserver(this);
+    this.addMouseMotionListener(handler);
+    this.addMouseListener(handler);
+  }
+
+  /**
+  * Update with data from the model.
+  */
+  public void update(Object observable)
+  {
+    revalidate();
+    repaint();
+  }
+  
+  public void paintComponent(Graphics g)
+  {
+    super.paintComponent(g);
+    Graphics2D gtemp = (Graphics2D) g;
+    ArrayList<Thingy> thingies = model.getThingies();
+    
+    for (Thingy t: thingies)
+    {
+      ArrayList<Point> points = t.getPoints();
+      gtemp.setColor(t.getColour());
+      gtemp.setStroke(new BasicStroke(t.getThiccness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+      
+      if (t.getVisibleLen() == 0) {}
+      else if (t.getVisibleLen() ==  1)
+      {
+        gtemp.drawLine(points.get(0).x, points.get(0).y, points.get(0).x, points.get(0).y);
+      }
+      else
+      {
+        for (int i = 1; i < t.getVisibleLen(); i++)
+        {
+          gtemp.drawLine(points.get(i - 1).x, points.get(i - 1).y, points.get(i).x, points.get(i).y);
+        }
+      }
+    }
+  }
+}

BIN
assignments/a2/src/main/resources/backbutton.png


BIN
assignments/a2/src/main/resources/backwardsplaybutton.jpg


BIN
assignments/a2/src/main/resources/forwardsbutton.png


BIN
assignments/a2/src/main/resources/playbutton.jpg


+ 1 - 0
assignments/a2/src/main/resources/rainbowicon.svg

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;" xml:space="preserve" version="1.1" id="svg2"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs6"><clipPath id="clipPath16" clipPathUnits="userSpaceOnUse"><path id="path18" d="M 4,31 C 1.791,31 0,29.209 0,27 L 0,27 0,9 C 0,6.791 1.791,5 4,5 l 0,0 28,0 c 2.209,0 4,1.791 4,4 l 0,0 0,18 c 0,2.209 -1.791,4 -4,4 l 0,0 -28,0 z"/></clipPath></defs><g transform="matrix(1.25,0,0,-1.25,0,45)" id="g10"><g id="g12"><g clip-path="url(#clipPath16)" id="g14"><path id="path20" style="fill:#880082;fill-opacity:1;fill-rule:nonzero;stroke:none" d="M 36,9.5 0,9.5 0,5 36,5 36,9.5 Z"/><path id="path22" style="fill:#3558a0;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,13.93 -36,0 0,-4.6 36,0 0,4.6 z"/><path id="path24" style="fill:#138f3e;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,18.17 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path26" style="fill:#fad220;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,22.5 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path28" style="fill:#ff5000;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,26.83 -36,0 0,-4.5 36,0 0,4.5 z"/><path id="path30" style="fill:#ff000e;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 36,31 -36,0 0,-4.33 36,0 0,4.33 z"/></g></g></g></svg>