Browse Source

First Project Upload

Martin Herbers 6 years ago
parent
commit
036b2ce91b
53 changed files with 4985 additions and 0 deletions
  1. 4 0
      .gitignore
  2. 23 0
      .idea/compiler.xml
  3. 2 0
      .idea/description.html
  4. 5 0
      .idea/encodings.xml
  5. 7 0
      .idea/gradle.xml
  6. 12 0
      .idea/misc.xml
  7. 8 0
      .idea/modules.xml
  8. 125 0
      .idea/uiDesigner.xml
  9. 6 0
      .idea/vcs.xml
  10. 995 0
      .idea/workspace.xml
  11. 20 0
      OLIP2.0.iml
  12. 3 0
      src/META-INF/MANIFEST.MF
  13. 174 0
      src/OpenSCADFiles/acceleration.scad
  14. 205 0
      src/OpenSCADFiles/flip.scad
  15. 171 0
      src/OpenSCADFiles/iceFreezing.scad
  16. 167 0
      src/OpenSCADFiles/iceMelting.scad
  17. 217 0
      src/OpenSCADFiles/squeeze.scad
  18. 145 0
      src/OpenSCADFiles/tilt.scad
  19. 132 0
      src/OpenSCADFiles/weight.scad
  20. 114 0
      src/controller/Controller.java
  21. 353 0
      src/controller/Export.java
  22. 59 0
      src/controller/SettingsController.java
  23. 135 0
      src/model/Instructions.java
  24. 176 0
      src/model/Settings.java
  25. 108 0
      src/model/Specifications.java
  26. BIN
      src/pictures/acceleration.png
  27. BIN
      src/pictures/blue.PNG
  28. BIN
      src/pictures/cog.png
  29. BIN
      src/pictures/cyan.PNG
  30. BIN
      src/pictures/gray.PNG
  31. BIN
      src/pictures/green.PNG
  32. BIN
      src/pictures/information-icon-6086.png
  33. BIN
      src/pictures/lightBlue.PNG
  34. BIN
      src/pictures/loadingCircle.gif
  35. BIN
      src/pictures/pressure.png
  36. BIN
      src/pictures/red.PNG
  37. BIN
      src/pictures/rotation.png
  38. BIN
      src/pictures/save.png
  39. BIN
      src/pictures/simpleAcceleration.png
  40. BIN
      src/pictures/simpleFlip.png
  41. BIN
      src/pictures/simpleSqueeze.png
  42. BIN
      src/pictures/simpleTemperatureFreeze.png
  43. BIN
      src/pictures/simpleTemperatureMelt.png
  44. BIN
      src/pictures/simpleTilt.png
  45. BIN
      src/pictures/simpleWeight.png
  46. BIN
      src/pictures/temperature.png
  47. BIN
      src/pictures/weight.png
  48. 52 0
      src/ui/InformationWindow.fxml
  49. 895 0
      src/ui/Main.java
  50. 224 0
      src/ui/MainWindow.fxml
  51. 81 0
      src/ui/SettingsWindow.fxml
  52. 138 0
      src/ui/SettingsWindow.java
  53. 229 0
      src/ui/UIController.java

+ 4 - 0
.gitignore

@@ -1,6 +1,10 @@
 # ---> Java
 *.class
 
+#IntelliJ Files
+*/.idea/workspace.xml
+*/.idea/tasks.xml
+
 # Mobile Tools for Java (J2ME)
 .mtj.tmp/
 

+ 23 - 0
.idea/compiler.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
+

+ 2 - 0
.idea/description.html

@@ -0,0 +1,2 @@
+<html>Simple <b>JavaFX 2.0</b> application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided.
+</html>

+ 5 - 0
.idea/encodings.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+

+ 7 - 0
.idea/gradle.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="gradleHome" value="C:/Program Files (x86)/Gradle/gradle-1.0-rc-3" />
+  </component>
+</project>
+

+ 12 - 0
.idea/misc.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ProjectKey">
+    <option name="state" value="project://e79810c8-c5c8-43b1-b19c-90c1f4095425" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

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

+ 125 - 0
.idea/uiDesigner.xml

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>
+

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 995 - 0
.idea/workspace.xml

