From d47625fead650375bde89ceeca04e0f21bd79d85 Mon Sep 17 00:00:00 2001
From: ervelae <97437577+ervelae@users.noreply.github.com>
Date: Wed, 12 Jan 2022 19:12:20 +0200
Subject: [PATCH] Initial commit

:)
---
 Project 1/.gitignore                          |  20 +
 Project 1/.gitlab-ci.yml                      |  13 +
 Project 1/README.md                           |  39 ++
 Project 1/build.sbt                           | 236 +++++++++
 Project 1/pom.xml                             | 452 ++++++++++++++++++
 Project 1/project/build.properties            |   1 +
 Project 1/project/plugins.sbt                 |   7 +
 .../java/fi/utu/tech/gui/javafx/Dialogs.java  |  13 +
 .../utu/tech/gui/javafx/FXMLController.java   |  63 +++
 .../utu/tech/gui/javafx/FXMLController2.java  |  83 ++++
 .../java/fi/utu/tech/gui/javafx/Main.java     |  29 ++
 .../java/fi/utu/tech/gui/javafx/MainApp.java  |  59 +++
 .../fi/utu/tech/gui/javafx/MainApp10.java     |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp4.java |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp5.java |  62 +++
 .../fi/utu/tech/gui/javafx/OtherWindow.java   |  47 ++
 .../fi/utu/tech/gui/javafx/OtherWindow10.java |  48 ++
 .../fi/utu/tech/gui/javafx/OtherWindow4.java  |  50 ++
 .../utu/tech/gui/javafx/ResourceLoader.java   |  42 ++
 .../fi/utu/tech/gui/javafx/Teht_5_ikkuna.java |  80 ++++
 .../resources/fi/utu/tech/gui/javafx/hmm.png  | Bin 0 -> 9965 bytes
 .../fi/utu/tech/gui/javafx/otherwindow.fxml   |  45 ++
 .../fi/utu/tech/gui/javafx/scene.fxml         |  48 ++
 .../fi/utu/tech/gui/javafx/styles.css         |   3 +
 .../fi/utu/tech/gui/javafx/styles2.css        |   7 +
 Project 2/.gitignore                          |  21 +
 Project 2/.gitlab-ci.yml                      |  13 +
 Project 2/README.md                           |  39 ++
 Project 2/build.sbt                           | 236 +++++++++
 Project 2/pom.xml                             | 452 ++++++++++++++++++
 Project 2/project/build.properties            |   1 +
 Project 2/project/plugins.sbt                 |   7 +
 .../main/java/fi/utu/tech/gui/javafx/BMI.java |  46 ++
 .../fi/utu/tech/gui/javafx/CanvasWindow.java  |  84 ++++
 .../java/fi/utu/tech/gui/javafx/Dialogs.java  |  13 +
 .../utu/tech/gui/javafx/FXMLController.java   |  63 +++
 .../java/fi/utu/tech/gui/javafx/Main.java     |  29 ++
 .../java/fi/utu/tech/gui/javafx/MainApp.java  |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp1.java |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp2.java |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp3.java |  76 +++
 .../java/fi/utu/tech/gui/javafx/MainApp4.java |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp5.java |  59 +++
 .../java/fi/utu/tech/gui/javafx/MainApp6.java |  59 +++
 .../fi/utu/tech/gui/javafx/OtherWindow.java   |  14 +
 .../utu/tech/gui/javafx/PasswordWindow.java   |  91 ++++
 .../utu/tech/gui/javafx/ResourceLoader.java   |  42 ++
 .../utu/tech/gui/javafx/StackPaneWindow.java  |  41 ++
 .../fi/utu/tech/gui/javafx/WebSelain.java     |  40 ++
 .../resources/fi/utu/tech/gui/javafx/hmm.png  | Bin 0 -> 9965 bytes
 .../fi/utu/tech/gui/javafx/scene.fxml         |  48 ++
 .../fi/utu/tech/gui/javafx/styles.css         |   3 +
 Project 3/.gitignore                          |  20 +
 Project 3/.gitlab-ci.yml                      |  13 +
 Project 3/README.md                           |  39 ++
 Project 3/build.sbt                           | 236 +++++++++
 Project 3/pom.xml                             | 452 ++++++++++++++++++
 Project 3/project/build.properties            |   1 +
 Project 3/project/plugins.sbt                 |   7 +
 .../java/fi/utu/tech/gui/javafx/Dialogs.java  |  13 +
 .../java/fi/utu/tech/gui/javafx/Main.java     |  31 ++
 .../java/fi/utu/tech/gui/javafx/MainApp.java  |  40 ++
 .../utu/tech/gui/javafx/ResourceLoader.java   |  42 ++
 .../gui/javafx/gimmick/GimmickController.java |  27 ++
 .../utu/tech/gui/javafx/gimmick/MainApp2.java |  20 +
 .../fi/utu/tech/gui/javafx/gimmick/View.java  |  17 +
 .../fi/utu/tech/gui/javafx/gimmick/View1.java |  63 +++
 .../fi/utu/tech/gui/javafx/gimmick/View2.java |  36 ++
 .../utu/tech/gui/javafx/zipper/MainApp1.java  |  27 ++
 .../fi/utu/tech/gui/javafx/zipper/Zipper.java | 134 ++++++
 .../gui/javafx/zipper/ZipperController.java   | 112 +++++
 .../fi/utu/tech/gui/javafx/alien.png          | Bin 0 -> 46129 bytes
 .../fi/utu/tech/gui/javafx/gimmick.fxml       |  54 +++
 .../resources/fi/utu/tech/gui/javafx/hmm.png  | Bin 0 -> 8752 bytes
 .../fi/utu/tech/gui/javafx/package.png        | Bin 0 -> 8960 bytes
 .../fi/utu/tech/gui/javafx/styles.css         |   7 +
 .../fi/utu/tech/gui/javafx/zipper.fxml        |  70 +++
 77 files changed, 4739 insertions(+)
 create mode 100644 Project 1/.gitignore
 create mode 100644 Project 1/.gitlab-ci.yml
 create mode 100644 Project 1/README.md
 create mode 100644 Project 1/build.sbt
 create mode 100644 Project 1/pom.xml
 create mode 100644 Project 1/project/build.properties
 create mode 100644 Project 1/project/plugins.sbt
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController2.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/Main.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp10.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow10.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow4.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
 create mode 100644 Project 1/src/main/java/fi/utu/tech/gui/javafx/Teht_5_ikkuna.java
 create mode 100644 Project 1/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
 create mode 100644 Project 1/src/main/resources/fi/utu/tech/gui/javafx/otherwindow.fxml
 create mode 100644 Project 1/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml
 create mode 100644 Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles.css
 create mode 100644 Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles2.css
 create mode 100644 Project 2/.gitignore
 create mode 100644 Project 2/.gitlab-ci.yml
 create mode 100644 Project 2/README.md
 create mode 100644 Project 2/build.sbt
 create mode 100644 Project 2/pom.xml
 create mode 100644 Project 2/project/build.properties
 create mode 100644 Project 2/project/plugins.sbt
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/BMI.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/CanvasWindow.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/Main.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp1.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp2.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp3.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp6.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/PasswordWindow.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/StackPaneWindow.java
 create mode 100644 Project 2/src/main/java/fi/utu/tech/gui/javafx/WebSelain.java
 create mode 100644 Project 2/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
 create mode 100644 Project 2/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml
 create mode 100644 Project 2/src/main/resources/fi/utu/tech/gui/javafx/styles.css
 create mode 100644 Project 3/.gitignore
 create mode 100644 Project 3/.gitlab-ci.yml
 create mode 100644 Project 3/README.md
 create mode 100644 Project 3/build.sbt
 create mode 100644 Project 3/pom.xml
 create mode 100644 Project 3/project/build.properties
 create mode 100644 Project 3/project/plugins.sbt
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/Main.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/GimmickController.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/MainApp2.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View1.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View2.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/MainApp1.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/Zipper.java
 create mode 100644 Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/ZipperController.java
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/alien.png
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/gimmick.fxml
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/package.png
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/styles.css
 create mode 100644 Project 3/src/main/resources/fi/utu/tech/gui/javafx/zipper.fxml