@@ -0,0 +1,995 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ArtifactsWorkspaceSettings">
+    <artifacts-to-build>
+      <artifact name="OLIP2.0:jar" />
+    </artifacts-to-build>
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="cdb932d9-7e58-4d94-93a9-e7b232ef17da" name="Default" comment="" />
+    <ignored path="JavaFxApplication.iws" />
+    <ignored path=".idea/workspace.xml" />
+    <ignored path="$PROJECT_DIR$/out/" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="CreatePatchCommitExecutor">
+    <option name="PATCH_PATH" value="" />
+  </component>
+  <component name="DebuggerManager">
+    <breakpoint_any default_suspend_policy="SuspendAll" default_condition_enabled="true" converted="true">
+      <breakpoint>
+        <option name="NOTIFY_CAUGHT" value="true" />
+        <option name="NOTIFY_UNCAUGHT" value="true" />
+        <option name="ENABLED" value="false" />
+        <option name="LOG_ENABLED" value="false" />
+        <option name="LOG_EXPRESSION_ENABLED" value="false" />
+        <option name="SUSPEND_POLICY" value="SuspendAll" />
+        <option name="SUSPEND" value="true" />
+        <option name="COUNT_FILTER_ENABLED" value="false" />
+        <option name="COUNT_FILTER" value="0" />
+        <option name="CONDITION_ENABLED" value="true" />
+        <option name="CLASS_FILTERS_ENABLED" value="false" />
+        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+        <option name="CONDITION" value="" />
+        <option name="LOG_MESSAGE" value="" />
+      </breakpoint>
+      <breakpoint>
+        <option name="NOTIFY_CAUGHT" value="true" />
+        <option name="NOTIFY_UNCAUGHT" value="true" />
+        <option name="ENABLED" value="false" />
+        <option name="LOG_ENABLED" value="false" />
+        <option name="LOG_EXPRESSION_ENABLED" value="false" />
+        <option name="SUSPEND_POLICY" value="SuspendAll" />
+        <option name="SUSPEND" value="true" />
+        <option name="COUNT_FILTER_ENABLED" value="false" />
+        <option name="COUNT_FILTER" value="0" />
+        <option name="CONDITION_ENABLED" value="true" />
+        <option name="CLASS_FILTERS_ENABLED" value="false" />
+        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+        <option name="CONDITION" value="" />
+        <option name="LOG_MESSAGE" value="" />
+      </breakpoint>
+    </breakpoint_any>
+    <ui_properties converted="true" />
+    <breakpoint_rules converted="true" />
+  </component>
+  <component name="FavoritesManager">
+    <favorites_list name="JavaFxApplication" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf SIDE_TABS_SIZE_LIMIT_KEY="450">
+      <file leaf-file-name="MainWindow.fxml" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="4200">
+              <caret line="168" column="26" lean-forward="false" selection-start-line="168" selection-start-column="26" selection-end-line="168" selection-end-column="26" />
+              <folding />
+            </state>
+          </provider>
+          <provider editor-type-id="JavaFX-Scene-Builder">
+            <state />
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="SettingsWindow.fxml" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/ui/SettingsWindow.fxml">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="1175">
+              <caret line="47" column="47" lean-forward="false" selection-start-line="47" selection-start-column="24" selection-end-line="47" selection-end-column="47" />
+              <folding>
+                <marker date="1513788601917" expanded="true" signature="4335:4455" ph="..." />
+              </folding>
+            </state>
+          </provider>
+          <provider editor-type-id="JavaFX-Scene-Builder">
+            <state />
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="InformationWindow.fxml" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/ui/InformationWindow.fxml">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="1150">
+              <caret line="46" column="22" lean-forward="false" selection-start-line="46" selection-start-column="22" selection-end-line="46" selection-end-column="22" />
+              <folding>
+                <marker date="1513793527057" expanded="true" signature="2153:2156" ph="..." />
+              </folding>
+            </state>
+          </provider>
+          <provider editor-type-id="JavaFX-Scene-Builder">
+            <state />
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Main.java" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="842">
+              <caret line="526" column="41" lean-forward="false" selection-start-line="526" selection-start-column="41" selection-end-line="526" selection-end-column="41" />
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="Export.java" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/controller/Export.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="1750">
+              <caret line="90" column="49" lean-forward="false" selection-start-line="90" selection-start-column="49" selection-end-line="90" selection-end-column="49" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="UIController.java" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/ui/UIController.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="5200">
+              <caret line="210" column="0" lean-forward="false" selection-start-line="210" selection-start-column="0" selection-end-line="210" selection-end-column="0" />
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="SettingsWindow.java" pinned="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/ui/SettingsWindow.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="2350">
+              <caret line="100" column="27" lean-forward="false" selection-start-line="93" selection-start-column="16" selection-end-line="100" selection-end-column="27" />
+              <folding>
+                <element signature="imports" expanded="true" />
+              </folding>
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="Class" />
+        <option value="FxmlFile" />
+      </list>
+    </option>
+  </component>
+  <component name="FindInProjectRecents">
+    <findStrings>
+      <find>saveObj</find>
+      <find>task</find>
+      <find>saveobj</find>
+      <find>fxPanel.getChildren().get(</find>
+      <find>cog</find>
+      <find>settings</find>
+    </findStrings>
+  </component>
+  <component name="FindManager">
+    <FindUsagesManager>
+      <setting name="OPEN_NEW_TAB" value="false" />
+    </FindUsagesManager>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="GradleLocalSettings">
+    <option name="externalProjectsViewState">
+      <projects_view />
+    </option>
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="CHANGED_PATHS">
+      <list>
+        <option value="$PROJECT_DIR$/src/sample/Main.java" />
+        <option value="$PROJECT_DIR$/src/sample/sample.fxml" />
+        <option value="$PROJECT_DIR$/src/main/Main.java" />
+        <option value="$PROJECT_DIR$/src/ui/sample.fxml" />
+        <option value="$PROJECT_DIR$/src/ui/AccelerationInformation.fxml" />
+        <option value="$PROJECT_DIR$/src/controller/Controller.java" />
+        <option value="$PROJECT_DIR$/src/controller/Export.java" />
+        <option value="$PROJECT_DIR$/src/ui/SettingsWindow.java" />
+        <option value="$PROJECT_DIR$/src/ui/SettingsWindow.fxml" />
+        <option value="$PROJECT_DIR$/src/ui/InformationWindow.fxml" />
+        <option value="$PROJECT_DIR$/src/ui/UIController.java" />
+        <option value="$PROJECT_DIR$/src/ui/MainWindow.fxml" />
+        <option value="$PROJECT_DIR$/src/ui/Main.java" />
+      </list>
+    </option>
+  </component>
+  <component name="PhpWorkspaceProjectConfiguration" backward_compatibility_performed="true" />
+  <component name="ProjectFrameBounds" extendedState="6">
+    <option name="x" value="-8" />
+    <option name="y" value="-8" />
+    <option name="width" value="1612" />
+    <option name="height" value="876" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
+  <component name="ProjectReloadState">
+    <option name="STATE" value="0" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scratches" />
+      <pane id="AndroidView" />
+      <pane id="PackagesPane" />
+      <pane id="Scope" />
+      <pane id="ProjectPane">
+        <subPane>
+          <expand>
+            <path>
+              <item name="OLIP2.0" type="b2602c69:ProjectViewProjectNode" />
+              <item name="OLIP2.0" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="OLIP2.0" type="b2602c69:ProjectViewProjectNode" />
+              <item name="OLIP2.0" type="462c0819:PsiDirectoryNode" />
+              <item name="jars" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="OLIP2.0" type="b2602c69:ProjectViewProjectNode" />
+              <item name="OLIP2.0" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="OLIP2.0" type="b2602c69:ProjectViewProjectNode" />
+              <item name="OLIP2.0" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="controller" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="OLIP2.0" type="b2602c69:ProjectViewProjectNode" />
+              <item name="OLIP2.0" type="462c0819:PsiDirectoryNode" />
+              <item name="src" type="462c0819:PsiDirectoryNode" />
+              <item name="pictures" type="462c0819:PsiDirectoryNode" />
+            </path>
+          </expand>
+          <select />
+        </subPane>
+      </pane>
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="GoToFile.includeJavaFiles" value="false" />
+    <property name="OverrideImplement.combined" value="false" />
+    <property name="GoToClass.toSaveIncludeLibraries" value="false" />
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="recentsLimit" value="5" />
+    <property name="MemberChooser.sorted" value="false" />
+    <property name="MemberChooser.showClasses" value="true" />
+    <property name="GoToClass.includeLibraries" value="false" />
+    <property name="dynamic.classpath" value="false" />
+    <property name="MemberChooser.copyJavadoc" value="false" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="project.structure.last.edited" value="Artifacts" />
+    <property name="project.structure.proportion" value="0.15625" />
+    <property name="project.structure.side.proportion" value="0.2" />
+    <property name="settings.editor.selected.configurable" value="project.propVCSSupport.Mappings" />
+  </component>
+  <component name="RecentsManager">
+    <key name="MoveClassesOrPackagesDialog.RECENTS_KEY">
+      <recent name="ui" />
+      <recent name="main" />
+    </key>
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="C:\Users\HairBears\IdeaProjects\OLIP2.0\src\pictures" />
+    </key>
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="RunManager" selected="Application.Main">
+    <configuration name="Main" type="Application" factoryName="Application">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea">
+        <pattern>
+          <option name="PATTERN" value="ui.*" />
+          <option name="ENABLED" value="true" />
+        </pattern>
+      </extension>
+      <option name="MAIN_CLASS_NAME" value="ui.Main" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="OLIP2.0" />
+      <envs />
+      <RunnerSettings RunnerId="Run" />
+      <ConfigurationWrapper RunnerId="Run" />
+    </configuration>
+    <configuration default="true" type="Applet" factoryName="Applet">
+      <module />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+    </configuration>
+    <configuration default="true" type="Application" factoryName="Application">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="" />
+      <envs />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="moduleWithDependencies" />
+      </option>
+      <envs />
+      <patterns />
+    </configuration>
+    <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
+      <module name="" />
+      <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m" />
+      <option name="PROGRAM_PARAMETERS" />
+      <predefined_log_file id="idea.log" enabled="true" />
+    </configuration>
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+    </configuration>
+    <configuration default="true" type="TestNG" factoryName="TestNG">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="SUITE_NAME" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="GROUP_NAME" />
+      <option name="TEST_OBJECT" value="CLASS" />
+      <option name="VM_PARAMETERS" value="-ea" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="OUTPUT_DIRECTORY" />
+      <option name="ANNOTATION_TYPE" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="moduleWithDependencies" />
+      </option>
+      <option name="USE_DEFAULT_REPORTERS" value="false" />
+      <option name="PROPERTIES_FILE" />
+      <envs />
+      <properties />
+      <listeners />
+    </configuration>
+    <configuration default="true" type="DartUnitRunConfigurationType" factoryName="DartUnit">
+      <option name="VMOptions" />
+      <option name="arguments" />
+      <option name="filePath" />
+      <option name="scope" value="ALL" />
+      <option name="testName" />
+      <method />
+    </configuration>
+    <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
+      <Host>localhost</Host>
+      <Port>5050</Port>
+    </configuration>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="cdb932d9-7e58-4d94-93a9-e7b232ef17da" name="Default" comment="" />
+      <created>1359379246138</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1359379246138</updated>
+      <workItem from="1359379250712" duration="1302000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TimeTrackingManager">
+    <option name="totallyTimeSpent" value="1302000" />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="-11" y="-11" width="3862" height="2122" extended-state="6" />
+    <layout>
+      <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+      <window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32968178" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.17239584" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="13" side_tool="false" content_ui="tabs" />
+      <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.11591512" sideWeight="0.6703755" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Theme Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.1765625" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Profiler" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
+      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3296875" sideWeight="0.5" order="14" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="JetGradle" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Problems" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="12" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3296875" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="VcsManagerConfiguration">
+    <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
+    <option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager>
+      <breakpoints>
+        <line-breakpoint enabled="true" type="java-line">
+          <url>file://$PROJECT_DIR$/src/ui/SettingsWindow.java</url>
+          <line>92</line>
+          <properties />
+          <option name="timeStamp" value="31" />
+        </line-breakpoint>
+        <line-breakpoint enabled="true" type="java-line">
+          <url>file://$PROJECT_DIR$/src/model/Settings.java</url>
+          <line>108</line>
+          <properties />
+          <option name="timeStamp" value="32" />
+        </line-breakpoint>
+        <line-breakpoint enabled="true" type="java-line">
+          <url>file://$PROJECT_DIR$/src/model/Settings.java</url>
+          <line>112</line>
+          <properties />
+          <option name="timeStamp" value="33" />
+        </line-breakpoint>
+        <line-breakpoint enabled="true" type="java-line">
+          <url>file://$PROJECT_DIR$/src/ui/Main.java</url>
+          <line>296</line>
+          <properties />
+          <option name="timeStamp" value="37" />
+        </line-breakpoint>
+      </breakpoints>
+      <option name="time" value="38" />
+    </breakpoint-manager>
+    <watches-manager />
+  </component>
+  <component name="antWorkspaceConfiguration">
+    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="FILTER_TARGETS" value="false" />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/src/model/Settings.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="575">
+          <caret line="23" column="40" lean-forward="false" selection-start-line="23" selection-start-column="40" selection-end-line="23" selection-end-column="40" />
+          <folding>
+            <element signature="e#2098#2099#0" expanded="true" />
+            <element signature="e#2122#2123#0" expanded="true" />
+            <element signature="e#2177#2178#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Controller.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="2100">
+          <caret line="114" column="0" lean-forward="false" selection-start-line="114" selection-start-column="0" selection-end-line="114" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Export.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="7675">
+          <caret line="327" column="21" lean-forward="false" selection-start-line="327" selection-start-column="21" selection-end-line="327" selection-end-column="21" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/SettingsController.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="225">
+          <caret line="15" column="13" lean-forward="false" selection-start-line="15" selection-start-column="13" selection-end-line="15" selection-end-column="13" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/model/Instructions.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="825">
+          <caret line="34" column="133" lean-forward="false" selection-start-line="34" selection-start-column="133" selection-end-line="34" selection-end-column="133" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="5000">
+          <caret line="235" column="47" lean-forward="false" selection-start-line="235" selection-start-column="47" selection-end-line="235" selection-end-column="47" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/model/Settings.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="575">
+          <caret line="23" column="40" lean-forward="false" selection-start-line="23" selection-start-column="40" selection-end-line="23" selection-end-column="40" />
+          <folding>
+            <element signature="e#2098#2099#0" expanded="true" />
+            <element signature="e#2122#2123#0" expanded="true" />
+            <element signature="e#2177#2178#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Export.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="6775">
+          <caret line="291" column="0" lean-forward="false" selection-start-line="291" selection-start-column="0" selection-end-line="291" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="3600">
+          <caret line="144" column="17" lean-forward="true" selection-start-line="144" selection-start-column="17" selection-end-line="144" selection-end-column="17" />
+          <folding />
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Export.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="7000">
+          <caret line="300" column="25" lean-forward="true" selection-start-line="300" selection-start-column="25" selection-end-line="300" selection-end-column="25" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1325">
+          <caret line="53" column="31" lean-forward="false" selection-start-line="53" selection-start-column="31" selection-end-line="53" selection-end-column="31" />
+          <folding />
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="100">
+          <caret line="8" column="0" lean-forward="false" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Controller.java" />
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider editor-type-id="text-editor">
+        <state relative-caret-position="1350">
+          <caret line="54" column="0" lean-forward="true" selection-start-line="54" selection-start-column="0" selection-end-line="54" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+      <provider selected="true" editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="100">
+          <caret line="8" column="0" lean-forward="false" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Controller.java" />
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider editor-type-id="text-editor">
+        <state relative-caret-position="175">
+          <caret line="7" column="11" lean-forward="false" selection-start-line="7" selection-start-column="11" selection-end-line="7" selection-end-column="11" />
+          <folding />
+        </state>
+      </provider>
+      <provider selected="true" editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="100">
+          <caret line="8" column="0" lean-forward="false" selection-start-line="8" selection-start-column="0" selection-end-line="8" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="175">
+          <caret line="7" column="11" lean-forward="true" selection-start-line="7" selection-start-column="11" selection-end-line="7" selection-end-column="11" />
+          <folding />
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Controller.java" />
+    <entry file="file://$PROJECT_DIR$/src/ui/Controller.java" />
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/com/sun/glass/ui/win/WinApplication.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="822">
+          <caret line="142" column="24" lean-forward="false" selection-start-line="142" selection-start-column="24" selection-end-line="142" selection-end-column="24" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/com/sun/javafx/sg/prism/NGSubScene.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="518">
+          <caret line="207" column="0" lean-forward="false" selection-start-line="207" selection-start-column="0" selection-end-line="207" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/src.zip!/javax/swing/Timer.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-7">
+          <caret line="149" column="13" lean-forward="false" selection-start-line="149" selection-start-column="13" selection-end-line="149" selection-end-column="13" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/javafx/fxml/FXMLLoader.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1490">
+          <caret line="1772" column="0" lean-forward="false" selection-start-line="1772" selection-start-column="0" selection-end-line="1772" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/model/Specifications.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="500">
+          <caret line="21" column="13" lean-forward="false" selection-start-line="21" selection-start-column="13" selection-end-line="21" selection-end-column="13" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/javafx/beans/value/ChangeListener.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="975">
+          <caret line="62" column="9" lean-forward="false" selection-start-line="62" selection-start-column="9" selection-end-line="62" selection-end-column="9" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/model/Instructions.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="825">
+          <caret line="34" column="133" lean-forward="false" selection-start-line="34" selection-start-column="133" selection-end-line="34" selection-end-column="133" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/SettingsController.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="225">
+          <caret line="15" column="13" lean-forward="false" selection-start-line="15" selection-start-column="13" selection-end-line="15" selection-end-column="13" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/information-icon-6086.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/javafx/concurrent/Task.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1172">
+          <caret line="1461" column="0" lean-forward="false" selection-start-line="1461" selection-start-column="0" selection-end-line="1461" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/acceleration.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/openscadAcceleration.PNG" />
+    <entry file="file://$PROJECT_DIR$/src/model/Settings.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1093">
+          <caret line="112" column="0" lean-forward="false" selection-start-line="112" selection-start-column="0" selection-end-line="112" selection-end-column="0" />
+          <folding>
+            <element signature="e#2098#2099#0" expanded="true" />
+            <element signature="e#2122#2123#0" expanded="true" />
+            <element signature="e#2177#2178#0" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/SettingsWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1175">
+          <caret line="47" column="47" lean-forward="false" selection-start-line="47" selection-start-column="24" selection-end-line="47" selection-end-column="47" />
+          <folding>
+            <marker date="1513788601917" expanded="true" signature="4335:4455" ph="..." />
+          </folding>
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/simpleAcceleration.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Controller.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="900">
+          <caret line="44" column="16" lean-forward="false" selection-start-line="44" selection-start-column="16" selection-end-line="44" selection-end-column="16" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/simpleTemperatureFreeze.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/red.PNG">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/simpleSqueeze.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/InformationWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1150">
+          <caret line="46" column="22" lean-forward="false" selection-start-line="46" selection-start-column="22" selection-end-line="46" selection-end-column="22" />
+          <folding>
+            <marker date="1513793527057" expanded="true" signature="2153:2156" ph="..." />
+          </folding>
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/simpleTemperatureMelt.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/pictures/weight.png">
+      <provider selected="true" editor-type-id="images">
+        <state />
+      </provider>
+    </entry>
+    <entry file="jar://C:/Program Files/Java/jdk1.8.0_66/javafx-src.zip!/javafx/event/Event.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1322">
+          <caret line="197" column="0" lean-forward="false" selection-start-line="197" selection-start-column="0" selection-end-line="197" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/SettingsWindow.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="2350">
+          <caret line="100" column="27" lean-forward="false" selection-start-line="93" selection-start-column="16" selection-end-line="100" selection-end-column="27" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/UIController.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="5200">
+          <caret line="210" column="0" lean-forward="false" selection-start-line="210" selection-start-column="0" selection-end-line="210" selection-end-column="0" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/MainWindow.fxml">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="4200">
+          <caret line="168" column="26" lean-forward="false" selection-start-line="168" selection-start-column="26" selection-end-line="168" selection-end-column="26" />
+          <folding />
+        </state>
+      </provider>
+      <provider editor-type-id="JavaFX-Scene-Builder">
+        <state />
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/controller/Export.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1750">
+          <caret line="90" column="49" lean-forward="false" selection-start-line="90" selection-start-column="49" selection-end-line="90" selection-end-column="49" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/ui/Main.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="842">
+          <caret line="526" column="41" lean-forward="false" selection-start-line="526" selection-start-column="41" selection-end-line="526" selection-end-column="41" />
+          <folding>
+            <element signature="imports" expanded="true" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+  </component>
+  <component name="masterDetails">
+    <states>
+      <state key="ArtifactsStructureConfigurable.UI">
+        <settings>
+          <artifact-editor />
+          <last-edited>OLIP2.0:jar</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+                <option value="0.5" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+      <state key="FacetStructureConfigurable.UI">
+        <settings>
+          <last-edited>No facets are configured</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+      <state key="GlobalLibrariesConfigurable.UI">
+        <settings>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+      <state key="JdkListConfigurable.UI">
+        <settings>
+          <last-edited>1.8</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+      <state key="ModuleStructureConfigurable.UI">
+        <settings>
+          <last-edited>OLIP2.0</last-edited>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+      <state key="ProjectLibrariesConfigurable.UI">
+        <settings>
+          <splitter-proportions>
+            <option name="proportions">
+              <list>
+                <option value="0.2" />
+              </list>
+            </option>
+          </splitter-proportions>
+        </settings>
+      </state>
+    </states>
+  </component>
+</project>

+ 20 - 0
OLIP2.0.iml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/jars/jimStlMeshImporterJFX.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
+  </component>
+</module>

+ 3 - 0
src/META-INF/MANIFEST.MF

@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: ui.Main
+

+ 174 - 0
src/OpenSCADFiles/acceleration.scad

@@ -0,0 +1,174 @@
+//This object changes its state if a specific acceleration is reached.
+//The necessary acceleration is dependend on the wall height.
+//Water will be filled into the bigger chamber and will swap over that wall into the smaller chamber where it can be detected.
+
+
+//Parting wall height
+wallHeight = 18;
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = false;
+//Add a hole to fill the object after finishing printing
+fillLater = false;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//The main block where everything else gets cut out
+module baseBlock() {
+    cube([40,20,30], center=true);
+}
+
+//Adding 2 half-cylinder on the sides for easier recognition which object this is
+module recognitionAddition() {
+    difference (){
+        union() {
+            color("green")
+            translate([0,-10,5])
+            cylinder(r=3,h=40, $fa=1, $fs=0.5, center=true);
+            
+            color("green")
+            translate([0,10,5])
+            cylinder(r=3,h=40, $fa=1, $fs=0.5, center=true);
+        }
+        baseBlock();
+        roofAddition();
+   }
+}
+
+//The smaller chamber that contains the conductive parts
+module conductiveChamber() {
+    color("blue")
+    translate([-12,0,2])
+    cube([8,16,26], center=true);
+}
+
+//The bigger chamber that contains the water
+module initialWaterChamber() {
+    color("blue")
+    translate([6,0,2])
+    cube([24,16,26], center=true);
+}
+
+//The wall where the water will swap over
+module partitionWall() {
+    color("blue")
+    translate([-6,0,2+(wallHeight/2)])
+    cube([10,16,26-wallHeight], center=true);
+}
+
+//Addition to the main block, added later. TODO remove, add to baseBlock
+module roofAddition() {
+    translate([0,0,20])
+    cube([40,20,10], center=true);
+}
+
+//The roof in a 45 degree angle for better printing
+module roofCutout() {
+    difference() {
+        color("blue")
+        translate([1,0,15])
+        rotate([45,0,0])
+        cube([34,11.3,11.3], center=true);
+        translate([1,0,2])
+        cube([34,20,20],center=true);
+    }
+}
+
+//The hole through which the water can be filled in later
+module fillInHole() {
+    color("blue")
+    translate([7,0,23])
+    cylinder(r=1,h=4, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive bar on the wall which is connected to the finger
+module condBarWall() {
+    color("red")
+    translate([-16.5,0,-8])
+    cube([1,14,4], center=true);
+}
+
+//Conductive part on the outside where the finger has to be placed
+module condFinger() {
+    color("red")
+    translate([-19,0,0])
+    rotate([0,90,0])
+    cylinder(r=sizeFinger/2,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//A conductive part inside of a wall that connects the two modules above
+module condConnectionFingerWall() {
+    color("red")
+    translate([-17.5,0,-4])
+    cube([1,6,12], center=true);
+}
+
+//Conductive bar on the floor that is connected to the touch screen
+module condBarFloor() {
+    color("red")
+    translate([-10,0,-11.5])
+    cube([4,14,1], center=true);
+}
+
+//Conductive part on the outside that connects to the touchscreen
+module condFloorScreen() {
+    color("red")
+    translate([-10,0,-13.5])
+    cylinder(r=sizeScreen/2,h=3, $fa=1, $fs=0.5, center=true);
+}
+
+//Combine all conductive parts to one module
+module conductive() {
+    union() {
+        condBarFloor();
+        condBarWall();
+        condFinger();
+        condConnectionFingerWall();
+        condFloorScreen();
+    }
+}
+
+//The complete non-conducitve object
+module completeObject() {
+    difference() {
+       union() {
+            baseBlock();
+            roofAddition();
+            recognitionAddition();
+        }
+        union() {
+            conductiveChamber();
+            initialWaterChamber();
+            conductive();
+            partitionWall();
+            roofCutout();
+            if (fillLater)
+                fillInHole();
+        }
+    }
+}
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+        if (conductive) {
+            conductive();
+        }
+        else {
+            completeObject();
+        }
+        translate([-30,-60,-30])
+        cube([60,60,60]);
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 205 - 0
src/OpenSCADFiles/flip.scad

@@ -0,0 +1,205 @@
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = true;
+//Add a hole to fill the object after finishing printing
+fillLater = true;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//Base block where everything else gets cut out
+module baseBlock() {
+    translate([0,0,3.5])
+     cylinder(r=17,h=51, $fa=1, $fs=0.5, center=true);
+}
+
+//Cylinder cut out, outer ring
+module outerRingCutOut() {
+    color("blue")
+    translate([0,0,-1])
+    cylinder(r=14,h=30, $fa=1, $fs=0.5, center=true);
+}
+
+//The hole through which the water can be filled in later
+module fillInHole() {
+    color("blue")
+    translate([0,0,23])
+    cylinder(r=1,h=14, $fa=1, $fs=0.5, center=true);
+}
+
+//Parting wall, inner cylinder, cut out
+module partingWallInner() {
+    color("blue")
+    cylinder(r=6.5,h=30, $fa=1, $fs=0.5, center=true);
+}
+
+//Parting wall, outer cylinder, wall thickness
+module partingWallOuter() {
+    cylinder(r=8,h=30, $fa=1, $fs=0.5, center=true);
+}
+
+//Combining the two to one module, complete parting wall
+module partingWall() {
+    translate([0,0,-1])
+    difference() {
+        partingWallOuter();
+        partingWallInner();
+    }
+}
+
+//Parting wall, ceiling
+module partingWallCeiling() {
+    color("blue")
+    translate([0,0,14])
+    difference() {
+        sphere(r=8, center=true);
+        sphere(r=6.5, center=true);
+        translate([0,0,-5])
+        cube([20,20,10], center=true);
+        translate([0,0,7])
+        rotate([0,0,90])
+        cylinder(r=3.5,h=4, $fa=1, $fs=0.5, center=true);
+    }
+}
+
+//Cut out sphere, ceiling for the whole object
+module ball() {
+    color("blue")
+    sphere(r=14, center=true);
+}
+
+//cube that cuts away half the ball
+module cutCube() {
+    translate([0,0,-7.5])
+    cube([30,30,15],center=true);
+}
+
+//Ceiling for the whole object
+module ceiling() {
+    translate([0,0,14])
+    difference() {
+        ball();
+        cutCube();
+        if (fillLater)
+            fillInHole();
+    }
+}
+
+//Slope to collect the water at one point
+module slope() {
+    difference() {
+        translate([5,0,-16])
+        rotate([0,-30,0])
+        cylinder(r=16.5, h=20, $fa=1, $fs=0.5, center=true);
+        
+        partingWallInner();
+    }
+}
+
+//Connects the conductive point on the touch screen with the inner conductive part 
+module condConnectionHorizontal() {
+    color("red")
+    translate([-4.5,0,-19])
+    cube([12,4,2], center=true);
+}
+
+//Conductive part on the bottom that connects to the touch screen
+module condTouchscreen() {
+    color("red")
+    translate([0,0,-21])
+    cylinder(r=2, h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive part that connects the inner conductive part with the touch screen
+module condConnectionVertical() {
+    color("red")
+    translate([-9.5,0,-16])
+    cube([2,4,4], center=true);
+}
+
+//Conductive part inside for touchscreen
+module condFloor() {
+    intersection() {
+        color("red")
+        translate([-9.5,0,-13])
+        cube([2,16,2], center=true);
+        
+        slope();
+    }
+}
+
+//Conducitve part for the finger
+module condFinger() {
+    difference() {
+        intersection() {
+            color("red")
+            translate([-15.5,0,-8])
+            rotate([0,90,0])
+            cylinder(r=2, h=4, $fa=1, $fs=0.5, center=true);
+            
+            baseBlock();
+        }
+        outerRingCutOut();
+    }
+}
+
+//All conductive parts in one module
+module conductive() {
+    union() {
+        condConnectionHorizontal();
+        condTouchscreen();
+        condConnectionVertical();
+        condFloor();
+        condFinger();
+    }
+}
+
+//The complete object
+module completeObject() {
+    union() {
+        difference() {
+            baseBlock();
+            union() {
+                outerRingCutOut();
+                if (fillLater)
+                    fillInHole();
+                ceiling();
+                conductive();
+                
+            }
+        }
+        partingWall();
+        partingWallCeiling();
+        difference() {
+            intersection() {
+                slope();
+                baseBlock();
+            }
+            conductive();
+        }
+    }
+}
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+        if (conductive) {
+            conductive();
+        }
+        else {
+            completeObject();
+        }
+        translate([-30,-60,-30])
+        cube([60,60,60]);
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 171 - 0
src/OpenSCADFiles/iceFreezing.scad

@@ -0,0 +1,171 @@
+//This object changes its state when the water in the bigger chamber is freezing.
+//The ice will break through the red wall, when melting water will flow through the crack into the smaller chamber.
+
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = true;
+//Add a hole to fill the object after finishing printing
+fillLater = true;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//Base block where everything else gets cut out
+module baseBlock() {
+    translate([-7.5,0,-1])
+    cube([43,20,32], center=true);
+}
+
+//Part on the outside for easier recognition which object this is
+module recognitionAddition() {
+    difference (){
+        color("green")
+        translate([0,-10,-1])
+        cylinder(r=3,h=32, $fa=1, $fs=0.5, center=true);
+        baseBlock();
+   }
+}
+
+//chamber where the water gets filled in
+module waterChamber() {
+    color("blue")
+    translate([0,0,-2])
+    cube([25,16,16], center=true);
+}
+
+//Chamber where water will be caught
+module frozenChamber() {
+    color("blue")
+    translate([-19,0,-4])
+    cube([12,16,12], center=true);
+}
+
+//Cheiling for the chamber with the caught water
+module ceilingFrozen() {
+    color("blue")
+    difference() {
+        translate([-13,0,2])
+        rotate([0,45,0])
+        cube([17,16,17], center=true);
+        
+        translate([-3,0,2])
+        cube([20,20,40], center=true);
+        
+        translate([-13,0,-8])
+        cube([40,20,20], center=true);
+        
+    }
+}
+
+//Ceiling for the water chamber
+module ceiling() {
+     color("blue")
+    translate([0,0,6])
+    rotate([45,0,0])
+    cube([25,11.3,11.3], center=true);
+}
+
+//Hole to fill the object after printing
+module fillInHole() {
+     color("blue")
+    translate([0,0,14])
+    cylinder(r=1,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Wall made out of conductive filament. Not used for recognition, only the fragile characteristic is used.
+module condWall() {
+    color("red")
+    translate([-12.75,0,2])
+    cube([0.5,12,20], center=true);
+}
+
+//Conductive part on the inside, connected to the touch screen
+module condFloor() {
+    color("red")
+    translate([-16,0,-10.5])
+    cube([4,14,1], center=true);
+}
+
+//Conductive part on the bottom, connected to the touch screen
+module condTouchscreen() {
+    color("red")
+    translate([-16,0,-14])
+    cylinder(r=sizeScreen/2,h=6, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive part on the inside, connected to the finger
+module condSide() {
+    color("red")
+    translate([-25.5,0,-7])
+    cube([1,12,4], center=true);
+}
+
+//Conducitve part on the outside, connected to the finger
+module condFinger() {
+    color("red")
+    translate([-28,0,0])
+    rotate([0,90,0])
+    cylinder(r=sizeFinger/2,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Connects the inner and outer part for the finger connection
+module condConnection() {
+    color("red")
+    translate([-26.5,0,-4])
+    cube([2,4,10], center=true);
+}
+
+//All conducitve parts in one module
+module conductive() {
+    union() {
+        condWall();
+        condFloor();
+        condTouchscreen();
+        condSide();
+        condFinger();
+        condConnection();
+    }
+}
+
+//The whole object
+module completeObject() {
+    difference() {
+        union() {
+            baseBlock();
+            recognitionAddition();
+        }
+        union() {
+            waterChamber();
+            frozenChamber();
+            ceilingFrozen();
+            ceiling();
+            if (fillLater)
+                fillInHole();
+            conductive();
+        }
+    }
+}
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+        if (conductive) {
+            conductive();
+        }
+        else {
+            completeObject();
+        }
+        translate([-30,-60,-30])
+        cube([60,60,60]);
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 167 - 0
src/OpenSCADFiles/iceMelting.scad

@@ -0,0 +1,167 @@
+//This object changes its state when its temperature is above 0°C for some minutes.
+//The ice will melt and flow into the other chamber where it can be detected.
+//The temperature is changeable depending on what the ice is made of. For example saturated salt water will melt at ~21°C and can be detected through this method.
+
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = true;
+//Add a hole to fill the object after finishing printing
+fillLater = true;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//The main block where everything else gets cut out
+module baseBlock() {
+    translate([1,0,0])
+    cube([42,20,30], center=true);
+}
+
+//Additional part on the side wall for easier recognition which object this is
+module recognitionAddition() {
+    difference (){
+        color("green")
+        translate([-21,0,5])
+        cube([2,10,40], center=true);
+        baseBlock();
+        roofAddition();
+   }
+}
+
+//The chamber where the melted water will be caught
+module conductiveChamber() {
+    color("blue")
+    translate([10,0,8])
+    cube([16,16,26], center=true);
+}
+
+//The chamber where the ice will be filled in
+module iceChamber() {
+    color("blue")
+    translate([-10,0,13])
+    cube([16,16,16], center=true);
+}
+
+//The roof of the ice chamber
+module iceRoof() {
+     color("blue")
+    translate([-10,0,5])
+    rotate([0,45,0])
+    cube([11.3,16,11.3], center=true);
+}
+
+//The roof of the conductive chamber
+module conductiveRoof() {
+     color("blue")
+    translate([10,0,-5])
+    rotate([0,45,0])
+    cube([11.3,16,11.3], center=true);
+}
+
+//The tunnel where the melted water flows through to get into the conductive chamber
+module meltingTunnel() {
+    color("blue")
+    translate([-4.5,0,-0.5])
+    rotate([0,100,0])
+    cylinder(r=1.5,h=15, $fa=1, $fs=0.5, center=true);
+}
+
+//Addition to the main block, added later for the roof cutout. TODO move to baseBlock
+module roofAddition() {
+    translate([1,0,20])
+    cube([42,20,10], center=true);
+}
+
+//The hole through which the water can be filled in later
+module fillInHole() {
+    color("blue")
+    translate([-10,0,23])
+    cylinder(r=1,h=4, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive bar on the floor, connected to the touch screen
+module condBarFloor() {
+    color("red")
+    translate([4,0,22])
+    cube([4,14,2], center=true);
+}
+
+//Conductive bar on the wall, connected to the finger
+module condBarWall() {
+    color("red")
+    translate([19,0,13])
+    cube([2,14,14], center=true);
+}
+
+//Conductive part on the outside, connected to the touchscreen
+module condTouchscreen() {
+    color("red")
+    translate([4,0,24])
+    cylinder(r=sizeScreen/2,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive part on the outside, connected to the finger
+module condFinger() {
+    color("red")
+    translate([21,0,8])
+    rotate([0,90,0])
+    cylinder(r=sizeFinger/2,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//All conductive parts combined to one module
+module conductive() {
+    union() {
+        condBarFloor();
+        condBarWall();
+        condTouchscreen();
+        condFinger();
+    }
+}
+
+//The complete non-conducitve object
+module completeObject() {
+    difference() {
+         union() {
+            baseBlock();
+            roofAddition();
+             recognitionAddition();
+        }
+        union() {
+            conductiveChamber();
+            iceChamber();
+            iceRoof();
+            conductiveRoof();
+            meltingTunnel();
+            if (fillLater)
+                fillInHole();
+            conductive();
+        }
+    }
+}
+
+//Rotate the object for easier printing
+rotate([0,180,0])
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+        if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+    translate([-30,-60,-30]) 
+    cube([60,60,60]);
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 217 - 0
src/OpenSCADFiles/squeeze.scad

@@ -0,0 +1,217 @@
+//This object changes its state when the bottom half gets squeezed.
+//Water will be squeezed from the bottom chamber into the top one where it can be detected.
+
+
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = true;
+//Add a hole to fill the object after finishing printing
+fillLater = false;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//Bottom cylinder
+module bottomCylinder() {
+    translate([0,0,-10])
+    cylinder(r=13,h=20, $fa=1, $fs=0.5, center=true);
+}
+
+//Bottom cut out cylinder where the water will be filled in
+module bottomCutout() {
+    color("blue")
+    translate([0,0,-9])
+    cylinder(r=8,h=18, $fa=1, $fs=0.5, center=true);
+}
+
+//Top cylinder
+module topCylinder() {
+    translate([0,0,10])
+    cylinder(r=13,h=20, $fa=1, $fs=0.5, center=true);
+}
+
+//Top cot out where the water will be caught
+module topCutout() {
+    color("blue")
+    translate([0,0,5])
+    cylinder(r=8,h=10, $fa=1, $fs=0.5, center=true);
+}
+
+//The cone for the roof, used for easier printing
+module topCone() {
+   color("blue")
+    translate([0,0,14.5])
+    cylinder(r1=8, r2=0,h=9, $fa=1, $fs=0.5, center=true); 
+}
+
+//The hole through which the water can be filled in later
+module fillInHole() {
+    color("blue")
+    translate([0,0,19])
+    cylinder(r=1,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Outer part of the cone
+module coneOutside() {
+   translate([0,0,5])
+    cylinder(10,10,2, $fa=1, $fs=0.5, center=true); 
+}
+
+//Inner cut out part of the cone
+module coneCutout() {
+   translate([0,0,5])
+    cylinder(10,8,1, $fa=1, $fs=0.5, center=true); 
+}
+
+//The cone where the water gets squeezed through, the water will be caught on its top
+module coneMid() {
+    difference() {
+        coneOutside();
+        coneCutout();
+    }
+}
+
+//Isolation around the conductive bottom part
+module isolationBottom() {
+    difference() {
+        color("blue")
+        translate([0,-12-sizeScreen/2,-6])
+        cube([4+sizeScreen,4+sizeScreen,28], center=true);
+        topCylinder();
+        bottomCylinder();
+    }
+}
+
+//Isolation around the conductive top part
+module isolationTop() {
+    difference() {
+        color("blue")
+        translate([0,12+sizeFinger/2,11])
+        cube([sizeFinger+4,sizeFinger+4,18], center=true);
+        topCylinder();
+        bottomCylinder();
+    }
+}
+
+//Bevel for the top isolation, for easier printing and recognizing what the top part is
+module isolationTopBevel() {
+   difference() {
+        color("blue")
+        translate([0,9.9+sizeFinger/2,5-sizeFinger/2])
+       rotate([45,0,0])
+        cube([sizeFinger+4,1+sizeFinger*1.5,10], center=true);
+        topCylinder();
+        bottomCylinder();
+    } 
+}
+
+//Conductive bar on the top part, connected to the finger
+module condTop() {
+    color("red")
+        translate([0,12+sizeFinger/2,11])
+        cube([sizeFinger,sizeFinger,18], center=true);
+}
+
+//Conductive part that connects the bar to the inside
+module condTopInside() {
+    difference() {
+    color("red")
+        translate([0,10,4])
+        cube([4,7,3], center=true);
+        topCutout();
+    }
+}
+
+//Conductive bar on the bottom part, connected to the touchscreen
+module condBottom() {
+    color("red")
+        translate([0,-12-sizeScreen/2,-7])
+        cube([sizeScreen,sizeScreen,26], center=true);
+}
+
+//Conductive part that connects the bar to the inside
+module condBottomInside() {
+    difference() {
+    color("red")
+        translate([0,-10,4])
+        cube([4,7,3], center=true);
+        topCutout();
+        coneMid();
+    }
+}
+
+//All conductive parts combined to one module
+module conductive() {
+    union() {
+        condTop();
+        condTopInside();
+        condBottom();
+        condBottomInside();
+    }
+}
+
+//The combined, non-conductive bottom part
+module combinedBottom() {
+    difference() {
+        bottomCylinder();   
+        union() {
+            bottomCutout();
+            conductive();
+        }
+    }
+}
+
+//The combined, non-conductive top part
+module combinedTop() {
+    union() {
+        coneMid();
+        difference() {
+            union() {
+               topCylinder(); 
+               isolationBottom();
+               isolationTop();
+               isolationTopBevel();
+            }  
+            union() {
+                conductive();
+                topCone();
+                topCutout();
+                if (fillLater)
+                    fillInHole();
+            }
+        }
+    }
+}
+
+//Combined top and bottom parts to one module.
+//If a printer can choose different densities for different parts, you can print the top part with 100% infill (solid) and the bottom part with ~20% (flexible) 
+module completeObject() {
+    union() {
+        combinedBottom();
+        combinedTop();
+    }
+}
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+       if (conductive) {
+           conductive();
+       }
+       else {
+           completeObject();
+       }
+       translate([0,-30,-30])
+       cube([60,60,60]) ;
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 145 - 0
src/OpenSCADFiles/tilt.scad

@@ -0,0 +1,145 @@
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = true;
+//Add a hole to fill the object after finishing printing
+fillLater = false;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+
+//Base block where everything else gets cut out
+module baseBlock() {
+    translate([0,0,0])
+    cube([30,18,40], center=true);
+}
+
+//Chamber that will be filled with water
+module waterChamber() {
+    color("blue")
+    translate([-6,0,-2])
+    cylinder(r=7.5,h=30, $fa=1, $fs=0.5, center=true);
+}
+
+//Roof of the water chamber
+module waterRoof() {
+    color("blue")
+    translate([-6,0,12])
+    sphere(r=7.5, center=true);
+}
+
+//Hole to fill water into the chamber
+module waterHole() {
+    color("blue")
+    translate([-6,0,18])
+    cylinder(r=1,h=6, $fa=1, $fs=0.5, center=true);
+}
+
+//Connection between the two chambers
+module tunnel() {
+    color("blue")
+    translate([])
+    rotate([0,90,0])
+    cylinder(r=3,h=10, $fa=1, $fs=0.5, center=true);
+}
+
+//Second chamber that catches the water
+module catchChamber() {
+    color("blue")
+    translate([8,0,0])
+    cylinder(r=5,h=30, $fa=1, $fs=0.5, center=true);
+}
+
+//Roof of the second chamber
+module roofCatch() {
+    color("blue")
+    translate([8,0,14])
+    sphere(r=5, center=true);
+}
+
+//Hole where the air gets pushed through
+module holeCatch() {
+    color("blue")
+    translate([8,0,18])
+    cylinder(r=1,h=6, $fa=1, $fs=0.5, center=true);
+}
+
+//Conductive part on the inside bottom
+module condFloor() {
+    color("red")
+    translate([8,0,-16])
+    cylinder(r=5,h=2, $fa=1, $fs=0.5, center=true);
+}
+
+//Touchscreen electrode
+module condTouchscreen() {
+    color("red")
+    translate([8,0,-18.5])
+    cylinder(r=sizeScreen/2,h=3, $fa=1, $fs=0.5, center=true);
+}
+
+//Finger electrode
+module condFinger() {
+    color("red")
+    translate([13,0,-10])
+    rotate([0,90,0])
+    cylinder(r=sizeFinger/2,h=4, $fa=1, $fs=0.5, center=true);
+}
+
+//Finger electrode cut to match the cylinder shape
+module condFingerCut() {
+    difference() {
+        condFinger();
+         catchChamber();
+    }
+}
+
+module conductive() {
+    difference() {
+        union() {
+            condFloor();
+            condTouchscreen();
+            condFingerCut();
+        }
+         catchChamber();
+    }
+}
+
+module completeObject() {
+    difference() {
+        baseBlock();
+        union() {
+            waterChamber();
+            waterRoof();
+            waterHole();
+            tunnel();
+            catchChamber();
+            roofCatch();
+            holeCatch();
+            conductive();
+        }
+    }    
+}
+
+//Render the object depending on the input
+if (crossSection) {
+    difference() {
+        if (conductive) {
+            conductive();
+        }
+        else {
+            completeObject();
+        }
+        translate([-30,-60,-30])
+        cube([60,60,60]);
+    }
+}
+else {
+    if (conductive) {
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 132 - 0
src/OpenSCADFiles/weight.scad

@@ -0,0 +1,132 @@
+//Render conductive or non-conductive parts
+conductive = false;
+//Render the cross section or complete object
+crossSection = false;
+//Add a hole to fill the object after finishing printing
+fillLater = true;
+//Diameter of the conductive part that will be on the touch screen
+sizeScreen=4.0;
+//Diameter of the conductive part that will be connected to the finger
+sizeFinger=4.0;
+//Number of supports between the plates
+numberSupports=2;
+
+//Calculate for the for-loop
+a=numberSupports/2 - 1;
+
+//First plate
+module plateOne() {
+    cube([61,20,4], center=true);
+}
+
+//Second plate
+module plateTwo() {
+    translate([0,0,10])
+    cube([61,20,4], center=true);
+}
+
+//Supports between the plates, number dependend on input
+module supports() { 
+    color("red")
+   for (i = [0:1:a]) {
+      translate([-26+i*8,0,5])
+       rotate([0,45,0])
+       cube([0.5,20,12], center=true);
+   } 
+   
+   color("red")
+   for (i = [0:1:a]) {
+       translate([26-i*8,0,5])
+       rotate([0,45,0])
+       cube([0.5,20,12], center=true);
+   }
+}
+
+//Larger bottom area for better printing
+module printSupportOne() {
+    translate([0,-9.75,-3])
+    rotate([90,0,0])
+    cube([61,10,0.5], center=true);
+}
+
+module printSupportTwo() {
+    translate([0,-9.75,13])
+    rotate([90,0,0])
+    cube([61,10,0.5], center=true);
+}
+
+//Conductive bars between the plates
+module condBar1() {
+    color("red")
+    translate([1,0,2.25])
+    cube([4,20,2],center=true);
+}
+
+module condBar2() {
+    color("red")
+    translate([-1,0,7.75])
+    cube([4,20,2],center=true);
+}
+
+//Conductive pins on the outside, connected to the finger or touchscreen
+module condPin1() {
+    color("red")
+    translate([1,0,-0.05])
+    cylinder(r=sizeFinger/2,h=4.1, $fa=1, $fs=0.5, center=true);
+}
+
+module condPin2() {
+    color("red")
+    translate([-1,0,10.05])
+    cylinder(r=sizeScreen/2,h=4.1, $fa=1, $fs=0.5, center=true);
+}
+
+//All conductive parts in one module
+module conductive() {
+    union() {
+        condBar1();
+        condBar2();
+        condPin1();
+        condPin2();
+        supports();
+    }
+}
+
+//All non-conducitve parts in one module
+module completeObject() {
+    rotate([90,0,0])
+    difference() {
+        union() {
+            plateOne();
+            plateTwo();
+            printSupportOne();
+            printSupportTwo();
+        }
+        conductive();
+    }
+}
+
+//Render dependend on inputs
+if (crossSection) {
+    difference() {
+        if(conductive) {
+            rotate([90,0,0])
+            conductive();
+        }
+        else {
+            completeObject();
+        }
+        translate([-40,-30,-60])
+        cube([80,60,60]);
+        
+    }
+}
+else {
+    if(conductive) {
+        rotate([90,0,0])
+        conductive();
+    }
+    else {
+        completeObject();
+    }
+}

+ 114 - 0
src/controller/Controller.java

@@ -0,0 +1,114 @@
+package controller;
+
+import java.nio.file.Path;
+
+import model.Settings;
+import model.Settings.Temp;
+import model.Settings.Tilt;
+
+/**
+ * Controller class that connects the view with the model.
+ * @author Martin Herbers
+ *
+ */
+public class Controller {
+
+	private static Settings settings = Settings.getSettings();
+	
+	private static Controller controller = new Controller();
+	
+	
+	
+	public static Controller getC() {
+		return controller;
+	}
+	
+	
+	public void acceleration(boolean enable) {
+		if (enable)
+      		settings.addAcceleration();
+      	else
+      		settings.removeAcceleration();
+	}
+	
+	public void setAcceleration(double a) {
+		settings.setAcceleration(a);
+	}
+	
+	public void weight(boolean enable) {
+		if (enable)
+      		settings.addWeight();
+      	else
+      		settings.removeWeight();
+	}
+	
+	public void setWeight(int w) {
+		settings.setWeight(w);
+	}
+	
+	public void temperature(boolean enable) {
+		if (enable)
+      		settings.addTemperature();
+      	else
+      		settings.removeTemperature();
+	}
+	
+	public void setTemperature(Temp t) {
+		settings.setTemperature(t);
+	}
+	
+	public void tilt(boolean enable) {
+		if (enable)
+      		settings.addTilt();
+      	else
+      		settings.removeTilt();
+	}
+	
+	public void setTilt(Tilt t) {
+		settings.setTilting(t);
+	}
+	
+	public void squeeze(boolean enable) {
+		if (enable)
+      		settings.addSqueeze();
+      	else
+      		settings.removeSqueeze();
+	}
+
+
+	public void setFill(boolean selected) {
+		settings.setFill(selected);
+	}
+	
+	public boolean getFill() {
+		return settings.getFill();
+	}
+
+	public void setSizeScreen(float f) {
+		settings.setSizeScreen(f);
+	}
+	
+	public float getSizeScreen() {
+		return settings.getSizeScreen();
+	}
+	
+	public void setSizeFinger(float f) {
+		settings.setSizeFinger(f);
+	}
+	
+	public float getSizeFinger() {
+		return settings.getSizeFinger();
+	}
+	
+	public void setOpenSCADPath(Path p) {
+		settings.setOpenSCADPath(p);
+	}
+
+	public Path getOpenSCADPath() {
+		return settings.getOpenSCADPath();
+	}
+	
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//Only connect model and view, similar to those above
+	
+}

+ 353 - 0
src/controller/Export.java

@@ -0,0 +1,353 @@
+package controller;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+
+import model.Instructions;
+import model.Settings;
+import model.Settings.Temp;
+import model.Settings.Tilt;
+import model.Specifications;
+import ui.Main;
+
+/**
+ * The Export-Class that creates the STLs, instructions and the Android-file.
+ * @author Martin Herbers
+ *
+ */
+public class Export {
+	
+	private static Settings settings = Settings.getSettings();
+	//Depending on the OS, a path with spaces needs different symbols around it. E.g. Windows: "C:\program files\" or MacOS: '/Applications/'
+	private static String pathComma;
+
+	
+	public static void createSTL() {	
+		
+		//Set the console's chaining/parallel starting syntax and the "PathComma" depending on the OS
+		String start = "";
+		if (System.getProperty("os.name").contains("Windows")) {
+			start = " && start ";
+			pathComma = "\"";
+		}
+		else if (System.getProperty("os.name").contains("Linux")) {
+			start = " & ";
+			pathComma = "\"";
+		}
+		else if (System.getProperty("os.name").toLowerCase().contains("mac")) {
+			start = " && open -a ";
+			pathComma = "'";
+		}
+		
+		//Part the command in 5 parts that get additions depending on which object got chosen
+		//comFolder changes the directory to the .exe on Windows or the binary file in MacOs. Not needed in Linux
+		String comFolder = "cd " + pathComma + settings.getOpenSCADPath() + pathComma;
+		//Line for the full non-conductive object
+		String comLine =  start + "openscad "+ (System.getProperty("os.name").toLowerCase().contains("mac")?"-W -n --args ":"") +"-o " + pathComma + System.getProperty("user.dir") + File.separator + "output.stl"+ pathComma + " ";
+		//Line for all conductive parts
+		String comLine2 = start + "openscad "+ (System.getProperty("os.name").toLowerCase().contains("mac")?"-W -n --args ":"") +"-o " + pathComma + System.getProperty("user.dir") + File.separator + "output_conductive.stl" + pathComma + " ";
+		//Line for the non-conductive part for cross-section view
+		String comLine3 = start + "openscad "+ (System.getProperty("os.name").toLowerCase().contains("mac")?"-W -n --args ":"") +"-o " + pathComma + System.getProperty("user.dir") + File.separator + "output_crossSection.stl" + pathComma + " ";
+		//Line for the conducive parts for cross-section view
+		String comLine4 = start + "openscad "+ (System.getProperty("os.name").toLowerCase().contains("mac")?"-W -n --args ":"") +"-o " + pathComma + System.getProperty("user.dir") + File.separator + "output_crossSection_conductive.stl" + pathComma + " ";
+		//Instructions that will be added to the .txt file
+		List<String> instructions = null;
+		//Specification of the selected object, used for the android app to show the correct shape
+		List<String> android = null;
+		//Copy the OpenSCAD-file temporarily from the .jar, otherwise it can't be used by OpenSCAD.
+		File tempFile = null;
+		
+		//If weight is selected...
+		if (settings.isWeight()) {
+			tempFile = new File("weight.scad");
+			//Copy the .scad file
+			try {
+				InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/weight.scad");
+				OutputStream out = new FileOutputStream(tempFile);
+				int read;
+				byte[] bytes = new byte[1024];
+
+				while ((read = in.read(bytes)) != -1) {
+					out.write(bytes, 0, read);
+				}
+				in.close();
+				out.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			//Add the necessary variables to the command line arguments
+			int walls = Math.round(settings.getWeight()/27);
+			comLine += "-D numberSupports=" + walls + " -D conductive=false -D crossSection=false -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "weight.scad" + pathComma;
+			comLine2+= "-D numberSupports=" + walls + " -D conductive=true -D crossSection=false -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "weight.scad" + pathComma;
+			comLine3+= "-D numberSupports=" + walls + " -D conductive=false -D crossSection=true -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "weight.scad" + pathComma;
+			comLine4+= "-D numberSupports=" + walls + " -D conductive=true -D crossSection=true -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "weight.scad" + pathComma;
+			instructions = Instructions.getWeightInstruction();
+			android = Specifications.getWeightSpecs();
+		}
+		
+		else if (settings.isAcceleration()) {
+				tempFile = new File("acceleration.scad");
+				try {
+					InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/acceleration.scad");
+					OutputStream out = new FileOutputStream(tempFile);
+					int read;
+					byte[] bytes = new byte[1024];
+
+					while ((read = in.read(bytes)) != -1) {
+						out.write(bytes, 0, read);
+					}
+					in.close();
+					out.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+				
+			double height = (settings.getAcceleration()<8?10:18);//TODO function from acceleration to wall height? linear? exponential? something else?
+			comLine += "-D wallHeight=" + height + " -D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "acceleration.scad" + pathComma;
+			comLine2+= "-D wallHeight=" + height + " -D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "acceleration.scad" + pathComma;
+			comLine3+= "-D wallHeight=" + height + " -D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "acceleration.scad" + pathComma;
+			comLine4+= "-D wallHeight=" + height + " -D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "acceleration.scad" + pathComma;
+			instructions = Instructions.getAccelerationInstruction();
+			android = Specifications.getAccelerationSpecs();
+		}
+		
+		else if (settings.isSqueeze()) {
+				tempFile = new File("squeeze.scad");
+				try {
+					InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/squeeze.scad");
+					OutputStream out = new FileOutputStream(tempFile);
+					int read;
+					byte[] bytes = new byte[1024];
+
+					while ((read = in.read(bytes)) != -1) {
+						out.write(bytes, 0, read);
+					}
+					in.close();
+					out.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+				
+			comLine += "-D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "squeeze.scad" + pathComma;
+			comLine2+= "-D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "squeeze.scad" + pathComma;
+			comLine3+= "-D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "squeeze.scad" + pathComma;
+			comLine4+= "-D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "squeeze.scad" + pathComma;
+			instructions = Instructions.getSqueezeInstruction();
+			android = Specifications.getSqueezeSpecs();
+		}
+		
+		else if (settings.isTemperature()) {
+			if (settings.getTemperature() == Temp.OVER0) {
+					tempFile = new File("iceMelting.scad");
+					try {
+						InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/iceMelting.scad");
+						OutputStream out = new FileOutputStream(tempFile);
+						int read;
+						byte[] bytes = new byte[1024];
+
+						while ((read = in.read(bytes)) != -1) {
+							out.write(bytes, 0, read);
+						}
+						in.close();
+						out.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+				
+				comLine += "-D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceMelting.scad" + pathComma;
+				comLine2+= "-D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceMelting.scad" + pathComma; 
+				comLine3+= "-D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceMelting.scad" + pathComma; 
+				comLine4+= "-D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceMelting.scad" + pathComma;
+				instructions = Instructions.getTemperatureMeltInstruction();
+				android = Specifications.getTemperatureMeltSpecs();
+			}
+			else {
+					tempFile = new File("iceFreezing.scad");
+					try {
+						InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/iceFreezing.scad");
+						OutputStream out = new FileOutputStream(tempFile);
+						int read;
+						byte[] bytes = new byte[1024];
+
+						while ((read = in.read(bytes)) != -1) {
+							out.write(bytes, 0, read);
+						}
+						in.close();
+						out.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					
+				comLine += "-D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceFreezing.scad" + pathComma;  
+				comLine2+= "-D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceFreezing.scad" + pathComma;  
+				comLine3+= "-D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceFreezing.scad" + pathComma;   
+				comLine4+= "-D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "iceFreezing.scad" + pathComma;  
+				instructions = Instructions.getTemperatureFreezeInstruction();
+				android = Specifications.getTemperatureFreezeSpecs();
+			}
+		}
+		
+		else if (settings.isTilt()) {
+			if (settings.getTilting().equals(Tilt.FLIP)) {
+					tempFile = new File("flip.scad");
+					try {
+						InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/flip.scad");
+						OutputStream out = new FileOutputStream(tempFile);
+						int read;
+						byte[] bytes = new byte[1024];
+
+						while ((read = in.read(bytes)) != -1) {
+							out.write(bytes, 0, read);
+						}
+						in.close();
+						out.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					
+				comLine += "-D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "flip.scad" + pathComma;   
+				comLine2+= "-D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "flip.scad" + pathComma;  
+				comLine3+= "-D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "flip.scad" + pathComma;   
+				comLine4+= "-D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "flip.scad" + pathComma; 
+				instructions = Instructions.getFlipInstruction();
+				android = Specifications.getFlipSpecs();
+			}
+			
+			else {
+					tempFile = new File("tilt.scad");
+					try {
+						InputStream in = Export.class.getResourceAsStream("/OpenSCADFiles/tilt.scad");
+						OutputStream out = new FileOutputStream(tempFile);
+						int read;
+						byte[] bytes = new byte[1024];
+
+						while ((read = in.read(bytes)) != -1) {
+							out.write(bytes, 0, read);
+						}
+						in.close();
+						out.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					
+				comLine += "-D conductive=false -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "tilt.scad" + pathComma;   
+				comLine2+= "-D conductive=true -D crossSection=false -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "tilt.scad" + pathComma;    
+				comLine3+= "-D conductive=false -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "tilt.scad" + pathComma; 
+				comLine4+= "-D conductive=true -D crossSection=true -D fillLater="+ settings.getFill() +" -D sizeScreen=" + settings.getSizeScreen() + " -D sizeFinger=" + settings.getSizeFinger() + " " + pathComma + System.getProperty("user.dir") + File.separator + "tilt.scad" + pathComma;  
+				instructions = Instructions.getTiltInstruction();
+				android = Specifications.getTiltSpecs();
+			}
+			
+		}
+		//ADD CODE HERE FOR ADDITIONAL INTERACTION
+		//(else if()...)
+		//Needs: 
+				//Copying openscad-file to current folder
+				//Commandline addition for each view-part
+				//Instructions-text and object-specification
+		
+		if (instructions == null || android == null)
+			return;
+
+		String[] arguments = new String[3];
+		
+		//Depending on the os more arguments are needed to interpret the strings as commands
+		if (System.getProperty("os.name").contains("Windows")) {
+			arguments[0] = "cmd.exe";
+			arguments[1] = "/c";
+		}
+		else if (System.getProperty("os.name").contains("Linux")) {
+			arguments[0] = "bash";
+			arguments[1] = "-c";
+		}
+		else {
+			arguments[0] = "/bin/bash";
+			arguments[1] = "-c";
+		}
+		
+		arguments[2] = (System.getProperty("os.name").contains("Linux")?"":comFolder) + 
+				(System.getProperty("os.name").contains("Linux")?comLine.substring(3):comLine) +
+				comLine2 + comLine4 + comLine3;
+		
+		//Run the command line
+		try {
+			Process p = Runtime.getRuntime().exec(arguments);
+			 BufferedReader stdOut=new BufferedReader(new InputStreamReader(p.getInputStream()));
+			 @SuppressWarnings("unused")
+		        String s;
+		        while((s=stdOut.readLine())!=null){
+		        	System.out.println(s);
+		        }
+			Main.finished();
+		} catch (IOException e1) {
+			e1.printStackTrace();
+		}
+    
+		//Create the instructions .txt file
+	    Path file = Paths.get("instructions.txt");
+	    try {
+			Files.write(file, instructions, Charset.forName("UTF-8"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	    //Create the objectSpecs.txt file
+	    Path output = Paths.get("objectSpecs.txt");
+	    try {
+			Files.write(output, android, Charset.forName("UTF-8"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	    
+	    //Delete all created files after closing the programm. If you want permanent files, either use the "save object" button or copy the files before closing the programm.
+	    File f1 = new File(System.getProperty("user.dir") + File.separator + "output.stl");
+		f1.deleteOnExit();
+		File f2 = new File(System.getProperty("user.dir") + File.separator + "output_conductive.stl");
+		f2.deleteOnExit();
+		File f3 = new File(System.getProperty("user.dir") + File.separator + "output_crossSection.stl");
+		f3.deleteOnExit();
+		File f4 = new File(System.getProperty("user.dir") + File.separator + "output_crossSection_conductive.stl");
+		f4.deleteOnExit();
+		File f5 = new File(System.getProperty("user.dir") + File.separator + "instructions.txt");
+		f5.deleteOnExit();
+		File f6 = new File(System.getProperty("user.dir") + File.separator + "objectSpecs.txt");
+		f6.deleteOnExit();
+		
+		//Delete the OpenSCAD file
+		tempFile.delete();
+	}
+	
+	/**
+	 * Copy all files that are necessary for printing and using the object to a location of your choice.
+	 * @param folder	directory where the files will be saved to
+	 */
+	public static void saveFilesTo(File folder) {
+		try {
+			File output = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "output.stl");
+			Files.copy(output.toPath(), new File(folder.getAbsolutePath() + File.separator + "output.stl").toPath(), StandardCopyOption.REPLACE_EXISTING);
+			
+			File outputCond = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "output_conductive.stl");
+			Files.copy(outputCond.toPath(), new File(folder.getAbsolutePath() + File.separator + "output_conductive.stl").toPath(), StandardCopyOption.REPLACE_EXISTING);
+			
+			File instructions = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "instructions.txt");
+			Files.copy(instructions.toPath(), new File(folder.getAbsolutePath() + File.separator + "instructions.txt").toPath(), StandardCopyOption.REPLACE_EXISTING);
+			
+			File android = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "objectSpecs.txt");
+			Files.copy(android.toPath(), new File(folder.getAbsolutePath() + File.separator + "objectSpecs.txt").toPath(), StandardCopyOption.REPLACE_EXISTING);
+	
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 59 - 0
src/controller/SettingsController.java

@@ -0,0 +1,59 @@
+package controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.util.List;
+
+import model.Settings;
+
+/**
+ * Save and Load functions for the settings.ini
+ * @author Martin Herbers
+ *
+ */
+public class SettingsController {
+
+	private static Settings settings = Settings.getSettings();
+	
+	/**
+	 * Create or override a settings.ini file with all necessary information
+	 */
+	public static void saveSettings() {
+		try {
+			File file = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "settings.ini");
+			PrintWriter writer = new PrintWriter(file);
+			writer.print("[Settings]\r\n");
+			writer.print("Fill=" + settings.getFill() + "\r\n");
+			writer.print("SizeScreen=" + settings.getSizeScreen() + "\r\n");
+			writer.print("SizeFinger=" + settings.getSizeFinger() + "\r\n");
+			writer.print("OpenSCADPath=" + settings.getOpenSCADPath());
+			writer.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	/**
+	 * Parse the settings.ini
+	 */
+	public static void loadSettings() {
+		try {
+			File file = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "settings.ini");
+			if (file.exists()) {
+				List<String> lines = Files.readAllLines(file.toPath());
+				settings.setFill(Boolean.parseBoolean(lines.get(1).substring(lines.get(1).indexOf('=')+1)));
+				settings.setSizeScreen(Float.parseFloat(lines.get(2).substring(lines.get(2).indexOf('=')+1)));
+				settings.setSizeFinger(Float.parseFloat(lines.get(3).substring(lines.get(3).indexOf('=')+1)));
+				String path = lines.get(4).substring(lines.get(4).indexOf('=')+1);
+				if (path.equals("null"))
+					settings.setOpenSCADPath(null);
+				else
+					settings.setOpenSCADPath(new File(path).toPath());
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 135 - 0
src/model/Instructions.java

@@ -0,0 +1,135 @@
+package model;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Lists instructions for each object in its own function. Those are functions because otherwise it would only check the first time which string it should take (fill later or not)
+ * @author Martin Herbers
+ *
+ */
+public class Instructions {
+
+	public static List<String> getSqueezeInstruction() {
+		List<String> squeeze = Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding flexible filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 "NOTE: It can be difficult to get the flexible part to be leakproof. Try printing at a lower speed and/or using more filament (e.g. Cura: Flow 125%)",
+			 Settings.getSettings().getFill()?
+					 "5. When finished printing fill around 5ml of tap water with, for example, a syringe through the whole into the lower chamber. The needle needs to be straight downwards, otherwise the water will be in the wrong chamber.":
+					 "5. Pause the print at some point and fill around 5ml of tap water with, for example, a syringe through the cone into the lower chamber until it is full.",
+		 	 "6. If you want to check the object's current state, load the objectSpecs.txt into the Android app and place the object with the bottom on the screen.",
+		 	 "NOTE: If you're unsure which side is the top and wich one is the bottom: The conductive part with a bevel is the top one.",
+		 	 "NOTE: If you want to test whether no water got into the wrong chamber, test this object with the app before you start the interaction."
+		 	 );
+	
+		return squeeze;
+	}
+	
+	public static List<String> getWeightInstruction() {
+		List<String> weight = Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 "5. When finished printing cut off the print support area with e.g. scissors.",
+			 "6. During the test phase, the weight has to come from one flat side of the plate.",
+			 "7. If you want to check the object's current state, load the objectSpecs.txt into the Android app, place one plate on the touchscreen (ideally the one where the conductive part stands out more) and put your finger on the top plate's conductive part. You can use some pressure to counteract the support's spring effect.",
+			 "NOTE: If you want to test whether the conductive bars already have a connection, test this object wit hthe app before you start the interaction."
+			 );
+	
+		return weight;
+	}
+			
+	public static List<String> getTemperatureMeltInstruction() {
+		List<String> temperatureMelt = Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 Settings.getSettings().getFill()?
+					"5. When the print is finished, place the object on the side that is standing out, so that the side with only the conductive point is on top and the hole is on the side. Now fill some water through that hole with e.g. a syringe and freeze it either in the same position without tilting it or with the hole on the bottom. It can be helpful to seal the hole with a bit of glue.":
+					"5. Before the chamber without conductive parts gets closed, pause the print and fill in some ice or water. When you're done filling resume the print. If you chose water, freeze it with the same orientation.",
+			 "6. When the water is frozen, flip the object so the conductive point is on the top side. In this position the molten water will flow into the other chamber.",
+			 "7. If you want to check the current state of the object, load the objectSpecs.txt into the Android app and flip the object again (conductive part on the bottom). Let the object warm up for at least 30 minutes in this position. After that the state can be checked with the Android app.",
+			 "NOTE: If you're unsure which side with a conductive point is the top/bottom one and which is the one on the side, check for the printing direction. The top/bottom one is much smoother.",
+			 "NOTE: If you want to test whether no water got into the second chamber, test this object with the app before you start the interaction"
+			 );
+		
+		return temperatureMelt;
+	}
+	
+	public static List<String> getTemperatureFreezeInstruction() {
+		List<String> temperatureFreeze = Arrays.asList(
+				 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+				 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+				 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+				 "4. Print.",
+				 Settings.getSettings().getFill()?
+						"5. When the print is finished, fill around 8ml of tap water through the hole with, for example, a syringe. Ideally a bit of water comes back out. You can seal the hole with some glue.":
+						"5. Before the chamber without conductive parts gets closed, pause the printing and fill it with water. The more water the better it will work.",
+				 "6. When the print and filling finished, the object can be used instantly. When it freezes, the water ice will expand and break through the conductive wall. When melting again, the water will flow through the broken wall.",
+				 "7. If you want to check the current state of the object, load the objectSpecs.txt into the Android app and let the object warm up for at least 30 minutes. After that the state can be checked with the Android app.",
+				 "NOTE: If you want to test whether no water got into the wrong chamber (e.g. the wall isn't leakproof), test this object with the app before you start the interaction."
+				);
+		
+		return temperatureFreeze;
+	}
+
+	public static List<String> getAccelerationInstruction() {
+		List<String> acceleration = Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 Settings.getSettings().getFill()?
+					"5. Fill 3ml  of tap water with, for example, a syringe into the part without conductive material.":
+					"5. Before the ceiling gets printed, pause the print and fill 3ml of tap water into the chamber without conductive parts.",
+			 "NOTE: A small derivation of the water volume can change the acceleration at which the state changes, so try to be as accurate as possible.",
+			 "NOTE: Try to hold the object without tilt since a small tilt will change the acceleratoin at which the state changes.",
+			 "6. During the test phase and before reading the object's state try not to tilt it. The object will keep it's state until it gets tilted.",
+			 "7. If you want to check the object's current state, load the objectSpecs.txt into the Android app and place the bottom side of the object on the touchscreen and put your finger on conductive part on the side."
+			 );
+	
+		return acceleration;	
+	}
+	
+	public static List<String> getFlipInstruction() {
+		List<String> flip =  Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 Settings.getSettings().getFill()?
+					 "5. After the print finished fill around 4ml of tap water with, for example, a syringe through the hole into the middle part. Try holding both the object and the syringe straight upwards so no water can accidently get into the outer chamber. You can seal the hole with some glue.":
+					 "5. Before the ceiling gets printed, pause the print and fill 4ml of tap water into the middle chamber.",
+			 "6. During the test phase, small tilts won't change the state. Only around 90-270° tilts will change the state.",
+			 "7. If you want to check the current state of the object, load the objectSpecs.txt into the Android app and place the object on the screen. Put your finger on the conductive part on the side.",
+			 "NOTE: If you want to test whether no water got into the wrong chamber, test this object with the app before you start the interaction"
+			 );
+	
+		return flip;
+	}
+	
+	public static List<String> getTiltInstruction() {
+		List<String> tilt =  Arrays.asList( 
+			 "1. \"output.stl\" contains the main object, \"output_conductive.stl\" contains the object's conductive parts. Put \"objectSpecs.txt\" into the Android app.",
+			 "2. Import output.stl into your slicing software and set it's extruder to the one extruding non-conductive filament.",
+			 "3. Add output_conductive.stl as a part of your object and set it's extruder to the one extruding conductive filament.",
+			 "4. Print.",
+			 Settings.getSettings().getFill()?
+					 "5. After the print finished fill around 2ml of tap water with, for example, a syringe through the hole into the part further away from the electrodes.":
+					 "5. Before the ceiling gets printed, pause the print and fill 2ml of tap water into the chamber without conductive parts.",
+			 "6. During the test phase, small tilts won't change the state. Only around 45-135° tilts will change the state.",
+			 "7. If you want to check the current state of the object, load the objectSpecs.txt into the Android app and place the object on the screen. Put your finger on the conductive part on the side.",
+			 "NOTE: If you want to test whether no water got into the wrong chamber, test this object with the app before you start the interaction"
+			 );
+	
+		return tilt;
+	}
+	
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//New function that returns the textual instructions as a List of Strings
+}

+ 176 - 0
src/model/Settings.java

@@ -0,0 +1,176 @@
+package model;
+
+import java.nio.file.Path;
+
+/**
+ * This class saves the current settings. Those are needed for creating the STLs.
+ * @author Martin Herbers
+ *
+ */
+public class Settings {
+	public enum Temp {
+		UNDER0, OVER0
+	}
+	
+	public enum Tilt {
+		TILT, FLIP
+	}
+
+	//The 5 interactions that can currently be detected.
+	private boolean weight = false;
+	private boolean acceleration = false;
+	private boolean squeeze = false;
+	private boolean tilt = false;
+	private boolean temperature = false;
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//New boolean for each interaction, allows combining them later
+	
+	//Some more settings to create more interaction possibilities
+	private int weightSetting = 54;
+	private double accelerationSetting = 5;
+	private Temp temperatureSetting = Temp.OVER0;
+	private Tilt tiltSetting = Tilt.TILT;
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//Only if additional data is necessary
+	
+	//Settings from the settings window that can be used for multiple objects
+	private boolean fill = false;
+	private float sizeScreen = 4.0f;
+	private float sizeFinger = 4.0f;
+	private Path openScadPath = null;
+	
+	private static Settings settings = new Settings();
+	
+	public static Settings getSettings() {
+		return settings;
+	}
+	
+	public void addWeight() {
+		weight = true;
+	}
+	
+	public void removeWeight() {
+		weight = false;
+	}
+	
+	public boolean isWeight() {
+		return weight;
+	}
+	
+	public void addAcceleration() {
+		acceleration = true;
+	}
+	
+	public void removeAcceleration() {
+		acceleration = false;
+	}
+	
+	public boolean isAcceleration() {
+		return acceleration;
+	}
+	
+	public void addSqueeze() {
+		squeeze = true;
+	}
+	
+	public void removeSqueeze() {
+		squeeze = false;
+	}
+	
+	public boolean isSqueeze() {
+		return squeeze;
+	}
+	
+	public void addTilt() {
+		tilt = true;
+	}
+	
+	public void removeTilt() {
+		tilt = false;
+	}
+	
+	public boolean isTilt() {
+		return tilt;
+	}
+	
+	public void addTemperature() {
+		temperature = true;
+	}
+	
+	public void removeTemperature() {
+		temperature = false;
+	}
+	
+	public boolean isTemperature() {
+		return temperature;
+	}
+	
+	public void setWeight(int w) {
+		weightSetting = w;
+	}
+	
+	public int getWeight() {
+		return weightSetting;
+	}
+	
+	public void setAcceleration(double a) {
+		accelerationSetting = a;
+	}
+	
+	public double getAcceleration() {
+		return accelerationSetting;
+	}
+	
+	public void setTemperature(Temp t) {
+		temperatureSetting = t;
+	}
+	
+	public Temp getTemperature() {
+		return temperatureSetting;
+	}
+	
+	public void setTilting (Tilt t) {
+		tiltSetting = t;
+	}
+	
+	public Tilt getTilting() {
+		return tiltSetting;
+	}
+	
+	public void setFill(boolean b) {
+		fill = b;
+	}
+	
+	public boolean getFill() {
+		return fill;
+	}
+	
+	public void setSizeScreen(float f) {
+		sizeScreen = f;
+	}
+	
+	public float getSizeScreen() {
+		return sizeScreen;
+	}
+	
+	public void setSizeFinger(float f) {
+		sizeFinger = f;
+	}
+	
+	public float getSizeFinger() {
+		return sizeFinger;
+	}
+	
+	public void setOpenSCADPath(Path p) {
+		openScadPath = p;
+	}
+	
+	public Path getOpenSCADPath() {
+		return openScadPath;
+	}
+	
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//At least get/set for the boolean, possibly also for additional data like size
+	
+}
+

+ 108 - 0
src/model/Specifications.java

@@ -0,0 +1,108 @@
+package model;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * Lists the specification. Used for the Android app. Template:
+ * Name:[Object name, shown on top of the app]
+ * Shape:[object's shape and position][...]...
+ * Contact:[shape and position of the conductive part]
+ * ButtonTrue:[message that appears below the object on the app if the object did change its state]
+ * ButtonFalse:[initial message that stays if the object didn't change its state]
+ * 
+ * Shape information: 	rectangle: [R; x position from the object's middle; y position; width; height;]
+ * 						circle: [C; x position; y position; diameter]
+ * 						position and size in millimeter. E.g.: [R;5;5;20;20]
+ * @author Martin Herbers
+ *
+ */
+
+public class Specifications {
+	public static List<String> getSqueezeSpecs() {
+		List<String> squeeze = Arrays.asList( 
+				"Name:Squeeze",
+				"Shape:[C;0;0;26][R;0;" + (Settings.getSettings().getSizeScreen() + 12) + ";" + (Settings.getSettings().getSizeScreen() + 4) + ";" + (Settings.getSettings().getSizeScreen() + 4) + "]",
+				"Contact:[R;0;" + (Settings.getSettings().getSizeScreen() + 12) + ";" + Settings.getSettings().getSizeScreen() + ";" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object got squeezed!",
+				"ButtonFalse:The object didn't get squeezed."
+			 );
+		return squeeze;
+	}
+	
+	public static List<String> getWeightSpecs() {
+		List<String> weight = Arrays.asList( 
+				"Name:Weight " + (Settings.getSettings().getWeight()/10.0f) + "kg",
+				"Shape:[R;0;0;20;61]",
+				"Contact:[C;0;1;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:A weight of more than " + (Settings.getSettings().getWeight()/10.0f) + " Kg was applied!",
+				"ButtonFalse:A weight of less than " + (Settings.getSettings().getWeight()/10.0f) + " Kg was applied."
+			 );
+	
+		return weight;
+	}
+			
+	public static List<String> getTemperatureMeltSpecs() {
+		List<String> temperatureMelt = Arrays.asList( 
+				"Name:Melt",
+				"Shape:[R;0;0;20;42][R;0;-20;10;2]",
+				"Contact:[C;0;3;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object was stored above 0°C!",
+				"ButtonFalse:The object was cooled the whole time."
+			);
+		
+		return temperatureMelt;
+	}
+	
+	public static List<String> getTemperatureFreezeSpecs() {
+		List<String> temperatureFreeze = Arrays.asList(
+				"Name:Freeze",
+				"Shape:[R;0;0;20;43][C;10;-8;6]",
+				"Contact:[C;0;7;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object was stored below 0°C!",
+				"ButtonFalse:The object was above 0°C the whole time."
+				);
+		
+		return temperatureFreeze;
+	}
+
+	public static List<String> getAccelerationSpecs() {
+		List<String> acceleration = Arrays.asList( 
+				"Name:Acceleration " + Settings.getSettings().getAcceleration() + "m/s²",
+				"Shape:[R;0;0;20;40][C;0;-10;6][C;0;10;6]",
+				"Contact:[C;0;10;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object was accelerated with " + Settings.getSettings().getAcceleration() + "m/s²!",
+				"ButtonFalse:The object was accelerated with less than " + Settings.getSettings().getAcceleration() + "m/s²."
+			 );
+	
+		return acceleration;	
+	}
+	
+	public static List<String> getFlipSpecs() {
+		List<String> flip =  Arrays.asList( 
+				"Name:Flip",
+				"Shape:[C;0;0;34]",
+				"Contact:[C;0;0;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object got flipped!",
+				"ButtonFalse:The object didn't get flipped."
+			 );
+	
+		return flip;
+	}
+	
+	public static List<String> getTiltSpecs() {
+		List<String> tilt =  Arrays.asList( 
+				"Name:Tilt",
+				"Shape:[R;0;0;18;30]",
+				"Contact:[C;0;8;" + Settings.getSettings().getSizeScreen() + "]",
+				"ButtonTrue:The object got tilted!",
+				"ButtonFalse:The object didn't get tilted."
+			);
+	
+		return tilt;
+	}
+	
+	//ADD CODE HERE FOR ADDITIONAL INTERACTION
+	//New function that returns the specification as listed in the top comment in a List of Stings
+}

BIN
src/pictures/acceleration.png


BIN
src/pictures/blue.PNG


BIN
src/pictures/cog.png


BIN
src/pictures/cyan.PNG


BIN
src/pictures/gray.PNG


BIN
src/pictures/green.PNG


BIN
src/pictures/information-icon-6086.png


BIN
src/pictures/lightBlue.PNG


BIN
src/pictures/loadingCircle.gif


BIN
src/pictures/pressure.png


BIN
src/pictures/red.PNG


BIN
src/pictures/rotation.png


BIN
src/pictures/save.png


BIN
src/pictures/simpleAcceleration.png


BIN
src/pictures/simpleFlip.png


BIN
src/pictures/simpleSqueeze.png


BIN
src/pictures/simpleTemperatureFreeze.png


BIN
src/pictures/simpleTemperatureMelt.png


BIN
src/pictures/simpleTilt.png


BIN
src/pictures/simpleWeight.png


BIN
src/pictures/temperature.png


BIN
src/pictures/weight.png


+ 52 - 0
src/ui/InformationWindow.fxml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TitledPane?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
+
+<HBox xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
+   <children>
+      <VBox prefHeight="200.0" prefWidth="100.0" HBox.hgrow="ALWAYS">
+         <children>
+            <TitledPane animated="false" collapsible="false" prefHeight="1071.0" prefWidth="184.0" text="Functional Principle" VBox.vgrow="ALWAYS">
+               <content>
+                  <HBox>
+                     <children>
+                        <Label fx:id="text1" alignment="TOP_LEFT" text="Label" wrapText="true" />
+                     </children>
+                  </HBox>
+               </content>
+               <VBox.margin>
+                  <Insets bottom="10.0" left="10.0" top="10.0" />
+               </VBox.margin>
+            </TitledPane>
+         </children>
+      </VBox>
+      <TitledPane collapsible="false" text="Preview" VBox.vgrow="ALWAYS">
+         <VBox.margin>
+            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+         </VBox.margin>
+         <content>
+            <VBox fx:id="previewPane" alignment="CENTER_LEFT" prefHeight="1038.0" prefWidth="228.0" spacing="3.0">
+               <children>
+                  <ImageView fx:id="image" fitHeight="200.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true">
+                     <VBox.margin>
+                        <Insets bottom="10.0"/>
+                     </VBox.margin>
+                  </ImageView>
+                  <Label fx:id="greenText" text="Object's walls" />
+                  <Label fx:id="redText" text="Conductive parts" />
+                  <Label fx:id="blueText" text="Water" />
+                  <Label fx:id="iceText" text="Ice" />
+               </children>
+            </VBox>
+         </content>
+         <HBox.margin>
+            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+         </HBox.margin>
+      </TitledPane>
+   </children>
+</HBox>

+ 895 - 0
src/ui/Main.java

@@ -0,0 +1,895 @@
+package ui;
+
+import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
+import controller.Controller;
+import controller.Export;
+import controller.SettingsController;
+import javafx.animation.KeyFrame;
+import javafx.animation.Timeline;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.concurrent.Task;
+import javafx.event.EventHandler;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.*;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.*;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.PhongMaterial;
+import javafx.scene.shape.Mesh;
+import javafx.scene.shape.MeshView;
+import javafx.scene.transform.Rotate;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.util.Duration;
+import model.Settings;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Collections;
+
+public class Main extends Application {
+
+	private static Main window;
+
+    //Save the last x/y value of the mouse, used for rotating the object in the javaFX panel
+    private int lastX = 0;
+    private int lastY = 0;
+
+    //Which view is currently used for the javaFX panel
+    private static final int VIEW_ALL = 0;
+    private static final int VIEW_CONDUCTIVE = 1;
+    private static final int VIEW_NON_CONDUCTIVE = 2;
+    private static final int VIEW_CROSS_SECTION = 3;
+
+    //If creating the STLs is finished. If yes, change the javaFX view
+    private static boolean finished = false;
+    //If the openSCAD installation got detected. If not, show a message.
+    private static boolean detected = true;
+
+    private CheckBox accelerationCheckBox;
+    private Label accelerationLabel;
+    private CheckBox weightCheckBox;
+    private Label weightLabel;
+    private CheckBox tempCheckBox;
+    private Label tempLabel;
+    private CheckBox rotationCheckBox;
+    private Label rotationLabel;
+    private CheckBox pressureCheckBox;
+    private Label pressureLabel;
+    private Button createObjectButton;
+    private ComboBox<String> comboBox;
+    private Pane fxPanel;
+    private Group rootGroup;
+    private StackPane glassPane;
+	private Parent root;
+	private Spinner<String> accelerationSpinner;
+	private Spinner<String> loadSpinner;
+
+	@Override
+    public void start(Stage primaryStage) throws Exception{
+
+        root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
+        primaryStage.setTitle("Off-Line Interactor Printing");
+
+        primaryStage.setOnCloseRequest(e -> {
+			try {
+				Platform.exit();
+			}
+			catch (Exception e1) {
+				e1.printStackTrace();
+			}
+		});
+
+        UIController.setPath(getClass().getResource("/pictures/acceleration.png").toString().replace("acceleration.png", ""));
+
+        Node nodeAccel = root.lookup("#accelerationPane");
+        TitledPane pane = (TitledPane) nodeAccel;
+        BorderPane borderPane = new BorderPane();
+        accelerationCheckBox = new CheckBox();
+        borderPane.setLeft(accelerationCheckBox);
+        BorderPane.setAlignment(accelerationCheckBox, Pos.CENTER_LEFT);
+        accelerationLabel = new Label(" Acceleration");
+
+        accelerationLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				accelerationCheckBox.setSelected(!accelerationCheckBox.isSelected());
+				accelerationClicked();
+			}
+		});
+        Image imgAccelSymbol = new Image(getClass().getResource("/pictures/acceleration.png").toString());
+		ImageView imViewAccelSymbol = new ImageView(imgAccelSymbol);
+		imViewAccelSymbol.setFitWidth(30);
+		imViewAccelSymbol.setFitHeight(30);
+        accelerationLabel.setGraphic(imViewAccelSymbol);
+        borderPane.setCenter(accelerationLabel);
+        pane.setGraphic(borderPane);
+        accelerationCheckBox.setOnAction(event -> {
+			accelerationClicked();
+			event.consume();
+		});
+
+        Node nodeWeight = root.lookup("#weightPane");
+        TitledPane paneWeight = (TitledPane) nodeWeight;
+        BorderPane borderPaneWeight = new BorderPane();
+        weightCheckBox = new CheckBox();
+        borderPaneWeight.setLeft(weightCheckBox);
+		BorderPane.setAlignment(weightCheckBox, Pos.CENTER_LEFT);
+        weightLabel = new Label(" Load");
+        weightLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				weightCheckBox.setSelected(!weightCheckBox.isSelected());
+				weightClicked();
+			}
+		});
+		Image imgWeightSymbol = new Image(getClass().getResource("/pictures/weight.png").toString());
+		ImageView imViewWeightSymbol = new ImageView(imgWeightSymbol);
+		imViewWeightSymbol.setFitWidth(30);
+		imViewWeightSymbol.setFitHeight(30);
+		weightLabel.setGraphic(imViewWeightSymbol);
+        borderPaneWeight.setCenter(weightLabel);
+        paneWeight.setGraphic(borderPaneWeight);
+        weightCheckBox.setOnAction(event -> {
+			weightClicked();
+			event.consume();
+		});
+
+        Node nodeTemp = root.lookup("#temperaturePane");
+        TitledPane paneTemp = (TitledPane) nodeTemp;
+        BorderPane borderPaneTemp = new BorderPane();
+        tempCheckBox = new CheckBox();
+        borderPaneTemp.setLeft(tempCheckBox);
+		BorderPane.setAlignment(tempCheckBox, Pos.CENTER_LEFT);
+        tempLabel = new Label(" Temperature");
+		tempLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				tempCheckBox.setSelected(!tempCheckBox.isSelected());
+				temperatureClicked();
+			}
+		});
+		Image imgTempSymbol = new Image(getClass().getResource("/pictures/temperature.png").toString());
+		ImageView imViewTempSymbol = new ImageView(imgTempSymbol);
+		imViewTempSymbol.setFitWidth(14);
+		imViewTempSymbol.setFitHeight(30);
+		tempLabel.setGraphic(imViewTempSymbol);
+        borderPaneTemp.setCenter(tempLabel);
+        paneTemp.setGraphic(borderPaneTemp);
+        tempCheckBox.setOnAction(event -> {
+			temperatureClicked();
+			event.consume();
+		});
+
+        Node nodeRotation = root.lookup("#rotationPane");
+        TitledPane paneRotation = (TitledPane) nodeRotation;
+        BorderPane borderPaneRotation = new BorderPane();
+        rotationCheckBox = new CheckBox();
+        borderPaneRotation.setLeft(rotationCheckBox);
+		BorderPane.setAlignment(rotationCheckBox, Pos.CENTER_LEFT);
+        rotationLabel = new Label(" Rotation");
+        rotationLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				rotationCheckBox.setSelected(!rotationCheckBox.isSelected());
+				rotationClicked();
+			}
+		});
+		Image imgRotationSymbol = new Image(getClass().getResource("/pictures/rotation.png").toString());
+		ImageView imViewRotationSymbol = new ImageView(imgRotationSymbol);
+		imViewRotationSymbol.setFitWidth(30);
+		imViewRotationSymbol.setFitHeight(30);
+		rotationLabel.setGraphic(imViewRotationSymbol);
+        borderPaneRotation.setCenter(rotationLabel);
+        paneRotation.setGraphic(borderPaneRotation);
+        rotationCheckBox.setOnAction(event -> {
+			rotationClicked();
+			event.consume();
+		});
+
+        Node nodePressure = root.lookup("#pressurePane");
+        TitledPane panePressure = (TitledPane) nodePressure;
+        BorderPane borderPanePressure = new BorderPane();
+        pressureCheckBox = new CheckBox();
+        borderPanePressure.setLeft(pressureCheckBox);
+		BorderPane.setAlignment(pressureCheckBox, Pos.CENTER_LEFT);
+        pressureLabel = new Label(" Pressure");
+        pressureLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+			@Override
+			public void handle(MouseEvent event) {
+				pressureCheckBox.setSelected(!pressureCheckBox.isSelected());
+				pressureClicked();
+			}
+		});
+		Image imgPressureSymbol = new Image(getClass().getResource("/pictures/pressure.png").toString());
+		ImageView imViewPressureSymbol = new ImageView(imgPressureSymbol);
+		imViewPressureSymbol.setFitWidth(30);
+		imViewPressureSymbol.setFitHeight(30);
+		pressureLabel.setGraphic(imViewPressureSymbol);
+        borderPanePressure.setCenter(pressureLabel);
+        panePressure.setGraphic(borderPanePressure);
+        pressureCheckBox.setOnAction(event -> {
+			pressureClicked();
+			event.consume();
+		});
+
+
+        primaryStage.setScene(new Scene(root, 1280, 720));
+        primaryStage.show();
+
+
+		accelerationLabel.setMinWidth(((TitledPane) nodeAccel).getWidth() * 0.83);
+		weightLabel.setMinWidth(((TitledPane) nodeAccel).getWidth() * 0.83);
+		tempLabel.setMinWidth(((TitledPane) nodeAccel).getWidth() * 0.83);
+		rotationLabel.setMinWidth(((TitledPane) nodeAccel).getWidth() * 0.83);
+		pressureLabel.setMinWidth(((TitledPane) nodeAccel).getWidth() * 0.83);
+
+		ObservableList<String> accelerationEntries = FXCollections.observableArrayList("5.0 m/s²", "12.0 m/s²");
+		accelerationSpinner = new Spinner<>();
+		SpinnerValueFactory<String> accelerationValueFactory = new SpinnerValueFactory<String>() {
+			@Override
+			public void decrement(int steps) {
+				String current = this.getValue();
+				int index = accelerationEntries.indexOf(current);
+				this.setValue(accelerationEntries.get((accelerationEntries.size() + index - steps)%accelerationEntries.size()));
+				double value = Double.parseDouble(this.getValue().replace(" m/s²", ""));
+				Controller.getC().setAcceleration(value);
+			}
+
+			@Override
+			public void increment(int steps) {
+				String current = this.getValue();
+				int index = accelerationEntries.indexOf(current);
+				this.setValue(accelerationEntries.get((index + steps)%accelerationEntries.size()));
+				double value = Double.parseDouble(this.getValue().replace(" m/s²", ""));
+				Controller.getC().setAcceleration(value);
+			}
+		};
+		accelerationValueFactory.setValue("5.0 m/s²");
+		accelerationSpinner.setValueFactory(accelerationValueFactory);
+		accelerationSpinner.setDisable(true);
+		accelerationSpinner.setMaxWidth(120);
+
+		HBox accelHBox = ((HBox)root.lookup("#accelerationContent"));
+		accelHBox.getChildren().add(accelerationSpinner);
+		ObservableList<Node> workingCollection = FXCollections.observableArrayList(accelHBox.getChildren());
+		Collections.swap(workingCollection, 1, 3);
+		Collections.swap(workingCollection, 2, 3);
+		accelHBox.getChildren().setAll(workingCollection);
+
+		ObservableList<String> loadEntries = FXCollections.observableArrayList("5.4 Kg", "10.8 Kg", "16.2 Kg");
+		loadSpinner = new Spinner<>();
+		SpinnerValueFactory<String> loadValueFactory = new SpinnerValueFactory<String>() {
+			@Override
+			public void decrement(int steps) {
+				String current = this.getValue();
+				int index = loadEntries.indexOf(current);
+				this.setValue(loadEntries.get((loadEntries.size() + index - steps)%loadEntries.size()));
+				double value = Double.parseDouble(this.getValue().replace(" Kg", ""));
+				Controller.getC().setWeight((int)(value*10));
+			}
+
+			@Override
+			public void increment(int steps) {
+				String current = this.getValue();
+				int index = loadEntries.indexOf(current);
+				this.setValue(loadEntries.get((index + steps)%loadEntries.size()));
+				double value = Double.parseDouble(this.getValue().replace(" Kg", ""));
+				Controller.getC().setWeight((int)(value*10));
+			}
+		};
+		loadValueFactory.setValue("5.4 Kg");
+		loadSpinner.setValueFactory(loadValueFactory);
+		loadSpinner.setDisable(true);
+		loadSpinner.setMaxWidth(120);
+
+		HBox loadHBox = ((HBox)root.lookup("#weightContent"));
+		loadHBox.getChildren().add(loadSpinner);
+		ObservableList<Node> loadWorkingCollection = FXCollections.observableArrayList(loadHBox.getChildren());
+		Collections.swap(loadWorkingCollection, 1, 3);
+		Collections.swap(loadWorkingCollection, 2, 3);
+		loadHBox.getChildren().setAll(loadWorkingCollection);
+
+      /*  ((ScrollBar) root.lookup("#accelerationScrollBar")).valueProperty().addListener((observable, oldValue, newValue) -> {
+			double d = newValue.intValue();
+			Controller.getC().setAcceleration(d);
+			((Label) root.lookup("#accelerationLabel")).setText("Acceleration limit: " + d + " m/s²");
+		});
+
+        ((ScrollBar) root.lookup("#weightScrollBar")).valueProperty().addListener((observable, oldValue, newValue) -> {
+			int w = newValue.intValue();
+			Controller.getC().setWeight(w);
+			((Label) root.lookup("#weightLabel")).setText("Load limit: " + (w/10.0) + " Kg");
+		});*/
+
+        ToggleGroup groupTemp = new ToggleGroup();
+        ((RadioButton) root.lookup("#temperatureRadio1")).setToggleGroup(groupTemp);
+        ((RadioButton) root.lookup("#temperatureRadio2")).setToggleGroup(groupTemp);
+
+        ((RadioButton) root.lookup("#temperatureRadio1")).selectedProperty().addListener((observable, oldValue, newValue) -> {
+			if (newValue)
+				Controller.getC().setTemperature(Settings.Temp.OVER0);
+		});
+
+        ((RadioButton) root.lookup("#temperatureRadio2")).selectedProperty().addListener((observable, oldValue, newValue) -> {
+			if (newValue)
+				Controller.getC().setTemperature(Settings.Temp.UNDER0);
+		});
+
+        ToggleGroup groupTilt = new ToggleGroup();
+        ((RadioButton) root.lookup("#rotationRadio1")).setToggleGroup(groupTilt);
+        ((RadioButton) root.lookup("#rotationRadio2")).setToggleGroup(groupTilt);
+
+        ((RadioButton) root.lookup("#rotationRadio1")).selectedProperty().addListener((observable, oldValue, newValue) -> {
+			if (newValue)
+				Controller.getC().setTilt(Settings.Tilt.TILT);
+		});
+
+        ((RadioButton) root.lookup("#rotationRadio2")).selectedProperty().addListener((observable, oldValue, newValue) -> {
+			if (newValue)
+				Controller.getC().setTilt(Settings.Tilt.FLIP);
+		});
+
+
+        fxPanel = (Pane) root.lookup("#fxPanel");
+
+        SubScene subScene = createScene();
+        fxPanel.getChildren().add(subScene);
+        subScene.heightProperty().bind(fxPanel.heightProperty());
+        subScene.widthProperty().bind(fxPanel.widthProperty());
+
+
+        fxPanel.setOnMousePressed(event -> {
+			lastX = (int) event.getX();
+			lastY = (int) event.getY();
+		});
+
+        fxPanel.setOnMouseDragged(event -> {
+			//Rotation
+			Group root1 = rootGroup;//(SubScene) fxPanel.getChildren().get(1);
+			Rotate rY = (Rotate) root1.getTransforms().get(0);
+			rY.setAngle(rY.getAngle()+ event.getY() - lastY);
+			lastY = (int) event.getY();
+
+			Rotate rX = (Rotate) root1.getTransforms().get(1);
+			rX.setAngle(rX.getAngle()+ event.getX() - lastX);
+			lastX = (int) event.getX();
+		});
+
+        fxPanel.setOnScroll(event -> {
+			//Zooming
+			Group root12 = rootGroup;//(SubScene) fxPanel.getChildren().get(1);
+			int direction;
+			if (root12.getScaleX() > 0) {
+				if (event.getDeltaY() > 0)
+					direction = 1;
+				else
+					direction = -1;
+			}
+			else {
+				if (event.getDeltaY() > 0)
+					direction = 1;
+				else
+					direction = 0;
+			}
+
+			root12.setScaleX(root12.getScaleX() + direction);
+			root12.setScaleY(root12.getScaleY() + direction);
+			root12.setScaleZ(root12.getScaleZ() + direction);
+		});
+
+        comboBox = (ComboBox<String>) root.lookup("#comboBox");
+        ObservableList<String> options = FXCollections.observableArrayList(
+                "Show All Parts",
+                "Show Conductive Only",
+                "Show Non-Conductive Only",
+                "Show Cross-Section"
+        );
+        comboBox.getItems().addAll(options);
+        comboBox.setValue(options.get(3));
+        comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> Platform.runLater(() -> {
+        	clearView((SubScene)fxPanel.getChildren().get(0));
+			int index = -1;
+			switch (newValue) {
+				case "Show All Parts": index = 0; break;
+				case "Show Conductive Only": index = 1; break;
+				case "Show Non-Conductive Only": index = 2; break;
+				case "Show Cross-Section": index = 3; break;
+			}
+			changeObject((SubScene)fxPanel.getChildren().get(0), index);
+		}));
+
+        createObjectButton = (Button) root.lookup("#createObjectButton");
+        Image imageCreate = new Image(getClass().getResource("/pictures/cog.png").toString());
+        ImageView imageViewCreate = new ImageView(imageCreate);
+        imageViewCreate.setFitWidth(30);
+        imageViewCreate.setFitHeight(30);
+        createObjectButton.setGraphic(imageViewCreate);
+        createObjectButton.setContentDisplay(ContentDisplay.LEFT);
+        createObjectButton.setOnAction(event -> {
+			Task task = new Task() {
+
+				@Override
+				protected Void call() throws Exception {
+					Export.createSTL();
+					return null;
+				}
+			};
+			task.setOnSucceeded( e -> {
+				glassPane.setVisible(false);
+			});
+			task.setOnRunning(e -> {
+				glassPane.setVisible(true);
+				clearView((SubScene) fxPanel.getChildren().get(0));
+				this.root.lookup("#saveObjectButton").setDisable(true);
+			});
+
+			new Thread(task).start();
+			//Same as above
+
+			comboBox.setDisable(false);
+			Task task2 = new Task() {
+
+				@Override
+				protected Void call() throws Exception {
+					while (!finished) {
+						try {
+							Thread.sleep(100);
+						} catch (InterruptedException e) {
+							e.printStackTrace();
+						}
+					}
+					finished = false;
+					int index = -1;
+					switch (comboBox.getValue()) {
+						case "Show All Parts": index = 0; break;
+						case "Show Conductive Only": index = 1; break;
+						case "Show Non-Conductive Only": index = 2; break;
+						case "Show Cross-Section": index = 3; break;
+					}
+					int finalIndex = index;
+					Platform.runLater(() -> changeObject((SubScene) fxPanel.getChildren().get(0), finalIndex));
+					return null;
+				}
+			};
+			new Thread(task2).start();
+		});
+		Button saveObjectButton = ((Button) root.lookup("#saveObjectButton"));
+		Image imageSave = new Image(getClass().getResource("/pictures/save.png").toString());
+		ImageView imageViewSave = new ImageView(imageSave);
+		imageViewSave.setFitWidth(30);
+		imageViewSave.setFitHeight(30);
+		saveObjectButton.setGraphic(imageViewSave);
+		saveObjectButton.setContentDisplay(ContentDisplay.LEFT);
+		saveObjectButton.setOnAction(event -> {
+			DirectoryChooser chooser = new DirectoryChooser();
+			Platform.runLater(() -> {
+				File file = chooser.showDialog(primaryStage);
+
+				if (file != null) {
+					Export.saveFilesTo(file);
+				}
+			});
+		/*	JFileChooser chooser = new JFileChooser();
+			chooser.setCurrentDirectory(new File("."));
+			chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+			chooser.setAcceptAllFileFilterUsed(false);
+			chooser.showOpenDialog(null);
+
+			if (chooser.getSelectedFile() != null) {
+				Export.saveFilesTo(chooser.getSelectedFile());
+			}*/
+		});
+
+        Image image = new Image(getClass().getResource("/pictures/information-icon-6086.png").toString());
+        ImageView imViewAccel = new ImageView(image);
+        imViewAccel.setFitWidth(15);
+        imViewAccel.setFitHeight(15);
+		((Button) root.lookup("#accelerationInfo")).setGraphic(imViewAccel);
+		ImageView imViewWeight = new ImageView(image);
+		imViewWeight.setFitWidth(15);
+		imViewWeight.setFitHeight(15);
+		((Button) root.lookup("#weightInfo")).setGraphic(imViewWeight);
+		ImageView imViewFreeze = new ImageView(image);
+		imViewFreeze.setFitWidth(15);
+		imViewFreeze.setFitHeight(15);
+		((Button) root.lookup("#freezeInfo")).setGraphic(imViewFreeze);
+		ImageView imViewMelt = new ImageView(image);
+		imViewMelt.setFitWidth(15);
+		imViewMelt.setFitHeight(15);
+		((Button) root.lookup("#meltInfo")).setGraphic(imViewMelt);
+		ImageView imViewTilt = new ImageView(image);
+		imViewTilt.setFitWidth(15);
+		imViewTilt.setFitHeight(15);
+		((Button) root.lookup("#tiltInfo")).setGraphic(imViewTilt);
+		ImageView imViewFlip = new ImageView(image);
+		imViewFlip.setFitWidth(15);
+		imViewFlip.setFitHeight(15);
+		((Button) root.lookup("#flipInfo")).setGraphic(imViewFlip);
+		ImageView imViewSqueeze = new ImageView(image);
+		imViewSqueeze.setFitWidth(15);
+		imViewSqueeze.setFitHeight(15);
+		((Button) root.lookup("#squeezeInfo")).setGraphic(imViewSqueeze);
+
+		Image imageSettings = new Image(getClass().getResource("/pictures/cog.png").toString());
+		ImageView imageViewSettings = new ImageView(imageSettings);
+		imageViewSettings.setFitWidth(20);
+		imageViewSettings.setFitHeight(20);
+		((Button)root.lookup("#settingsButton")).setGraphic(imageViewSettings);
+
+
+        glassPane = new StackPane();
+        glassPane.setStyle("-fx-background-color: rgba(0, 0, 0, 0.2);");
+        glassPane.setVisible(false);
+        Label loadingLabel = new Label("Creating Object...");
+        Image loadingImage = new Image(getClass().getResource("/pictures/loadingCircle.gif").toString());
+        ImageView imView = new ImageView(loadingImage);
+        imView.setFitHeight(16);
+        imView.setFitWidth(128);
+      //  loadingLabel.setGraphic(new ImageView(image));
+		VBox vb = new VBox();
+
+		//ProgressBar pbar = new ProgressBar();
+		//pbar.setProgress(0.5);
+
+		vb.setAlignment(Pos.CENTER);
+		//vb.getChildren().add(pbar);
+		vb.getChildren().add(imView);
+		vb.getChildren().add(loadingLabel);
+		glassPane.getChildren().add(vb);
+		StackPane.setAlignment(vb, Pos.CENTER);
+        ((GridPane)root).add(glassPane, 1, 0);
+
+        //If openSCAD could not be found, show a warning. The text depends on the OS.
+        if (!detected) {
+            if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+                Alert alert = new Alert(Alert.AlertType.INFORMATION);
+                alert.initStyle(StageStyle.UTILITY);
+                alert.setTitle("Information");
+                alert.setHeaderText("Warning");
+                alert.setContentText("Couldn't find openscad.exe.\nMake sure that OpenSCAD is installed and select its folder under Menu -> Settings.");
+
+                alert.showAndWait();
+            }
+            else if (System.getProperty("os.name").toLowerCase().contains("linux")) {
+                Alert alert = new Alert(Alert.AlertType.INFORMATION);
+                alert.initStyle(StageStyle.UTILITY);
+                alert.setTitle("Information");
+                alert.setHeaderText("Warning");
+                alert.setContentText("Couldn't find openscad.\nMake sure that OpenSCAD is installed and is visible gloabaly.");
+
+                alert.showAndWait();
+            }
+            else if (System.getProperty("os.name").toLowerCase().contains("mac")) {
+                Alert alert = new Alert(Alert.AlertType.INFORMATION);
+                alert.initStyle(StageStyle.UTILITY);
+                alert.setTitle("Information");
+                alert.setHeaderText("Warning");
+                alert.setContentText("Couldn't find openscad.app.\nMake sure that OpenSCAD is installed and select its folder under Menu -> Settings.");
+
+                alert.showAndWait();
+            }
+        }
+    }
+
+
+    public static void main(String[] args) {
+        //Load the settings.ini
+        try {
+            File file = new File(new java.io.File( "." ).getCanonicalPath() + File.separator + "settings.ini");
+            if (file.exists())
+                SettingsController.loadSettings();
+            else {
+                //If there isn't a settings.ini file, create a new one and search if OpenSCAD is installed.
+                //Windows: exe typically under the given path.
+                if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+                    File openscadexe = new File("C:\\Program Files\\OpenSCAD\\openscad.exe");
+                    if (openscadexe.exists())
+                        Controller.getC().setOpenSCADPath(openscadexe.toPath().getParent());
+                    else {
+                        notDetected();
+                    }
+                }
+                //Linux: OpenSCAD is visible globally, so check via command line
+                else if (System.getProperty("os.name").toLowerCase().contains("linux")) {
+                    try {
+                        Process p = Runtime.getRuntime().exec("which openscad");
+                        p.waitFor();
+                        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+                        String s = in.readLine();
+                        if (s != null) {
+                            Controller.getC().setOpenSCADPath(new File(s).toPath());
+                        }
+                        else {
+                            notDetected();
+                        }
+                    } catch (IOException | InterruptedException e1) {
+                        e1.printStackTrace();
+                    }
+                }
+                //MacOS: OpenSCAD is installed as an app, so look for in in the application folder
+                else if (System.getProperty("os.name").toLowerCase().contains("mac")) {
+                    File openscadapp = new File("/Applications/OpenSCAD.app");
+                    if (openscadapp.exists())
+                        Controller.getC().setOpenSCADPath(new File(openscadapp.toPath().toString() + "/Contents/MacOS/").toPath());
+                    else
+                        notDetected();
+                }
+                SettingsController.saveSettings();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        launch(args);
+    }
+
+    private void accelerationClicked() {
+		boolean disable = accelerationCheckBox.isSelected();
+
+		createObjectButton.setDisable(!disable);
+		disableWeight();
+		disableTemperature();
+		disableRotation();
+		disablePressure();
+
+		root.lookup("#accelerationLabel").setDisable(!disable);
+		accelerationSpinner.setDisable(!disable);
+
+		Controller.getC().acceleration(disable);
+	}
+
+	private void disableAcceleration() {
+		accelerationCheckBox.setSelected(false);
+		Controller.getC().acceleration(false);
+		root.lookup("#accelerationLabel").setDisable(true);
+		accelerationSpinner.setDisable(true);
+	}
+
+	private void weightClicked() {
+		boolean disable = weightCheckBox.isSelected();
+
+		createObjectButton.setDisable(!disable);
+		disableAcceleration();
+		disableTemperature();
+		disableRotation();
+		disablePressure();
+
+		root.lookup("#weightLabel").setDisable(!disable);
+		loadSpinner.setDisable(!disable);
+
+		Controller.getC().weight(disable);
+	}
+
+	private void disableWeight() {
+		weightCheckBox.setSelected(false);
+		Controller.getC().weight(false);
+		root.lookup("#weightLabel").setDisable(true);
+		loadSpinner.setDisable(true);
+	}
+
+	private void temperatureClicked() {
+		boolean disable = tempCheckBox.isSelected();
+
+		createObjectButton.setDisable(!disable);
+		disableWeight();
+		disableAcceleration();
+		disableRotation();
+		disablePressure();
+
+		root.lookup("#temperatureRadio1").setDisable(!disable);
+		root.lookup("#temperatureRadio2").setDisable(!disable);
+
+		Controller.getC().temperature(disable);
+	}
+
+	private void disableTemperature() {
+		tempCheckBox.setSelected(false);
+		Controller.getC().temperature(false);
+		root.lookup("#temperatureRadio1").setDisable(true);
+		root.lookup("#temperatureRadio2").setDisable(true);
+	}
+
+	private void rotationClicked() {
+		boolean disable = rotationCheckBox.isSelected();
+
+		createObjectButton.setDisable(!disable);
+		disableWeight();
+		disableTemperature();
+		disableAcceleration();
+		disablePressure();
+
+		root.lookup("#rotationRadio1").setDisable(!disable);
+		root.lookup("#rotationRadio2").setDisable(!disable);
+
+		Controller.getC().tilt(disable);
+	}
+
+	private void disableRotation() {
+		rotationCheckBox.setSelected(false);
+		Controller.getC().tilt(false);
+		root.lookup("#rotationRadio1").setDisable(true);
+		root.lookup("#rotationRadio2").setDisable(true);
+	}
+
+	private void pressureClicked() {
+		boolean disable = pressureCheckBox.isSelected();
+
+		createObjectButton.setDisable(!disable);
+		disableWeight();
+		disableTemperature();
+		disableRotation();
+		disableAcceleration();
+
+		//root.lookup("#pressureContent").setDisable(!disable);
+
+		Controller.getC().squeeze(disable);
+	}
+
+	private void disablePressure() {
+		pressureCheckBox.setSelected(false);
+		Controller.getC().squeeze(false);
+	}
+
+    /**
+     * Initialize the JavaFX panel
+     * @return	initialized panel
+     */
+    private SubScene createScene() {
+        rootGroup  =  new  Group();
+        SubScene  scene  =  new  SubScene(rootGroup, 1000, 1000, true, null);
+        scene.setFill(new Color(0.9, 0.9, 0.9, 1.0));
+
+        Timeline timer = new Timeline(new KeyFrame(Duration.seconds(0.001667), event -> {
+			rootGroup.setTranslateX(fxPanel.getWidth()/2);
+			rootGroup.setTranslateY(fxPanel.getHeight()/2);
+
+		}));
+        timer.setCycleCount(Timeline.INDEFINITE);
+        timer.play();
+
+		rootGroup.setScaleX(Math.min(fxPanel.getWidth()/80, fxPanel.getHeight()/80));
+		rootGroup.setScaleY(Math.min(fxPanel.getWidth()/80, fxPanel.getHeight()/80));
+		rootGroup.setScaleZ(Math.min(fxPanel.getWidth()/80, fxPanel.getHeight()/80));
+
+        //rootGroup.setTranslateX(400);
+        //rootGroup.setTranslateY(400);
+        rootGroup.setTranslateZ(0);
+        Rotate r = new Rotate();
+        r.setAngle(-60);
+        r.setAxis(Rotate.Y_AXIS);
+        rootGroup.getTransforms().add(r);
+        Rotate r2 = new Rotate();
+        r.setAxis(Rotate.X_AXIS);
+        r2.setAngle(-20);
+        rootGroup.getTransforms().add(r2);
+
+        rootGroup.getChildren().add(new AmbientLight(Color.WHITE));
+
+        return scene;
+    }
+
+    /**
+     * Reload the object (changes if another object got created) or just change the view mode
+     * @param scene     area to show the 3d scene
+     * @param viewMode  view mode, dependend on dropdown menu
+     */
+    private void changeObject(SubScene scene, int viewMode) {
+
+		Label previewlabel = ((Label) this.root.lookup("#previewLabel"));
+		Label propertiesLabel = ((Label) this.root.lookup("#propertiesLabel"));
+		if (Settings.getSettings().isAcceleration()) {
+			previewlabel.setText("Preview for Acceleration");
+			propertiesLabel.setText("Acceleration Limit: " + Settings.getSettings().getAcceleration() + " m/s²\n" +
+					"Fill Hole " + (Controller.getC().getFill()?"enabled":"disabled")+ "\n" +
+					"Touchscreen Dot Size " + Controller.getC().getSizeScreen() + " mm\n" +
+					"Finger Dot Size " + Controller.getC().getSizeFinger() + " mm");
+		} else if (Settings.getSettings().isWeight()) {
+			previewlabel.setText("Preview for Load");
+			propertiesLabel.setText("Weight Limit: " + Settings.getSettings().getWeight()/10.0 + " Kg\n" +
+					"Fill Hole " + (Controller.getC().getFill()?"enabled":"disabled")+ "\n" +
+					"Touchscreen Dot Size " + Controller.getC().getSizeScreen() + " mm\n" +
+					"Finger Dot Size " + Controller.getC().getSizeFinger() + " mm");
+		} else if (Settings.getSettings().isTemperature()) {
+			previewlabel.setText("Preview for Temperature");
+			propertiesLabel.setText((Settings.getSettings().getTemperature()== Settings.Temp.OVER0?"Rising":"Falling") + " Temperature\n" +
+					"Fill Hole " + (Controller.getC().getFill()?"enabled":"disabled") + "\n" +
+					"Touchscreen Dot Size " + Controller.getC().getSizeScreen() + " mm\n" +
+					"Finger Dot Size " + Controller.getC().getSizeFinger() + " mm");
+		} else if (Settings.getSettings().isTilt()) {
+			previewlabel.setText("Preview for Rotation");
+			propertiesLabel.setText("Rotation by " + (Settings.getSettings().getTilting()== Settings.Tilt.TILT?"90°":"180°") + "\n" +
+					"Fill Hole " + (Controller.getC().getFill()?"enabled":"disabled")+ "\n" +
+					"Touchscreen Dot Size " + Controller.getC().getSizeScreen() + " mm\n" +
+					"Finger Dot Size " + Controller.getC().getSizeFinger() + " mm");
+		} else if (Settings.getSettings().isSqueeze()) {
+			previewlabel.setText("Preview for Pressure");
+			propertiesLabel.setText("Fill Hole " + (Controller.getC().getFill()?"enabled":"disabled")+ "\n" +
+					"Touchscreen Dot Size " + Controller.getC().getSizeScreen() + " mm\n" +
+					"Finger Dot Size " + Controller.getC().getSizeFinger() + " mm");
+		} else {
+			previewlabel.setText("Preview");
+			propertiesLabel.setText("");
+		}
+
+        Group root = (Group) scene.getRoot();
+
+        StlMeshImporter stlimport = new StlMeshImporter();
+        String fileName;
+
+        switch (viewMode) {
+            case VIEW_ALL: fileName = "output.stl"; break;
+            case VIEW_CONDUCTIVE: fileName = "output_conductive.stl"; break;
+            case VIEW_NON_CONDUCTIVE: fileName = "output.stl"; break;
+            case VIEW_CROSS_SECTION: fileName = "output_crosssection.stl"; break;
+            default: fileName = "output.stl";
+        }
+
+        stlimport.read(new File(fileName));
+        Mesh mesh = stlimport.getImport();
+        MeshView meshView = new MeshView(mesh);
+
+
+
+        PhongMaterial mat = new PhongMaterial();
+        mat.setSpecularColor(Color.WHITE);
+        if (viewMode == VIEW_CONDUCTIVE)
+            mat.setDiffuseColor(Color.RED);
+        else
+            mat.setDiffuseColor(Color.LIGHTGRAY);
+        meshView.setMaterial(mat);
+
+        root.getChildren().add(meshView);
+
+        if (viewMode == VIEW_ALL || viewMode == VIEW_CROSS_SECTION) {
+            String fileName2;
+            if (viewMode == VIEW_ALL)
+                fileName2 = "output_conductive.stl";
+            else
+                fileName2 = "output_crosssection_conductive.stl";
+            stlimport.read(new File(fileName2));
+            Mesh mesh2 = stlimport.getImport();
+            MeshView meshView2 = new MeshView(mesh2);
+
+            PhongMaterial mat2 = new PhongMaterial();
+            mat2.setSpecularColor(Color.WHITE);
+            mat2.setDiffuseColor(Color.RED);
+            meshView2.setMaterial(mat2);
+
+            root.getChildren().add(meshView2);
+        }
+		this.root.lookup("#saveObjectButton").setDisable(false);
+    }
+
+    private void clearView(SubScene scene) {
+		Group root = (Group) scene.getRoot();
+		while (root.getChildren().size() > 0)
+			root.getChildren().remove(0);
+	}
+
+
+    /**
+     * Tell this frame that the creation of the STLs is finished
+     */
+    public static void finished() {
+        finished = true;
+    }
+
+    /**
+     * Tell this frame that openSCAD could not be found
+     */
+    private static void notDetected() {
+        detected = false;
+    }
+
+}

+ 224 - 0
src/ui/MainWindow.fxml

@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.text.*?>
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ComboBox?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.Menu?>
+<?import javafx.scene.control.MenuBar?>
+<?import javafx.scene.control.MenuItem?>
+<?import javafx.scene.control.RadioButton?>
+<?import javafx.scene.control.ScrollBar?>
+<?import javafx.scene.control.TitledPane?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.BorderPane?>
+<?import javafx.scene.layout.ColumnConstraints?>
+<?import javafx.scene.layout.GridPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Pane?>
+<?import javafx.scene.layout.RowConstraints?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.UIController">
+  <columnConstraints>
+    <ColumnConstraints hgrow="SOMETIMES" minWidth="350.0" percentWidth="0.0" prefWidth="100.0" />
+    <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
+  </columnConstraints>
+  <rowConstraints>
+    <RowConstraints vgrow="ALWAYS" />
+  </rowConstraints>
+   <children>
+      <GridPane>
+        <columnConstraints>
+          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+        </columnConstraints>
+        <rowConstraints>
+          <RowConstraints minHeight="50.0" percentHeight="0.0" prefHeight="30.0" vgrow="SOMETIMES" />
+          <RowConstraints maxHeight="99.0" minHeight="10.0" percentHeight="0.0" prefHeight="83.0" vgrow="SOMETIMES" />
+          <RowConstraints maxHeight="131.0" minHeight="10.0" percentHeight="0.0" prefHeight="109.0" vgrow="SOMETIMES" />
+            <RowConstraints maxHeight="143.0" minHeight="10.0" percentHeight="0.0" prefHeight="120.0" vgrow="SOMETIMES" />
+            <RowConstraints maxHeight="153.0" minHeight="10.0" percentHeight="0.0" prefHeight="135.0" vgrow="SOMETIMES" />
+            <RowConstraints maxHeight="164.0" minHeight="10.0" percentHeight="0.0" prefHeight="87.0" vgrow="SOMETIMES" />
+            <RowConstraints maxHeight="110.0" minHeight="10.0" percentHeight="0.0" prefHeight="100.0" vgrow="SOMETIMES" />
+        </rowConstraints>
+         <children>
+            <TitledPane id="accelerationPane" fx:id="accelerationPane" animated="false" collapsible="false" contentDisplay="RIGHT" textAlignment="RIGHT" GridPane.rowIndex="1">
+               <padding>
+                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+               </padding>
+               <content>
+                  <HBox id="accelerationContent" fx:id="accelerationContent" alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0">
+                     <children>
+                        <Label id="accelerationLabel" fx:id="accelerationLabel" disable="true" text="Acceleration limit:" HBox.hgrow="NEVER" />
+                        <Region prefWidth="0.0" HBox.hgrow="ALWAYS" />
+                        <Button fx:id="accelerationInfo" mnemonicParsing="false" onAction="#openAccelInfo" />
+                     </children>
+                  </HBox>
+               </content>
+            </TitledPane>
+            <TitledPane id="weightPane" fx:id="weightPane" animated="false" collapsible="false" GridPane.rowIndex="2">
+               <padding>
+                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+               </padding>
+               <content>
+                  <HBox id="weightContent" fx:id="loadContent" alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" spacing="10.0">
+                     <children>
+                        <Label id="weightLabel" fx:id="weightLabel" disable="true" text="Load limit:" HBox.hgrow="NEVER">
+                           <HBox.margin>
+                              <Insets right="38.0" />
+                           </HBox.margin></Label>
+                        <Region prefWidth="0.0" HBox.hgrow="ALWAYS" />
+                        <Button fx:id="weightInfo" mnemonicParsing="false" onAction="#openWeightInfo" />
+                     </children>
+                  </HBox>
+               </content>
+            </TitledPane>
+            <TitledPane id="temperaturePane" fx:id="temperaturePane" animated="false" collapsible="false" GridPane.rowIndex="3">
+               <padding>
+                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+               </padding>
+               <content>
+                  <VBox id="temperatureContent" prefHeight="400.0" prefWidth="100.0" spacing="10.0">
+                     <children>
+                        <HBox alignment="CENTER_LEFT">
+                           <children>
+                              <RadioButton id="temperatureRadio1" fx:id="temperatureRadio1" disable="true" mnemonicParsing="false" prefHeight="27.0" prefWidth="413.0" selected="true" text="Check for rising temperature" />
+                              <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                              <Button fx:id="meltInfo" mnemonicParsing="false" onAction="#openTemperatureUpInfo" />
+                           </children>
+                        </HBox>
+                        <HBox alignment="CENTER_LEFT">
+                           <children>
+                              <RadioButton id="temperatureRadio2" fx:id="temperatureRadio2" disable="true" mnemonicParsing="false" prefHeight="27.0" prefWidth="409.0" text="Check for falling temperature" />
+                              <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                              <Button fx:id="freezeInfo" mnemonicParsing="false" onAction="#openTemperatureDownInfo" />
+                           </children>
+                        </HBox>
+                     </children>
+                  </VBox>
+               </content>
+            </TitledPane>
+            <TitledPane id="rotationPane" fx:id="rotationPane" animated="false" collapsible="false" GridPane.rowIndex="4">
+               <padding>
+                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+               </padding>
+               <content>
+                  <VBox id="rotationContent" prefHeight="200.0" prefWidth="100.0" spacing="10.0">
+                     <children>
+                        <HBox alignment="CENTER_LEFT">
+                           <children>
+                              <RadioButton id="rotationRadio1" fx:id="rotationRadio1" disable="true" mnemonicParsing="false" selected="true" text="Rotate by 90°" />
+                              <Region prefWidth="0.0" HBox.hgrow="ALWAYS" />
+                              <Button fx:id="tiltInfo" mnemonicParsing="false" onAction="#openTiltInfo" />
+                           </children>
+                        </HBox>
+                        <HBox alignment="CENTER_LEFT">
+                           <children>
+                              <RadioButton id="rotationRadio2" fx:id="rotationRadio2" disable="true" mnemonicParsing="false" text="Flip Over by 180°" />
+                              <Region HBox.hgrow="ALWAYS" />
+                              <Button fx:id="flipInfo" mnemonicParsing="false" onAction="#openFlipInfo" />
+                           </children>
+                        </HBox>
+                     </children>
+                  </VBox>
+               </content>
+            </TitledPane>
+            <TitledPane id="pressurePane" fx:id="pressurePane" animated="false" collapsible="false" GridPane.rowIndex="5">
+               <padding>
+                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+               </padding>
+               <content>
+                  <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
+                     <children>
+                        <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                        <Button fx:id="squeezeInfo" mnemonicParsing="false" onAction="#openSqueezeInfo" />
+                     </children>
+                  </HBox>
+               </content>
+            </TitledPane>
+            <VBox alignment="CENTER" GridPane.rowIndex="6">
+               <children>
+                  <HBox alignment="CENTER" prefHeight="51.0" prefWidth="430.0" spacing="10.0">
+                     <children>
+                        <Button id="createObjectButton" alignment="CENTER" contentDisplay="CENTER" disable="true" mnemonicParsing="false" prefHeight="66.0" prefWidth="337.0" style="-fx-padding: 10;" text=" Create Object" textAlignment="CENTER" />
+                        <Button id="saveObjectButton" alignment="CENTER" contentDisplay="CENTER" disable="true" mnemonicParsing="false" prefHeight="67.0" prefWidth="339.0" style="-fx-padding: 10;" text=" Save Object" />
+                     </children>
+                     <VBox.margin>
+                        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+                     </VBox.margin>
+                  </HBox>
+               </children>
+            </VBox>
+            <HBox alignment="CENTER_LEFT" prefHeight="50.0">
+               <children>
+                  <Label text="Choose Off-Line Sensor" textAlignment="CENTER">
+                     <font>
+                        <Font name="System Bold" size="14.0" />
+                     </font>
+                     <HBox.margin>
+                        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+                     </HBox.margin>
+                  </Label>
+               </children>
+               <opaqueInsets>
+                  <Insets />
+               </opaqueInsets>
+               <GridPane.margin>
+                  <Insets right="10.0" />
+               </GridPane.margin>
+            </HBox>
+         </children>
+         <opaqueInsets>
+            <Insets />
+         </opaqueInsets>
+      </GridPane>
+      <BorderPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
+         <bottom>
+            <HBox alignment="BOTTOM_RIGHT" prefHeight="89.0" prefWidth="830.0" spacing="10.0" style="-fx-background-color: #E6E6E6;" BorderPane.alignment="CENTER">
+               <children>
+                  <Label fx:id="propertiesLabel" alignment="BOTTOM_LEFT" prefHeight="69.0" prefWidth="316.0" wrapText="true">
+                     <HBox.margin>
+                        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+                     </HBox.margin></Label>
+                  <Region prefHeight="89.0" prefWidth="0.0" HBox.hgrow="ALWAYS" />
+                  <ComboBox id="comboBox" disable="true" prefHeight="39.0" prefWidth="282.0" visibleRowCount="4">
+                     <HBox.margin>
+                        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+                     </HBox.margin></ComboBox>
+               </children>
+               <BorderPane.margin>
+                  <Insets />
+               </BorderPane.margin>
+            </HBox>
+         </bottom>
+         <top>
+            <HBox alignment="CENTER_LEFT" prefHeight="50.0" prefWidth="830.0" BorderPane.alignment="CENTER">
+               <children>
+                  <Label fx:id="previewLabel" text="Preview">
+                     <font>
+                        <Font name="System Bold" size="14.0" />
+                     </font>
+                     <HBox.margin>
+                        <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+                     </HBox.margin>
+                  </Label>
+                  <Region prefHeight="200.0" HBox.hgrow="ALWAYS" />
+                  <Button id="settingsButton" mnemonicParsing="false" onAction="#openSettings" />
+               </children>
+               <BorderPane.margin>
+                  <Insets right="10.0" />
+               </BorderPane.margin>
+            </HBox>
+         </top>
+         <center>
+            <Pane id="fxPanel" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
+         </center>
+      </BorderPane>
+   </children>
+</GridPane>

+ 81 - 0
src/ui/SettingsWindow.fxml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.CheckBox?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.ScrollBar?>
+<?import javafx.scene.control.TitledPane?>
+<?import javafx.scene.layout.ColumnConstraints?>
+<?import javafx.scene.layout.GridPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Region?>
+<?import javafx.scene.layout.RowConstraints?>
+<?import javafx.scene.layout.VBox?>
+
+<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="600.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.SettingsWindow">
+  <columnConstraints>
+    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+    <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
+  </columnConstraints>
+  <rowConstraints>
+    <RowConstraints maxHeight="226.0" minHeight="10.0" prefHeight="155.0" vgrow="SOMETIMES" />
+    <RowConstraints maxHeight="223.0" minHeight="10.0" prefHeight="214.0" vgrow="SOMETIMES" />
+    <RowConstraints maxHeight="101.0" minHeight="0.0" prefHeight="95.0" vgrow="SOMETIMES" />
+      <RowConstraints maxHeight="80.0" minHeight="10.0" prefHeight="47.0" vgrow="SOMETIMES" />
+  </rowConstraints>
+   <children>
+      <Button fx:id="saveButton" mnemonicParsing="false" onAction="#saveClicked" text="Ok" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" />
+      <TitledPane animated="false" collapsible="false" text="Filling Hole" GridPane.columnSpan="2">
+         <content>
+            <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
+               <children>
+                  <Label prefHeight="54.0" prefWidth="359.0" text="Add a hole to the object. Helps filling water into the object after printing" wrapText="true" />
+                  <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                  <CheckBox fx:id="holeCheckBox" mnemonicParsing="false" onAction="#fillHoleChecked" />
+               </children>
+            </HBox>
+         </content>
+      </TitledPane>
+      <TitledPane animated="false" collapsible="false" text="Conductive Sizes" GridPane.columnSpan="2" GridPane.rowIndex="1">
+         <content>
+            <VBox prefHeight="200.0" prefWidth="100.0">
+               <children>
+                  <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
+                     <children>
+                        <Label fx:id="touchscreenLabel" text="Conductive dot diameter touchscreen: 4.0mm" wrapText="true" />
+                        <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                        <ScrollBar fx:id="touchscreenSlider" prefHeight="22.0" prefWidth="250.0" value="40.0" />
+                     </children>
+                  </HBox>
+                  <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
+                     <children>
+                        <Label fx:id="fingerLabel" text="Conducitve dot diameter finger: 4.0mm" wrapText="true" />
+                        <Region prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                        <ScrollBar fx:id="fingerSlider" prefHeight="22.0" prefWidth="230.0" value="40.0" />
+                     </children>
+                  </HBox>
+               </children>
+            </VBox>
+         </content>
+      </TitledPane>
+      <TitledPane animated="false" collapsible="false" text="OpenSCAD" GridPane.columnSpan="2" GridPane.rowIndex="2">
+         <content>
+            <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0">
+               <children>
+                  <Label prefHeight="27.0" prefWidth="247.0" text="OpenSCAD Folder" wrapText="true" />
+                  <Button fx:id="scadPath" mnemonicParsing="false" onAction="#pathClicked" prefHeight="39.0" prefWidth="376.0" text="Button" />
+               </children>
+            </HBox>
+         </content>
+      </TitledPane>
+      <Button mnemonicParsing="false" onAction="#cancelSettings" text="Cancel" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" />
+   </children>
+   <padding>
+      <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+   </padding>
+</GridPane>

+ 138 - 0
src/ui/SettingsWindow.java

@@ -0,0 +1,138 @@
+package ui;
+
+import controller.Controller;
+import controller.SettingsController;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.concurrent.Task;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollBar;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.IOException;
+
+public class SettingsWindow {
+
+	@FXML
+	private CheckBox holeCheckBox;
+	@FXML
+	private ScrollBar touchscreenSlider;
+	@FXML
+	private Label touchscreenLabel;
+	@FXML
+	private ScrollBar fingerSlider;
+	@FXML
+	private Label fingerLabel;
+	@FXML
+	private Button scadPath;
+
+	private static SettingsWindow window;
+	private Stage stage;
+
+	public SettingsWindow() {
+		window = this;
+	}
+
+	public static SettingsWindow getWindow() {
+		return window;
+	}
+
+	protected void setUpListener() {
+		holeCheckBox.setSelected(Controller.getC().getFill());
+		touchscreenSlider.setValue(Controller.getC().getSizeScreen() * 10);
+		touchscreenScrolled();
+		fingerSlider.setValue(Controller.getC().getSizeFinger() * 10);
+		fingerScrolled();
+		String s = Controller.getC().getOpenSCADPath().toString();
+		scadPath.setText(Controller.getC().getOpenSCADPath().toString());
+
+		touchscreenSlider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				touchscreenScrolled();
+			}
+		});
+		fingerSlider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				fingerScrolled();
+			}
+		});
+	}
+
+	@FXML
+	protected void fillHoleChecked() {
+		Controller.getC().setFill(holeCheckBox.isSelected());
+	}
+
+	@FXML
+	protected void touchscreenScrolled() {
+		Controller.getC().setSizeScreen(Math.round(touchscreenSlider.getValue())/10f);
+		touchscreenLabel.setText("Conductive dot diameter touchscreen: "+ Math.round(touchscreenSlider.getValue())/10f+"mm");
+	}
+
+	@FXML
+	protected void fingerScrolled() {
+		Controller.getC().setSizeFinger(Math.round(fingerSlider.getValue())/10f);
+		fingerLabel.setText("Conductive dot diameter finger: "+ Math.round(fingerSlider.getValue())/10f +"mm");
+	}
+
+	@FXML
+	protected void pathClicked() {
+		Task task = new Task() {
+			@Override
+			protected Void call() throws Exception {
+				DirectoryChooser chooser = new DirectoryChooser();
+				Platform.runLater(() -> {
+							File file = chooser.showDialog(stage);
+
+							if (file != null) {
+								Controller.getC().setOpenSCADPath(file.toPath());
+								Platform.runLater(() -> scadPath.setText(file.toPath().toString()));
+							}
+						});
+			/*	JFileChooser chooser = new JFileChooser();
+				chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+				chooser.showOpenDialog(null);
+
+				if (chooser.getSelectedFile() != null && chooser.getSelectedFile().isDirectory()) {
+					Controller.getC().setOpenSCADPath(chooser.getSelectedFile().toPath());
+					Platform.runLater(() -> scadPath.setText(chooser.getSelectedFile().toPath().toString()));
+				}*/
+				return null;
+			}
+		};
+		new Thread(task).start();
+	}
+
+	@FXML
+	protected void saveClicked() {
+		SettingsController.saveSettings();
+		stage.close();
+	}
+
+	@FXML
+	protected void cancelSettings() {
+		File file = null;
+		try {
+			file = new File(new File( "." ).getCanonicalPath() + File.separator + "settings.ini");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		if (file.exists())
+			SettingsController.loadSettings();
+		stage.close();
+	}
+
+	public void setStage(Stage stage) {
+		this.stage = stage;
+	}
+}

+ 229 - 0
src/ui/UIController.java

@@ -0,0 +1,229 @@
+package ui;
+
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Label;
+import javafx.scene.control.TitledPane;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+
+public class UIController  {
+
+	private Parent root;
+	private Stage stage;
+
+	private static String path;
+
+
+
+	public static void setPath(String p) {
+		path = p;
+	}
+
+	public UIController() {
+		try {
+			root = FXMLLoader.load(getClass().getResource("InformationWindow.fxml"));
+			stage = new Stage();
+			stage.setResizable(false);
+			stage.setScene(new Scene(root, 450, 450));
+		}
+		catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	protected void exit() {
+		try {
+			Platform.exit();
+		}
+		catch (Exception e1) {
+			e1.printStackTrace();
+		}
+	}
+
+	private void setLegend() {
+
+		Image imgBlue = new Image(getClass().getResource("/pictures/lightBlue.PNG").toString());	//Was blue
+		ImageView imgViewBlue = new ImageView(imgBlue);
+		imgViewBlue.setFitWidth(20);
+		imgViewBlue.setFitHeight(20);
+		((Label) root.lookup("#blueText")).setGraphic(imgViewBlue);
+
+		Image imgRed = new Image(getClass().getResource("/pictures/red.PNG").toString());
+		ImageView imgViewRed = new ImageView(imgRed);
+		imgViewRed.setFitWidth(20);
+		imgViewRed.setFitHeight(20);
+		((Label) root.lookup("#redText")).setGraphic(imgViewRed);
+
+		Image imgGreen = new Image(getClass().getResource("/pictures/gray.PNG").toString());	//was green
+		ImageView imgViewGreen = new ImageView(imgGreen);
+		imgViewGreen.setFitWidth(20);
+		imgViewGreen.setFitHeight(20);
+		((Label) root.lookup("#greenText")).setGraphic(imgViewGreen);
+
+		Image imgIce = new Image(getClass().getResource("/pictures/cyan.PNG").toString());	//delete?
+		ImageView imgViewIce = new ImageView(imgIce);
+		imgViewIce.setFitWidth(20);
+		imgViewIce.setFitHeight(20);
+		((Label) root.lookup("#iceText")).setGraphic(imgViewIce);
+
+	}
+
+	@FXML
+	protected void openSettings() {
+		Parent root;
+		try {
+			root = FXMLLoader.load(getClass().getResource("SettingsWindow.fxml"));
+
+			Stage stage = new Stage();
+			stage.setResizable(false);
+			stage.setTitle("Settings");
+			stage.setScene(new Scene(root, 450, 450));
+			stage.show();
+			stage.toFront();
+			SettingsWindow.getWindow().setUpListener();
+			SettingsWindow.getWindow().setStage(stage);
+		}
+		catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@FXML
+	protected void openAccelInfo() {
+		stage.setTitle("Acceleration Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(300);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleAcceleration.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when a specific acceleration is reached.\n" +
+				"The specific acceleration is dependend on the wall height between the two chambers. " +
+				"The acceleration can be either in the opposite direction of the small chamber or breaking after accelerating in the same direction as the small chamber.\n" +
+				"Tab water needs to be filled into the right chamber. " +
+				"When accelerating the object the water will swap over the wall into the small chamber where it can be detected.");
+
+	}
+
+	@FXML
+	protected void openWeightInfo() {
+		stage.setTitle("Load Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(300);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleWeight.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when a specific load lays on it." +
+				"\nThe specific load is dependend on the number of supports between the panels." +
+				" When enough weight lays on this object the supports will bend, leading to less space between the panels.");
+
+	}
+
+	@FXML
+	protected void openTemperatureUpInfo() {
+		stage.setTitle("Rising Temperature Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(300);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleTemperatureMelt.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when it is stored above 0°C for some minutes." +
+				"\nTab water or ice is used for this object. You have to freeze this object to make it work." +
+				" When stored above 0°C the ice starts to melt and reaches the other chamber where it can be detected. Otherwise it will stay in the first chamber." +
+				" When checking for this object's state, the object will be fliped and warmed up for 30 minutes.");
+
+	}
+
+	@FXML
+	protected void openTemperatureDownInfo() {
+		stage.setTitle("Falling Temperature Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(300);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleTemperatureFreeze.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when it is stored under 0°C for a while." +
+				"\nTab water is filled into the right chamber" +
+				" When stored under 0°C the water will freeze and the resulting ice will break the conductive wall." +
+				" After melting, water will flow through the crack." +
+				" When checking for this object's state, the object has to be placed on a touchscreen after letting it warm up for at least 30 minutes.");
+
+	}
+
+	@FXML
+	protected void openTiltInfo() {
+		stage.setTitle("Rotate by 90° Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(350);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleTilt.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when it gets tilted by around 90° in the right direction." +
+				"\nWhen tilted the water flows into the next chamber where it can be detected.");
+
+	}
+
+	@FXML
+	protected void openFlipInfo() {
+		stage.setTitle("Flip Over by 180° Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(380);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleFlip.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when it gets fliped (rotated by around 180°)." +
+				"\nThe water in the middle chamber will then flow into the outer chamber where it can be detected.");
+
+	}
+
+	@FXML
+	protected void openSqueezeInfo() {
+		stage.setTitle("Pressure Information");
+		stage.show();
+		stage.setWidth(800);
+		stage.setHeight(350);
+		stage.toFront();
+		setLegend();
+		ImageView img = ((ImageView) root.lookup("#image"));
+		img.setImage(new Image(getClass().getResource("/pictures/simpleSqueeze.png").toString()));
+		img.setFitWidth(480);
+		img.setFitHeight(350);
+		((Label) root.lookup("#text1")).setText("This object changes its state when the lower half gets squeezed." +
+				"\nThe lower chamber has to be filled with tab water." +
+				" The water will then be pressed from the lower chamber onto the cone where it then can be detected.");
+
+	}
+}