diff --git a/Project 1/.gitignore b/Project 1/.gitignore
new file mode 100644
index 0000000..5bfb48e
--- /dev/null
+++ b/Project 1/.gitignore	
@@ -0,0 +1,20 @@
+contracts/
+.classpath
+.project
+.history/
+.idea
+.jqwik-database
+.lib/
+.worksheet
+.settings/
+*.iml
+*.ipr
+*.iws
+*.log
+project/boot/
+project/plugins/project/
+project/project/
+project/*-shim.sbt
+project/target/
+target/
+openjfx/
diff --git a/Project 1/.gitlab-ci.yml b/Project 1/.gitlab-ci.yml
new file mode 100644
index 0000000..4b3553b
--- /dev/null
+++ b/Project 1/.gitlab-ci.yml	
@@ -0,0 +1,13 @@
+image: maven:latest
+
+stages:
+  - build
+  - test
+
+build:
+  script:
+    - mvn compile
+
+test:
+  script:
+    - mvn test
\ No newline at end of file
diff --git a/Project 1/README.md b/Project 1/README.md
new file mode 100644
index 0000000..2907fd1
--- /dev/null
+++ b/Project 1/README.md	
@@ -0,0 +1,39 @@
+# Project description
+
+Simple template for projects that make use of JavaFX and FXML (Scene Builder).
+Requires Java 11 or later. Compatible with
+Eclipse and IntelliJ IDEA. Minor issues with Netbeans. Automatically
+integrates with Gitlab CI.
+
+## Installation
+
+Maven:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ mvn compile exec:java
+```
+
+SBT:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ sbt compile run
+```
+
+## Further instructions
+
+  * Java platform: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/jvm-platform
+  * Maven: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/maven-misc
+  * SBT: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/sbt-misc
+  
+External sources:
+
+  * JavaFX: https://openjfx.io/javadoc/11/
+  * Scene Builder: https://docs.gluonhq.com/scenebuilder/
diff --git a/Project 1/build.sbt b/Project 1/build.sbt
new file mode 100644
index 0000000..e703e90
--- /dev/null
+++ b/Project 1/build.sbt	
@@ -0,0 +1,236 @@
+// Project template
+
+// Supported operating systems: Windows, Mac, Linux
+// Supported JDKs: 8, 10+
+
+// Project name
+name := "template-javafx"
+
+// organization name
+organization := "fi.utu.tech"
+
+version := "1.0"
+
+// project description
+description := "JavaFX project template"
+
+// main class
+Compile/mainClass := Some("fi.utu.tech.gui.javafx.Main")
+
+// force the java version by typing it here (remove the comment)
+val force_javaVersion = None // Some(13)
+
+// force the javafx version by typing it here (remove the comment)
+val force_javaFxVersion = None // Some(13)
+
+val useJavaFX = true
+
+val useScalaOrScalaFX = true
+
+// END_OF_SIMPLE_CONFIGURATION
+// you can copy the rest for each new project
+// --- --- ---
+
+def fail(msg: String) = {
+  println("Error :-/")
+  println
+  println(msg)
+  System.exit(1)
+  null
+}
+
+val detectedJDK = System.getProperty("java.version").replace("-ea","").split('.').dropWhile(_.toInt<8).head.toInt
+
+val javaVersionNum = force_javaVersion.getOrElse(detectedJDK)
+
+val javaVersionString = javaVersionNum match {
+  case 7 => "1.7"
+  case 8 => "1.8"
+  case x if x > 8 => x.toString
+}
+
+val lts = 11
+val dev = 13
+
+val supported = javaVersionNum match {
+  case x if x < 8              => fail("Your Java installation is obsolete. Please upgrade to Java " + lts + "LTS")
+  case 9                       => fail("Your Java installation is unsupported and has known issues. Please upgrade to Java " + lts + "LTS")
+  case x if x < lts            => println("Consider upgrading to Java " + lts + " LTS"); true
+  case x if x > lts && x < dev => println("Consider upgrading to Java " + dev); true
+  case x if x > dev            => println("Unsupported early access version. Consider switching back to Java " + dev); true
+  case _                       => true
+}
+
+javacOptions ++= Seq("-source", javaVersionString, "-target", javaVersionString, "-encoding", "utf8", "-Xlint:unchecked", "-Xlint:deprecation")
+javacOptions in doc := Seq("-source", javaVersionString) 
+
+enablePlugins(JShellPlugin)
+
+compileOrder := CompileOrder.JavaThenScala
+
+// Enables publishing to maven repo
+publishMavenStyle := true
+
+// Do not append Scala versions to the generated artifacts
+crossPaths := false
+
+// This forbids including Scala related libraries into the dependency
+autoScalaLibrary := false
+
+assemblyMergeStrategy in assembly := {
+  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
+  case _ => MergeStrategy.first
+}
+
+// contains libraries provided by utu/ft dep
+resolvers += "ftdev" at "https://ftdev.utu.fi/maven2"
+
+fork in Global := true
+
+val javaVersion = taskKey[Unit]("Prints the Java version.")
+
+javaVersion := { println("SBT uses Java SDK located at "+System.getProperty("java.home")) }
+
+publishTo := Some(Resolver.file("file", new File("/tmp/repository")))
+
+val oomkit = "fi.utu.tech" % "oomkit" % "1.15"
+
+libraryDependencies ++= Seq()
+
+////
+//// JQWIK / JUNIT configuration
+////
+
+resolvers in ThisBuild += Resolver.jcenterRepo
+
+val junit_version = "5.5.2"
+
+// library dependencies. (orginization name) % (project name) % (version)
+libraryDependencies ++= Seq(
+  "net.aichler"        % "jupiter-interface"              % JupiterKeys.jupiterVersion.value % Test,
+  "org.junit.platform" % "junit-platform-commons"         % ("1"+junit_version.tail) % Test,
+  "org.junit.platform" % "junit-platform-runner"          % ("1"+junit_version.tail) % Test,
+  "org.junit.jupiter"  % "junit-jupiter-engine"           % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-api"              % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-migrationsupport" % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-params"           % junit_version % Test,
+  "net.jqwik"          % "jqwik"                          % "1.2.0" % Test,
+  "org.scalatest"      %% "scalatest"                     % "3.0.8" % Test,
+)
+
+testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-c")
+
+////
+//// JAVAFX configuration
+////
+
+val javafx_versions = if (!useJavaFX) (0,"-","-") else (force_javaFxVersion getOrElse javaVersionNum) match {
+  case 7 => (7, "7", "8.0.181-R13")
+  case 8 => (8, "8", "8.0.181-R13")
+  case 10 => (11, "11.0.2", "11-R16")
+  case x if x>10 => (13, "13", "12.0.2-R18")
+  case _ => fail("Unsupported Java version for JavaFX")
+}
+
+// JAVA_HOME location
+val javaHomeDir = {
+  val path = try {
+    if (scala.sys.env("JAVA_HOME").trim.isEmpty) throw new Exception("Empty JAVA_HOME") else scala.sys.env("JAVA_HOME")
+  } catch {
+    case _: Throwable => System.getProperty("java.home") // not set -> ask from current JVM
+  }
+
+  val f = file(path)
+  if (!f.exists()) fail("The environment variable JAVA_HOME points to a non-existent directory!\nSolution: Edit your system settings (Windows control panel / *nix .bashrc) and fix the JAVA_HOME location.")
+  f
+}
+
+val osName: SettingKey[String] = SettingKey[String]("osName")
+
+osName := (System.getProperty("os.name") match {
+  case n if n.startsWith("Linux")   => "linux"
+  case n if n.startsWith("Mac")     => "mac"
+  case n if n.startsWith("Windows") => "win"
+  case _ => throw new Exception("Unknown platform!")
+})
+
+def legacyJavaFX() = {
+  val searchDirs = Seq(
+    "/jre/lib/jfxrt.jar",     // OpenJDK 7
+    "/jre/lib/ext/jfxrt.jar", // OpenJDK 8
+    "/lib/ext/jfxrt.jar"      // Windows & Oracle Java 8
+  )
+
+  if (detectedJDK > 8) fail(s"Trying to use legacy non-modular JavaFX with a modern JDK [$detectedJDK].\nSolution: Check the line 'val force_javaFxVersion =' in build.sbt.")
+
+  val javaFxJAR = searchDirs.map{ searchDir => file(javaHomeDir + searchDir) }.find{ _.exists() }
+
+  javaFxJAR.getOrElse {
+    fail(s"Java FX runtime not installed in [${javaHomeDir.toString}]!\nSolution: Install JavaFX or consider upgrading your JDK so that JavaFX can be installed automatically.")
+  }
+}
+
+val jfx_sdk_version = javafx_versions._2
+val jfx_scalafx_version = javafx_versions._3
+
+val javaFxPath = Def.taskKey[File]("OpenJFX fetcher")
+javaFxPath := {
+  val javaFxHome =
+    try {
+      val envHome = file(scala.sys.env("JAVAFX_HOME"))
+      if (envHome.toString.trim.isEmpty) throw new Exception("Empty JAVAFX_HOME")
+      println("Using OpenJFX from " + envHome)
+      envHome
+    }
+    catch { case _: Throwable =>
+        println("Using local OpenJFX")
+        baseDirectory.value / "openjfx"
+    }
+
+  if (!javaFxHome.exists()) java.nio.file.Files.createDirectory(javaFxHome.toPath)
+
+  val jfx_os = osName.value match {
+    case "linux" => "linux"
+    case "mac"   => "osx"
+    case "win"   => "windows"
+  }
+
+  val sdkURL = "http://download2.gluonhq.com/openjfx/" + jfx_sdk_version + "/openjfx-" + jfx_sdk_version + "_" + jfx_os + "-x64_bin-sdk.zip"
+
+  try {
+    val testDir = javaFxHome / "all.ok"
+    if (!testDir.exists()) {
+      println("Fetching OpenJFX from "+sdkURL+"..")
+      IO.unzipURL(new URL(sdkURL), javaFxHome)
+      java.nio.file.Files.createDirectory(testDir.toPath)
+      println("Fetching OpenJFX done.")
+    } else {
+      println("Using OpenJFX from "+javaFxHome)
+    }
+
+    javaFxHome
+  }
+  catch {
+    case t: Throwable => fail("Could not load OpenJFX! Reason:" + t.getMessage)
+  }
+}
+
+val jfxModules = Seq("base","controls","fxml","graphics","media","swing","web")
+
+
+if (!useJavaFX) Seq() else javafx_versions._1 match {
+  case 7 =>
+    // TODO libraryDependencies
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case 8 =>
+    (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" %% "scalafx" % jfx_scalafx_version) else Seq()) ++
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case _ =>
+    Seq(
+      javaOptions in run ++= Seq(
+        "--module-path", (javaFxPath.value / ("javafx-sdk-" + jfx_sdk_version) / "lib").toString,
+        "--add-modules=" + jfxModules.map("javafx."+_).mkString(","))
+    ) ++
+      (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" % "scalafx_2.13" % jfx_scalafx_version) else Seq()) ++
+      jfxModules.map(module => libraryDependencies += "org.openjfx" % ("javafx-"+module) % jfx_sdk_version classifier osName.value)
+}
diff --git a/Project 1/pom.xml b/Project 1/pom.xml
new file mode 100644
index 0000000..40e1bb8
--- /dev/null
+++ b/Project 1/pom.xml	
@@ -0,0 +1,452 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!--
+     
+      Welcome!
+      This pom.xml is *THE* file that defines your Maven style Java project.
+      
+      Eclipse, IDEA and other development environments with Maven support
+      or plugins can *import* this project by reading this file.
+      
+      It usually contains tons of barely readable configuration. Luckily
+      this basic pom.xml is somewhat readable. All necessary configuration
+      for customizing your project if located here on top before the
+      'END OF SIMPLE CONFIGURATION' line below.
+      
+      Some basics:
+      
+        - Maven is a build system for Java/JVM
+        - the Maven projects define an artifact that has a three part id:
+          groupId - artifactId - version
+          
+        - For example, this project is called:
+          fi.utu.tech - oomkit - 1.15
+          
+        - The group id is usually a web domain in reverse order.
+          
+        - You can use these id parts to search for projects at
+          https://search.maven.org/
+          
+        - If your version is not final and you have plans to modify the
+          source code at some point, please use a version id that ends with
+          -SNAPSHOT, e.g 1.0-SNAPSHOT. Maven may cache the project jar
+          and refuse to overwrite old cached versions with new ones unless
+          you remember this convention.
+          
+        - This file supports
+          compiling the project with      'mvn compile' (see target/)
+          cleaning the class files with   'mvn clean'
+          executing the main routine with 'mvn exec:java'
+          executing the unit tests with   'mvn test'
+          packaging the application with  'mvn package' (see target/)
+          
+        - the Maven project structure is as follows:
+          https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
+          
+    -->
+    
+    <!-- ==== START OF SIMPLE CONFIGURATION ==== -->
+    
+    <!-- the three parts of the artifact name -->
+    <groupId>fi.utu.tech</groupId>
+    <artifactId>template-javafx</artifactId>
+    <version>1.0</version>
+    
+    <!-- additional information about the project -->
+    <name>JavaFX project template</name>
+    <url>https://gitlab.utu.fi/tech/education/gui/template-javafx</url>
+    
+    <packaging>jar</packaging>
+
+    <!-- HINT: More configuration here! -->
+    <properties>
+        <!-- Configures this project to use 'fi.utu.tech.AppMain' as its main class -->
+        <project.mainclass>fi.utu.tech.gui.javafx.Main</project.mainclass>
+        
+        
+        <!-- Don't touch these unless you know what you're doing!
+        
+             For example, the source encoding should always be utf-8.
+             You're probably doing something stupid if you think it
+             should be a 8-bit code page in 2019. -->
+        <jdk.version>11</jdk.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jqwik.version>1.2.0</jqwik.version>
+        <junit.version>5.5.2</junit.version>
+        <junitplatform.version>1.5.2</junitplatform.version>
+        <javafx.version>13</javafx.version>
+    </properties>
+
+    <!-- ==== END OF SIMPLE CONFIGURATION ==== -->
+    
+    <repositories>
+        <repository>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <id>central</id>
+            <name>Central Repository</name>
+            <url>https://repo.maven.apache.org/maven2</url>
+        </repository>
+        <repository>
+            <id>jcenter</id>
+            <name>jcenter</name>
+            <url>https://jcenter.bintray.com/</url>
+        </repository>
+        <!-- UTU repository -->
+        <repository>
+            <id>ftdev</id>
+            <name>ftdev</name>
+            <url>https://ftdev.utu.fi/maven2</url>
+        </repository>
+    </repositories>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-commons</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.jqwik</groupId>
+            <artifactId>jqwik</artifactId>
+            <version>${jqwik.version}</version>
+            <scope>test</scope>
+        </dependency><!--
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-migrationsupport</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-runner</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency> -->
+        
+        <!-- JavaFX (remove if not needed to speed up dep downloads)-->
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-base</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-fxml</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-graphics</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-media</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-swing</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-web</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- Make a 'fat' jar, that is, jar that contains all its dependencies and runs as is.
+                 See: https://stackoverflow.com/a/57691362 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>module-info.class</exclude>
+                                        <exclude>META-INF/*.SF</exclude>
+                                        <exclude>META-INF/*.DSA</exclude>
+                                        <exclude>META-INF/*.RSA</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>${project.mainclass}</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Run this app with exec:java -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.6.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                    <arguments>
+                        <argument>arg1</argument>
+                        <argument>arg2</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+
+            <!-- Make the packaged jar executable -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.1.2</version>
+                <configuration>
+                    <!-- DO NOT include log4j.properties file in your Jar -->
+                    <excludes>
+                        <exclude>**/log4j.properties</exclude>
+                    </excludes>
+                    <archive>
+                        <manifest>
+                            <!-- Jar file entry point -->
+                            <mainClass>${project.mainclass}</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <!-- download source code in Eclipse, best practice -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-eclipse-plugin</artifactId>
+                <version>2.10</version>
+                <configuration>
+                    <downloadSources>true</downloadSources>
+                    <downloadJavadocs>false</downloadJavadocs>
+                </configuration>
+            </plugin>
+
+            <!-- JDK source/target versions -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${jdk.version}</source>
+                    <target>${jdk.version}</target>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>3.1.1</version>
+                <executions>
+                    <execution>
+                    <id>attach-javadocs</id>
+                    <goals>
+                        <goal>jar</goal>
+                    </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <tags>
+                        <tag>
+                            <name>toDo</name>
+                            <placement>a</placement>
+                            <head>To&nbsp;do:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariant</name>
+                            <placement>t</placement>
+                            <head>Class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantProtected</name>
+                            <placement>t</placement>
+                            <head>Protected&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantPrivate</name>
+                            <placement>t</placement>
+                            <head>Private&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>abstractionFunction</name>
+                            <placement>t</placement>
+                            <head>Abstraction&nbsp;function:</head>
+                        </tag>
+                        <tag>
+                            <name>pre</name>
+                            <placement>cm</placement>
+                            <head>Precondition:</head>
+                        </tag>
+                        <tag>
+                            <name>post</name>
+                            <placement>cm</placement>
+                            <head>Postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postProtected</name>
+                            <placement>cm</placement>
+                            <head>Protected&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postPrivate</name>
+                            <placement>cm</placement>
+                            <head>Private&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>time</name>
+                            <placement>cmf</placement>
+                            <head>Time&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>space</name>
+                            <placement>cmf</placement>
+                            <head>Space&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>correspondence</name>
+                            <placement>a</placement>
+                            <head>Correspondence:</head>
+                        </tag>
+                        <tag>
+                            <name>download</name>
+                            <placement>a</placement>
+                            <head>Download:</head>
+                        </tag>
+                    </tags>
+                    <show>protected</show>
+                    <failOnError>false</failOnError>
+                    <sourceFileExcludes>
+                        <sourceFileExclude>**/module-info.java</sourceFileExclude>
+                    </sourceFileExcludes>
+                </configuration>
+            </plugin>
+
+            <!-- JUnit & JQwik test integration -->
+
+            <!-- junit-platform-maven-plugin: supports modular tests
+                 maven-surefire-plugin: non-modular tests
+
+                 Modular testing works via command line mvn, but is
+                 still broken in Eclipse due to this
+                 https://bugs.eclipse.org/bugs/show_bug.cgi?id=520667
+              -->
+            <plugin>
+                <groupId>de.sormuras.junit</groupId>
+                <artifactId>junit-platform-maven-plugin</artifactId>
+                <version>1.0.0-M5</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <executor>JAVA</executor>
+                </configuration>
+            </plugin>
+
+            <!--
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin> -->
+
+            <!-- javafx:jlink:
+                 https://github.com/openjfx/javafx-maven-plugin
+                 Use 'mvn package' instead if you don't need jlink.
+
+            <plugin>
+                <groupId>org.openjfx</groupId>
+                <artifactId>javafx-maven-plugin</artifactId>
+                <version>0.0.3</version>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                </configuration>
+            </plugin> -->
+
+        </plugins>
+        <extensions>
+            <!-- Enables the use of SSH for deployments -->
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh-external</artifactId>
+                <version>3.3.3</version>
+            </extension>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh</artifactId>
+                <version>3.3.3</version>
+            </extension>
+        </extensions>
+    </build>
+    <distributionManagement>
+        <repository>
+            <id>ftdev</id>
+            <name>UTU tech ftdev repository</name>
+            <url>scp://localhost:2222/var/www/maven2</url>
+        </repository>
+    </distributionManagement>
+</project>
diff --git a/Project 1/project/build.properties b/Project 1/project/build.properties
new file mode 100644
index 0000000..6adcdc7
--- /dev/null
+++ b/Project 1/project/build.properties	
@@ -0,0 +1 @@
+sbt.version=1.3.3
diff --git a/Project 1/project/plugins.sbt b/Project 1/project/plugins.sbt
new file mode 100644
index 0000000..37ca261
--- /dev/null
+++ b/Project 1/project/plugins.sbt	
@@ -0,0 +1,7 @@
+resolvers += Resolver.jcenterRepo
+
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
+addSbtPlugin("net.aichler" % "sbt-jupiter-interface" % "0.8.3")
+addSbtPlugin("com.github.xuwei-k" % "sbt-jshell" % "0.1.2")
+//addSbtPlugin("org.xerial.sbt" % "sbt-sql-sqlite" % "0.8")
+addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.4.0")
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
new file mode 100644
index 0000000..a4d0180
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java	
@@ -0,0 +1,13 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.scene.control.Alert;
+
+public class Dialogs {
+    public static void warning(String title, String header, String content) {
+        Alert alert = new Alert(Alert.AlertType.WARNING);
+        alert.setTitle(title);
+        alert.setHeaderText(header);
+        alert.setContentText(content);
+        alert.showAndWait();
+    }
+}
\ No newline at end of file
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java
new file mode 100644
index 0000000..7777d66
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java	
@@ -0,0 +1,63 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Platform;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+import java.util.function.Supplier;
+
+public class FXMLController {
+    private IntegerProperty clicks = new SimpleIntegerProperty(0);
+
+    private Supplier<Parent> supplier;
+
+    @FXML
+    private Label clicksLabel;
+
+    protected void updateClicks() {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.textProperty().bind(clicks.asString().concat(" clicks."));
+
+        clicks.setValue(clicks.getValue() + 1);
+    }
+
+    protected void setLabel(String text) {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.setText(text);
+    }
+
+    @FXML
+    protected void handleDialogButton(ActionEvent event) {
+        updateClicks();
+        Dialogs.warning("Example dialog", "Content header", "Content");
+    }
+
+    @FXML
+    protected void handleExitButton(ActionEvent event) {
+        System.out.println("Closing app.");
+        Platform.exit();
+    }
+
+    @FXML
+    protected void handleWindowButton(ActionEvent event) {
+        updateClicks();
+        Scene other = new Scene(supplier.get());
+        Stage otherStage = new Stage();
+        otherStage.setScene(other);
+        otherStage.show();
+    }
+
+    protected void setWindowFactory(Supplier<Parent> supplier) {
+        this.supplier = supplier;
+    }
+
+    public void initialize() {
+        System.out.println("2-A");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController2.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController2.java
new file mode 100644
index 0000000..11ce009
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/FXMLController2.java	
@@ -0,0 +1,83 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Platform;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+import java.util.function.Supplier;
+
+public class FXMLController2 {
+    private IntegerProperty clicks = new SimpleIntegerProperty(0);
+
+    private Supplier<Parent> supplier;
+    private Parent parent;
+    private int ikkunoita_avattu = 0;
+    private Scene other;
+    private Stage otherStage;
+
+
+    private Label clicksLabel;
+
+    protected void updateClicks() {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.textProperty().bind(clicks.asString().concat(" clicks."));
+
+        clicks.setValue(clicks.getValue() + 1);
+    }
+
+    protected void setLabel(Label l) {clicksLabel = l;}
+    
+    
+    protected void setLabel(String text) {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.setText(text);
+    }
+
+    protected void handleDialogButton(ActionEvent event) {
+        updateClicks();
+        Dialogs.warning("Example dialog", "Content header", "Content");
+    }
+
+
+    protected void handleExitButton(ActionEvent event) {
+        System.out.println("Closing app.");
+        Platform.exit();
+    }
+
+    protected void handleWindowButton(ActionEvent event) {
+    	if(ikkunoita_avattu < 1) {
+    		setLabel("Welcome!");
+    		updateClicks();
+        	ResourceLoader<Parent, FXMLController2> loader = new ResourceLoader<>("otherwindow.fxml");
+    		other = new Scene(loader.root);
+    		otherStage = new Stage();
+    		otherStage.setScene(other);
+    		otherStage.show();
+    		System.out.println("Uusi ikkuna avattu");
+    		ikkunoita_avattu += 1;
+    	}
+    	else if(otherStage.isShowing()){
+    		otherStage.hide();
+    	}
+    	else if (!otherStage.isShowing() || !otherStage.isFocused()) {
+    		otherStage.show();
+    		otherStage.toFront();
+    	}
+    }
+
+    protected void setWindowFactory(Supplier<Parent> supplier) {
+        this.supplier = supplier;
+    }
+    
+    protected void setParent(Parent p) {parent = p;System.out.println(parent + " parent asetettu");}
+
+    public void initialize() {
+        System.out.println("2-A");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/Main.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Main.java
new file mode 100644
index 0000000..f3f3688
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Main.java	
@@ -0,0 +1,29 @@
+package fi.utu.tech.gui.javafx;
+
+public class Main {
+    /**
+     * The main() method is ignored in correctly deployed JavaFX application.
+     * main() serves only as fallback in case the application can not be
+     * launched through deployment artifacts, e.g., in IDEs with limited FX
+     * support. NetBeans ignores main().
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        System.out.println("Stage A");
+        if (args.length == 1 && args[0].equals("--test")) return;
+
+        int exercise = 1;
+        if (args.length == 1) exercise = Integer.parseInt(args[0]);
+        switch(exercise) {
+            case 1:
+            case 2:
+            case 3:
+            case 4: MainApp.launch(MainApp4.class, args); break;
+            case 5: MainApp.launch(MainApp5.class, args); break;
+            case 10: MainApp.launch(MainApp10.class, args); break;
+            default: MainApp.launch(MainApp.class, args); break;
+        }
+    }
+
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
new file mode 100644
index 0000000..6dc8ba3
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new OtherWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp10.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp10.java
new file mode 100644
index 0000000..3875e03
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp10.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp10 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new OtherWindow10();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java
new file mode 100644
index 0000000..3833d30
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp4 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new OtherWindow4();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java
new file mode 100644
index 0000000..921f7d7
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java	
@@ -0,0 +1,62 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp5 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new Teht_5_ikkuna();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        
+        //Teht_5_ikkuna loader = new Teht_5_ikkuna();
+        
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java
new file mode 100644
index 0000000..3f64448
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java	
@@ -0,0 +1,47 @@
+package fi.utu.tech.gui.javafx;
+
+import java.io.IOException;
+
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.layout.StackPane; 
+
+
+public class OtherWindow extends BorderPane {
+    public OtherWindow() {
+        Circle c = new Circle(200, Color.NAVY);
+        setLeft(new ImageView(ResourceLoader.image("hmm.png")));
+        
+        Label terve = new Label("Terve");
+        setAlignment(terve,Pos.CENTER);
+        setTop(terve);
+        
+        Label maailma = new Label("Maailma");
+        
+        StackPane stackPane = new StackPane();
+        stackPane.getChildren().addAll(c, maailma);
+        setCenter(stackPane);
+        
+        TextField textField1 = new TextField();
+        TextField textField2 = new TextField();
+        TextField textField3 = new TextField();
+        HBox hBox = new HBox(textField1,textField2,textField3);
+        setBottom(hBox);
+        
+        
+        
+        
+        
+        
+        
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow10.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow10.java
new file mode 100644
index 0000000..158757f
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow10.java	
@@ -0,0 +1,48 @@
+package fi.utu.tech.gui.javafx;
+
+import java.io.IOException;
+
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.layout.StackPane; 
+
+
+public class OtherWindow10 extends BorderPane {
+    public OtherWindow10() {
+        Circle c = new Circle(200, Color.NAVY);
+        setLeft(new ImageView(ResourceLoader.image("hmm.png")));
+        
+        Label terve = new Label("Terve");
+        setAlignment(terve,Pos.CENTER);
+        setTop(terve);
+        
+        Label maailma = new Label("Maailma");
+        
+        StackPane stackPane = new StackPane();
+        stackPane.getChildren().addAll(c, maailma);
+        setCenter(stackPane);
+        
+        TextField textField1 = new TextField();
+        TextField textField2 = new TextField();
+        TextField textField3 = new TextField();
+        HBox hBox = new HBox(textField1,textField2,textField3);
+        setBottom(hBox);
+        
+        
+        textField1.textProperty().bindBidirectional(textField2.textProperty());
+        textField2.textProperty().bindBidirectional(textField3.textProperty());
+        
+        
+        
+        
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow4.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow4.java
new file mode 100644
index 0000000..58a71d1
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/OtherWindow4.java	
@@ -0,0 +1,50 @@
+package fi.utu.tech.gui.javafx;
+
+import java.io.IOException;
+
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.layout.StackPane; 
+
+
+public class OtherWindow4 extends BorderPane {
+    public OtherWindow4() {
+    	
+    	getStylesheets().add(getClass().getResource("styles2.css").toExternalForm());
+    	
+        Circle c = new Circle(200, Color.NAVY);
+        setLeft(new ImageView(ResourceLoader.image("hmm.png")));
+        
+        Label terve = new Label("Terve");
+        setAlignment(terve,Pos.CENTER);
+        setTop(terve);
+        
+        Label maailma = new Label("Maailma");
+        
+        StackPane stackPane = new StackPane();
+        stackPane.getChildren().addAll(c, maailma);
+        setCenter(stackPane);
+        
+        TextField textField1 = new TextField();
+        TextField textField2 = new TextField();
+        TextField textField3 = new TextField();
+        HBox hBox = new HBox(textField1,textField2,textField3);
+        setBottom(hBox);
+        
+        
+        
+        
+        
+        
+        
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
new file mode 100644
index 0000000..f917bd3
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java	
@@ -0,0 +1,42 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+
+public class ResourceLoader<N extends Parent, C> {
+    protected final N root;
+    protected final C controller;
+
+    public ResourceLoader(String contentPath) {
+        N root_ = null;
+        C controller_ = null;
+        try {
+            // determines where to look for the resources (the root path)
+            Class resourceRootClass = getClass();
+
+            FXMLLoader loader = new FXMLLoader(resourceRootClass.getResource(contentPath));
+            root_ = loader.load();
+            controller_ = loader.getController();
+            System.out.println("DEBUG: " + contentPath + " loaded.");
+        } catch (Exception e) {
+            Dialogs.warning(
+                    "Internal error",
+                    "Could not open FXML file: " + contentPath,
+                    "Reason: " + e.getMessage()
+            );
+            System.exit(1);
+        }
+        root = root_;
+        controller = controller_;
+    }
+
+    // finds images both outside and inside jars
+    public static String image(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+    
+    // finds stylesheets both outside and inside jars
+    public static String stylesheet(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+}
diff --git a/Project 1/src/main/java/fi/utu/tech/gui/javafx/Teht_5_ikkuna.java b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Teht_5_ikkuna.java
new file mode 100644
index 0000000..30402f3
--- /dev/null
+++ b/Project 1/src/main/java/fi/utu/tech/gui/javafx/Teht_5_ikkuna.java	
@@ -0,0 +1,80 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.VBox;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.text.Font;
+
+public class Teht_5_ikkuna extends BorderPane{
+	
+	Label label2;
+
+	public Teht_5_ikkuna(){
+		
+		setLeft(new ImageView(ResourceLoader.image("hmm.png")));
+		
+		FXMLController2 ctrl = new FXMLController2();
+		BorderPane bp = new BorderPane();
+		setAlignment(bp, Pos.CENTER);
+		bp.setPadding(new Insets(16, 16, 16, 16));
+		//setPrefHeight(bp);
+		//setMargin(bp, new Insets(16.0, 16.0, 16.0, 16.0));
+		bp.setTop(new Label("What should we do?"));
+		Button button1 = new Button("Open a new window");
+		Button button2 = new Button("Display Dialog");
+		Button button3 = new Button("Exit");
+		Label label1 = new Label("Loading...");
+		
+		ctrl.setLabel(label1);
+		label2 = new Label("Welcome!");
+		
+		EventHandler<ActionEvent> event = new EventHandler<ActionEvent>() { 
+            public void handle(ActionEvent e) 
+            { 
+                ctrl.handleWindowButton(e);
+           } 
+        }; 
+        EventHandler<ActionEvent> event2 = new EventHandler<ActionEvent>() { 
+            public void handle(ActionEvent e) 
+            { 
+                ctrl.handleDialogButton(e);
+           } 
+        }; 
+        EventHandler<ActionEvent> event3 = new EventHandler<ActionEvent>() { 
+            public void handle(ActionEvent e) 
+            { 
+                ctrl.handleExitButton(e);
+           } 
+        }; 
+        button1.setOnAction(event);
+        button2.setOnAction(event2);
+        button3.setOnAction(event3);
+        
+        button1.setPadding(new Insets(5, 110, 5, 110));
+        button2.setPadding(new Insets(5, 122, 5, 122));
+        button3.setPadding(new Insets(5, 154, 5, 154));
+        
+		VBox vbox = new VBox(button1, button2, button3, label1);
+		vbox.setAlignment(Pos.CENTER);
+		vbox.setPadding(new Insets(16, 16, 16, 16));
+		
+		Label otsikko = new Label("What should we do?");
+		bp.setTop(otsikko);
+		bp.setAlignment(otsikko, Pos.CENTER);
+		bp.setMargin(otsikko,new Insets(15, 0, 15, 0));
+		otsikko.setFont(new Font(28));
+		
+		bp.setCenter(vbox);
+		setAlignment(bp ,Pos.CENTER);
+		bp.setMargin(vbox,new Insets(5, 40, 5, 40));
+	
+		setCenter(bp);
+	}
+	
+}
\ No newline at end of file
diff --git a/Project 1/src/main/resources/fi/utu/tech/gui/javafx/hmm.png b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
new file mode 100644
index 0000000000000000000000000000000000000000..25e8eb650f6752e716570cfb3c590bf09dff41ee
GIT binary patch
literal 9965
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

literal 0
HcmV?d00001

diff --git a/Project 1/src/main/resources/fi/utu/tech/gui/javafx/otherwindow.fxml b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/otherwindow.fxml
new file mode 100644
index 0000000..cfaf34b
--- /dev/null
+++ b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/otherwindow.fxml	
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.shape.Circle?>
+
+
+<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="550.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fi.utu.tech.gui.javafx.FXMLController2">
+   <left>
+      <ImageView fitHeight="379.0" fitWidth="163.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@hmm.png" />
+         </image>
+         <BorderPane.margin>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </BorderPane.margin>
+      </ImageView>
+   </left>
+   <top>
+      <Label text="Terve" BorderPane.alignment="CENTER" />
+   </top>
+   <center>
+      <StackPane prefHeight="358.0" prefWidth="388.0" BorderPane.alignment="CENTER">
+         <children>
+            <Circle fill="#0e166f" radius="178.0" smooth="false" stroke="BLACK" strokeType="INSIDE" />
+            <Label text="Maailma" />
+         </children>
+      </StackPane>
+   </center>
+   <bottom>
+      <HBox alignment="BOTTOM_RIGHT" prefHeight="14.0" prefWidth="600.0" BorderPane.alignment="CENTER">
+         <children>
+            <TextField prefHeight="25.0" prefWidth="103.0" />
+            <TextField prefHeight="25.0" prefWidth="108.0" />
+            <TextField prefHeight="25.0" prefWidth="113.0" />
+         </children>
+      </HBox>
+   </bottom>
+</BorderPane>
diff --git a/Project 1/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml
new file mode 100644
index 0000000..434e233
--- /dev/null
+++ b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml	
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fi.utu.tech.gui.javafx.FXMLController">
+   <left>
+      <ImageView fitHeight="368.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@hmm.png" />
+         </image>
+         <BorderPane.margin>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </BorderPane.margin>
+      </ImageView>
+   </left>
+   <center>
+      <BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
+         <padding>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </padding>
+         <center>
+            <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="16.0" BorderPane.alignment="CENTER">
+               <padding>
+                  <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+               </padding>
+               <children>
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleWindowButton" text="Open a new window" />
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleDialogButton" text="Display a dialog" />
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleExitButton" text="Exit" />
+                  <Label fx:id="clicksLabel" text="Loading..." />
+               </children></VBox>
+         </center>
+         <top>
+            <Label text="What should we do?" BorderPane.alignment="CENTER">
+               <font>
+                  <Font size="26.0" />
+               </font></Label>
+         </top>
+      </BorderPane>
+   </center>
+</BorderPane>
diff --git a/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles.css b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles.css
new file mode 100644
index 0000000..3ab643a
--- /dev/null
+++ b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles.css	
@@ -0,0 +1,3 @@
+.button {
+    -fx-font-weight: bold;
+}
diff --git a/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles2.css b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles2.css
new file mode 100644
index 0000000..6444aaf
--- /dev/null
+++ b/Project 1/src/main/resources/fi/utu/tech/gui/javafx/styles2.css	
@@ -0,0 +1,7 @@
+.root {
+	-fx-font-weight: bold;
+	-fx-background-color: black;
+}
+.root .label {
+	-fx-text-fill: white;
+}
diff --git a/Project 2/.gitignore b/Project 2/.gitignore
new file mode 100644
index 0000000..2b18655
--- /dev/null
+++ b/Project 2/.gitignore	
@@ -0,0 +1,21 @@
+bin/
+contracts/
+.classpath
+.project
+.history/
+.idea
+.jqwik-database
+.lib/
+.worksheet
+.settings/
+*.iml
+*.ipr
+*.iws
+*.log
+project/boot/
+project/plugins/project/
+project/project/
+project/*-shim.sbt
+project/target/
+target/
+openjfx/
diff --git a/Project 2/.gitlab-ci.yml b/Project 2/.gitlab-ci.yml
new file mode 100644
index 0000000..4b3553b
--- /dev/null
+++ b/Project 2/.gitlab-ci.yml	
@@ -0,0 +1,13 @@
+image: maven:latest
+
+stages:
+  - build
+  - test
+
+build:
+  script:
+    - mvn compile
+
+test:
+  script:
+    - mvn test
\ No newline at end of file
diff --git a/Project 2/README.md b/Project 2/README.md
new file mode 100644
index 0000000..2907fd1
--- /dev/null
+++ b/Project 2/README.md	
@@ -0,0 +1,39 @@
+# Project description
+
+Simple template for projects that make use of JavaFX and FXML (Scene Builder).
+Requires Java 11 or later. Compatible with
+Eclipse and IntelliJ IDEA. Minor issues with Netbeans. Automatically
+integrates with Gitlab CI.
+
+## Installation
+
+Maven:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ mvn compile exec:java
+```
+
+SBT:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ sbt compile run
+```
+
+## Further instructions
+
+  * Java platform: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/jvm-platform
+  * Maven: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/maven-misc
+  * SBT: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/sbt-misc
+  
+External sources:
+
+  * JavaFX: https://openjfx.io/javadoc/11/
+  * Scene Builder: https://docs.gluonhq.com/scenebuilder/
diff --git a/Project 2/build.sbt b/Project 2/build.sbt
new file mode 100644
index 0000000..e703e90
--- /dev/null
+++ b/Project 2/build.sbt	
@@ -0,0 +1,236 @@
+// Project template
+
+// Supported operating systems: Windows, Mac, Linux
+// Supported JDKs: 8, 10+
+
+// Project name
+name := "template-javafx"
+
+// organization name
+organization := "fi.utu.tech"
+
+version := "1.0"
+
+// project description
+description := "JavaFX project template"
+
+// main class
+Compile/mainClass := Some("fi.utu.tech.gui.javafx.Main")
+
+// force the java version by typing it here (remove the comment)
+val force_javaVersion = None // Some(13)
+
+// force the javafx version by typing it here (remove the comment)
+val force_javaFxVersion = None // Some(13)
+
+val useJavaFX = true
+
+val useScalaOrScalaFX = true
+
+// END_OF_SIMPLE_CONFIGURATION
+// you can copy the rest for each new project
+// --- --- ---
+
+def fail(msg: String) = {
+  println("Error :-/")
+  println
+  println(msg)
+  System.exit(1)
+  null
+}
+
+val detectedJDK = System.getProperty("java.version").replace("-ea","").split('.').dropWhile(_.toInt<8).head.toInt
+
+val javaVersionNum = force_javaVersion.getOrElse(detectedJDK)
+
+val javaVersionString = javaVersionNum match {
+  case 7 => "1.7"
+  case 8 => "1.8"
+  case x if x > 8 => x.toString
+}
+
+val lts = 11
+val dev = 13
+
+val supported = javaVersionNum match {
+  case x if x < 8              => fail("Your Java installation is obsolete. Please upgrade to Java " + lts + "LTS")
+  case 9                       => fail("Your Java installation is unsupported and has known issues. Please upgrade to Java " + lts + "LTS")
+  case x if x < lts            => println("Consider upgrading to Java " + lts + " LTS"); true
+  case x if x > lts && x < dev => println("Consider upgrading to Java " + dev); true
+  case x if x > dev            => println("Unsupported early access version. Consider switching back to Java " + dev); true
+  case _                       => true
+}
+
+javacOptions ++= Seq("-source", javaVersionString, "-target", javaVersionString, "-encoding", "utf8", "-Xlint:unchecked", "-Xlint:deprecation")
+javacOptions in doc := Seq("-source", javaVersionString) 
+
+enablePlugins(JShellPlugin)
+
+compileOrder := CompileOrder.JavaThenScala
+
+// Enables publishing to maven repo
+publishMavenStyle := true
+
+// Do not append Scala versions to the generated artifacts
+crossPaths := false
+
+// This forbids including Scala related libraries into the dependency
+autoScalaLibrary := false
+
+assemblyMergeStrategy in assembly := {
+  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
+  case _ => MergeStrategy.first
+}
+
+// contains libraries provided by utu/ft dep
+resolvers += "ftdev" at "https://ftdev.utu.fi/maven2"
+
+fork in Global := true
+
+val javaVersion = taskKey[Unit]("Prints the Java version.")
+
+javaVersion := { println("SBT uses Java SDK located at "+System.getProperty("java.home")) }
+
+publishTo := Some(Resolver.file("file", new File("/tmp/repository")))
+
+val oomkit = "fi.utu.tech" % "oomkit" % "1.15"
+
+libraryDependencies ++= Seq()
+
+////
+//// JQWIK / JUNIT configuration
+////
+
+resolvers in ThisBuild += Resolver.jcenterRepo
+
+val junit_version = "5.5.2"
+
+// library dependencies. (orginization name) % (project name) % (version)
+libraryDependencies ++= Seq(
+  "net.aichler"        % "jupiter-interface"              % JupiterKeys.jupiterVersion.value % Test,
+  "org.junit.platform" % "junit-platform-commons"         % ("1"+junit_version.tail) % Test,
+  "org.junit.platform" % "junit-platform-runner"          % ("1"+junit_version.tail) % Test,
+  "org.junit.jupiter"  % "junit-jupiter-engine"           % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-api"              % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-migrationsupport" % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-params"           % junit_version % Test,
+  "net.jqwik"          % "jqwik"                          % "1.2.0" % Test,
+  "org.scalatest"      %% "scalatest"                     % "3.0.8" % Test,
+)
+
+testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-c")
+
+////
+//// JAVAFX configuration
+////
+
+val javafx_versions = if (!useJavaFX) (0,"-","-") else (force_javaFxVersion getOrElse javaVersionNum) match {
+  case 7 => (7, "7", "8.0.181-R13")
+  case 8 => (8, "8", "8.0.181-R13")
+  case 10 => (11, "11.0.2", "11-R16")
+  case x if x>10 => (13, "13", "12.0.2-R18")
+  case _ => fail("Unsupported Java version for JavaFX")
+}
+
+// JAVA_HOME location
+val javaHomeDir = {
+  val path = try {
+    if (scala.sys.env("JAVA_HOME").trim.isEmpty) throw new Exception("Empty JAVA_HOME") else scala.sys.env("JAVA_HOME")
+  } catch {
+    case _: Throwable => System.getProperty("java.home") // not set -> ask from current JVM
+  }
+
+  val f = file(path)
+  if (!f.exists()) fail("The environment variable JAVA_HOME points to a non-existent directory!\nSolution: Edit your system settings (Windows control panel / *nix .bashrc) and fix the JAVA_HOME location.")
+  f
+}
+
+val osName: SettingKey[String] = SettingKey[String]("osName")
+
+osName := (System.getProperty("os.name") match {
+  case n if n.startsWith("Linux")   => "linux"
+  case n if n.startsWith("Mac")     => "mac"
+  case n if n.startsWith("Windows") => "win"
+  case _ => throw new Exception("Unknown platform!")
+})
+
+def legacyJavaFX() = {
+  val searchDirs = Seq(
+    "/jre/lib/jfxrt.jar",     // OpenJDK 7
+    "/jre/lib/ext/jfxrt.jar", // OpenJDK 8
+    "/lib/ext/jfxrt.jar"      // Windows & Oracle Java 8
+  )
+
+  if (detectedJDK > 8) fail(s"Trying to use legacy non-modular JavaFX with a modern JDK [$detectedJDK].\nSolution: Check the line 'val force_javaFxVersion =' in build.sbt.")
+
+  val javaFxJAR = searchDirs.map{ searchDir => file(javaHomeDir + searchDir) }.find{ _.exists() }
+
+  javaFxJAR.getOrElse {
+    fail(s"Java FX runtime not installed in [${javaHomeDir.toString}]!\nSolution: Install JavaFX or consider upgrading your JDK so that JavaFX can be installed automatically.")
+  }
+}
+
+val jfx_sdk_version = javafx_versions._2
+val jfx_scalafx_version = javafx_versions._3
+
+val javaFxPath = Def.taskKey[File]("OpenJFX fetcher")
+javaFxPath := {
+  val javaFxHome =
+    try {
+      val envHome = file(scala.sys.env("JAVAFX_HOME"))
+      if (envHome.toString.trim.isEmpty) throw new Exception("Empty JAVAFX_HOME")
+      println("Using OpenJFX from " + envHome)
+      envHome
+    }
+    catch { case _: Throwable =>
+        println("Using local OpenJFX")
+        baseDirectory.value / "openjfx"
+    }
+
+  if (!javaFxHome.exists()) java.nio.file.Files.createDirectory(javaFxHome.toPath)
+
+  val jfx_os = osName.value match {
+    case "linux" => "linux"
+    case "mac"   => "osx"
+    case "win"   => "windows"
+  }
+
+  val sdkURL = "http://download2.gluonhq.com/openjfx/" + jfx_sdk_version + "/openjfx-" + jfx_sdk_version + "_" + jfx_os + "-x64_bin-sdk.zip"
+
+  try {
+    val testDir = javaFxHome / "all.ok"
+    if (!testDir.exists()) {
+      println("Fetching OpenJFX from "+sdkURL+"..")
+      IO.unzipURL(new URL(sdkURL), javaFxHome)
+      java.nio.file.Files.createDirectory(testDir.toPath)
+      println("Fetching OpenJFX done.")
+    } else {
+      println("Using OpenJFX from "+javaFxHome)
+    }
+
+    javaFxHome
+  }
+  catch {
+    case t: Throwable => fail("Could not load OpenJFX! Reason:" + t.getMessage)
+  }
+}
+
+val jfxModules = Seq("base","controls","fxml","graphics","media","swing","web")
+
+
+if (!useJavaFX) Seq() else javafx_versions._1 match {
+  case 7 =>
+    // TODO libraryDependencies
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case 8 =>
+    (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" %% "scalafx" % jfx_scalafx_version) else Seq()) ++
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case _ =>
+    Seq(
+      javaOptions in run ++= Seq(
+        "--module-path", (javaFxPath.value / ("javafx-sdk-" + jfx_sdk_version) / "lib").toString,
+        "--add-modules=" + jfxModules.map("javafx."+_).mkString(","))
+    ) ++
+      (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" % "scalafx_2.13" % jfx_scalafx_version) else Seq()) ++
+      jfxModules.map(module => libraryDependencies += "org.openjfx" % ("javafx-"+module) % jfx_sdk_version classifier osName.value)
+}
diff --git a/Project 2/pom.xml b/Project 2/pom.xml
new file mode 100644
index 0000000..40e1bb8
--- /dev/null
+++ b/Project 2/pom.xml	
@@ -0,0 +1,452 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!--
+     
+      Welcome!
+      This pom.xml is *THE* file that defines your Maven style Java project.
+      
+      Eclipse, IDEA and other development environments with Maven support
+      or plugins can *import* this project by reading this file.
+      
+      It usually contains tons of barely readable configuration. Luckily
+      this basic pom.xml is somewhat readable. All necessary configuration
+      for customizing your project if located here on top before the
+      'END OF SIMPLE CONFIGURATION' line below.
+      
+      Some basics:
+      
+        - Maven is a build system for Java/JVM
+        - the Maven projects define an artifact that has a three part id:
+          groupId - artifactId - version
+          
+        - For example, this project is called:
+          fi.utu.tech - oomkit - 1.15
+          
+        - The group id is usually a web domain in reverse order.
+          
+        - You can use these id parts to search for projects at
+          https://search.maven.org/
+          
+        - If your version is not final and you have plans to modify the
+          source code at some point, please use a version id that ends with
+          -SNAPSHOT, e.g 1.0-SNAPSHOT. Maven may cache the project jar
+          and refuse to overwrite old cached versions with new ones unless
+          you remember this convention.
+          
+        - This file supports
+          compiling the project with      'mvn compile' (see target/)
+          cleaning the class files with   'mvn clean'
+          executing the main routine with 'mvn exec:java'
+          executing the unit tests with   'mvn test'
+          packaging the application with  'mvn package' (see target/)
+          
+        - the Maven project structure is as follows:
+          https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
+          
+    -->
+    
+    <!-- ==== START OF SIMPLE CONFIGURATION ==== -->
+    
+    <!-- the three parts of the artifact name -->
+    <groupId>fi.utu.tech</groupId>
+    <artifactId>template-javafx</artifactId>
+    <version>1.0</version>
+    
+    <!-- additional information about the project -->
+    <name>JavaFX project template</name>
+    <url>https://gitlab.utu.fi/tech/education/gui/template-javafx</url>
+    
+    <packaging>jar</packaging>
+
+    <!-- HINT: More configuration here! -->
+    <properties>
+        <!-- Configures this project to use 'fi.utu.tech.AppMain' as its main class -->
+        <project.mainclass>fi.utu.tech.gui.javafx.Main</project.mainclass>
+        
+        
+        <!-- Don't touch these unless you know what you're doing!
+        
+             For example, the source encoding should always be utf-8.
+             You're probably doing something stupid if you think it
+             should be a 8-bit code page in 2019. -->
+        <jdk.version>11</jdk.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jqwik.version>1.2.0</jqwik.version>
+        <junit.version>5.5.2</junit.version>
+        <junitplatform.version>1.5.2</junitplatform.version>
+        <javafx.version>13</javafx.version>
+    </properties>
+
+    <!-- ==== END OF SIMPLE CONFIGURATION ==== -->
+    
+    <repositories>
+        <repository>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <id>central</id>
+            <name>Central Repository</name>
+            <url>https://repo.maven.apache.org/maven2</url>
+        </repository>
+        <repository>
+            <id>jcenter</id>
+            <name>jcenter</name>
+            <url>https://jcenter.bintray.com/</url>
+        </repository>
+        <!-- UTU repository -->
+        <repository>
+            <id>ftdev</id>
+            <name>ftdev</name>
+            <url>https://ftdev.utu.fi/maven2</url>
+        </repository>
+    </repositories>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-commons</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.jqwik</groupId>
+            <artifactId>jqwik</artifactId>
+            <version>${jqwik.version}</version>
+            <scope>test</scope>
+        </dependency><!--
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-migrationsupport</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-runner</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency> -->
+        
+        <!-- JavaFX (remove if not needed to speed up dep downloads)-->
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-base</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-fxml</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-graphics</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-media</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-swing</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-web</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- Make a 'fat' jar, that is, jar that contains all its dependencies and runs as is.
+                 See: https://stackoverflow.com/a/57691362 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>module-info.class</exclude>
+                                        <exclude>META-INF/*.SF</exclude>
+                                        <exclude>META-INF/*.DSA</exclude>
+                                        <exclude>META-INF/*.RSA</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>${project.mainclass}</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Run this app with exec:java -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.6.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                    <arguments>
+                        <argument>arg1</argument>
+                        <argument>arg2</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+
+            <!-- Make the packaged jar executable -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.1.2</version>
+                <configuration>
+                    <!-- DO NOT include log4j.properties file in your Jar -->
+                    <excludes>
+                        <exclude>**/log4j.properties</exclude>
+                    </excludes>
+                    <archive>
+                        <manifest>
+                            <!-- Jar file entry point -->
+                            <mainClass>${project.mainclass}</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <!-- download source code in Eclipse, best practice -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-eclipse-plugin</artifactId>
+                <version>2.10</version>
+                <configuration>
+                    <downloadSources>true</downloadSources>
+                    <downloadJavadocs>false</downloadJavadocs>
+                </configuration>
+            </plugin>
+
+            <!-- JDK source/target versions -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${jdk.version}</source>
+                    <target>${jdk.version}</target>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>3.1.1</version>
+                <executions>
+                    <execution>
+                    <id>attach-javadocs</id>
+                    <goals>
+                        <goal>jar</goal>
+                    </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <tags>
+                        <tag>
+                            <name>toDo</name>
+                            <placement>a</placement>
+                            <head>To&nbsp;do:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariant</name>
+                            <placement>t</placement>
+                            <head>Class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantProtected</name>
+                            <placement>t</placement>
+                            <head>Protected&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantPrivate</name>
+                            <placement>t</placement>
+                            <head>Private&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>abstractionFunction</name>
+                            <placement>t</placement>
+                            <head>Abstraction&nbsp;function:</head>
+                        </tag>
+                        <tag>
+                            <name>pre</name>
+                            <placement>cm</placement>
+                            <head>Precondition:</head>
+                        </tag>
+                        <tag>
+                            <name>post</name>
+                            <placement>cm</placement>
+                            <head>Postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postProtected</name>
+                            <placement>cm</placement>
+                            <head>Protected&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postPrivate</name>
+                            <placement>cm</placement>
+                            <head>Private&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>time</name>
+                            <placement>cmf</placement>
+                            <head>Time&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>space</name>
+                            <placement>cmf</placement>
+                            <head>Space&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>correspondence</name>
+                            <placement>a</placement>
+                            <head>Correspondence:</head>
+                        </tag>
+                        <tag>
+                            <name>download</name>
+                            <placement>a</placement>
+                            <head>Download:</head>
+                        </tag>
+                    </tags>
+                    <show>protected</show>
+                    <failOnError>false</failOnError>
+                    <sourceFileExcludes>
+                        <sourceFileExclude>**/module-info.java</sourceFileExclude>
+                    </sourceFileExcludes>
+                </configuration>
+            </plugin>
+
+            <!-- JUnit & JQwik test integration -->
+
+            <!-- junit-platform-maven-plugin: supports modular tests
+                 maven-surefire-plugin: non-modular tests
+
+                 Modular testing works via command line mvn, but is
+                 still broken in Eclipse due to this
+                 https://bugs.eclipse.org/bugs/show_bug.cgi?id=520667
+              -->
+            <plugin>
+                <groupId>de.sormuras.junit</groupId>
+                <artifactId>junit-platform-maven-plugin</artifactId>
+                <version>1.0.0-M5</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <executor>JAVA</executor>
+                </configuration>
+            </plugin>
+
+            <!--
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin> -->
+
+            <!-- javafx:jlink:
+                 https://github.com/openjfx/javafx-maven-plugin
+                 Use 'mvn package' instead if you don't need jlink.
+
+            <plugin>
+                <groupId>org.openjfx</groupId>
+                <artifactId>javafx-maven-plugin</artifactId>
+                <version>0.0.3</version>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                </configuration>
+            </plugin> -->
+
+        </plugins>
+        <extensions>
+            <!-- Enables the use of SSH for deployments -->
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh-external</artifactId>
+                <version>3.3.3</version>
+            </extension>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh</artifactId>
+                <version>3.3.3</version>
+            </extension>
+        </extensions>
+    </build>
+    <distributionManagement>
+        <repository>
+            <id>ftdev</id>
+            <name>UTU tech ftdev repository</name>
+            <url>scp://localhost:2222/var/www/maven2</url>
+        </repository>
+    </distributionManagement>
+</project>
diff --git a/Project 2/project/build.properties b/Project 2/project/build.properties
new file mode 100644
index 0000000..6adcdc7
--- /dev/null
+++ b/Project 2/project/build.properties	
@@ -0,0 +1 @@
+sbt.version=1.3.3
diff --git a/Project 2/project/plugins.sbt b/Project 2/project/plugins.sbt
new file mode 100644
index 0000000..37ca261
--- /dev/null
+++ b/Project 2/project/plugins.sbt	
@@ -0,0 +1,7 @@
+resolvers += Resolver.jcenterRepo
+
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
+addSbtPlugin("net.aichler" % "sbt-jupiter-interface" % "0.8.3")
+addSbtPlugin("com.github.xuwei-k" % "sbt-jshell" % "0.1.2")
+//addSbtPlugin("org.xerial.sbt" % "sbt-sql-sqlite" % "0.8")
+addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.4.0")
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/BMI.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/BMI.java
new file mode 100644
index 0000000..c6c72d3
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/BMI.java	
@@ -0,0 +1,46 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.event.EventHandler;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+
+public class BMI extends BorderPane{
+	
+	public BMI() {
+		Label label1 = new Label("Pituus: ");
+		Label label2 = new Label("Paino: ");
+		Label tulos = new Label("Virhellinen syöttö");
+		Label BMI = new Label("BMI: ");
+		TextField tf1 = new TextField();
+		TextField tf2 = new TextField();
+		
+		VBox vb1 = new VBox(label1, tf1);
+		VBox vb2 = new VBox(label2, tf2);
+		
+		HBox hb = new HBox(vb1, vb2);
+		HBox hb2 = new HBox(BMI, tulos);
+		
+		EventHandler<KeyEvent> BMIKaava = e -> {
+			try {
+				float pituus = Float.valueOf(tf1.getText());
+				float paino = Float.valueOf(tf2.getText());
+				tulos.setText(String.valueOf((paino/(pituus*pituus))));
+			} catch(Exception a) {
+				tulos.setText("Virheellinen syöttö");
+			}
+		};
+		
+		
+		tf1.setOnKeyTyped(BMIKaava);
+		tf2.setOnKeyTyped(BMIKaava);
+
+	
+		setCenter(hb);
+		setBottom(hb2);
+	
+	}
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/CanvasWindow.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/CanvasWindow.java
new file mode 100644
index 0000000..c01c54d
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/CanvasWindow.java	
@@ -0,0 +1,84 @@
+package fi.utu.tech.gui.javafx;
+
+import java.util.Random;
+
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.paint.Color;
+
+public class CanvasWindow extends BorderPane{
+
+	public CanvasWindow() {
+		
+		Canvas canvas = new Canvas(500, 500);
+		final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();		
+		initDraw(graphicsContext);
+		Random r = new Random();
+		
+		
+		canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>(){
+				
+		@Override
+		public void handle(MouseEvent event) {
+			if (event.getButton() == MouseButton.PRIMARY) {
+				graphicsContext.beginPath();
+				graphicsContext.moveTo(event.getX(), event.getY());
+				graphicsContext.stroke();
+			} else if (event.getButton() == MouseButton.SECONDARY) {
+            	
+            }
+		}
+		});
+		
+		canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>(){
+ 
+        @Override
+        public void handle(MouseEvent event) {
+        	if (event.getButton() == MouseButton.PRIMARY) {
+        		graphicsContext.lineTo(event.getX(), event.getY());
+        		graphicsContext.stroke();
+            } else if (event.getButton() == MouseButton.SECONDARY) {
+            	graphicsContext.fillRect(event.getX()+ (r.nextInt(20)-10), event.getY()+ (r.nextInt(20)-10), 2, 2);
+            	graphicsContext.stroke();
+            }
+        }
+        });
+		
+		canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>(){
+ 
+            @Override
+            public void handle(MouseEvent event) {
+ 
+            }
+        });
+		
+		setCenter(canvas);
+	}
+	
+	private void initDraw(GraphicsContext gc){
+        double canvasWidth = gc.getCanvas().getWidth();
+        double canvasHeight = gc.getCanvas().getHeight();
+         
+        gc.setFill(Color.BLACK);
+        gc.setStroke(Color.BLACK);
+        gc.setLineWidth(5);
+ 
+        gc.fill();
+        gc.strokeRect(
+                0,              //x of the upper left corner
+                0,              //y of the upper left corner
+                canvasWidth,    //width of the rectangle
+                canvasHeight);  //height of the rectangle
+         
+        gc.setFill(Color.BLACK);
+        gc.setStroke(Color.BLACK);
+        gc.setLineWidth(1);
+         
+    }
+	
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
new file mode 100644
index 0000000..a4d0180
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java	
@@ -0,0 +1,13 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.scene.control.Alert;
+
+public class Dialogs {
+    public static void warning(String title, String header, String content) {
+        Alert alert = new Alert(Alert.AlertType.WARNING);
+        alert.setTitle(title);
+        alert.setHeaderText(header);
+        alert.setContentText(content);
+        alert.showAndWait();
+    }
+}
\ No newline at end of file
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java
new file mode 100644
index 0000000..7777d66
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/FXMLController.java	
@@ -0,0 +1,63 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Platform;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+import java.util.function.Supplier;
+
+public class FXMLController {
+    private IntegerProperty clicks = new SimpleIntegerProperty(0);
+
+    private Supplier<Parent> supplier;
+
+    @FXML
+    private Label clicksLabel;
+
+    protected void updateClicks() {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.textProperty().bind(clicks.asString().concat(" clicks."));
+
+        clicks.setValue(clicks.getValue() + 1);
+    }
+
+    protected void setLabel(String text) {
+        if (!clicksLabel.textProperty().isBound())
+            clicksLabel.setText(text);
+    }
+
+    @FXML
+    protected void handleDialogButton(ActionEvent event) {
+        updateClicks();
+        Dialogs.warning("Example dialog", "Content header", "Content");
+    }
+
+    @FXML
+    protected void handleExitButton(ActionEvent event) {
+        System.out.println("Closing app.");
+        Platform.exit();
+    }
+
+    @FXML
+    protected void handleWindowButton(ActionEvent event) {
+        updateClicks();
+        Scene other = new Scene(supplier.get());
+        Stage otherStage = new Stage();
+        otherStage.setScene(other);
+        otherStage.show();
+    }
+
+    protected void setWindowFactory(Supplier<Parent> supplier) {
+        this.supplier = supplier;
+    }
+
+    public void initialize() {
+        System.out.println("2-A");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/Main.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/Main.java
new file mode 100644
index 0000000..8039f74
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/Main.java	
@@ -0,0 +1,29 @@
+package fi.utu.tech.gui.javafx;
+
+public class Main {
+    /**
+     * The main() method is ignored in correctly deployed JavaFX application.
+     * main() serves only as fallback in case the application can not be
+     * launched through deployment artifacts, e.g., in IDEs with limited FX
+     * support. NetBeans ignores main().
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        System.out.println("Stage A");
+        if (args.length == 1 && args[0].equals("--test")) return;
+        
+        int exercise = 1;
+        if (args.length == 1) exercise = Integer.parseInt(args[0]);
+        switch(exercise) {
+            case 1: MainApp1.launch(MainApp1.class, args); break;
+            case 2: MainApp2.launch(MainApp2.class, args); break;
+            case 3: MainApp3.launch(MainApp3.class, args); break;
+            case 4: MainApp4.launch(MainApp4.class, args); break;
+            case 5: MainApp5.launch(MainApp5.class, args); break;
+            case 6: MainApp6.launch(MainApp6.class, args); break;
+            default: MainApp.launch(MainApp.class, args); break;
+        }
+    }
+
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
new file mode 100644
index 0000000..6dc8ba3
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new OtherWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp1.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp1.java
new file mode 100644
index 0000000..5b8c8b3
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp1.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp1 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new PasswordWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp2.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp2.java
new file mode 100644
index 0000000..f86a01d
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp2.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp2 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new BMI();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp3.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp3.java
new file mode 100644
index 0000000..58ea02f
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp3.java	
@@ -0,0 +1,76 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.animation.Animation;
+import javafx.animation.Interpolator;
+import javafx.animation.RotateTransition;
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import javafx.util.Duration;
+
+public class MainApp3 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new OtherWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+        
+        RotateTransition rt = new RotateTransition(Duration.millis(5000), loader.root);
+        
+        rt.setCycleCount(Animation.INDEFINITE);
+        rt.setFromAngle(0);
+        rt.setToAngle(360);
+        rt.setInterpolator(Interpolator.LINEAR);
+        rt.play();
+        
+        loader.root.setOnMouseClicked(mouseEvent -> {
+        	rt.setRate(-1*rt.getRate());
+        });
+        
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java
new file mode 100644
index 0000000..253aaae
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp4.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp4 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new WebSelain();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java
new file mode 100644
index 0000000..73acf69
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp5.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp5 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new StackPaneWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp6.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp6.java
new file mode 100644
index 0000000..fefcf2d
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/MainApp6.java	
@@ -0,0 +1,59 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp6 extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+        System.out.println("Stage B");
+    }
+
+    @Override
+    public void stop() {
+        System.out.println("Stage E");
+    }
+
+    protected Parent createWindow() {
+        return new CanvasWindow();
+    }
+    
+    protected String createStyle() {
+        return ResourceLoader.stylesheet("styles.css");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        System.out.println("Stage C");
+        ResourceLoader<Parent, FXMLController> loader = new ResourceLoader<>("scene.fxml");
+
+        loader.controller.setLabel("Welcome!");
+
+        // configure the menu to create windows with createWindow
+        loader.controller.setWindowFactory(this::createWindow);
+
+        Scene scene = new Scene(loader.root);
+        scene.getStylesheets().add(createStyle());
+        
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+        System.out.println("Stage D");
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java
new file mode 100644
index 0000000..5328b15
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/OtherWindow.java	
@@ -0,0 +1,14 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+
+public class OtherWindow extends BorderPane {
+    public OtherWindow() {
+        Circle c = new Circle(200, Color.NAVY);
+        setCenter(c);
+        setLeft(new ImageView(ResourceLoader.image("hmm.png")));
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/PasswordWindow.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/PasswordWindow.java
new file mode 100644
index 0000000..9c79998
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/PasswordWindow.java	
@@ -0,0 +1,91 @@
+package fi.utu.tech.gui.javafx;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Formatter;
+
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+
+public class PasswordWindow extends BorderPane {
+
+	public PasswordWindow() {
+		PasswordField pf = new PasswordField();
+		Label label = new Label("Aseta salasana");
+		Button b1 = new Button("Tyhjennä");
+		Button b2 = new Button("Hyväksy");
+		HBox hb = new HBox(b1, b2);
+		Alert alert = new Alert(Alert.AlertType.NONE);
+
+		
+		EventHandler<KeyEvent> salasanaPituus = e -> {
+			if(pf.getLength() < 8) {
+				label.setText("Salasana liian lyhyt");
+			}else {
+				label.setText("Salasana on riittävän pitkä");
+			}
+		};
+		
+		
+		EventHandler<ActionEvent> tyhjennys = e -> {
+			pf.clear();
+			label.setText("Aseta salasana");
+		};
+		
+		EventHandler<ActionEvent> hyvaksy = e -> {
+			Dialogs.warning("SHA1", "Salasana SHA1 muodossa", encryptPassword(pf.getText()) );
+		};
+		
+		pf.setOnKeyTyped(salasanaPituus);
+		b1.setOnAction(tyhjennys);
+		b2.setOnAction(hyvaksy);
+		
+		setTop(label);
+		setCenter(pf);
+		setBottom(hb);
+		
+	}
+	
+	
+	private static String encryptPassword(String password)
+	{
+	    String sha1 = "";
+	    try
+	    {
+	        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
+	        crypt.reset();
+	        crypt.update(password.getBytes("UTF-8"));
+	        sha1 = byteToHex(crypt.digest());
+	    }
+	    catch(NoSuchAlgorithmException e)
+	    {
+	        e.printStackTrace();
+	    }
+	    catch(UnsupportedEncodingException e)
+	    {
+	        e.printStackTrace();
+	    }
+	    return sha1;
+	}
+
+	private static String byteToHex(final byte[] hash)
+	{
+	    Formatter formatter = new Formatter();
+	    for (byte b : hash)
+	    {
+	        formatter.format("%02x", b);
+	    }
+	    String result = formatter.toString();
+	    formatter.close();
+	    return result;
+	}
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
new file mode 100644
index 0000000..f917bd3
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java	
@@ -0,0 +1,42 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+
+public class ResourceLoader<N extends Parent, C> {
+    protected final N root;
+    protected final C controller;
+
+    public ResourceLoader(String contentPath) {
+        N root_ = null;
+        C controller_ = null;
+        try {
+            // determines where to look for the resources (the root path)
+            Class resourceRootClass = getClass();
+
+            FXMLLoader loader = new FXMLLoader(resourceRootClass.getResource(contentPath));
+            root_ = loader.load();
+            controller_ = loader.getController();
+            System.out.println("DEBUG: " + contentPath + " loaded.");
+        } catch (Exception e) {
+            Dialogs.warning(
+                    "Internal error",
+                    "Could not open FXML file: " + contentPath,
+                    "Reason: " + e.getMessage()
+            );
+            System.exit(1);
+        }
+        root = root_;
+        controller = controller_;
+    }
+
+    // finds images both outside and inside jars
+    public static String image(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+    
+    // finds stylesheets both outside and inside jars
+    public static String stylesheet(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/StackPaneWindow.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/StackPaneWindow.java
new file mode 100644
index 0000000..a0cadac
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/StackPaneWindow.java	
@@ -0,0 +1,41 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.event.EventHandler;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.StackPane;
+import javafx.scene.paint.Paint;
+import javafx.scene.shape.Rectangle;
+
+public class StackPaneWindow extends BorderPane {
+
+	public StackPaneWindow() {
+		
+		Rectangle r = new Rectangle(300,300, Paint.valueOf("#ff0000"));
+		
+		StackPane sp1 = new StackPane(r);
+		StackPane sp2 = new StackPane(sp1);
+		
+		EventHandler<MouseEvent> rKlikkaus = e -> {
+			System.out.println(r.toString());
+			e.consume();
+		};
+		
+		EventHandler<MouseEvent> sp1Klikkaus = e -> {
+			System.out.println(sp1.toString());
+		};
+		
+		EventHandler<MouseEvent> sp2Klikkaus = e -> {
+			System.out.println(sp2.toString());
+		};
+		
+		r.setOnMouseClicked(rKlikkaus);
+		sp1.setOnMouseClicked(sp1Klikkaus);
+		sp2.setOnMouseClicked(sp2Klikkaus);
+		
+		setCenter(sp2);
+		
+	}
+	
+}
diff --git a/Project 2/src/main/java/fi/utu/tech/gui/javafx/WebSelain.java b/Project 2/src/main/java/fi/utu/tech/gui/javafx/WebSelain.java
new file mode 100644
index 0000000..ae0bb79
--- /dev/null
+++ b/Project 2/src/main/java/fi/utu/tech/gui/javafx/WebSelain.java	
@@ -0,0 +1,40 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.event.EventHandler;
+import javafx.scene.Scene;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+
+public class WebSelain extends BorderPane {
+
+	public WebSelain() {
+		
+		TextField osoiteRivi = new TextField();
+		
+		WebView webView = new WebView();
+		setCenter(webView);
+		
+		setTop(osoiteRivi);
+		
+		osoiteRivi.setOnKeyPressed(new EventHandler<KeyEvent>(){
+	        @Override
+	        public void handle(KeyEvent ke)
+	        {
+	            if (ke.getCode().equals(KeyCode.ENTER))
+	            {
+	            	System.out.println("moi");
+	            	
+	            	webView.getEngine().load(osoiteRivi.getText());
+	                
+	            }
+	        }
+	    });
+		
+	}
+}
diff --git a/Project 2/src/main/resources/fi/utu/tech/gui/javafx/hmm.png b/Project 2/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
new file mode 100644
index 0000000000000000000000000000000000000000..25e8eb650f6752e716570cfb3c590bf09dff41ee
GIT binary patch
literal 9965
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

literal 0
HcmV?d00001

diff --git a/Project 2/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml b/Project 2/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml
new file mode 100644
index 0000000..434e233
--- /dev/null
+++ b/Project 2/src/main/resources/fi/utu/tech/gui/javafx/scene.fxml	
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fi.utu.tech.gui.javafx.FXMLController">
+   <left>
+      <ImageView fitHeight="368.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@hmm.png" />
+         </image>
+         <BorderPane.margin>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </BorderPane.margin>
+      </ImageView>
+   </left>
+   <center>
+      <BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
+         <padding>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </padding>
+         <center>
+            <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="16.0" BorderPane.alignment="CENTER">
+               <padding>
+                  <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+               </padding>
+               <children>
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleWindowButton" text="Open a new window" />
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleDialogButton" text="Display a dialog" />
+                  <Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#handleExitButton" text="Exit" />
+                  <Label fx:id="clicksLabel" text="Loading..." />
+               </children></VBox>
+         </center>
+         <top>
+            <Label text="What should we do?" BorderPane.alignment="CENTER">
+               <font>
+                  <Font size="26.0" />
+               </font></Label>
+         </top>
+      </BorderPane>
+   </center>
+</BorderPane>
diff --git a/Project 2/src/main/resources/fi/utu/tech/gui/javafx/styles.css b/Project 2/src/main/resources/fi/utu/tech/gui/javafx/styles.css
new file mode 100644
index 0000000..3ab643a
--- /dev/null
+++ b/Project 2/src/main/resources/fi/utu/tech/gui/javafx/styles.css	
@@ -0,0 +1,3 @@
+.button {
+    -fx-font-weight: bold;
+}
diff --git a/Project 3/.gitignore b/Project 3/.gitignore
new file mode 100644
index 0000000..5bfb48e
--- /dev/null
+++ b/Project 3/.gitignore	
@@ -0,0 +1,20 @@
+contracts/
+.classpath
+.project
+.history/
+.idea
+.jqwik-database
+.lib/
+.worksheet
+.settings/
+*.iml
+*.ipr
+*.iws
+*.log
+project/boot/
+project/plugins/project/
+project/project/
+project/*-shim.sbt
+project/target/
+target/
+openjfx/
diff --git a/Project 3/.gitlab-ci.yml b/Project 3/.gitlab-ci.yml
new file mode 100644
index 0000000..4b3553b
--- /dev/null
+++ b/Project 3/.gitlab-ci.yml	
@@ -0,0 +1,13 @@
+image: maven:latest
+
+stages:
+  - build
+  - test
+
+build:
+  script:
+    - mvn compile
+
+test:
+  script:
+    - mvn test
\ No newline at end of file
diff --git a/Project 3/README.md b/Project 3/README.md
new file mode 100644
index 0000000..2907fd1
--- /dev/null
+++ b/Project 3/README.md	
@@ -0,0 +1,39 @@
+# Project description
+
+Simple template for projects that make use of JavaFX and FXML (Scene Builder).
+Requires Java 11 or later. Compatible with
+Eclipse and IntelliJ IDEA. Minor issues with Netbeans. Automatically
+integrates with Gitlab CI.
+
+## Installation
+
+Maven:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ mvn compile exec:java
+```
+
+SBT:
+
+```bash
+$ git clone https://gitlab.utu.fi/tech/education/gui/template-javafx
+
+$ cd template-javafx
+
+$ sbt compile run
+```
+
+## Further instructions
+
+  * Java platform: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/jvm-platform
+  * Maven: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/maven-misc
+  * SBT: https://gitlab.utu.fi/soft/ftdev/wikis/tutorials/sbt-misc
+  
+External sources:
+
+  * JavaFX: https://openjfx.io/javadoc/11/
+  * Scene Builder: https://docs.gluonhq.com/scenebuilder/
diff --git a/Project 3/build.sbt b/Project 3/build.sbt
new file mode 100644
index 0000000..e703e90
--- /dev/null
+++ b/Project 3/build.sbt	
@@ -0,0 +1,236 @@
+// Project template
+
+// Supported operating systems: Windows, Mac, Linux
+// Supported JDKs: 8, 10+
+
+// Project name
+name := "template-javafx"
+
+// organization name
+organization := "fi.utu.tech"
+
+version := "1.0"
+
+// project description
+description := "JavaFX project template"
+
+// main class
+Compile/mainClass := Some("fi.utu.tech.gui.javafx.Main")
+
+// force the java version by typing it here (remove the comment)
+val force_javaVersion = None // Some(13)
+
+// force the javafx version by typing it here (remove the comment)
+val force_javaFxVersion = None // Some(13)
+
+val useJavaFX = true
+
+val useScalaOrScalaFX = true
+
+// END_OF_SIMPLE_CONFIGURATION
+// you can copy the rest for each new project
+// --- --- ---
+
+def fail(msg: String) = {
+  println("Error :-/")
+  println
+  println(msg)
+  System.exit(1)
+  null
+}
+
+val detectedJDK = System.getProperty("java.version").replace("-ea","").split('.').dropWhile(_.toInt<8).head.toInt
+
+val javaVersionNum = force_javaVersion.getOrElse(detectedJDK)
+
+val javaVersionString = javaVersionNum match {
+  case 7 => "1.7"
+  case 8 => "1.8"
+  case x if x > 8 => x.toString
+}
+
+val lts = 11
+val dev = 13
+
+val supported = javaVersionNum match {
+  case x if x < 8              => fail("Your Java installation is obsolete. Please upgrade to Java " + lts + "LTS")
+  case 9                       => fail("Your Java installation is unsupported and has known issues. Please upgrade to Java " + lts + "LTS")
+  case x if x < lts            => println("Consider upgrading to Java " + lts + " LTS"); true
+  case x if x > lts && x < dev => println("Consider upgrading to Java " + dev); true
+  case x if x > dev            => println("Unsupported early access version. Consider switching back to Java " + dev); true
+  case _                       => true
+}
+
+javacOptions ++= Seq("-source", javaVersionString, "-target", javaVersionString, "-encoding", "utf8", "-Xlint:unchecked", "-Xlint:deprecation")
+javacOptions in doc := Seq("-source", javaVersionString) 
+
+enablePlugins(JShellPlugin)
+
+compileOrder := CompileOrder.JavaThenScala
+
+// Enables publishing to maven repo
+publishMavenStyle := true
+
+// Do not append Scala versions to the generated artifacts
+crossPaths := false
+
+// This forbids including Scala related libraries into the dependency
+autoScalaLibrary := false
+
+assemblyMergeStrategy in assembly := {
+  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
+  case _ => MergeStrategy.first
+}
+
+// contains libraries provided by utu/ft dep
+resolvers += "ftdev" at "https://ftdev.utu.fi/maven2"
+
+fork in Global := true
+
+val javaVersion = taskKey[Unit]("Prints the Java version.")
+
+javaVersion := { println("SBT uses Java SDK located at "+System.getProperty("java.home")) }
+
+publishTo := Some(Resolver.file("file", new File("/tmp/repository")))
+
+val oomkit = "fi.utu.tech" % "oomkit" % "1.15"
+
+libraryDependencies ++= Seq()
+
+////
+//// JQWIK / JUNIT configuration
+////
+
+resolvers in ThisBuild += Resolver.jcenterRepo
+
+val junit_version = "5.5.2"
+
+// library dependencies. (orginization name) % (project name) % (version)
+libraryDependencies ++= Seq(
+  "net.aichler"        % "jupiter-interface"              % JupiterKeys.jupiterVersion.value % Test,
+  "org.junit.platform" % "junit-platform-commons"         % ("1"+junit_version.tail) % Test,
+  "org.junit.platform" % "junit-platform-runner"          % ("1"+junit_version.tail) % Test,
+  "org.junit.jupiter"  % "junit-jupiter-engine"           % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-api"              % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-migrationsupport" % junit_version % Test,
+  "org.junit.jupiter"  % "junit-jupiter-params"           % junit_version % Test,
+  "net.jqwik"          % "jqwik"                          % "1.2.0" % Test,
+  "org.scalatest"      %% "scalatest"                     % "3.0.8" % Test,
+)
+
+testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-c")
+
+////
+//// JAVAFX configuration
+////
+
+val javafx_versions = if (!useJavaFX) (0,"-","-") else (force_javaFxVersion getOrElse javaVersionNum) match {
+  case 7 => (7, "7", "8.0.181-R13")
+  case 8 => (8, "8", "8.0.181-R13")
+  case 10 => (11, "11.0.2", "11-R16")
+  case x if x>10 => (13, "13", "12.0.2-R18")
+  case _ => fail("Unsupported Java version for JavaFX")
+}
+
+// JAVA_HOME location
+val javaHomeDir = {
+  val path = try {
+    if (scala.sys.env("JAVA_HOME").trim.isEmpty) throw new Exception("Empty JAVA_HOME") else scala.sys.env("JAVA_HOME")
+  } catch {
+    case _: Throwable => System.getProperty("java.home") // not set -> ask from current JVM
+  }
+
+  val f = file(path)
+  if (!f.exists()) fail("The environment variable JAVA_HOME points to a non-existent directory!\nSolution: Edit your system settings (Windows control panel / *nix .bashrc) and fix the JAVA_HOME location.")
+  f
+}
+
+val osName: SettingKey[String] = SettingKey[String]("osName")
+
+osName := (System.getProperty("os.name") match {
+  case n if n.startsWith("Linux")   => "linux"
+  case n if n.startsWith("Mac")     => "mac"
+  case n if n.startsWith("Windows") => "win"
+  case _ => throw new Exception("Unknown platform!")
+})
+
+def legacyJavaFX() = {
+  val searchDirs = Seq(
+    "/jre/lib/jfxrt.jar",     // OpenJDK 7
+    "/jre/lib/ext/jfxrt.jar", // OpenJDK 8
+    "/lib/ext/jfxrt.jar"      // Windows & Oracle Java 8
+  )
+
+  if (detectedJDK > 8) fail(s"Trying to use legacy non-modular JavaFX with a modern JDK [$detectedJDK].\nSolution: Check the line 'val force_javaFxVersion =' in build.sbt.")
+
+  val javaFxJAR = searchDirs.map{ searchDir => file(javaHomeDir + searchDir) }.find{ _.exists() }
+
+  javaFxJAR.getOrElse {
+    fail(s"Java FX runtime not installed in [${javaHomeDir.toString}]!\nSolution: Install JavaFX or consider upgrading your JDK so that JavaFX can be installed automatically.")
+  }
+}
+
+val jfx_sdk_version = javafx_versions._2
+val jfx_scalafx_version = javafx_versions._3
+
+val javaFxPath = Def.taskKey[File]("OpenJFX fetcher")
+javaFxPath := {
+  val javaFxHome =
+    try {
+      val envHome = file(scala.sys.env("JAVAFX_HOME"))
+      if (envHome.toString.trim.isEmpty) throw new Exception("Empty JAVAFX_HOME")
+      println("Using OpenJFX from " + envHome)
+      envHome
+    }
+    catch { case _: Throwable =>
+        println("Using local OpenJFX")
+        baseDirectory.value / "openjfx"
+    }
+
+  if (!javaFxHome.exists()) java.nio.file.Files.createDirectory(javaFxHome.toPath)
+
+  val jfx_os = osName.value match {
+    case "linux" => "linux"
+    case "mac"   => "osx"
+    case "win"   => "windows"
+  }
+
+  val sdkURL = "http://download2.gluonhq.com/openjfx/" + jfx_sdk_version + "/openjfx-" + jfx_sdk_version + "_" + jfx_os + "-x64_bin-sdk.zip"
+
+  try {
+    val testDir = javaFxHome / "all.ok"
+    if (!testDir.exists()) {
+      println("Fetching OpenJFX from "+sdkURL+"..")
+      IO.unzipURL(new URL(sdkURL), javaFxHome)
+      java.nio.file.Files.createDirectory(testDir.toPath)
+      println("Fetching OpenJFX done.")
+    } else {
+      println("Using OpenJFX from "+javaFxHome)
+    }
+
+    javaFxHome
+  }
+  catch {
+    case t: Throwable => fail("Could not load OpenJFX! Reason:" + t.getMessage)
+  }
+}
+
+val jfxModules = Seq("base","controls","fxml","graphics","media","swing","web")
+
+
+if (!useJavaFX) Seq() else javafx_versions._1 match {
+  case 7 =>
+    // TODO libraryDependencies
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case 8 =>
+    (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" %% "scalafx" % jfx_scalafx_version) else Seq()) ++
+    Seq(unmanagedJars in Compile += Attributed.blank(legacyJavaFX()))
+  case _ =>
+    Seq(
+      javaOptions in run ++= Seq(
+        "--module-path", (javaFxPath.value / ("javafx-sdk-" + jfx_sdk_version) / "lib").toString,
+        "--add-modules=" + jfxModules.map("javafx."+_).mkString(","))
+    ) ++
+      (if (useScalaOrScalaFX) Seq(libraryDependencies += "org.scalafx" % "scalafx_2.13" % jfx_scalafx_version) else Seq()) ++
+      jfxModules.map(module => libraryDependencies += "org.openjfx" % ("javafx-"+module) % jfx_sdk_version classifier osName.value)
+}
diff --git a/Project 3/pom.xml b/Project 3/pom.xml
new file mode 100644
index 0000000..d5e6482
--- /dev/null
+++ b/Project 3/pom.xml	
@@ -0,0 +1,452 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <!--
+     
+      Welcome!
+      This pom.xml is *THE* file that defines your Maven style Java project.
+      
+      Eclipse, IDEA and other development environments with Maven support
+      or plugins can *import* this project by reading this file.
+      
+      It usually contains tons of barely readable configuration. Luckily
+      this basic pom.xml is somewhat readable. All necessary configuration
+      for customizing your project if located here on top before the
+      'END OF SIMPLE CONFIGURATION' line below.
+      
+      Some basics:
+      
+        - Maven is a build system for Java/JVM
+        - the Maven projects define an artifact that has a three part id:
+          groupId - artifactId - version
+          
+        - For example, this project is called:
+          fi.utu.tech - oomkit - 1.15
+          
+        - The group id is usually a web domain in reverse order.
+          
+        - You can use these id parts to search for projects at
+          https://search.maven.org/
+          
+        - If your version is not final and you have plans to modify the
+          source code at some point, please use a version id that ends with
+          -SNAPSHOT, e.g 1.0-SNAPSHOT. Maven may cache the project jar
+          and refuse to overwrite old cached versions with new ones unless
+          you remember this convention.
+          
+        - This file supports
+          compiling the project with      'mvn compile' (see target/)
+          cleaning the class files with   'mvn clean'
+          executing the main routine with 'mvn exec:java'
+          executing the unit tests with   'mvn test'
+          packaging the application with  'mvn package' (see target/)
+          
+        - the Maven project structure is as follows:
+          https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
+          
+    -->
+    
+    <!-- ==== START OF SIMPLE CONFIGURATION ==== -->
+    
+    <!-- the three parts of the artifact name -->
+    <groupId>fi.utu.tech</groupId>
+    <artifactId>template-javafx</artifactId>
+    <version>1.0</version>
+    
+    <!-- additional information about the project -->
+    <name>JavaFX project template</name>
+    <url>https://gitlab.utu.fi/tech/education/gui/template-javafx</url>
+    
+    <packaging>jar</packaging>
+
+    <!-- HINT: More configuration here! -->
+    <properties>
+        <!-- Configures this project to use 'fi.utu.tech.AppMain' as its main class -->
+        <project.mainclass>fi.utu.tech.gui.javafx.Main</project.mainclass>
+        
+        
+        <!-- Don't touch these unless you know what you're doing!
+        
+             For example, the source encoding should always be utf-8.
+             You're probably doing something stupid if you think it
+             should be a 8-bit code page in 2019. -->
+        <jdk.version>11</jdk.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jqwik.version>1.2.0</jqwik.version>
+        <junit.version>5.5.2</junit.version>
+        <junitplatform.version>1.5.2</junitplatform.version>
+        <javafx.version>13.0.2</javafx.version>
+    </properties>
+
+    <!-- ==== END OF SIMPLE CONFIGURATION ==== -->
+    
+    <repositories>
+        <repository>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <id>central</id>
+            <name>Central Repository</name>
+            <url>https://repo.maven.apache.org/maven2</url>
+        </repository>
+        <repository>
+            <id>jcenter</id>
+            <name>jcenter</name>
+            <url>https://jcenter.bintray.com/</url>
+        </repository>
+        <!-- UTU repository -->
+        <repository>
+            <id>ftdev</id>
+            <name>ftdev</name>
+            <url>https://ftdev.utu.fi/maven2</url>
+        </repository>
+    </repositories>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-commons</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.jqwik</groupId>
+            <artifactId>jqwik</artifactId>
+            <version>${jqwik.version}</version>
+            <scope>test</scope>
+        </dependency><!--
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-migrationsupport</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-runner</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency> -->
+        
+        <!-- JavaFX (remove if not needed to speed up dep downloads)-->
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-base</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-fxml</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-graphics</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-media</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-swing</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-web</artifactId>
+            <version>${javafx.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- Make a 'fat' jar, that is, jar that contains all its dependencies and runs as is.
+                 See: https://stackoverflow.com/a/57691362 -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <filters>
+                                <filter>
+                                    <artifact>*:*</artifact>
+                                    <excludes>
+                                        <exclude>module-info.class</exclude>
+                                        <exclude>META-INF/*.SF</exclude>
+                                        <exclude>META-INF/*.DSA</exclude>
+                                        <exclude>META-INF/*.RSA</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <transformers>
+                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                                    <mainClass>${project.mainclass}</mainClass>
+                                </transformer>
+                            </transformers>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Run this app with exec:java -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.6.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                    <arguments>
+                        <argument>arg1</argument>
+                        <argument>arg2</argument>
+                    </arguments>
+                </configuration>
+            </plugin>
+
+            <!-- Make the packaged jar executable -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.1.2</version>
+                <configuration>
+                    <!-- DO NOT include log4j.properties file in your Jar -->
+                    <excludes>
+                        <exclude>**/log4j.properties</exclude>
+                    </excludes>
+                    <archive>
+                        <manifest>
+                            <!-- Jar file entry point -->
+                            <mainClass>${project.mainclass}</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+
+            <!-- download source code in Eclipse, best practice -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-eclipse-plugin</artifactId>
+                <version>2.10</version>
+                <configuration>
+                    <downloadSources>true</downloadSources>
+                    <downloadJavadocs>false</downloadJavadocs>
+                </configuration>
+            </plugin>
+
+            <!-- JDK source/target versions -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${jdk.version}</source>
+                    <target>${jdk.version}</target>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>3.1.1</version>
+                <executions>
+                    <execution>
+                    <id>attach-javadocs</id>
+                    <goals>
+                        <goal>jar</goal>
+                    </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <tags>
+                        <tag>
+                            <name>toDo</name>
+                            <placement>a</placement>
+                            <head>To&nbsp;do:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariant</name>
+                            <placement>t</placement>
+                            <head>Class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantProtected</name>
+                            <placement>t</placement>
+                            <head>Protected&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>classInvariantPrivate</name>
+                            <placement>t</placement>
+                            <head>Private&nbsp;class&nbsp;invariant:</head>
+                        </tag>
+                        <tag>
+                            <name>abstractionFunction</name>
+                            <placement>t</placement>
+                            <head>Abstraction&nbsp;function:</head>
+                        </tag>
+                        <tag>
+                            <name>pre</name>
+                            <placement>cm</placement>
+                            <head>Precondition:</head>
+                        </tag>
+                        <tag>
+                            <name>post</name>
+                            <placement>cm</placement>
+                            <head>Postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postProtected</name>
+                            <placement>cm</placement>
+                            <head>Protected&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>postPrivate</name>
+                            <placement>cm</placement>
+                            <head>Private&nbsp;postcondition:</head>
+                        </tag>
+                        <tag>
+                            <name>time</name>
+                            <placement>cmf</placement>
+                            <head>Time&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>space</name>
+                            <placement>cmf</placement>
+                            <head>Space&nbsp;complexity:</head>
+                        </tag>
+                        <tag>
+                            <name>correspondence</name>
+                            <placement>a</placement>
+                            <head>Correspondence:</head>
+                        </tag>
+                        <tag>
+                            <name>download</name>
+                            <placement>a</placement>
+                            <head>Download:</head>
+                        </tag>
+                    </tags>
+                    <show>protected</show>
+                    <failOnError>false</failOnError>
+                    <sourceFileExcludes>
+                        <sourceFileExclude>**/module-info.java</sourceFileExclude>
+                    </sourceFileExcludes>
+                </configuration>
+            </plugin>
+
+            <!-- JUnit & JQwik test integration -->
+
+            <!-- junit-platform-maven-plugin: supports modular tests
+                 maven-surefire-plugin: non-modular tests
+
+                 Modular testing works via command line mvn, but is
+                 still broken in Eclipse due to this
+                 https://bugs.eclipse.org/bugs/show_bug.cgi?id=520667
+              -->
+            <plugin>
+                <groupId>de.sormuras.junit</groupId>
+                <artifactId>junit-platform-maven-plugin</artifactId>
+                <version>1.0.0-M5</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <executor>JAVA</executor>
+                </configuration>
+            </plugin>
+
+            <!--
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>3.0.0-M3</version>
+            </plugin> -->
+
+            <!-- javafx:jlink:
+                 https://github.com/openjfx/javafx-maven-plugin
+                 Use 'mvn package' instead if you don't need jlink.
+
+            <plugin>
+                <groupId>org.openjfx</groupId>
+                <artifactId>javafx-maven-plugin</artifactId>
+                <version>0.0.3</version>
+                <configuration>
+                    <mainClass>${project.mainclass}</mainClass>
+                </configuration>
+            </plugin> -->
+
+        </plugins>
+        <extensions>
+            <!-- Enables the use of SSH for deployments -->
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh-external</artifactId>
+                <version>3.3.3</version>
+            </extension>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh</artifactId>
+                <version>3.3.3</version>
+            </extension>
+        </extensions>
+    </build>
+    <distributionManagement>
+        <repository>
+            <id>ftdev</id>
+            <name>UTU tech ftdev repository</name>
+            <url>scp://localhost:2222/var/www/maven2</url>
+        </repository>
+    </distributionManagement>
+</project>
diff --git a/Project 3/project/build.properties b/Project 3/project/build.properties
new file mode 100644
index 0000000..6adcdc7
--- /dev/null
+++ b/Project 3/project/build.properties	
@@ -0,0 +1 @@
+sbt.version=1.3.3
diff --git a/Project 3/project/plugins.sbt b/Project 3/project/plugins.sbt
new file mode 100644
index 0000000..37ca261
--- /dev/null
+++ b/Project 3/project/plugins.sbt	
@@ -0,0 +1,7 @@
+resolvers += Resolver.jcenterRepo
+
+addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
+addSbtPlugin("net.aichler" % "sbt-jupiter-interface" % "0.8.3")
+addSbtPlugin("com.github.xuwei-k" % "sbt-jshell" % "0.1.2")
+//addSbtPlugin("org.xerial.sbt" % "sbt-sql-sqlite" % "0.8")
+addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.4.0")
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java
new file mode 100644
index 0000000..a4d0180
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/Dialogs.java	
@@ -0,0 +1,13 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.scene.control.Alert;
+
+public class Dialogs {
+    public static void warning(String title, String header, String content) {
+        Alert alert = new Alert(Alert.AlertType.WARNING);
+        alert.setTitle(title);
+        alert.setHeaderText(header);
+        alert.setContentText(content);
+        alert.showAndWait();
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/Main.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/Main.java
new file mode 100644
index 0000000..ae8c3e3
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/Main.java	
@@ -0,0 +1,31 @@
+package fi.utu.tech.gui.javafx;
+
+import fi.utu.tech.gui.javafx.gimmick.MainApp2;
+import fi.utu.tech.gui.javafx.zipper.MainApp1;
+
+public class Main {
+    /**
+     * The main() method is ignored in correctly deployed JavaFX application.
+     * main() serves only as fallback in case the application can not be
+     * launched through deployment artifacts, e.g., in IDEs with limited FX
+     * support. NetBeans ignores main().
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        System.out.println("Launching..");
+        if (args.length == 1 && args[0].equals("--test")) return;
+
+        int exercise = 2;
+        if (args.length == 1) exercise = Integer.parseInt(args[0]);
+        switch (exercise) {
+            case 1:
+                MainApp1.launch(MainApp1.class, args);
+                break;
+            default:
+                MainApp2.launch(MainApp2.class, args);
+                break;
+        }
+    }
+
+}
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/MainApp.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/MainApp.java
new file mode 100644
index 0000000..519b92e
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/MainApp.java	
@@ -0,0 +1,40 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
+
+public class MainApp extends Application {
+
+    // https://openjfx.io/javadoc/11/javafx.graphics/javafx/application/Application.html
+
+    // The JavaFX runtime does the following, in order, whenever an application is launched:
+
+    // 1. Starts the JavaFX runtime, if not already started (see Platform.startup(Runnable) for more information)
+    // 2. Constructs an instance of the specified Application class
+    // 3. Calls the Application's init() method
+    // 4. Calls the Application's start(javafx.stage.Stage) method
+    // 5. Waits for the application to finish, which happens when either of the following occur:
+    //   a) the application calls Platform.exit()
+    //   b) the last window has been closed and the implicitExit attribute on Platform is true
+    // 6. Calls the Application's stop() method
+
+    @Override
+    public void init() {
+    }
+
+    @Override
+    public void stop() {
+    }
+
+    @Override
+    public void start(Stage stage) {
+        Scene scene = new Scene(new BorderPane(new Rectangle(300, 300)));
+
+        stage.setTitle("JavaFX template");
+        stage.setScene(scene);
+        stage.show();
+    }
+}
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java
new file mode 100644
index 0000000..e5c2d1d
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/ResourceLoader.java	
@@ -0,0 +1,42 @@
+package fi.utu.tech.gui.javafx;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+
+public class ResourceLoader<N extends Parent, C> {
+    public final N root;
+    public final C controller;
+
+    public ResourceLoader(String contentPath) {
+        N root_ = null;
+        C controller_ = null;
+        try {
+            // determines where to look for the resources (the root path)
+            Class resourceRootClass = getClass();
+
+            FXMLLoader loader = new FXMLLoader(resourceRootClass.getResource(contentPath));
+            root_ = loader.load();
+            controller_ = loader.getController();
+            System.out.println("DEBUG: " + contentPath + " loaded.");
+        } catch (Exception e) {
+            Dialogs.warning(
+                    "Internal error",
+                    "Could not open FXML file: " + contentPath,
+                    "Reason: " + e.getMessage()
+            );
+            System.exit(1);
+        }
+        root = root_;
+        controller = controller_;
+    }
+
+    // finds images both outside and inside jars
+    public static String image(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+
+    // finds stylesheets both outside and inside jars
+    public static String stylesheet(String fileName) {
+        return ResourceLoader.class.getResource(fileName).toExternalForm();
+    }
+}
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/GimmickController.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/GimmickController.java
new file mode 100644
index 0000000..871c432
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/GimmickController.java	
@@ -0,0 +1,27 @@
+package fi.utu.tech.gui.javafx.gimmick;
+
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.scene.layout.TilePane;
+
+public class GimmickController {
+    @FXML
+    private TilePane tilePane;
+
+    public void initialize() {
+        tilePane.getChildren().clear();
+        
+            new Thread(() -> {
+            	
+            	for (int i = 0; i < 20; i++) {
+                    final int j = i;
+                    try { Thread.sleep(500); }
+                    catch(Exception e) {
+                    }
+                    View c = j % 2 == 0 ? new View1(150, 150) : new View2(150, 150);
+                    Platform.runLater(() -> tilePane.getChildren().add(c));
+                    new Thread(c).start();
+            	}}).start();
+        
+    }
+}
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/MainApp2.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/MainApp2.java
new file mode 100644
index 0000000..353ad8d
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/MainApp2.java	
@@ -0,0 +1,20 @@
+package fi.utu.tech.gui.javafx.gimmick;
+
+import fi.utu.tech.gui.javafx.MainApp;
+import fi.utu.tech.gui.javafx.ResourceLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+public class MainApp2 extends MainApp {
+    @Override
+    public void start(Stage stage) {
+        ResourceLoader<Parent, GimmickController> loader = new ResourceLoader<>("gimmick.fxml");
+
+        Scene scene = new Scene(loader.root);
+
+        stage.setTitle("The Gimmick Show");
+        stage.setScene(scene);
+        stage.show();
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View.java
new file mode 100644
index 0000000..666104e
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View.java	
@@ -0,0 +1,17 @@
+package fi.utu.tech.gui.javafx.gimmick;
+
+import javafx.scene.canvas.Canvas;
+
+abstract class View extends Canvas implements Runnable {
+    protected boolean active = true;
+
+    public View(double width, double height) {
+        super(width, height);
+
+        setOnMouseClicked(e -> {
+            active = false;
+            setVisible(false);
+            setManaged(false);
+        });
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View1.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View1.java
new file mode 100644
index 0000000..2fb6b9e
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View1.java	
@@ -0,0 +1,63 @@
+package fi.utu.tech.gui.javafx.gimmick;
+
+import javafx.scene.image.PixelFormat;
+import javafx.scene.image.WritableImage;
+
+import java.util.Random;
+import java.util.Timer;
+import java.util.TimerTask;
+
+
+class View1 extends View {
+    protected final int width, height;
+    private final WritableImage buffer;
+    private final int[] data;
+
+    View1(int width, int height) {
+        super(width, height);
+        this.width = width;
+        this.height = height;
+        buffer = new WritableImage(width, height);
+        data = new int[width * height];
+    }
+
+    public void run() {
+        launchTimer();
+        // uncomment to test if it fails (java.lang.InternalError).
+        // it should work if you managed to program this correctly!
+        //launchTimer();
+    }
+
+    void render() {
+        // uncomment to test if it fails
+        // it should work if you managed to program this correctly!
+        //if (!Platform.isFxApplicationThread()) throw new Error("Wrong thread!");
+
+        for (int pixelIdx = 0; pixelIdx < data.length; pixelIdx++) {
+            final int idx = pixelIdx;
+            new Thread(() -> {
+                data[idx] = new Random().nextInt(200) | ((new Random().nextInt(16) * 16) << 24);
+            }).run();
+        }
+
+        buffer.getPixelWriter().setPixels(
+                0, 0,
+                width, height,
+                PixelFormat.getIntArgbPreInstance(), data, 0, width);
+
+        getGraphicsContext2D().clearRect(0.0, 0.0, width, height);
+        getGraphicsContext2D().drawImage(buffer, 0.0, 0.0);
+    }
+
+    void launchTimer() {
+        final Thread t = new Thread(() -> {
+            render();
+        });
+        new Timer().schedule(new TimerTask() {
+            @Override
+            public void run() {
+                t.run();
+            }
+        }, 0l, 1000l);
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View2.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View2.java
new file mode 100644
index 0000000..be80667
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/gimmick/View2.java	
@@ -0,0 +1,36 @@
+package fi.utu.tech.gui.javafx.gimmick;
+
+import javafx.scene.paint.Color;
+
+import java.util.Random;
+
+class View2 extends View {
+    protected final int width, height;
+
+    View2(int width, int height) {
+        super(width, height);
+        this.width = width;
+        this.height = height;
+    }
+
+    public void run() {
+        while (true) {
+            render();
+            try {
+                Thread.sleep(200 + new Random().nextInt(10) * 100);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    void render() {
+        // uncomment to test if it fails
+        // it should work if you managed to program this correctly!
+        //if (!Platform.isFxApplicationThread()) throw new Error("Wrong thread!");
+
+        getGraphicsContext2D().setFill(new Color(0.5,0,0,0.5));
+        getGraphicsContext2D().fillRect(0.0, 0.0, width, height);
+        getGraphicsContext2D().setFill(new Color(0,0,1,0.9));
+        getGraphicsContext2D().fillOval(new Random().nextDouble() * width, new Random().nextDouble() * height, 20, 20);
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/MainApp1.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/MainApp1.java
new file mode 100644
index 0000000..9f4449e
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/MainApp1.java	
@@ -0,0 +1,27 @@
+package fi.utu.tech.gui.javafx.zipper;
+
+import fi.utu.tech.gui.javafx.MainApp;
+import fi.utu.tech.gui.javafx.ResourceLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+public class MainApp1 extends MainApp {
+    @Override
+    public void start(Stage stage) {
+        ResourceLoader<Parent, ZipperController> loader = new ResourceLoader<>("zipper.fxml");
+
+        
+        
+        loader.controller.setLabel("Welcome!");
+        loader.controller.setStage(stage);
+
+        Scene scene = new Scene(loader.root);
+
+        stage.setTitle("Zip Master 2020");
+        stage.setScene(scene);
+        stage.show();
+        
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/Zipper.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/Zipper.java
new file mode 100644
index 0000000..11ac8a0
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/Zipper.java	
@@ -0,0 +1,134 @@
+package fi.utu.tech.gui.javafx.zipper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.concurrent.Task;
+import javafx.scene.control.Label;
+
+public class Zipper extends Task<Void> {
+	
+	String sourceDir;
+	String destinationFile;
+	StringProperty currentFile = new SimpleStringProperty();
+	StringProperty zipItButtonText = new SimpleStringProperty();
+	FileOutputStream fos;
+	ZipOutputStream zipOut;
+	BooleanProperty currentlyZipping = new SimpleBooleanProperty();
+	//Boolean currentlyZipping;
+	
+	public Zipper (String sourceDir, String destinationFile) {
+		this.sourceDir = sourceDir;
+		this.destinationFile = destinationFile;
+		try {
+		this.fos = new FileOutputStream(destinationFile);
+	    this.zipOut = new ZipOutputStream(fos);
+	    }
+		catch(Exception e) {}
+		
+	}
+	
+	//runlater
+	public Void call() {
+		
+		//if(currentlyZipping) {
+		//	cancelZip();
+		//}
+		//currentlyZipping.set(true);
+		//currentlyZipping = true;
+		//System.out.println("zipper "+ currentlyZipping.get());
+		
+		try{
+			
+		//Platform.runLater(() -> {zipItButtonText.set("Cancel");
+	    //});	
+		
+		zip();
+		
+		//currentlyZipping.set(false);
+		//currentlyZipping = false;
+		
+		}catch(Exception e){}
+		return null;
+	}
+	
+	public void cancelZip() {
+		try {
+			
+			fos.close();
+			
+		} catch(Exception e) {}
+		
+		Platform.runLater(() -> {zipItButtonText.set("Zip It!");
+	    });	
+		
+		Platform.runLater(() -> {currentFile.set("Zippaus peruutettu");
+        });
+		
+	}
+	
+    public void zip() throws IOException {
+         {
+
+        	
+            File fileToZip = new File(sourceDir);
+            
+            //currentFileLabel.setText(fileToZip.getName());
+            
+            
+            
+            //System.out.println(fileToZip.getName());
+            
+            zipFile(fileToZip, fileToZip.getName(), zipOut);
+            
+        }
+    }
+
+    private void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
+    	Platform.runLater(() -> {currentFile.set("Zipataan tiedostoa: " + fileToZip.getName());
+        });
+        if (fileToZip.isHidden()) {
+            return;
+        }
+        if (fileToZip.isDirectory()) {
+            if (fileName.endsWith("/")) {
+                zipOut.putNextEntry(new ZipEntry(fileName));
+                zipOut.closeEntry();
+            } else {
+                zipOut.putNextEntry(new ZipEntry(fileName + "/"));
+                zipOut.closeEntry();
+            }
+            File[] children = fileToZip.listFiles();
+            for (File childFile : children) {
+                zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
+            }
+            
+            Platform.runLater(() -> {currentFile.set("Valamis");
+            });
+            
+            return;
+        }
+        try (FileInputStream fis = new FileInputStream(fileToZip)) {
+            ZipEntry zipEntry = new ZipEntry(fileName);
+            zipOut.putNextEntry(zipEntry);
+            byte[] bytes = new byte[1024];
+            int length;
+            while ((length = fis.read(bytes)) >= 0) {
+                zipOut.write(bytes, 0, length);
+            }
+            
+            Platform.runLater(() -> {currentFile.set("Valamis");
+            });
+            
+        }
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/ZipperController.java b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/ZipperController.java
new file mode 100644
index 0000000..8293271
--- /dev/null
+++ b/Project 3/src/main/java/fi/utu/tech/gui/javafx/zipper/ZipperController.java	
@@ -0,0 +1,112 @@
+package fi.utu.tech.gui.javafx.zipper;
+
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ZipperController  {
+    private Stage stage;
+
+    public void setStage(Stage stage) {
+        this.stage = stage;
+    }
+
+    @FXML
+    private TextField sourceField;
+
+    @FXML
+    private TextField destField;
+
+    @FXML
+    private Button zipItButton;
+
+    public Label statusLabel;
+    
+    public Zipper zipper;
+    
+    public BooleanProperty zipping = new SimpleBooleanProperty();
+
+    public void setLabel(String text) {
+        if (!statusLabel.textProperty().isBound())
+            statusLabel.setText(text);
+    }
+
+    @FXML
+    void chooseDest(ActionEvent event) {
+        FileChooser chooser = new FileChooser();
+        chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Zip files (.zip)", "*.zip"));
+        chooser.setTitle("Destination zip");
+        File selected = chooser.showSaveDialog(stage);
+        if (selected == null) return;
+        destField.setText(selected.getAbsolutePath());
+        if (!destField.getText().endsWith(".zip"))
+            destField.setText(destField.getText() + ".zip");
+        setButtonState(null);
+    }
+
+    @FXML
+    void chooseSource(ActionEvent event) {
+        DirectoryChooser chooser = new DirectoryChooser();
+        chooser.setTitle("Source folder");
+        File selected = chooser.showDialog(stage);
+        if (selected == null) return;
+        sourceField.setText(selected.getAbsolutePath());
+    }
+
+    @FXML
+    //yksisuuntanen bind statuslabelille, zipper status
+    void zipIt(ActionEvent event) {
+        try {
+        	
+        	
+        	
+        	zipper = new Zipper(sourceField.getText(), destField.getText());
+        	
+            //zipping.bind(zipper.currentlyZipping);
+        	//zipper.currentlyZipping.bind(zipping);
+            
+            //zipping.set(true);
+        	//System.out.println(zipping.get());
+        	
+        	if(zipper.currentlyZipping.get()) {
+        		zipper.cancelZip();
+        		
+        	}else {
+        	
+            new Thread(zipper).start();
+            
+            //setLabel(zipper.currentFile);
+            
+            statusLabel.textProperty().bind(zipper.currentFile);
+            
+            zipItButton.textProperty().bind(zipper.zipItButtonText);
+            
+            
+            
+        	}
+            
+        } catch (Exception e) {
+            setLabel(e.getMessage());
+        }
+    }
+
+    <T> void setButtonState(T t) {
+        zipItButton.setDisable(!destField.getText().endsWith(".zip"));
+    }
+
+    public void initialize() {
+        setButtonState(null);
+        destField.setOnKeyTyped(this::setButtonState);
+    }
+}
\ No newline at end of file
diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/alien.png b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/alien.png
new file mode 100644
index 0000000000000000000000000000000000000000..e94c775d601e2ae42159af0b4f86b7394ff3c47b
GIT binary patch
literal 46129
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

literal 0
HcmV?d00001

diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/gimmick.fxml b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/gimmick.fxml
new file mode 100644
index 0000000..f42f9b6
--- /dev/null
+++ b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/gimmick.fxml	
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.ScrollPane?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.layout.TilePane?>
+<?import javafx.scene.shape.Rectangle?>
+<?import javafx.scene.text.Font?>
+
+<StackPane maxHeight="580.0" maxWidth="770.0" stylesheets="@styles.css" xmlns="http://javafx.com/javafx/11.0.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fi.utu.tech.gui.javafx.gimmick.GimmickController">
+   <children>
+      <ImageView fitHeight="580.0" fitWidth="770.0" pickOnBounds="true" preserveRatio="true">
+         <image>
+            <Image url="@alien.png" />
+         </image>
+      </ImageView>
+      <BorderPane>
+         <center>
+            <ScrollPane fitToHeight="true" fitToWidth="true" vbarPolicy="ALWAYS" BorderPane.alignment="CENTER">
+               <content>
+                  <TilePane fx:id="tilePane" alignment="CENTER" hgap="16.0" opacity="0.85" prefColumns="3" vgap="16.0">
+                     <padding>
+                        <Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
+                     </padding>
+                     <children>
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                        <Rectangle arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="200.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
+                     </children>
+                  </TilePane>
+               </content>
+            </ScrollPane>
+         </center>
+         <top>
+            <Label text="The Gimmick Show" BorderPane.alignment="CENTER">
+               <font>
+                  <Font size="32.0" />
+               </font>
+            </Label>
+         </top>
+      </BorderPane>
+   </children>
+</StackPane>
diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/hmm.png b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/hmm.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb06d8873e15f2f9f690347c2298dea696cac12e
GIT binary patch
literal 8752
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
KKbLh*2~7Zwj#I|~

literal 0
HcmV?d00001

diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/package.png b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/package.png
new file mode 100644
index 0000000000000000000000000000000000000000..643eff6d60113e5e16ab4426c1f3a47ac4878c01
GIT binary patch
literal 8960
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
WQ&z6tsL8;<z~JfX=d#Wzp$PyhVUijE

literal 0
HcmV?d00001

diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/styles.css b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/styles.css
new file mode 100644
index 0000000..d1e250b
--- /dev/null
+++ b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/styles.css	
@@ -0,0 +1,7 @@
+.scroll-pane {
+   -fx-background-color:transparent;
+}
+
+.scroll-pane > .viewport {
+   -fx-background-color: transparent;
+}
diff --git a/Project 3/src/main/resources/fi/utu/tech/gui/javafx/zipper.fxml b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/zipper.fxml
new file mode 100644
index 0000000..9a011d1
--- /dev/null
+++ b/Project 3/src/main/resources/fi/utu/tech/gui/javafx/zipper.fxml	
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.image.Image?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fi.utu.tech.gui.javafx.zipper.ZipperController">
+   <left>
+      <ImageView fitHeight="368.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
+         <image>
+            <Image url="@package.png" />
+         </image>
+         <BorderPane.margin>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </BorderPane.margin>
+      </ImageView>
+   </left>
+   <center>
+      <BorderPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
+         <padding>
+            <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+         </padding>
+         <center>
+            <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" spacing="16.0" BorderPane.alignment="CENTER">
+               <padding>
+                  <Insets bottom="16.0" left="16.0" right="16.0" top="16.0" />
+               </padding>
+               <children>
+                  <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="200.0">
+                     <children>
+                        <Label prefHeight="30.0" text="Source: " />
+                        <TextField fx:id="sourceField" prefHeight="30.0" HBox.hgrow="ALWAYS">
+                           <HBox.margin>
+                              <Insets left="8.0" right="8.0" />
+                           </HBox.margin>
+                        </TextField>
+                        <Button maxHeight="30.0" maxWidth="30.0" mnemonicParsing="false" onAction="#chooseSource" prefHeight="30.0" prefWidth="30.0" text="..." />
+                     </children>
+                  </HBox>
+                  <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="200.0">
+                     <children>
+                        <Label prefHeight="30.0" text="Destination:" />
+                        <TextField fx:id="destField" prefHeight="30.0" HBox.hgrow="ALWAYS">
+                           <HBox.margin>
+                              <Insets left="8.0" right="8.0" />
+                           </HBox.margin>
+                        </TextField>
+                        <Button maxHeight="30.0" maxWidth="30.0" mnemonicParsing="false" onAction="#chooseDest" prefHeight="30.0" prefWidth="30.0" text="..." />
+                     </children>
+                  </HBox>
+                  <Button fx:id="zipItButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#zipIt" text="Zip it!" />
+                  <Label fx:id="statusLabel" text="Loading..." />
+               </children></VBox>
+         </center>
+         <top>
+            <Label text="Zip Master 2020" BorderPane.alignment="CENTER">
+               <font>
+                  <Font size="26.0" />
+               </font></Label>
+         </top>
+      </BorderPane>
+   </center>
+</BorderPane>
-- 
GitLab