Browse Source

Load/Save Basic implementation

TomTroppmann 2 years ago
parent
commit
ae24639cc2
58 changed files with 1407 additions and 3708 deletions
  1. 2 0
      build.gradle
  2. 0 44
      src/holeg/adapter/AbstractCpsObjectAdapter.java
  3. 34 0
      src/holeg/adapter/EdgeDeserializer.java
  4. 23 0
      src/holeg/adapter/EdgeSerializer.java
  5. 49 0
      src/holeg/adapter/ModelDeserializer.java
  6. 5 5
      src/holeg/addon/Randomizer.java
  7. 3 4
      src/holeg/algorithm/binary/BaseLine.java
  8. 5 5
      src/holeg/algorithm/example/DemoAlgo.java
  9. 3 6
      src/holeg/algorithm/example/FlexExample.java
  10. 2 7
      src/holeg/algorithm/objective_function/Evaluation.java
  11. 1 5
      src/holeg/algorithm/objective_function/GraphMetrics.java
  12. 2 6
      src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java
  13. 1 1
      src/holeg/algorithm/objective_function/SwitchObjectiveFunction.java
  14. 2 4
      src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java
  15. 1 1
      src/holeg/algorithm/topologie/AcoAlgorithm.java
  16. 1 1
      src/holeg/algorithm/topologie/GaAlgorithm.java
  17. 1 1
      src/holeg/algorithm/topologie/PsoAlgorithm.java
  18. 5 6
      src/holeg/api/AlgorithmFrameworkFlex.java
  19. 5 7
      src/holeg/api/TopologieAlgorithmFramework.java
  20. 1 1
      src/holeg/interfaces/GraphEditable.java
  21. 54 26
      src/holeg/interfaces/LocalMode.java
  22. 16 26
      src/holeg/model/AbstractCanvasObject.java
  23. 1 2
      src/holeg/model/Constrain.java
  24. 2 4
      src/holeg/model/Edge.java
  25. 199 191
      src/holeg/model/Flexibility.java
  26. 32 23
      src/holeg/model/GroupNode.java
  27. 239 276
      src/holeg/model/HolonElement.java
  28. 21 24
      src/holeg/model/HolonObject.java
  29. 7 35
      src/holeg/model/HolonSwitch.java
  30. 171 0
      src/holeg/model/Model.java
  31. 0 3
      src/holeg/model/Node.java
  32. 0 55
      src/holeg/ui/controller/AutoSaveController.java
  33. 113 217
      src/holeg/ui/controller/CanvasController.java
  34. 0 182
      src/holeg/ui/controller/CategoryController.java
  35. 0 397
      src/holeg/ui/controller/ClipboardController.java
  36. 205 317
      src/holeg/ui/controller/Control.java
  37. 4 12
      src/holeg/ui/controller/IndexTranslator.java
  38. 0 487
      src/holeg/ui/controller/LoadController.java
  39. 0 238
      src/holeg/ui/controller/NodeController.java
  40. 0 478
      src/holeg/ui/controller/SaveController.java
  41. 5 4
      src/holeg/ui/controller/SimulationManager.java
  42. 1 18
      src/holeg/ui/model/GuiSettings.java
  43. 10 40
      src/holeg/ui/model/IdCounter.java
  44. 0 177
      src/holeg/ui/model/Model.java
  45. 5 2
      src/holeg/ui/view/canvas/Canvas.java
  46. 3 3
      src/holeg/ui/view/canvas/Rendering.java
  47. 2 2
      src/holeg/ui/view/dialog/AddElementPopUp.java
  48. 3 4
      src/holeg/ui/view/dialog/AddObjectPopUp.java
  49. 1 1
      src/holeg/ui/view/dialog/CanvasResizePopUp.java
  50. 10 13
      src/holeg/ui/view/dialog/CreateTemplatePopUp.java
  51. 9 3
      src/holeg/ui/view/inspector/Inspector.java
  52. 2 2
      src/holeg/ui/view/inspector/InspectorTable.java
  53. 52 60
      src/holeg/ui/view/inspector/UnitGraph.java
  54. 0 1
      src/holeg/ui/view/main/Category.java
  55. 83 265
      src/holeg/ui/view/main/GUI.java
  56. 1 2
      src/holeg/ui/view/main/Main.java
  57. 9 13
      src/holeg/ui/view/window/FlexWindow.java
  58. 1 1
      src/holeg/ui/view/window/Outliner.java

+ 2 - 0
build.gradle

@@ -17,11 +17,13 @@ application {
 }
 
 repositories {
+    // maven { url "https://artifactory.cronapp.io/public-release/" }
     mavenCentral()
 }
 
 dependencies {
     implementation 'com.google.code.gson:gson:2.8.9'
+    // implementation 'com.google.code.gson:gson-extras:2.8.5'
     implementation 'org.apache.commons:commons-email:1.5'
     implementation 'org.wso2.orbit.org.apache.commons:commons-compress:1.18.0.wso2v1'
     implementation 'org.knowm.xchart:xchart:3.8.1'

+ 0 - 44
src/holeg/adapter/AbstractCpsObjectAdapter.java

@@ -1,44 +0,0 @@
-package holeg.adapter;
-
-import java.lang.reflect.Type;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.GroupNode;
-
-public class AbstractCpsObjectAdapter
-		implements JsonSerializer<AbstractCanvasObject>, JsonDeserializer<AbstractCanvasObject> {
-
-	@Override
-	public JsonElement serialize(AbstractCanvasObject object, Type type, JsonSerializationContext context) {
-		JsonObject jsonObject = new JsonObject();
-		jsonObject.add("type", new JsonPrimitive(object.getClass().getSimpleName()));
-		jsonObject.add("properties", context.serialize(object, object.getClass()));
-		if (object instanceof GroupNode)
-			jsonObject.add("hash", new JsonPrimitive(object.hashCode()));
-		return jsonObject;
-	}
-
-	@Override
-	public AbstractCanvasObject deserialize(JsonElement ele, Type type, JsonDeserializationContext context)
-			throws JsonParseException {
-		JsonObject object = ele.getAsJsonObject();
-		String typeName = object.get("type").getAsString();
-		JsonElement element = object.get("properties");
-		try {
-			String packageName = AbstractCanvasObject.class.getPackageName() + ".";
-			return context.deserialize(element, Class.forName(packageName + typeName));
-		} catch (ClassNotFoundException cnfe) {
-			throw new JsonParseException("Unknown element type: " + type, cnfe);
-		}
-	}
-
-}

+ 34 - 0
src/holeg/adapter/EdgeDeserializer.java

@@ -0,0 +1,34 @@
+package holeg.adapter;
+
+import com.google.gson.*;
+import holeg.model.AbstractCanvasObject;
+import holeg.model.Edge;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+public class EdgeDeserializer implements JsonDeserializer<Edge> {
+    public Map<Integer, AbstractCanvasObject> idMap= new HashMap<>();
+
+
+
+    @Override
+    public Edge deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        JsonObject jsonObj = json.getAsJsonObject();
+        Edge edge = new Edge(idToCanvasObject(jsonObj.get("idA").getAsInt()),
+                idToCanvasObject(jsonObj.get("idB").getAsInt()),
+                jsonObj.get("maxCapacity").getAsFloat());
+        edge.mode = Edge.EdgeMode.valueOf(jsonObj.get("mode").getAsString());
+        return edge;
+    }
+
+    private AbstractCanvasObject idToCanvasObject(int id) throws JsonParseException{
+        AbstractCanvasObject object = idMap.get(id);
+        if(object == null){
+            throw new JsonParseException("Cannot find AbstractCanvasObject with id: " + id);
+        }
+        return object;
+    }
+}

+ 23 - 0
src/holeg/adapter/EdgeSerializer.java

@@ -0,0 +1,23 @@
+package holeg.adapter;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import holeg.model.Edge;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+public class EdgeSerializer implements JsonSerializer<Edge> {
+
+    @Override
+    public JsonElement serialize(Edge edge, Type typeOfSrc, JsonSerializationContext context) {
+        JsonObject jsonObj = new JsonObject();
+        jsonObj.addProperty("idA", edge.getA().getId());
+        jsonObj.addProperty("idB", edge.getB().getId());
+        jsonObj.addProperty("maxCapacity", edge.maxCapacity);
+        jsonObj.addProperty("mode", edge.mode.toString());
+        return jsonObj;
+    }
+}

+ 49 - 0
src/holeg/adapter/ModelDeserializer.java

@@ -0,0 +1,49 @@
+package holeg.adapter;
+
+import com.google.gson.*;
+import com.google.gson.reflect.TypeToken;
+import holeg.model.*;
+import holeg.ui.controller.Control;
+import holeg.ui.model.IdCounter;
+
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+public class ModelDeserializer implements JsonDeserializer<Model> {
+    private static final Logger log = Logger.getLogger(ModelDeserializer.class.getName());
+    private final static Type edgeSetType = new TypeToken<HashSet<Edge>>() {
+    }.getType();
+    private final Control control;
+    private final EdgeDeserializer edgeDeserializer = new EdgeDeserializer();
+    private final Gson gson = new GsonBuilder().registerTypeAdapter(Edge.class, edgeDeserializer).create();
+
+
+    public ModelDeserializer(Control control) {
+        this.control = control;
+    }
+
+    @Override
+    public Model deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        log.info("ModelDeserializer");
+        final JsonObject jsonObj = json.getAsJsonObject();
+        Model model = control.getModel();
+        model.clear();
+        GroupNode canvas = context.deserialize(jsonObj.getAsJsonObject("canvas"), GroupNode.class);
+        Map<Integer, AbstractCanvasObject> idMap = canvas.getAllObjectsRecursive()
+                .collect(Collectors.toMap(AbstractCanvasObject::getId, Function.identity()));
+        model.setCanvas(canvas);
+        edgeDeserializer.idMap = idMap;
+        //TODO(Tom2022-01-27): COMBINE methods sampleGraph and updateReference in Interface
+        model.getAllHolonElements().forEach(HolonElement::sampleGraph);
+        model.getCanvas().getAllSwitchObjectsRecursive().forEach(HolonSwitch::sampleGraph);
+        model.getCanvas().updateReference();
+        model.setEdgesOnCanvas(gson.fromJson(jsonObj.getAsJsonArray("edgesOnCanvas"), edgeSetType));
+        model.getCanvas().getAllObjectsRecursive().mapToInt(AbstractCanvasObject::getId).max()
+                .ifPresent(maxId -> IdCounter.set(maxId + 1));
+        return model;
+    }
+}

+ 5 - 5
src/holeg/addon/Randomizer.java

@@ -11,7 +11,6 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.stream.Collectors;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
@@ -40,6 +39,7 @@ import com.google.gson.JsonSyntaxException;
 import holeg.addon.helper.HolonElementSketch;
 import holeg.addon.helper.RandomPriotity;
 import holeg.api.AddOn;
+import holeg.model.AbstractCanvasObject;
 import holeg.model.HolonElement;
 import holeg.model.HolonObject;
 import holeg.ui.controller.Control;
@@ -70,8 +70,8 @@ public class Randomizer implements AddOn {
 	public double randomChance = 1.0;
 	
 	
-	private HashMap<HolonObject, Boolean> objectMap = new HashMap<HolonObject, Boolean>();
-	private List<JCheckBox> checkboxList = new ArrayList<JCheckBox>();
+	private final HashMap<HolonObject, Boolean> objectMap = new HashMap<>();
+	private final List<JCheckBox> checkboxList = new ArrayList<>();
 	
 	
 	
@@ -132,11 +132,11 @@ public class Randomizer implements AddOn {
 		
 		
 		//Entrys
-		for(HolonObject hObject: objectMap.keySet().stream().sorted(Comparator.comparing(ob -> ob.getName())).collect(Collectors.toList())) {
+		for(HolonObject hObject: objectMap.keySet().stream().sorted(Comparator.comparing(AbstractCanvasObject::getName)).toList()) {
 			//Entry
 			JPanel entryPanel = new JPanel();
 			entryPanel.setLayout(new BoxLayout(entryPanel, BoxLayout.LINE_AXIS));
-			JLabel label = new JLabel(hObject.getName() + "[" + hObject.getId() + "]", new ImageIcon(Import.loadImage(hObject.getImage(), lineSpace, lineSpace)), JLabel.LEFT);
+			JLabel label = new JLabel(hObject.getName() + "[" + hObject.getId() + "]", new ImageIcon(Import.loadImage(hObject.getImagePath(), lineSpace, lineSpace)), JLabel.LEFT);
 			entryPanel.add(label);
 			entryPanel.add(Box.createHorizontalGlue());
 			JCheckBox checkbox = new JCheckBox();

+ 3 - 4
src/holeg/algorithm/binary/BaseLine.java

@@ -9,7 +9,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Optional;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import javax.swing.BorderFactory;
@@ -33,7 +32,7 @@ import holeg.model.HolonSwitch;
 import holeg.model.HolonSwitch.SwitchMode;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 
 
@@ -348,7 +347,7 @@ public class BaseLine implements AddOn {
 	private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
 		nodes.forEach(aCps -> {
 			if (aCps instanceof HolonObject hO) {
-				hO.getElements().forEach(hE -> {
+				hO.elementsStream().forEach(hE -> {
 					positionToInit.add(hE.active);
 					access.put(positionToInit.size() - 1 , new AccessWrapper(hE));					
 				});
@@ -369,7 +368,7 @@ public class BaseLine implements AddOn {
 	
 	private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
 		groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
-			hObject.getElements().forEach(hE -> {
+			hObject.elementsStream().forEach(hE -> {
 				positionToInit.add(hE.active);
 				access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
 			});

+ 5 - 5
src/holeg/algorithm/example/DemoAlgo.java

@@ -36,7 +36,7 @@ import holeg.model.HolonSwitch;
 import holeg.model.HolonSwitch.SwitchMode;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 public class DemoAlgo implements AddOn {
 
@@ -293,7 +293,7 @@ public class DemoAlgo implements AddOn {
 			try {
 				//Schalte Slow das Windrad Ein
 				if(windrad == null)return;
-				windrad.getElements().forEach(hE -> {
+				windrad.elementsStream().forEach(hE -> {
 					hE.active = true;
 					try {
 						TimeUnit.MILLISECONDS.sleep(waitDurationWindradStep);
@@ -317,7 +317,7 @@ public class DemoAlgo implements AddOn {
 		
 		private void deactivateWindrad() {
 			if(windrad == null)return;
-			windrad.getElements().forEach(ele -> ele.active = false);
+			windrad.elementsStream().forEach(ele -> ele.active = false);
 		}
 		private void setHolonElemntsAktiv(int actualIteration) {
 			for(int i = 0;i<access.size();i++) {
@@ -357,7 +357,7 @@ public class DemoAlgo implements AddOn {
 		private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
 			nodes.forEach(aCps -> {
 				if (aCps instanceof HolonObject hO) {
-					hO.getElements().forEach(hE -> {
+					hO.elementsStream().forEach(hE -> {
 						positionToInit.add(hE.active);
 						access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
 					});
@@ -378,7 +378,7 @@ public class DemoAlgo implements AddOn {
 		
 		private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
 			groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
-				hObject.getElements().forEach(hE -> {
+				hObject.elementsStream().forEach(hE -> {
 					positionToInit.add(hE.active);
 					access.put(positionToInit.size() - 1 , new AccessWrapper(hE));					
 				});

+ 3 - 6
src/holeg/algorithm/example/FlexExample.java

@@ -8,7 +8,6 @@ import java.awt.image.BufferedImage;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
@@ -39,10 +38,9 @@ import holeg.model.HolonObject.HolonObjectState;
 import holeg.model.HolonSwitch.SwitchMode;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.model.HolonSwitch;
-import holeg.model.Flexibility.FlexState;
 import holeg.model.HolonElement.Priority;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 public class FlexExample implements AddOn {
 		
@@ -449,7 +447,6 @@ public class FlexExample implements AddOn {
 		/**
 		 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
 		 * Also initialize the Access Hashmap to swap faster positions.
-		 * @param ModelTest
 		 * @return
 		 */
 		private List<Boolean> extractPositionAndAccess() {
@@ -471,7 +468,7 @@ public class FlexExample implements AddOn {
 		private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
 			nodes.forEach(aCps -> {
 				if (aCps instanceof HolonObject hO) {
-					hO.getElements().forEach(hE -> {
+					hO.elementsStream().forEach(hE -> {
 						positionToInit.add(hE.active);
 						access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
 					});
@@ -492,7 +489,7 @@ public class FlexExample implements AddOn {
 		
 		private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
 			groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
-				hObject.getElements().forEach(hE -> {
+				hObject.elementsStream().forEach(hE -> {
 					positionToInit.add(hE.active);
 					access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
 				});

+ 2 - 7
src/holeg/algorithm/objective_function/Evaluation.java

@@ -1,20 +1,15 @@
 package holeg.algorithm.objective_function;
 
-import java.util.List;
-
-import holeg.model.Flexibility;
 import holeg.model.HolonObject;
 import holeg.model.HolonObject.HolonObjectState;
-import holeg.model.Flexibility.FlexState;
 import holeg.model.HolonElement.Priority;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 //TODO(Tom2022-01-13) Fix Evaluation
 public class Evaluation {
 	
 	/**
 	 * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position).
-	 * @param state
 	 * @return
 	 */
 	public static double getFitnessValueForState(Model model) {
@@ -87,7 +82,7 @@ public class Evaluation {
 	private static double inactiveHolonElementPenalty(HolonObject obj) {
 		float result = 0;
 		int activeElements = obj.getNumberOfActiveElements();
-		int maxElements = (int)obj.getElements().count();
+		int maxElements = (int)obj.elementsStream().count();
 		
 		//result = (float) Math.pow((maxElements -activeElements),2)*10;
 		result = (float) Math.pow(5, 4* ( (float) maxElements - (float) activeElements)/ (float) maxElements) - 1;

+ 1 - 5
src/holeg/algorithm/objective_function/GraphMetrics.java

@@ -6,12 +6,10 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.logging.Logger;
 
 import holeg.model.AbstractCanvasObject;
-import holeg.model.HolonSwitch;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 import java.util.Set;
 
@@ -56,7 +54,6 @@ public class GraphMetrics {
 	
 	/**
 	 * Convert a DecoratedNetwork to a Graph
-	 * @param net
 	 * @return a equivalent Graph to the DecoratedNetwork
 	 */
 	public static Graph convertDecoratedNetworkToGraph(Model model) {
@@ -263,7 +260,6 @@ public class GraphMetrics {
 
 	/**
 	  * Makes a deep Copy of a Integer Matrix
-	  * @param l_input
 	  * @return
 	  */
 	private static int[][] makeCopyOfMatrix(int[][] matrix) {

+ 2 - 6
src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java

@@ -1,12 +1,9 @@
 package holeg.algorithm.objective_function;
 
-import java.util.List;
 import java.util.logging.Logger;
 
-import holeg.model.Flexibility;
-import holeg.model.Flexibility.FlexState;
 import holeg.model.HolonElement.Priority;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 public class ObjectiveFunctionByCarlos {
 	// Parameters
@@ -76,8 +73,7 @@ public class ObjectiveFunctionByCarlos {
 	 * 
 	 * squash is the squashing function {@link ObjectiveFunctionByCarlos#squash}
 	 * 
-	 * 
-	 * @param state
+	 *
 	 * @return f_g value between 0 and 100
 	 */
 	//TODO(Tom2022-01-13) Fix ObjectiveFunctionByCarlos

+ 1 - 1
src/holeg/algorithm/objective_function/SwitchObjectiveFunction.java

@@ -1,6 +1,6 @@
 package holeg.algorithm.objective_function;
 
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 public class SwitchObjectiveFunction {
 	

+ 2 - 4
src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java

@@ -4,8 +4,7 @@ package holeg.algorithm.objective_function;
 import java.util.Locale;
 import java.util.logging.Logger;
 
-import holeg.algorithm.objective_function.GraphMetrics.Graph;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.utility.math.decimal.Sampler;
 
 public class TopologieObjectiveFunction {
@@ -93,8 +92,7 @@ public class TopologieObjectiveFunction {
 	 * 
 	 * squash is the squashing function {@link TopologieObjectiveFunction#squash}
 	 * 
-	 * 
-	 * @param state
+	 *
 	 * @param moreInformation if more prints should be made
 	 * @return f_g value between 0 and 100
 	 */

+ 1 - 1
src/holeg/algorithm/topologie/AcoAlgorithm.java

@@ -7,7 +7,7 @@ import java.util.ListIterator;
 
 import holeg.algorithm.objective_function.TopologieObjectiveFunction;
 import holeg.api.TopologieAlgorithmFramework;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.utility.math.Random;
 
 public class AcoAlgorithm extends TopologieAlgorithmFramework {

+ 1 - 1
src/holeg/algorithm/topologie/GaAlgorithm.java

@@ -9,7 +9,7 @@ import java.util.TreeSet;
 
 import holeg.algorithm.objective_function.TopologieObjectiveFunction;
 import holeg.api.TopologieAlgorithmFramework;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.utility.math.Random;
 
 public class GaAlgorithm extends TopologieAlgorithmFramework {

+ 1 - 1
src/holeg/algorithm/topologie/PsoAlgorithm.java

@@ -9,7 +9,7 @@ import java.util.stream.Collectors;
 
 import holeg.algorithm.objective_function.TopologieObjectiveFunction;
 import holeg.api.TopologieAlgorithmFramework;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.utility.math.Maths;
 import holeg.utility.math.Random;
 

+ 5 - 6
src/holeg/api/AlgorithmFrameworkFlex.java

@@ -56,7 +56,7 @@ import holeg.model.GroupNode;
 import holeg.model.HolonSwitch.SwitchMode;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.component.Console;
 import holeg.ui.view.image.Import;
 import holeg.utility.math.decimal.Format;
@@ -764,7 +764,6 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 	/**
 	 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
 	 * Also initialize the Access Hashmap to swap faster positions.
-	 * @param ModelTest
 	 * @return
 	 */
 	protected List<Boolean> extractPositionAndAccess() {
@@ -810,7 +809,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 				accessKillSwitch.put(hObject, killSwitchAccess);					
 			}
 			if(this.algoUseElements) {
-				hObject.getElements().forEach(hE -> {
+				hObject.elementsStream().forEach(hE -> {
 					positionToInit.add(hE.active);
 					access.add(new AccessWrapper(hE, killSwitchAccess));
 				});
@@ -1168,7 +1167,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 			type = AccessType.KillSwitch;
 			this.hObject = hObject;
 			intialStatesOfElementForKilllSwitch = new ArrayList<Boolean>();
-			hObject.getElements().forEach(hE -> {
+			hObject.elementsStream().forEach(hE -> {
 				intialStatesOfElementForKilllSwitch.add(hE.active);
 			});
 		}
@@ -1207,11 +1206,11 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 					break;
 				case KillSwitch:
 					if(state) {
-						hObject.getElements().forEach(hE -> {
+						hObject.elementsStream().forEach(hE -> {
 							hE.active = false;
 						});
 					}else {
-						List<HolonElement> eleList = hObject.getElements().toList();
+						List<HolonElement> eleList = hObject.elementsStream().toList();
 						for(int i = 0; i < eleList.size(); i++) {
 							eleList.get(i).active = intialStatesOfElementForKilllSwitch.get(i);
 						}

+ 5 - 7
src/holeg/api/TopologieAlgorithmFramework.java

@@ -43,7 +43,7 @@ import holeg.model.HolonSwitch.SwitchMode;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.component.Console;
 import holeg.ui.view.main.Category;
 
@@ -742,7 +742,6 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 
 
 	private void resetAllList() {
-		//-->reset
 		accessWildcards.clear();
 		this.countForAccessMap = 0;
 		amountOfExistingCables = 0;
@@ -756,7 +755,6 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 		switchList.clear();
 		accessSwitchGroupNode.clear();
 		edgeList.clear();
-		//<---
 	}
 	
 	
@@ -800,7 +798,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	
 	
 	protected void resetWildcards() {
-		this.accessWildcards.forEach(wrapper -> wrapper.resetState());
+		this.accessWildcards.forEach(AccessWrapper::resetState);
 	}
 	/**
 	 * All Nodes have to be in the access map !!
@@ -1138,8 +1136,8 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 						}else {
 							wildcard.setName("Wildcard");
 						}
-						wildcard.add(hO.getElements().toList());
-						wildcard.setImage(hO.getImage());
+						wildcard.add(hO.elementsStream().toList());
+						wildcard.setImagePath(hO.getImagePath());
 					}
 				}else {
 					resetState();
@@ -1149,7 +1147,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 		public void resetState() {
 			state = 0;
 			wildcard.setName("Wildcard");
-			wildcard.setImage(ImagePreference.Canvas.DefaultObject.House);
+			wildcard.setImagePath(ImagePreference.Canvas.DefaultObject.House);
 			wildcard.clearElements();
 		}
 		

+ 1 - 1
src/holeg/interfaces/GraphEditable.java

@@ -16,7 +16,7 @@ public interface GraphEditable {
 	/**
 	 * all types of graphs
 	 */
-	public static enum GraphType {
+	enum GraphType {
 		boolGraph, doubleGraph
 	}
 	/**

+ 54 - 26
src/holeg/interfaces/LocalMode.java

@@ -2,34 +2,62 @@ package holeg.interfaces;
 
 public interface LocalMode {
 	
-	public static final int STANDARD_GRAPH_ACCURACY=100;
-	/**
-	 * Sets the local period of the element. 
-	 * If the simulation has 100 steps and the local period is 50,
-	 * then there will be two full cycles during the simulation.
-	 * @param period The local period for this element.
-	 */
-	void setLocalPeriod(int period);
-	
-	/**
-	 * Used to query the local period of an element.
-	 * @return The local period of this element.
-	 * This should return the set local period,
-	 * which may be anything, even if the component is set to be "stretching",
-	 * that is,
-	 * acting as if the local period was the same
-	 * as the number of total iterations for this simulation.
-	 */
-	int getLocalPeriod();
-	
-	/**
-	 * @return true when using his own local Period.
-	 */
-	boolean isUsingLocalPeriod();
-	
+	int STANDARD_GRAPH_ACCURACY=100;
+	class Period {
+		public Period(Period other) {
+			this.type = other.type;
+			this.interval = other.interval;
+		}
+
+		public enum PeriodType{
+			Local, Global
+		}
+		private final PeriodType type;
+		private int interval;
+		public Period(int interval){
+			this.interval = interval;
+			type = PeriodType.Local;
+		}
+		public Period(){
+			type = PeriodType.Global;
+		};
+		/**
+		 * Sets the local period of the element.
+		 * If the simulation has 100 steps and the local period is 50,
+		 * then there will be two full cycles during the simulation.
+		 * @param interval The local period for this element.
+		 */
+		public void setInterval(int interval){
+			this.interval = interval;
+		}
+
+		/**
+		 * Used to query the local period of an element.
+		 * @return The local period of this element.
+		 * This should return the set local period,
+		 * which may be anything, even if the component is set to be "stretching",
+		 * that is,
+		 * acting as if the local period was the same
+		 * as the number of total iterations for this simulation.
+		 */
+		public int getInterval(){
+			if (type == PeriodType.Local) {
+				return interval;
+			}
+			return STANDARD_GRAPH_ACCURACY;
+		}
+
+		public Period.PeriodType getType() {
+			return type;
+		}
+	}
+
+
+
+	Period getPeriod();
 	/**
 	 *  Determine if it should use his own LocalPeriod or use the global Period over the entire simulation.
 	 * 	Local Period is opposed to repeated once the period is over.
 	 */
-	void setUseLocalPeriod(boolean state);
+	void setPeriod(Period period);
 }

+ 16 - 26
src/holeg/model/AbstractCanvasObject.java

@@ -1,8 +1,6 @@
 package holeg.model;
 
-import com.google.gson.annotations.Expose;
 import holeg.ui.model.IdCounter;
-import holeg.ui.model.IdCounter.CounterType;
 import holeg.utility.math.vector.Vec2i;
 
 import java.util.Optional;
@@ -15,22 +13,15 @@ import java.util.Optional;
  * @author Gruppe14
  */
 public abstract class AbstractCanvasObject {
-    /* Type of the Object. */
-    @Expose
-    String objName;
     /* Name given by the user. */
-    @Expose
     String name;
     /* Path of the image for the Obj. */
-    @Expose
-    String image;
+    String imagePath;
     /* Position with a X and Y value */
-    @Expose
     Vec2i position = new Vec2i(0, 0);
     /* ID of the Obj. */
-    @Expose
     private final int id;
-    private Optional<GroupNode> groupNode = Optional.empty();
+    private transient GroupNode groupNode;
 
     /**
      * Constructor for a CpsObejct with an unique ID.
@@ -39,7 +30,7 @@ public abstract class AbstractCanvasObject {
      */
     public AbstractCanvasObject(String objName) {
         setName(objName);
-        this.id = IdCounter.nextId(CounterType.Object);
+        this.id = IdCounter.next();
     }
 
     /**
@@ -47,25 +38,24 @@ public abstract class AbstractCanvasObject {
      * correspond to the interaction between the Categories and Canvas)-->
      * actually the "new" Object is a copy.
      *
-     * @param obj Object to be copied
+     * @param other Object to be copied
      */
-    public AbstractCanvasObject(AbstractCanvasObject obj) {
-        setName(obj.getName());
-        setImage(obj.getImage());
-        this.id = IdCounter.nextId(CounterType.Object);
+    public AbstractCanvasObject(AbstractCanvasObject other) {
+        setName(other.getName());
+        setImagePath(other.getImagePath());
+        this.position = other.position;
+        this.id = IdCounter.next();
 
     }
 
     public Optional<GroupNode> getGroupNode() {
-        return groupNode;
+        return Optional.ofNullable(groupNode);
     }
 
     public void setGroupNode(GroupNode groupNode) {
-        this.groupNode = Optional.of(groupNode);
+        this.groupNode = groupNode;
     }
 
-    public abstract void initForReflection();
-
 
     /**
      * Getter for the user-defined name (no unique).
@@ -90,17 +80,17 @@ public abstract class AbstractCanvasObject {
      *
      * @return String
      */
-    public String getImage() {
-        return image;
+    public String getImagePath() {
+        return imagePath;
     }
 
     /**
      * Set the path of the image.
      *
-     * @param image the Image to set
+     * @param imagePath the Image to set
      */
-    public void setImage(String image) {
-        this.image = image;
+    public void setImagePath(String imagePath) {
+        this.imagePath = imagePath;
     }
 
     public int getId() {

+ 1 - 2
src/holeg/model/Constrain.java

@@ -6,7 +6,6 @@ import com.google.gson.annotations.Expose;
 
 public class Constrain {
 	private Predicate<Flexibility> constrainFunction;
-	@Expose
 	private String name;
 	
 	public Constrain(Predicate<Flexibility> constrainFunction,String name) {
@@ -38,7 +37,7 @@ public class Constrain {
 	
 	
 	/**
-	 * Delete me ....
+	 * TODO(Tom2022-01-25): Delete me ....
 	 * @return
 	 */
 	public boolean fixJson() {

+ 2 - 4
src/holeg/model/Edge.java

@@ -1,20 +1,18 @@
 package holeg.model;
 
-import com.google.gson.annotations.Expose;
 
 public class Edge {
 
     // Max. capacity of the Edge, if flow is greater than the status --> is
     // Working would be false
-    @Expose
     public float maxCapacity;
     // Source
     AbstractCanvasObject a;
     // Destination
     AbstractCanvasObject b;
     public EdgeMode mode = EdgeMode.Normal;
-    private EdgeState state = initState();
-    private float flowEnergy = 0;
+    private transient EdgeState state = initState();
+    private transient float flowEnergy = 0;
 
     /**
      * Constructor with a user-defined max. capacity

+ 199 - 191
src/holeg/model/Flexibility.java

@@ -4,199 +4,207 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
 
-import com.google.gson.annotations.Expose;
-
 /**
  * Representative of a flexibility for a HolonElement.
- *
  */
 public class Flexibility {
-	/*
-	 *  MODEL
-	 */
-	/** The owner of the Flexibility.*/
-	private HolonElement element;
-	/** The Name of a Flexibility.*/
-	@Expose
-	public String name;
-	/** How fast in TimeSteps the Flexibility can be activated. */
-	@Expose
-	public int speed;
-	/** How high the cost for a activation are. */
-	@Expose
-	public float cost;
-	/** SHould this Flexibility be Offered when is constrainList is fulfilled the flexibility can be activated.*/
-	@Expose
-	public boolean offered;
-	/** The Duration in TimeSteps how long the Flexibility is activated.*/
-	@Expose
-	private int duration;
-	/** The Duration after a successful activation between the next possible activation.*/
-	@Expose
-	private int cooldown;
-	/** The Element this flexibility is assigned.*/
-
-
-
-
-
-	/** The List of Constrains the Flexibility */
-	@Expose
-	public List<Constrain> constrainList;
-	
-	
-	public Flexibility(HolonElement element){
-		this(0 , 0.f, 1, 0, false, element);		
-	}
-	public Flexibility(int speed, float cost, int duration, int cooldown, boolean offered, HolonElement element){
-		this.speed = speed;
-		this.cost = cost;
-		setDuration(duration);
-		setCooldown(cooldown);
-		this.offered=offered;
-		this.element = element;
-		constrainList = new ArrayList<Constrain>();	
-	}
-	
-	
-	
-	public HolonElement getElement() {
-		return element;
-	}
-	public void setElement(HolonElement element) {
-		this.element = element;
-	}
-
-	public int getDuration() {
-		return duration;
-	}
-	/** Minimum duration is 1 TimeStep.*/
-	public void setDuration(int duration) {
-		this.duration = Math.max(1, duration);
-	}
-
-	public int getCooldown() {
-		return cooldown;
-	}
-	/** No negative cooldown TimeSteps.*/
-	public void setCooldown(int cooldown) {
-		this.cooldown = Math.max(0, cooldown);
-	}
-
-	/** returns the total energy Amount accumulated over the TimeSteps.*/
-	public float magnitude() {
-		return ((float)duration) *  element.getEnergy();
-	}
-	
-	public float energyReleased(){
-		return (constrainList.stream().map(constrain -> constrain.getName()).anyMatch(name -> name.equals("onConstrain"))?-1.0f:1.0f) * element.getEnergy();
-	}
-	public boolean isPositive() {
-		return energyReleased() >= 0;
-	}
-	public boolean isNegative() {
-		return energyReleased() < 0;
-	}
-	
-	
-	
-	public int getSpeed() {
-		return speed;
-	}
-	public void setSpeed(int speed) {
-		this.speed = speed;
-	}
-	@Override
-	public String toString() {
-		return "Flexibility: " + name + " from [HolonElement: " + element.getName() + " ID:" + element.getId() +"]";
-	}
-
-	
-	public static enum FlexState{
-		IN_USE, ON_COOLDOWN, OFFERED, NOT_OFFERED, UNAVAILABLE
-	}		
-	
-
-	/*
-	 *  STATE
-	 */
-	private FlexState state = FlexState.OFFERED;
-	private int timestep;
-	private int activationTime = -1;
-	private int durationEndTime = -1;
-	private int coolDownEndTime = -1;
-
-	//TODO(Tom2021-12-1) public -> package 
-	public void calculateState(int timestep) {
-		this.timestep = timestep;
-		state = revalidateState();
-	}
-	//TODO(Tom2021-12-1) public -> package 
-	public boolean order() {
-		if(canOrder()) {
-			state = FlexState.IN_USE;
-			durationEndTime = timestep + this.getDuration();
-			coolDownEndTime = durationEndTime + this.getCooldown();
-			activationTime = timestep;
-			return true;
-		}
-		return false;
-	}
-	//TODO(Tom2021-12-1) public -> package 
-	public boolean cancel() {
-		if(activationTime == timestep) {
-			reset();
-			return true;
-		}
-		return false;
-	}
-	//TODO(Tom2021-12-2) public -> package 
-	public void reset() {
-		durationEndTime = -1;
-		coolDownEndTime = -1;
-		state=revalidateState();
-	}
-	public boolean canActivate() {
-		return remainingTimeTillActivation() == 0;
-	}
-	
-	public boolean canOrder() {
-		boolean flexIsOffered = state.equals(FlexState.OFFERED);
-		return  flexIsOffered && !element.isFlexActive() ;
-	}
-	public FlexState getState() {
-		return state;
-	}
-	
-	public int remainingTimeTillActivation() {
-		return Math.max(0, coolDownEndTime - timestep);
-	}
-	public int remainingDuration() {
-		return Math.max(0, durationEndTime - timestep);
-	}
-	
-	/** Checks if all assigned constrains are fulfilled. When no constrains assigned returns true.*/
-	private boolean fulfillsConstrains() {
-		return constrainList.stream().map(constrain -> constrain.getConstrainFunction()).reduce(Predicate::and).orElse(f -> true).test(this);
-	}
-	
-	private FlexState revalidateState() {
-		if(canActivate()) {
-			if (!this.fulfillsConstrains() || element.isFlexActive()) {
-				return FlexState.UNAVAILABLE;
-			}else if (this.offered){
-				return FlexState.OFFERED;
-			}
-			return FlexState.NOT_OFFERED;
-		}
-		else if(remainingDuration()== 0) {
-			return FlexState.ON_COOLDOWN;
-		}
-		else {
-			return FlexState.IN_USE;
-		}
-	}
-	
-
-	
+    /*
+     *  MODEL
+     */
+    /**
+     * The Name of a Flexibility.
+     */
+    public String name;
+    /**
+     * How fast in TimeSteps the Flexibility can be activated.
+     */
+    public int speed;
+    /**
+     * How high the cost for a activation are.
+     */
+    public float cost;
+    /**
+     * SHould this Flexibility be Offered when is constrainList is fulfilled the flexibility can be activated.
+     */
+    public boolean offered;
+    /**
+     * The List of Constrains the Flexibility
+     */
+    public List<Constrain> constrainList;
+    /**
+     * The owner of the Flexibility.
+     */
+    private transient HolonElement element;
+    /**
+     * The Duration in TimeSteps how long the Flexibility is activated.
+     */
+    private int duration;
+    /** The Element this flexibility is assigned.*/
+    /**
+     * The Duration after a successful activation between the next possible activation.
+     */
+    private int cooldown;
+    /*
+     *  STATE
+     */
+    private transient FlexState state = FlexState.OFFERED;
+    private transient int timeStep;
+    private transient int activationTime = -1;
+    private transient int durationEndTime = -1;
+    private transient int coolDownEndTime = -1;
+
+    public Flexibility(HolonElement element) {
+        this(0, 0.f, 1, 0, false, element);
+    }
+
+    public Flexibility(int speed, float cost, int duration, int cooldown, boolean offered, HolonElement element) {
+        this.speed = speed;
+        this.cost = cost;
+        setDuration(duration);
+        setCooldown(cooldown);
+        this.offered = offered;
+        this.element = element;
+        constrainList = new ArrayList<Constrain>();
+    }
+
+    public HolonElement getElement() {
+        return element;
+    }
+
+    public void setElement(HolonElement element) {
+        this.element = element;
+    }
+
+    public int getDuration() {
+        return duration;
+    }
+
+    /**
+     * Minimum duration is 1 TimeStep.
+     */
+    public void setDuration(int duration) {
+        this.duration = Math.max(1, duration);
+    }
+
+    public int getCooldown() {
+        return cooldown;
+    }
+
+    /**
+     * No negative cooldown TimeSteps.
+     */
+    public void setCooldown(int cooldown) {
+        this.cooldown = Math.max(0, cooldown);
+    }
+
+    /**
+     * returns the total energy Amount accumulated over the TimeSteps.
+     */
+    public float magnitude() {
+        return ((float) duration) * element.getEnergy();
+    }
+
+    public float energyReleased() {
+        return (constrainList.stream().map(Constrain::getName).anyMatch(name -> name.equals("onConstrain")) ? -1.0f : 1.0f) * element.getEnergy();
+    }
+
+    public boolean isPositive() {
+        return energyReleased() >= 0;
+    }
+
+    public boolean isNegative() {
+        return energyReleased() < 0;
+    }
+
+    public int getSpeed() {
+        return speed;
+    }
+
+    public void setSpeed(int speed) {
+        this.speed = speed;
+    }
+
+    @Override
+    public String toString() {
+        return "Flexibility: " + name + " from [HolonElement: " + element.getName() + "]";
+    }
+
+    void calculateState(int timestep) {
+        this.timeStep = timestep;
+        state = revalidateState();
+    }
+    public boolean order() {
+        if (canOrder()) {
+            state = FlexState.IN_USE;
+            durationEndTime = timeStep + this.getDuration();
+            coolDownEndTime = durationEndTime + this.getCooldown();
+            activationTime = timeStep;
+            return true;
+        }
+        return false;
+    }
+
+    public boolean cancel() {
+        if (activationTime == timeStep) {
+            reset();
+            return true;
+        }
+        return false;
+    }
+
+    void reset() {
+        durationEndTime = -1;
+        coolDownEndTime = -1;
+        state = revalidateState();
+    }
+
+    public boolean canActivate() {
+        return remainingTimeTillActivation() == 0;
+    }
+
+    public boolean canOrder() {
+        boolean flexIsOffered = state.equals(FlexState.OFFERED);
+        return flexIsOffered && !element.isFlexActive();
+    }
+
+    public FlexState getState() {
+        return state;
+    }
+
+    public int remainingTimeTillActivation() {
+        return Math.max(0, coolDownEndTime - timeStep);
+    }
+
+    public int remainingDuration() {
+        return Math.max(0, durationEndTime - timeStep);
+    }
+
+    /**
+     * Checks if all assigned constrains are fulfilled. When no constrains assigned returns true.
+     */
+    private boolean fulfillsConstrains() {
+        return constrainList.stream().map(Constrain::getConstrainFunction).reduce(Predicate::and).orElse(f -> true).test(this);
+    }
+
+    private FlexState revalidateState() {
+        if (canActivate()) {
+            if (!this.fulfillsConstrains() || element.isFlexActive()) {
+                return FlexState.UNAVAILABLE;
+            } else if (this.offered) {
+                return FlexState.OFFERED;
+            }
+            return FlexState.NOT_OFFERED;
+        } else if (remainingDuration() == 0) {
+            return FlexState.ON_COOLDOWN;
+        } else {
+            return FlexState.IN_USE;
+        }
+    }
+
+    public enum FlexState {
+        IN_USE, ON_COOLDOWN, OFFERED, NOT_OFFERED, UNAVAILABLE
+    }
+
+
+
 }

+ 32 - 23
src/holeg/model/GroupNode.java

@@ -10,33 +10,24 @@ import holeg.preferences.ImagePreference;
 public class GroupNode extends AbstractCanvasObject {
 	private static final Logger log = Logger.getLogger(AbstractCanvasObject.class.getName());
 
-	private ArrayList<HolonObject> objectList = new ArrayList<>();
-	private ArrayList<HolonSwitch> switchList = new ArrayList<>();
-	private ArrayList<Node> nodeList = new ArrayList<>();
-	private ArrayList<GroupNode> groupNodeList = new ArrayList<>();
+	private final ArrayList<HolonObject> objectList = new ArrayList<>();
+	private final ArrayList<HolonSwitch> switchList = new ArrayList<>();
+	private final ArrayList<Node> nodeList = new ArrayList<>();
+	private final ArrayList<GroupNode> groupNodeList = new ArrayList<>();
 
 	public GroupNode(String nodeName) {
 		super(nodeName);
 	}
 
 	@Override
-	public void initForReflection() {
-		log.info("Executed");
-		objectList = new ArrayList<>();
-		switchList = new ArrayList<>();
-		nodeList = new ArrayList<>();
-		groupNodeList = new ArrayList<>();
-	}
-
-	@Override
-	public String getImage() {
+	public String getImagePath() {
 		return ImagePreference.Canvas.GroupNode;
 	}
 	public void addAll(Stream<AbstractCanvasObject> stream) {
-		stream.forEach(obj -> add(obj));
+		stream.forEach(this::add);
 	}
 	public void addAll(Collection<AbstractCanvasObject> collection) {
-		collection.forEach(obj -> add(obj));
+		collection.forEach(this::add);
 	}
 	
 	public void add(AbstractCanvasObject object) {
@@ -64,7 +55,14 @@ public class GroupNode extends AbstractCanvasObject {
 		}
 		object.setGroupNode(null);
 	}
-	
+	public void removeAll(Stream<AbstractCanvasObject> stream){
+		stream.forEach(this::remove);
+	}
+	public void removeAll(Collection<AbstractCanvasObject> collection){
+		collection.forEach(this::remove);
+	}
+
+
 
 	public Stream<AbstractCanvasObject> getObjectsInThisLayer() {
 		return Stream.of(objectList.stream(), switchList.stream(), nodeList.stream(), groupNodeList.stream())
@@ -75,25 +73,25 @@ public class GroupNode extends AbstractCanvasObject {
 		Stream<AbstractCanvasObject> objects = Stream.of(objectList.stream(), switchList.stream(), nodeList.stream())
 				.flatMap(s -> s);
 		return Stream.concat(objects,
-				groupNodeList.stream().flatMap(groupnode -> groupnode.getObjectsInThisLayer()));
+				groupNodeList.stream().flatMap(GroupNode::getObjectsInThisLayer));
 
 	}
 
 	public Stream<HolonObject> getAllHolonObjectsRecursive() {
 		return Stream.concat(objectList.stream(),
-				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllHolonObjectsRecursive()));
+				groupNodeList.stream().flatMap(GroupNode::getAllHolonObjectsRecursive));
 	}
 	public Stream<HolonSwitch> getAllSwitchObjectsRecursive() {
 		return Stream.concat(switchList.stream(),
-				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllSwitchObjectsRecursive()));
+				groupNodeList.stream().flatMap(GroupNode::getAllSwitchObjectsRecursive));
 	}
 	public Stream<Node> getAllNodeObjectsRecursive() {
 		return Stream.concat(nodeList.stream(),
-				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllNodeObjectsRecursive()));
+				groupNodeList.stream().flatMap(GroupNode::getAllNodeObjectsRecursive));
 	}
 	public Stream<GroupNode> getAllGroupNodeObjectsRecursive() {
 		return Stream.concat(groupNodeList.stream(),
-				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllGroupNodeObjectsRecursive()));
+				groupNodeList.stream().flatMap(GroupNode::getAllGroupNodeObjectsRecursive));
 	}
 	
 	public Stream<HolonObject> getHolonObjects() {
@@ -110,11 +108,22 @@ public class GroupNode extends AbstractCanvasObject {
 	public Stream<GroupNode> getGroupNodes() {
 		return groupNodeList.stream();
 	}
-	
+
+	public Stream<HolonElement> getHolonElements(){
+		return objectList.stream().flatMap(HolonObject::elementsStream);
+	}
+
+
 	public void clear() {
 		objectList.clear();
 		switchList.clear();
 		nodeList.clear();
 		groupNodeList.clear();
 	}
+
+	public void updateReference() {
+		getObjectsInThisLayer().forEach(obj -> obj.setGroupNode(this));
+		objectList.forEach(HolonObject::updateReference);
+		groupNodeList.forEach(GroupNode::updateReference);
+	}
 }

+ 239 - 276
src/holeg/model/HolonElement.java

@@ -1,80 +1,62 @@
 package holeg.model;
 
-import com.google.gson.annotations.Expose;
-import com.google.gson.annotations.SerializedName;
-
 import holeg.interfaces.TimelineDependent;
 import holeg.model.Flexibility.FlexState;
 import holeg.ui.controller.IndexTranslator;
 import holeg.ui.model.IdCounter;
-import holeg.ui.model.IdCounter.CounterType;
 import holeg.utility.math.vector.Vec2f;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.ListIterator;
 import java.util.logging.Logger;
+
 /**
  * The class "HolonElement" represents any possible element that can be added to
  * a CpsObject (such as TV (consumer) or any energyPerElement source/producer).
  *
  * @author Gruppe14
  */
-public class HolonElement implements TimelineDependent{
+public class HolonElement implements TimelineDependent {
     private static final Logger log = Logger.getLogger(HolonElement.class.getName());
-	/*
-	 * MODEL
-	 */
-	/** Owner of the Element */
-	public HolonObject parentObject;
-    /** Points of new TestGraph 
-     * Represent the Graph 
+    /*
+     * MODEL
+     */
+    /**
+     * Owner of the Element
+     */
+    public transient HolonObject parentObject;
+    /**
+     * Whether the gadget is active or not (currently uses/produces the energy in energyPerElement)
+     */
+    public boolean active;
+    public Priority priority = Priority.Low;
+    public List<Flexibility> flexList = new ArrayList<>();
+    /**
+     * Points of new TestGraph
+     * Represent the Graph
      * the X component from a Point is period from 0..1
      * the Y component from a Point is the percentage from 0..1
-     * */
-    private LinkedList<Vec2f> graphPoints;
-    /** Name of the gadget, e.g. TV */
-    @Expose
-    @SerializedName(value = "name", alternate = "eleName")
+     */
+    private LinkedList<Vec2f> graphPoints = new LinkedList<>();
+    /**
+     * Name of the gadget, e.g. TV
+     */
     private String name;
-    /** Amount of same elements */
-    @Expose
-    @SerializedName(value = "energy", alternate = "energyPerElement")
+    /**
+     * Amount of same elements
+     */
     private float energy;
-    /** Whether the gadget is active or not (currently uses/produces the energy in energyPerElement) */
-    @Expose
-    public boolean active;
-    /** Gives us whether this element is flexible and can flexibly use any part of the energy in flexibleEnergyAvailable */
-    
-    
-    
-    
-    public enum Priority {
-    	Low, Medium, High, Essential
-    }
-    
-    @Expose
-    public Priority priority = Priority.Low;
-
-
-    /** ID */
-    @Expose
-    private int id;
-    
-    
-    public java.util.List<Flexibility> flexList = new ArrayList<Flexibility>();
-    
+    private Period period = new Period();
     /*
      * Energy at each point of the graph with 100 predefined points. At the
      * beginning, it starts with all values at energyPerElement.
      * If switched to flexible, this represents the maximum of usable energy
      */
-    private float[] curveSample;
-    
-    @Expose
-    private int localPeriod;
-    @Expose
-    private boolean isUsingLocalPeriod;
+    private transient float[] curveSample;
+    private transient float actualEnergy = 0;
+
 
     /**
      * Create a new HolonElement with a user-defined name, amount of the same
@@ -83,57 +65,52 @@ public class HolonElement implements TimelineDependent{
      * @param eleName String
      * @param energy  float
      */
-    //TODO(Tom2021-12-20): constructor should be remade
-    public HolonElement(HolonObject parentObject, String eleName, float energy) {
-    	
-    	this(parentObject, eleName, energy, IdCounter.nextId(CounterType.Element));
-    }
-    
 
     /**
      * same as standard constructor, but with already given id (so the counter is not increased twice)
      */
-    public HolonElement(HolonObject parentObject, String eleName, float energy, int id){
-    	this.parentObject = parentObject;
-    	setUseLocalPeriod(false);
-    	setName(eleName);
+    public HolonElement(HolonObject parentObject, String eleName, float energy) {
+        this.parentObject = parentObject;
+        setName(eleName);
         setEnergy(energy);
         this.active = true;
-        setGraphPoints(new LinkedList<>());
         initGraphPoints();
         sampleGraph();
-        this.id = id;
     }
 
+
     /**
      * Create a copy of the HolonElement given each one a new ID.
      *
-     * @param element element to copy
+     * @param other element to copy
      */
-    public HolonElement(HolonElement element) {
-    	this.parentObject = element.parentObject;
-    	this.priority = element.getPriority();
-    	setLocalPeriod(element.getLocalPeriod());
-    	setUseLocalPeriod(element.isUsingLocalPeriod());
-        setName(element.getName());
-        setLocalPeriod(element.getLocalPeriod());
-        setEnergy(element.getEnergy());
-        this.active = element.active;
+    public HolonElement(HolonElement other) {
+        this.parentObject = other.parentObject;
+        this.priority = other.getPriority();
+        this.period = other.period;
+        this.flexList = new ArrayList<>(other.flexList);
+        setName(other.getName());
+        setEnergy(other.getEnergy());
+        this.active = other.active;
         setGraphPoints(new LinkedList<>());
-        for (Vec2f p : element.getGraphPoints()) {
+        for (Vec2f p : other.getGraphPoints()) {
             this.graphPoints.add(new Vec2f(p));
         }
+        this.actualEnergy = other.actualEnergy;
         sampleGraph();
-        this.id = IdCounter.nextId(CounterType.Element);
     }
 
+    @Override
+    public Period getPeriod() {
+        return period;
+    }
 
-
-    
-    public int getId() {
-    	return id;
+    @Override
+    public void setPeriod(Period period) {
+        this.period = period;
     }
-    
+
+
 
     /**
      * Get the user-defined Name.
@@ -162,237 +139,223 @@ public class HolonElement implements TimelineDependent{
     public float getEnergy() {
         return energy;
     }
-    
+
     /**
      * Set the energyPerElement value of the selected Element.
      *
      * @param energyPerElement the energyPerElement to set
      */
     public void setEnergy(float energyPerElement) {
-    	log.finest(this.energy + " -> " + energyPerElement);
-    	this.energy = energyPerElement;
+        log.finest(this.energy + " -> " + energyPerElement);
+        this.energy = energyPerElement;
     }
-    
-    
+
+
     /**
-     *  Check the HolonElemnet is a Producer
-     * 	@return true when the energy used be each element is higher then 0
+     * Check the HolonElemnet is a Producer
+     *
+     * @return true when the energy used be each element is higher then 0
      */
-    public boolean isProducer()
-    {
-    	return (energy > 0);
+    public boolean isProducer() {
+        return (energy > 0);
     }
-    
+
     /**
-     *  Check the HolonElemnet is a Consumer
-     * 	@return true when the energy used be each element is lower then 0
+     * Check the HolonElemnet is a Consumer
+     *
+     * @return true when the energy used be each element is lower then 0
      */
-    public boolean isConsumer()
-    {
-    	return (energy < 0);
+    public boolean isConsumer() {
+        return (energy < 0);
     }
-    
-    
-    
+
+
     public Priority getPriority() {
-    	return priority;
+        return priority;
     }
-    
-    
+
+
     public void setPriority(Priority priority) {
-    	this.priority = priority;
+        this.priority = priority;
     }
 
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[HolonElement: ");
-        sb.append("id=").append(id)
-                .append(", eleName=").append(name)
-                .append(", parentName=").append(parentObject.getName())
-                .append(", active=").append(active)
-                .append(", energyPerElement used=").append(energy);
-        sb.append("]");
-
-        return sb.toString();
+        return "[HolonElement: " +
+                ", eleName=" + name +
+                ", parentName=" + parentObject.getName() +
+                ", active=" + active +
+                ", energyPerElement used=" + energy +
+                "]";
     }
 
     /**
      * Initialize the {@link HolonElement#graphPoints} List with the normal 2 Points at 100%.
      */
-	private void initGraphPoints()
-	{
-		graphPoints.clear();
-		graphPoints.add(new Vec2f(0f,1.0f));
-		graphPoints.add(new Vec2f(1f,1.0f));
-	}
-	/**
-	 * Getter for the graphPoint List.
-	 * @return {@link HolonElement#graphPoints}
-	 */
-	public LinkedList<Vec2f> getGraphPoints() {
-		return graphPoints;
-	}
-
-	/**
-	 * Setter for the graphPoint List.
-	 * @param testGraphPoints is new  {@link HolonElement#graphPoints}
-	 */
-	public void setGraphPoints(LinkedList<Vec2f> graphPoints) {
-		this.graphPoints = graphPoints;
-	}
-
-	
-	
-	
-	//interfaces.GraphEditable
-	@Override
-	public GraphType getGraphType() {
-		return GraphType.doubleGraph;
-	}
-
-
-	@Override
-	public LinkedList<Vec2f> getStateGraph() {
-		return getGraphPoints();
-	}
-
-	
-	@Override
-	public void sampleGraph() {
-		curveSample = sampleGraph(100);
-	}
-
-	@Override
-	public void reset() {
-		initGraphPoints();
-		sampleGraph();
-	}
-	/**
-	 * Generate out of the Graph Points a array of floats that represent the Curve at each sample position. The Values are in the Range [0,1]. 
-	 * e.g. 0.0 represent: "0%" , 0.34 represent: 34%  1.0 represent: "100%" 
-	 * @param sampleLength amount of samplePositions. The positions are equidistant on the Range[0,1].
-	 * @return the float array of samplepoints.
-	 */
-	private float[] sampleGraph(int sampleLength)
-	{		
-		ListIterator<Vec2f> iter = this.graphPoints.listIterator();
-		Vec2f before = iter.next();
-		Vec2f after = iter.next();
-		float [] sampleCurve = new float[sampleLength];	
-		for(int i = 0; i<sampleLength ; i++)
-		{
-			double graphX = (double)i / (double) (sampleLength - 1); //from 0.0 to 1.0
-			if(graphX > after.x)
-			{
-				before = after;
-				after = iter.next();
-			}
-			//t to determine how many percentage the graphX is to the next Point needed to calc Bezier
-			//inverseLerp(valueBetween, min, max) (valueBetween - min) / (max - min)
-			// e.g. old.x = 0.4, actual.x = 0.8 and graphX = 0.6 then t is 0.5
-			double t = (after.x -before.x > 0)? (graphX - before.x) / (after.x -before.x) : 0.0;			
-			sampleCurve[i] = (float) getYBetweenTwoPoints(t, before, after);
-		}
-		return sampleCurve;
-	}
-	
-	/**
-	 * Helper method for {@link HolonElement#sampleGraph(int)}.
-	 * <p>
-	 * Its get the start and Endposition and calculate the Points in between for the Bezi�r Curve.
-	 * Then its get the Y Value a.k.a. the percentage from the curve at the X value t.  
-	 * @param t is in Range [0,1] and represent how much the X value is traverse along the Curve between the two Points.
-	 * @param start is the start Point of the Curve.
-	 * @param end is the end Point of the Curve.
-	 * @return the percentage from the Curve at the X Value based on t.
-	 */
-	private double getYBetweenTwoPoints(double t, Vec2f start, Vec2f end) {
-		
-		float mitte = (start.x + end.x)* 0.5f;
-		Vec2f bezier = getBezierPoint(t, start, new Vec2f(mitte, start.y), new Vec2f(mitte, end.y), end);
-		return bezier.y;
-	}
-	/**
-	 * Helper method for {@link HolonElement#getYBetweenTwoPoints(double, Vec2f, Vec2f)}.
-	 * <p>
-	 * A Method for a normal Cubic Bezier Curve. A Cubic Bezier curve has four control points.
-	 * @param t is in Range [0,1] how much it traverse along the curve.
-	 * @param p0 StartPoint
-	 * @param p1 ControlPoint
-	 * @param p2 ControlPoint
-	 * @param p3 EndPoint
-	 * @return the BezierPosition at t.
-	 */
-	private Vec2f getBezierPoint(double t, Vec2f p0, Vec2f p1,Vec2f p2,Vec2f p3) {
-		/*
-		 * Calculate Bezi�r:
-		 * B(t) = (1-t)^3 * P0 + 3*(1-t)^2 * t * P1 + 3*(1-t)*t^2 * P2 + t^3 * P3 , 0 < t < 1
-		 * 
-		 * Source: //http://www.theappguruz.com/blog/bezier-curve-in-games
-		 */
-		Vec2f bezier = new Vec2f();
-		double OneSubT =  1-t;
-		double OneSubT2 = Math.pow(OneSubT, 2);
-		double OneSubT3 = Math.pow(OneSubT, 3);
-		double t2 = Math.pow(t , 2);
-		double t3 = Math.pow(t , 3);
-		
-		bezier.x = (float)(OneSubT3 * p0.x + 3 * OneSubT2 * t * p1.x + 3 * OneSubT * t2 * p2.x + t3 * p3.x);
-		bezier.y = (float)(OneSubT3 * p0.y + 3 * OneSubT2 * t * p1.y + 3 * OneSubT * t2 * p2.y + t3 * p3.y);
-		return bezier;
-		
-	}
-	//interfaces.LocalMode
-	@Override
-	public void setLocalPeriod(int period) {
-		localPeriod=period;
-	}
-	
-	@Override
-	public int getLocalPeriod() {
-		return localPeriod;
-	}
-	
-	@Override
-	public boolean isUsingLocalPeriod() {
-		return isUsingLocalPeriod;
-	}
-	
-	@Override
-	public void setUseLocalPeriod(boolean state) {
-		this.isUsingLocalPeriod=state;
-	}
-	
-	/*
-	 * STATE 
-	 */
-	
-	private float actualEnergy = 0;
-	//TODO(Tom2021-12-1): public -> package
-	public void calculateState(int timestep) {
-		flexList.forEach(flex -> flex.calculateState(timestep));
-		float energyWhenActive = energy * this.curveSample[IndexTranslator.getEffectiveIndex(this, timestep)];
-		actualEnergy = isOn() ? energyWhenActive : 0;
-	}
-	  /**
+    private void initGraphPoints() {
+        graphPoints.clear();
+        graphPoints.add(new Vec2f(0f, 1.0f));
+        graphPoints.add(new Vec2f(1f, 1.0f));
+    }
+
+    /**
+     * Getter for the graphPoint List.
+     *
+     * @return {@link HolonElement#graphPoints}
+     */
+    public LinkedList<Vec2f> getGraphPoints() {
+        return graphPoints;
+    }
+
+    /**
+     * Setter for the graphPoint List.
+     */
+    public void setGraphPoints(LinkedList<Vec2f> graphPoints) {
+        this.graphPoints = graphPoints;
+    }
+
+
+    //interfaces.GraphEditable
+    @Override
+    public GraphType getGraphType() {
+        return GraphType.doubleGraph;
+    }
+
+
+    @Override
+    public LinkedList<Vec2f> getStateGraph() {
+        return getGraphPoints();
+    }
+
+
+    @Override
+    public void sampleGraph() {
+        curveSample = sampleGraph(100);
+    }
+
+    @Override
+    public void reset() {
+        initGraphPoints();
+        sampleGraph();
+    }
+
+    /**
+     * Generate out of the Graph Points a array of floats that represent the Curve at each sample position. The Values are in the Range [0,1].
+     * e.g. 0.0 represent: "0%" , 0.34 represent: 34%  1.0 represent: "100%"
+     *
+     * @param sampleLength amount of samplePositions. The positions are equidistant on the Range[0,1].
+     * @return the float array of samplepoints.
+     */
+    private float[] sampleGraph(int sampleLength) {
+        ListIterator<Vec2f> iter = this.graphPoints.listIterator();
+        Vec2f before = iter.next();
+        Vec2f after = iter.next();
+        float[] sampleCurve = new float[sampleLength];
+        for (int i = 0; i < sampleLength; i++) {
+            double graphX = (double) i / (double) (sampleLength - 1); //from 0.0 to 1.0
+            if (graphX > after.x) {
+                before = after;
+                after = iter.next();
+            }
+            //t to determine how many percentage the graphX is to the next Point needed to calc Bezier
+            //inverseLerp(valueBetween, min, max) (valueBetween - min) / (max - min)
+            // e.g. old.x = 0.4, actual.x = 0.8 and graphX = 0.6 then t is 0.5
+            double t = (after.x - before.x > 0) ? (graphX - before.x) / (after.x - before.x) : 0.0;
+            sampleCurve[i] = (float) getYBetweenTwoPoints(t, before, after);
+        }
+        return sampleCurve;
+    }
+
+    /**
+     * Helper method for {@link HolonElement#sampleGraph(int)}.
+     * <p>
+     * Its get the start and Endposition and calculate the Points in between for the Bezi�r Curve.
+     * Then its get the Y Value a.k.a. the percentage from the curve at the X value t.
+     *
+     * @param t     is in Range [0,1] and represent how much the X value is traverse along the Curve between the two Points.
+     * @param start is the start Point of the Curve.
+     * @param end   is the end Point of the Curve.
+     * @return the percentage from the Curve at the X Value based on t.
+     */
+    private double getYBetweenTwoPoints(double t, Vec2f start, Vec2f end) {
+
+        float mitte = (start.x + end.x) * 0.5f;
+        Vec2f bezier = getBezierPoint(t, start, new Vec2f(mitte, start.y), new Vec2f(mitte, end.y), end);
+        return bezier.y;
+    }
+
+    /**
+     * Helper method for {@link HolonElement#getYBetweenTwoPoints(double, Vec2f, Vec2f)}.
+     * <p>
+     * A Method for a normal Cubic Bezier Curve. A Cubic Bezier curve has four control points.
+     *
+     * @param t  is in Range [0,1] how much it traverse along the curve.
+     * @param p0 StartPoint
+     * @param p1 ControlPoint
+     * @param p2 ControlPoint
+     * @param p3 EndPoint
+     * @return the BezierPosition at t.
+     */
+    private Vec2f getBezierPoint(double t, Vec2f p0, Vec2f p1, Vec2f p2, Vec2f p3) {
+        /*
+         * Calculate Bezi�r:
+         * B(t) = (1-t)^3 * P0 + 3*(1-t)^2 * t * P1 + 3*(1-t)*t^2 * P2 + t^3 * P3 , 0 < t < 1
+         *
+         * Source: //http://www.theappguruz.com/blog/bezier-curve-in-games
+         */
+        Vec2f bezier = new Vec2f();
+        double OneSubT = 1 - t;
+        double OneSubT2 = Math.pow(OneSubT, 2);
+        double OneSubT3 = Math.pow(OneSubT, 3);
+        double t2 = Math.pow(t, 2);
+        double t3 = Math.pow(t, 3);
+
+        bezier.x = (float) (OneSubT3 * p0.x + 3 * OneSubT2 * t * p1.x + 3 * OneSubT * t2 * p2.x + t3 * p3.x);
+        bezier.y = (float) (OneSubT3 * p0.y + 3 * OneSubT2 * t * p1.y + 3 * OneSubT * t2 * p2.y + t3 * p3.y);
+        return bezier;
+
+    }
+
+
+    /*
+     * STATE
+     */
+
+    //TODO(Tom2021-12-1): public -> package
+    public void calculateState(int timestep) {
+        flexList.forEach(flex -> flex.calculateState(timestep));
+        float energyWhenActive = energy * this.curveSample[IndexTranslator.getEffectiveIndex(this, timestep)];
+        actualEnergy = isOn() ? energyWhenActive : 0;
+    }
+
+    /**
      * Get the energyPerElement currently(at given time step) available
      */
     public float calculateExpectedEnergyAtTimeStep(int timestep) {
-    	float energyWhenActive = energy * this.curveSample[IndexTranslator.getEffectiveIndex(this, timestep)];
-    	return active ? energyWhenActive : 0;
+        float energyWhenActive = energy * this.curveSample[IndexTranslator.getEffectiveIndex(this, timestep)];
+        return active ? energyWhenActive : 0;
     }
-	
+
     public float getActualEnergy() {
-    	return actualEnergy;
+        return actualEnergy;
     }
 
     public boolean isOn() {
-    	//return isFlexActive()?!active:active; 
-    	//Bool logic XOR
-    	return isFlexActive() ^ active;
+        //return isFlexActive()?!active:active;
+        //Bool logic XOR
+        return isFlexActive() ^ active;
     }
+
     public boolean isFlexActive() {
-    	return flexList.stream().anyMatch(flex -> flex.getState() == FlexState.IN_USE || flex.getState() == FlexState.ON_COOLDOWN);
+        return flexList.stream().anyMatch(flex -> flex.getState() == FlexState.IN_USE || flex.getState() == FlexState.ON_COOLDOWN);
+    }
+
+    public enum Priority {
+        Low, Medium, High, Essential
+    }
+
+
+    public void updateReference(){
+        flexList.forEach(flex -> flex.setElement(this));
     }
-    
+
 }

+ 21 - 24
src/holeg/model/HolonObject.java

@@ -1,9 +1,6 @@
 package holeg.model;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -16,17 +13,17 @@ import java.util.stream.Stream;
  */
 public class HolonObject extends AbstractCanvasObject {
     /* Array of all consumers */
-    private List<HolonElement> elements = new ArrayList<>();
+    private final Set<HolonElement> elements = new HashSet<>();
 
     //Calculated values
-    private HolonObjectState state;
-    private float actualEnergy;
-    private float energyFromHolon;
-    private float energyToHolon;
-    private float minimumConsumingElementEnergy;
-    private float energyNeededFromHolon;
-    private float energyFromConsumingElements;
-    private float energySelfSupplied;
+    private transient HolonObjectState state;
+    private transient float actualEnergy;
+    private transient float energyFromHolon;
+    private transient float energyToHolon;
+    private transient float minimumConsumingElementEnergy;
+    private transient float energyNeededFromHolon;
+    private transient float energyFromConsumingElements;
+    private transient float energySelfSupplied;
 
     /**
      * Constructor Set by default the name of the object equals to the category
@@ -50,20 +47,18 @@ public class HolonObject extends AbstractCanvasObject {
         }
     }
 
-    @Override
-    public void initForReflection() {
-        elements = new ArrayList<HolonElement>();
-    }
-
     /**
      * Getter for all Elements in the HolonObject.
      *
      * @return the elements ArrayList
      */
-    public Stream<HolonElement> getElements() {
+    public Stream<HolonElement> elementsStream() {
         return elements.stream();
     }
 
+
+
+
     public void clearElements() {
         elements.clear();
     }
@@ -95,10 +90,6 @@ public class HolonObject extends AbstractCanvasObject {
         element.parentObject = null;
     }
 
-    public void removeElement(int index) {
-        HolonElement ele = elements.remove(index);
-        ele.parentObject = null;
-    }
 
     /**
      * This Method returns the smallest consuming HolonElement that is ACTIVE. If
@@ -240,7 +231,7 @@ public class HolonObject extends AbstractCanvasObject {
     }
 
     public String toString() {
-        return "[HolonObject: " + "id=" + getId() + ", name=" + name + ", state=" + state + ", elements=[" + getElements().map(HolonElement::getName).collect(Collectors.joining(", ")) + "]]";
+        return "[HolonObject: " + "id=" + getId() + ", name=" + name + ", state=" + state + ", elements=[" + elementsStream().map(HolonElement::getName).collect(Collectors.joining(", ")) + "]]";
     }
 
     public float getEnergyToHolon() {
@@ -271,5 +262,11 @@ public class HolonObject extends AbstractCanvasObject {
         NO_ENERGY, NOT_SUPPLIED, SUPPLIED, PRODUCER, PARTIALLY_SUPPLIED, OVER_SUPPLIED
     }
 
+    public void updateReference(){
+        elements.forEach(ele -> {
+            ele.parentObject = this;
+            ele.updateReference();
+        });
+    }
 
 }

+ 7 - 35
src/holeg/model/HolonSwitch.java

@@ -1,6 +1,5 @@
 package holeg.model;
 
-import com.google.gson.annotations.Expose;
 import holeg.interfaces.LocalMode;
 import holeg.interfaces.TimelineDependent;
 import holeg.preferences.ImagePreference;
@@ -18,10 +17,6 @@ import java.util.ListIterator;
  * @author Gruppe14
  */
 public class HolonSwitch extends AbstractCanvasObject implements TimelineDependent {
-
-
-    @Expose
-    boolean localPeriodActive = false;
     /**
      * Energy at each point of the graph with 50 predefined points. At the
      * beginning, it starts with all values at energy
@@ -31,13 +26,10 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
      * Points on the UnitGraph
      */
     LinkedList<Vec2f> graphPoints = new LinkedList<>();
-    @Expose
     private SwitchMode mode = SwitchMode.Auto;
-    @Expose
     private SwitchState manualState = SwitchState.Closed;
-    @Expose
-    private int localPeriod;
     private SwitchState state = SwitchState.Closed;
+    private Period period = new Period();
 
     /**
      * Create a new HolonSwitch with a custom name, a default value of automatic
@@ -61,9 +53,7 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
         mode = other.mode;
         manualState = other.manualState;
         state = other.state;
-
-        setLocalPeriod(other.getLocalPeriod());
-        setUseLocalPeriod(other.isUsingLocalPeriod());
+        setPeriod(other.getPeriod());
         activeAt = new boolean[LocalMode.STANDARD_GRAPH_ACCURACY];
         setName(other.getName());
         for (Vec2f p : other.getGraphPoints()) {
@@ -73,20 +63,13 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
     }
 
     @Override
-    public String getImage() {
+    public String getImagePath() {
         return switch (state) {
             case Open -> ImagePreference.Canvas.Switch.Open;
             case Closed -> ImagePreference.Canvas.Switch.Closed;
         };
     }
 
-    @Override
-    public void initForReflection() {
-        this.graphPoints = new LinkedList<>();
-        this.state = SwitchState.Closed;
-        this.reset();
-    }
-
     /**
      * Calculates the state of the Switch.
      */
@@ -203,24 +186,13 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
     }
 
     @Override
-    public int getLocalPeriod() {
-        return localPeriod;
-    }
-
-    // interfaces.LocalMode
-    @Override
-    public void setLocalPeriod(int period) {
-        localPeriod = period;
-    }
+    public Period getPeriod() {
 
-    @Override
-    public boolean isUsingLocalPeriod() {
-        return localPeriodActive;
+        return period;
     }
-
     @Override
-    public void setUseLocalPeriod(boolean state) {
-        this.localPeriodActive = state;
+    public void setPeriod(Period period) {
+        this.period = period;
     }
 
     public String toString() {

+ 171 - 0
src/holeg/model/Model.java

@@ -0,0 +1,171 @@
+package holeg.model;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+
+/**
+ * The Class Model is the class where everything is saved. All changes made to
+ * the Data is managed via a controller.
+ *
+ * @author Gruppe14
+ */
+public class Model {
+
+    private static final Logger log = Logger.getLogger(Model.class.getName());
+    private GroupNode canvas = new GroupNode("Canvas");
+    public transient Set<Holon> holons = new HashSet<>();
+
+    /** the amount of iterations */
+    private int currentIteration = 0;
+    private int maxIterations = 100;
+    /**
+     * the Fairness model in use
+     */
+    private FairnessModel fairnessModel = FairnessModel.MininumDemandFirst;
+    /*
+     * Array of all CpsObjects in our canvas. It is set by default as an empty
+     * list.
+     */
+    private Set<Edge> edgesOnCanvas = new HashSet<>();
+
+    public Model() {
+        log.fine("Init Model");
+    }
+
+    public GroupNode getCanvas() {
+        return canvas;
+    }
+
+    /**
+     * Get all Edges on the Canvas.
+     *
+     * @return the edgesOnCanvas
+     */
+    public Set<Edge> getEdgesOnCanvas() {
+        return edgesOnCanvas;
+    }
+
+    /**
+     * Adds an Edge to The Canvas.
+     *
+     * @param edge the edgesOnCanvas to add
+     */
+    public void addEdgeOnCanvas(Edge edge) {
+        this.edgesOnCanvas.add(edge);
+    }
+
+    /**
+     * Remove an edge from the Canvas.
+     *
+     * @param edge the edge to remove
+     */
+    public void removeEdgesOnCanvas(Edge edge) {
+        this.edgesOnCanvas.remove(edge);
+    }
+
+    /**
+     * Returns the maximum iterations.
+     *
+     * @return iterations
+     */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /**
+     * Returns the current iteration.
+     *
+     * @return current iteration
+     */
+    public int getCurrentIteration() {
+        return currentIteration;
+    }
+
+    /**
+     * sets the current Iteration.
+     *
+     * @param value the current Iteration
+     */
+    public void setCurrentIteration(int value) {
+        this.currentIteration = value;
+    }
+
+    public List<HolonElement> getAllHolonElements() {
+        return canvas.getAllHolonObjectsRecursive().flatMap(HolonObject::elementsStream).collect(Collectors.toList());
+    }
+
+    public List<Flexibility> getAllFlexibilities() {
+        return canvas.getAllHolonObjectsRecursive().flatMap(hO -> hO.elementsStream().flatMap(ele -> ele.flexList.stream())).collect(Collectors.toList());
+    }
+
+    public void reset() {
+        resetFlexibilities();
+        resetEdges();
+    }
+
+    private void resetFlexibilities() {
+        getAllFlexibilities().forEach(Flexibility::reset);
+    }
+
+    private void resetEdges() {
+        this.getEdgesOnCanvas().forEach(Edge::reset);
+    }
+
+    /**
+     * @param iterations the number of steps for this simulation
+     */
+    public void setIterations(int iterations) {
+        this.maxIterations = iterations;
+    }
+
+    /**
+     * @return the fairnessModel
+     */
+    public FairnessModel getFairnessModel() {
+        return fairnessModel;
+    }
+
+    /**
+     * @param fairnessModel the fairnessModel to set
+     */
+    public void setFairnessModel(FairnessModel fairnessModel) {
+        this.fairnessModel = fairnessModel;
+    }
+
+    public void clear() {
+        this.edgesOnCanvas.clear();
+        canvas.clear();
+    }
+
+    public void setCanvas(GroupNode canvas) {
+        this.canvas = canvas;
+    }
+
+    public void setEdgesOnCanvas(Set<Edge> edgesOnCanvas) {
+        this.edgesOnCanvas = edgesOnCanvas;
+    }
+
+    /**
+     * All implemented FairnessModels:<br>
+     * {@link FairnessModel#MininumDemandFirst}<br>
+     * {@link FairnessModel#AllEqual}
+     */
+    public enum FairnessModel {
+        /**
+         * One Element of each HolonObject will be powered first, starting with the
+         * smallest Demand. If ale HolonObjects have an active Element, the
+         * simulation will try to fully supply as many HolonObjects as possible.
+         */
+        MininumDemandFirst,
+        /**
+         * All HolonObjects will receive the same amount of energy.
+         */
+        AllEqual
+    }
+
+
+}

+ 0 - 3
src/holeg/model/Node.java

@@ -27,7 +27,4 @@ public class Node extends AbstractCanvasObject {
 		return "Node ID:" + getId();
 	}
 
-	@Override
-	public void initForReflection() {}
-
 }

+ 0 - 55
src/holeg/ui/controller/AutoSaveController.java

@@ -1,55 +0,0 @@
-package holeg.ui.controller;
-
-import holeg.ui.model.GuiSettings;
-
-/**
- * Autosave Controller.
- * 
- * @author Gruppe14
- */
-public class AutoSaveController {
-	private int max = Integer.MAX_VALUE;
-	private int numberOfSaves = 20;
-	private int currentSave;
-	private int count = 0;
-	private boolean isAllowed = false;
-
-	/**
-	 * Increase the Auto save number.
-	 */
-	public void increaseAutoSaveNr() {
-		currentSave = GuiSettings.autoSaveNr + 1;
-		if (count < currentSave) {
-			count = currentSave;
-		}
-		if (numberOfSaves == count) {
-			isAllowed = true;
-		}
-		if (currentSave > max) {
-			currentSave = 0;
-		}
-
-		GuiSettings.autoSaveNr = (currentSave);
-	}
-
-	/**
-	 * Decrease the Autosave Number.
-	 */
-	public void decreaseAutoSaveNr() {
-		currentSave = GuiSettings.autoSaveNr - 1;
-		// if (currentSave < 0) {
-		// currentSave = max;
-		// }
-		GuiSettings.autoSaveNr = (currentSave);
-	}
-
-
-	/**
-	 * Return isAllowed.
-	 * 
-	 * @return isAllowed
-	 */
-	public boolean allowed() {
-		return isAllowed;
-	}
-}

+ 113 - 217
src/holeg/ui/controller/CanvasController.java

@@ -1,239 +1,135 @@
 package holeg.ui.controller;
 
-import java.awt.Point;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.stream.Collectors;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Edge;
-import holeg.model.GroupNode;
-import holeg.model.HolonObject;
-import holeg.model.HolonSwitch;
-import holeg.model.Node;
+import holeg.model.*;
 import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
-import holeg.ui.view.main.GUI;
+import holeg.model.Model;
 import holeg.utility.math.vector.Vec2i;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
  * Controller for the Canvas.
- * 
+ *
  * @author Gruppe14
  */
-//TODO(Tom2022-01-11): remove CanvasController and merge with NodeController
-@Deprecated
 public class CanvasController {
 
-	private Model model;
-    private GUI gui;
-	/**
-	 * Constructor.
-	 * 
-	 * @param model
-	 *            the Model
-	 *            the MultipurposeController
-	 */
-	public CanvasController(Model model) {
-		this.model = model;
-	}
-
-	/**
-	 * Add an CpsObject to the model and notify the ObjectListener for update.
-	 * 
-	 * @param object
-	 *            CpsObject to be added.
-	 * @param replace when true objects could be replaced
-	 */
-	public void addObject(AbstractCanvasObject object, boolean replace) {
-		model.getCanvas().add(object);
-		/**
-		 * check if we should drag & drop replace
-		 */
-		if(!(object instanceof Node) && replace){
-			/** x of the dragged Object */
-			int x = object.getPosition().getX();
-			
-			/** y of the dragged Object */
-			int y = object.getPosition().getY();
-			
-			/** distance treshold for replacement */
-			int treshhold = GuiSettings.getPictureScale()/2;
-			
-			/** number of Objects that might be replaced (should be 1) */
-			int replaceCounter = 0;
-			
-			/** last object that could be replaced */
-			AbstractCanvasObject toBeReplaced = null;
-			
-			/** for each cps on Canvas */
-			for (AbstractCanvasObject cps : model.getCanvas().getObjectsInThisLayer().toList()){
-				
-				/** same object -> ignore */
-				if(cps == object)continue;
-				
-				/** x of object that might get replaced */
-				int c_x = cps.getPosition().getX();
-				
-				/** y of object that might get replaced */
-				int c_y = cps.getPosition().getY();
-				
-				/** if near enough */
-				if(Math.abs(x-c_x)<treshhold && Math.abs(y-c_y)<treshhold){
-					replaceCounter++;
-					toBeReplaced = cps;
-				}	
-			}
-			/** if replacement of exactly one object possible */
-			if(replaceCounter == 1 && toBeReplaced != null){
-				replaceObjectOnCanvas(toBeReplaced, object);
-			}
-		}
-	}
-
-	/**
-	 * Add a new Object.
-	 * 
-	 * @param object
-	 *            the Object
-	 */
-	public void addNewObject(AbstractCanvasObject object) {
-		// object.setConnections(new ArrayList<CpsEdge>());
-		addObject(object, true);
-	}
+    private final Control control;
 
+    /**
+     * Constructor.
+     *
+     * @param control the Controller
+     *
+     */
+    public CanvasController(Control control) {
+        this.control = control;
+    }
+
+    /**
+     * Add an CpsObject to the model and notify the ObjectListener for update.
+     *
+     * @param object CpsObject to be added.
+     */
+    public void addObject(GroupNode groupNode, AbstractCanvasObject object) {
+        groupNode.add(object);
+    }
 
 
-	/**
-	 * Deletes an CpsObject on the Canvas and its connections.
-	 * 
-	 * @param obj
-	 *            AbstractCpsObject
-	 */
-	public void deleteObjectOnCanvas(AbstractCanvasObject obj) {
-		removeAllConnectionsFromObject(obj);
-		model.getCanvas().remove(obj);
-	}
-	
-	public void deleteObjectsOnCanvas(Collection<AbstractCanvasObject> objects) {
-		for(AbstractCanvasObject obj: objects) {
-			removeAllConnectionsFromObject(obj);
-			model.getCanvas().remove(obj);
-		}
+    /**
+     * Deletes an CpsObject on the Canvas and its connections.
+     *
+     * @param obj AbstractCpsObject
+     */
+    public void deleteObject(AbstractCanvasObject obj) {
+        if(obj instanceof GroupNode groupNode) {
+            deleteAllObjectsInGroupNode(groupNode);
+        }else{
+            removeAllConnectionsFromObject(obj);
+        }
+        obj.getGroupNode().ifPresent(groupNode -> groupNode.remove(obj));
+    }
+
+    public void deleteObjects(Collection<AbstractCanvasObject> objects) {
+		objects.forEach(this::deleteObject);
 	}
 
-	/**
+    /**
      * Replaces {@code toBeReplaced} by {@code by} on the canvas
+     *
      * @param toBeReplaced the object that will be replaced
-     * @param by the object that will replace it
+     * @param by           the object that will replace it
      */
-	public void replaceObjectOnCanvas(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
-		
-		//Replace edges
-		Iterator<Edge> iter = model.getEdgesOnCanvas().iterator();
-		while(iter.hasNext() ) {
-			Edge edge = iter.next();
-			if(edge.getA() == toBeReplaced && edge.getB() != by) {
-				edge.setA(by);
-			}
-			else if( edge.getB() == toBeReplaced && edge.getA() != by) {
-				edge.setB(by);
-			}
-		}
-		/**
-		 * set Position of by to exactly toBeReplaced
-		 */
-		by.setPosition(toBeReplaced.getPosition());
-		deleteObjectOnCanvas(toBeReplaced);
-	}
-	
-	/**
-	 * Add an edge to the Canvas.
-	 * 
-	 * @param edge
-	 *            the edge
-	 */
-	public void addEdgeOnCanvas(Edge edge) {
-		model.getEdgesOnCanvas().add(edge);
-	}
-
-	/**
-	 * Removes an Edge from the Canvas.
-	 * 
-	 * @param edge
-	 *            the edge to remove
-	 */
-	public void removeEdgesOnCanvas(Edge edge) {
-		model.getEdgesOnCanvas().remove(edge);
-	}
-
-	/**
-	 * Paste all Selected Objects.
-	 * 
-	 * @param p
-	 *            the mouse Position
-	 */
-	public void pasteObjects(Point p) {
-		GuiSettings.getSelectedObjects().clear();
-		AbstractCanvasObject tCps = null;
-		int x = Integer.MAX_VALUE, y = Integer.MAX_VALUE;
-
-		// Location whre to copy the Elements
-		for (AbstractCanvasObject cps : GuiSettings.getClipboardObjects()) {
-			if (cps.getPosition().getX() < x) {
-				x = cps.getPosition().getX();
-			}
-			if (cps.getPosition().getY() < y) {
-				y = cps.getPosition().getY();
-			}
-		}
-
-		// Objects
-		for (AbstractCanvasObject cps : GuiSettings.getClipboardObjects()) {
-			if (cps instanceof HolonObject hO) {
-				tCps = new HolonObject(hO);
-			} else if (cps instanceof HolonSwitch sw) {
-				tCps = new HolonSwitch(sw);
-			} else {
-				tCps = new Node("Node");
-			}
-			tCps.setPosition(new Vec2i(p.x + (cps.getPosition().getX() - x), p.y + (cps.getPosition().getY() - y)));
-			addObject(tCps, false);
-		}
-
-		
-
-	}
-
-	/**
-	 * Cut all Selected Objects.
-	 */
-	public void cutObjects() {
-		GuiSettings.setClipboardObjects(GuiSettings.getSelectedObjects().stream().collect(Collectors.toSet()));
-		for (AbstractCanvasObject cps : GuiSettings.getClipboardObjects()) {
-			deleteObjectOnCanvas(cps);
-		}
-
-		GuiSettings.getSelectedObjects().clear();
-	}
+    public void replaceObject(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
+        //Replace edges
+        for (Edge edge : control.getModel().getEdgesOnCanvas()) {
+            if (edge.getA() == toBeReplaced && edge.getB() != by) {
+                edge.setA(by);
+            } else if (edge.getB() == toBeReplaced && edge.getA() != by) {
+                edge.setB(by);
+            }
+        }
+        // set Position of by to exactly toBeReplaced
+        by.setPosition(toBeReplaced.getPosition());
+        deleteObject(toBeReplaced);
+    }
+
+    /**
+     * Add an edge to the Canvas.
+     *
+     * @param edge the edge
+     */
+    public void addEdgeOnCanvas(Edge edge) {
+        control.getModel().getEdgesOnCanvas().add(edge);
+    }
+
+    /**
+     * Removes an Edge from the Canvas.
+     *
+     * @param edge the edge to remove
+     */
+    public void removeEdgesOnCanvas(Edge edge) {
+        control.getModel().getEdgesOnCanvas().remove(edge);
+    }
 
-	
-	/**
-	 * Some cleaning Algorithm which traverses the UpperNode through BFS Can be
-	 * extended with other cleaning stuff No need for coloring since there tree
-	 * is only directed in one direction
-	 * 
-	 * @param node
-	 */
-	public void deleteAllObjectsInGroupNode(GroupNode node) {
-		List<AbstractCanvasObject> objectsInGroupNode = node.getAllObjectsRecursive().toList();
-		model.getEdgesOnCanvas().removeIf(edge -> objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB()));
-	}
+    /**
+     * Paste all Selected Objects.
+     */
+    public void pasteObjects(Vec2i p) {
+        //TODO(Tom2022-01-27): paste
+        GuiSettings.getSelectedObjects().clear();
+    }
 
-	public void removeAllConnectionsFromObject(AbstractCanvasObject obj) {
-		model.getEdgesOnCanvas().removeIf(edge -> edge.getA() == obj || edge.getB() == obj);
-	}
-	
+    /**
+     * Cut all Selected Objects.
+     */
+    public void cutObjects() {
+        GuiSettings.setClipboardObjects(new HashSet<>(GuiSettings.getSelectedObjects()));
+        for (AbstractCanvasObject cps : GuiSettings.getClipboardObjects()) {
+            deleteObject(cps);
+        }
+        GuiSettings.getSelectedObjects().clear();
+    }
+
+
+    /**
+     * Some cleaning Algorithm which traverses the UpperNode through BFS Can be
+     * extended with other cleaning stuff No need for coloring since there tree
+     * is only directed in one direction
+     */
+    public void deleteAllObjectsInGroupNode(GroupNode node) {
+        Set<AbstractCanvasObject> objectsInGroupNode = node.getAllObjectsRecursive().collect(Collectors.toSet());
+        control.getModel().getEdgesOnCanvas().removeIf(edge -> objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB()));
+    }
+
+    public void removeAllConnectionsFromObject(AbstractCanvasObject obj) {
+        control.getModel().getEdgesOnCanvas().removeIf(edge -> edge.getA() == obj || edge.getB() == obj);
+    }
+
+    public void addGroupNode(GroupNode groupNode, Set<AbstractCanvasObject> toGroup) {
+        //TODO(Tom2022-01-27):
+    }
 }

+ 0 - 182
src/holeg/ui/controller/CategoryController.java

@@ -1,182 +0,0 @@
-package holeg.ui.controller;
-
-import java.util.AbstractMap.SimpleEntry;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.HolonElement;
-import holeg.model.HolonObject;
-import holeg.model.HolonSwitch;
-import holeg.preferences.ImagePreference;
-import holeg.ui.model.GuiSettings;
-import holeg.ui.view.main.Category;
-import holeg.utility.events.Event;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Controller for the Categories.
- * 
- * @author Gruppe14
- */
-public class CategoryController {
-	private final Event OnCategoryChanged;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param model
-	 *            the Model
-	 * @param mp
-	 *            the MultiPurposeController
-	 * @param control 
-	 */
-	public CategoryController(Control control) {
-		this.OnCategoryChanged = control.OnCategoryChanged;
-	}
-
-	/**
-	 * init default category and objects.
-	 */
-	public void initCategories() {
-		Category energy = createCategoryWithName("Energy");
-		Category building = createCategoryWithName("Building");
-		Category component = createCategoryWithName("Component");
-		HolonObject powerPlant = addNewHolonObject(energy, "Power Plant", new ArrayList<HolonElement>(),
-				ImagePreference.Canvas.DefaultObject.PowerPlant);
-		HolonObject house = addNewHolonObject(building, "House", new ArrayList<HolonElement>(), ImagePreference.Canvas.DefaultObject.House);
-		addNewHolonSwitch(component, "Switch");
-		powerPlant.add(new HolonElement(null, "Power", 10000));
-		energy.getObjects().add(powerPlant);
-	
-		house.add(new HolonElement(null, "TV", -250));
-		house.add(new HolonElement(null, "TV", -250));
-		house.add(new HolonElement(null, "Fridge", -500));
-		house.add(new HolonElement(null, "Radio", -100));
-		house.add(new HolonElement(null, "PC", -250));
-		house.add(new HolonElement(null, "PC", -250));
-		house.add(new HolonElement(null, "PC", -250));
-		house.add(new HolonElement(null, "Light", -50));
-		house.add(new HolonElement(null, "Light", -50));
-		house.add(new HolonElement(null, "Light", -50));
-		house.add(new HolonElement(null, "Light", -50));
-		house.add(new HolonElement(null, "Light", -50));
-		house.add(new HolonElement(null, "Solar Panel", 300));
-		building.getObjects().add(house);
-		OnCategoryChanged.broadcast();
-	}
-
-	
-	public Category createCategoryWithName(String categoryName) {
-		Optional<Category> category = findCategoryWithName(categoryName);
-		if(category.isEmpty()) {
-			Category cat = new Category(categoryName);
-			GuiSettings.getCategories().add(cat);	
-			OnCategoryChanged.broadcast();
-			return cat;			
-		}else {
-			return category.get();
-		}
-		
-	}
-
-
-	/**
-	 * remove a Category from Model.
-	 * 
-	 * @param c
-	 *            Category
-	 */
-	public void removeCategory(Category c) {
-		GuiSettings.getCategories().remove(c);
-		OnCategoryChanged.broadcast();
-	}
-
-	public void clearCategories() {
-		GuiSettings.getCategories().clear();
-	}
-
-	/**
-	 * Add Object into a Category.
-	 * 
-	 * @param category
-	 *            Category
-	 * @param object
-	 *            Object
-	 */
-	public void addObject(Category category, AbstractCanvasObject object) {
-		int i = 0;
-		boolean updateElementSaves = false;
-		String name = "";
-		//TODO(Tom2021-12-1) remove/redo this search
-		while (category.findObjectWithName(object.getName()).isPresent()) {
-			updateElementSaves = true;
-			if (object.getName().contains("_"))
-				object.setName(object.getName().substring(0, object.getName().indexOf('_')));
-			name = object.getName() + "_" + i;
-			object.setName(name);
-			i++;
-		}
-		category.getObjects().add(object);
-	}
-
-	/**
-	 * Add new Holon Object to a Category.
-	 * 
-	 * @param category
-	 *            Category
-	 * @param object
-	 *            New Object Name
-	 * @param list
-	 *            Array of Elements
-	 * @param image
-	 *            the image Path
-	 */
-	public HolonObject addNewHolonObject(Category category, String object, List<HolonElement> list, String image) {
-		HolonObject obj = new HolonObject(object);
-		obj.setImage(image);
-		obj.clearElements();
-		obj.add(list);
-		addObject(category, obj);
-		return obj;
-	}
-	
-
-	/**
-	 * Add new Holon Switch.
-	 * 
-	 * @param cat
-	 *            Category
-	 * @param objName
-	 *            New Object Name
-	 * @param image
-	 *            the Image Path
-	 */
-	public HolonSwitch addNewHolonSwitch(Category cat, String objName) {
-		HolonSwitch holonSwitch = new HolonSwitch(objName);
-		addObject(cat, holonSwitch);
-		return holonSwitch;
-	}
-	
-	
-	
-	/**
-	 * Removes an Object from a Category.
-	 * @param category Category
-	 * @param cps the Object
-	 */
-	public void removeObject(Category category, AbstractCanvasObject cps) {
-		category.getObjects().remove(cps);
-		OnCategoryChanged.broadcast();
-	}
-
-	
-	
-	public Optional<Category> findCategoryWithName(String categoryName) {
-		return GuiSettings.getCategories().stream().filter(cat -> cat.getName().equals(categoryName)).findAny();
-	}
-	
-	
-
-}

+ 0 - 397
src/holeg/ui/controller/ClipboardController.java

@@ -1,397 +0,0 @@
-package holeg.ui.controller;
-
-import com.google.gson.*;
-
-import holeg.model.*;
-import holeg.ui.controller.SaveController.EDGETYPE;
-import holeg.ui.controller.SaveController.GRAPHTYPE;
-import holeg.ui.controller.SaveController.NUMTYPE;
-import holeg.ui.controller.SaveController.TYPE;
-import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
-import holeg.utility.math.vector.Vec2f;
-import holeg.utility.math.vector.Vec2i;
-
-import java.awt.*;
-import java.awt.datatransfer.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class ClipboardController {
-
-    private Model model;
-    private SaveController store;
-    private LoadController load;
-    private CanvasController cvsC;
-    private NodeController uppC;
-    private Clipboard clipboard;
-    private HashMap<Integer, Integer> objIDMap;
-    private HashMap<Integer, Integer> eleIDMap;
-    private String sav;
-    private Point point;
-	private SimulationManager simManager;
-
-    ClipboardController(Model model, SaveController store, LoadController load, CanvasController cvs,
-                        NodeController uppC, SimulationManager simManager) {
-        this.model = model;
-        this.store = store;
-        this.load = load;
-        this.cvsC = cvs;
-        this.uppC = uppC;
-        this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
-        this.simManager = simManager;
-    }
-
-    /**
-     * Copy marked Objects into Clipboard in Json Format
-     */
-    public void copy(GroupNode upperNode) {
-
-        JsonObject file = new JsonObject();
-        ArrayDeque<AbstractCanvasObject> queue = new ArrayDeque<>();
-        AbstractCanvasObject u = null;
-
-        store.initNumeration();
-
-        file.add("SAV", new JsonPrimitive((upperNode == null ? "CVS" : "" + upperNode.getId())));
-        Vec2i pos = uppC.calculatePos(GuiSettings.getSelectedObjects());
-        file.add("CENTER", GuiSettings.gson.toJsonTree(pos, Vec2i.class));
-
-        for (AbstractCanvasObject abs : GuiSettings.getSelectedObjects()) {
-            queue.add(abs);
-        }
-        while (!queue.isEmpty()) {
-
-            u = queue.pop();
-
-            String key = "CVSOBJECT" + store.getNumerator(NUMTYPE.OBJECT);
-            file.add(key, GuiSettings.gson.toJsonTree(u, AbstractCanvasObject.class));
-            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new HashSet<>());
-
-            if (u instanceof HolonObject)
-                store.elementsToJson(TYPE.CANVAS, file, u);
-
-            if (u instanceof HolonSwitch sw)
-                if (sw.getGraphPoints().size() != 0)
-                    store.unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
-
-            if (u instanceof GroupNode groupnode) {
-                for (AbstractCanvasObject adjacent : groupnode.getObjectsInThisLayer().toList()) {
-                    queue.add(adjacent);
-                }
-            }
-        }
-        if (upperNode == null)
-            edgeToJson(EDGETYPE.LAYER, file, 0, model.getEdgesOnCanvas());
-
-        StringSelection selection = new StringSelection(GuiSettings.gson.toJson(file));
-        clipboard.setContents(selection, selection);
-
-    }
-
-    /**
-     * Paste the Copied JsonTree into Canvas
-     */
-    void paste(GroupNode upperNode, Point p)
-            throws UnsupportedFlavorException, IOException, JsonParseException {
-
-        if (p == null)
-            return;
-
-        JsonObject json;
-        Transferable content = clipboard.getContents(null);
-
-        if (content != null && content.isDataFlavorSupported(DataFlavor.stringFlavor)
-                && !content.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) {
-
-            String str = (String) content.getTransferData(DataFlavor.stringFlavor);
-
-            if (JsonParser.parseString(str).isJsonObject())
-                json = (JsonObject) JsonParser.parseString(str);
-            else
-                throw new JsonParseException("Unknown Clipboard Information");
-
-        } else
-            return;
-
-        List<String> keys = load.getKeys(json);
-        List<String> edges = keys.stream().filter(key -> key.contains("EDGE"))
-                .collect(Collectors.toCollection(ArrayList::new));
-
-        HashMap<Integer, AbstractCanvasObject> objDispatch = new HashMap<>();
-        HashMap<Integer, HolonElement> eleDispatch = new HashMap<>();
-        GuiSettings.getSelectedObjects().clear();
-
-        objIDMap = new HashMap<>();
-        eleIDMap = new HashMap<>();
-        sav = json.get("SAV").getAsString();
-
-        Vec2i old = GuiSettings.gson.getAdapter(Vec2i.class).fromJsonTree(json.get("CENTER"));
-        point = new Point(old.getX() - p.x, old.getY() - p.y);
-
-        forwardObjects(keys, json, objDispatch, eleDispatch, upperNode);
-        // for selecting Cps
-        getObjectsInDepth();
-        forwardEdges(edges, json, objDispatch, upperNode);
-        this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
-    }
-
-    /**
-     * Cuts the marked Objects out of Canvas and saves them into the Clipboard
-     */
-    void cut(GroupNode upperNode) {
-        copy(upperNode);
-        for (AbstractCanvasObject abs : GuiSettings.getSelectedObjects()) {
-            if (upperNode == null)
-                cvsC.deleteObjectOnCanvas(abs);
-            else
-                uppC.deleteObjectInGroupNode(abs, upperNode);
-
-            if (abs instanceof GroupNode groupnode)
-                cvsC.deleteAllObjectsInGroupNode(groupnode);
-        }
-        GuiSettings.getSelectedObjects().clear();
-        this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
-
-    }
-
-    private void forwardEdges(List<String> keys, JsonObject json, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                              GroupNode upperNode) {
-        List<String> conn = new ArrayList<>();
-
-        for (String edge : keys) {
-            if (edge.contains("LAYEREDGE"))
-                loadEdge(EDGETYPE.LAYER, json.get(edge), objDispatch, upperNode);
-            if (edge.contains("CONNEDGE"))
-                conn.add(edge);
-            if (edge.contains("NODEEDGE"))
-                loadEdge(EDGETYPE.NODE, json.get(edge), objDispatch, null);
-            if (edge.contains("OLDEDGE"))
-                loadEdge(EDGETYPE.OLD, json.get(edge), objDispatch, null);
-        }
-
-        for (String edge : conn) {
-            loadEdge(EDGETYPE.CONNECTION, json.get(edge), objDispatch, null);
-        }
-
-    }
-
-    private void forwardObjects(List<String> keys, JsonObject json, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                                HashMap<Integer, HolonElement> eleDispatch, GroupNode upperNode) {
-
-        for (String key : keys) {
-            if (key.contains("CVSOBJECT"))
-                loadCanvasObject(json.get(key), objDispatch, upperNode);
-            if (key.contains("CVSELEMENT"))
-                loadCanvasElements(json.get(key), objDispatch, eleDispatch);
-            if (key.contains("SWUNITGRAPH"))
-                loadUnitGraph(GRAPHTYPE.SWITCH, json.get(key), objDispatch, null);
-            if (key.contains("ELEUNITGRAPH"))
-                loadUnitGraph(GRAPHTYPE.ELEMENT, json.get(key), null, eleDispatch);
-            if (key.contains("ELETESTUNITGRAPH"))
-                loadUnitGraph(GRAPHTYPE.TESTELEMENT, json.get(key), null, eleDispatch);
-        }
-    }
-
-    private void loadCanvasObject(JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                                  GroupNode upperNode) {
-        AbstractCanvasObject temp = GuiSettings.gson.fromJson(jsonElement.getAsJsonObject(), AbstractCanvasObject.class);
-        temp.initForReflection();
-        objIDMapper(temp);
-        updatePosition(temp, upperNode);
-
-        // if its stored before on the canvas just put it there
-        if (upperNode == null)
-            cvsC.addObject(temp, false);
-        else
-            uppC.addObjectInGroupNode(temp, upperNode, false);
-        // mark the Pasted Objects
-        GuiSettings.getSelectedObjects().add(temp);
-
-
-        objDispatch.put(temp.getId(), temp);
-    }
-
-    private void loadCanvasElements(JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                                    HashMap<Integer, HolonElement> eleDispatch) {
-        JsonObject object = jsonElement.getAsJsonObject();
-
-        HolonElement ele = GuiSettings.gson.fromJson(object.get("properties"), HolonElement.class);
-        load.initElements(ele);
-        eleIDMapper(ele);
-        // id which Object it was stored before
-        int stored = objIDMap.get(object.get("ID").getAsInt());
-        // lookup that object
-        HolonObject obj = (HolonObject) objDispatch.get(stored);
-        // add it
-        obj.add(ele);
-        // store element also inside a table
-        eleDispatch.put(ele.getId(), ele);
-    }
-
-    private void loadUnitGraph(GRAPHTYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                               HashMap<Integer, HolonElement> eleDispatch) {
-        JsonObject object = jsonElement.getAsJsonObject();
-        List<String> keys = load.getKeys(object);
-        String p;
-        int mid;
-        int sav = 0;
-     	LinkedList<Vec2f> graphpointTEST = new LinkedList<>();
-        for (String k : keys) {
-            if (!k.equals("ID")) {
-                p = object.get(k).getAsString();
-                mid = p.indexOf(':');
-                float x1 = Float.parseFloat(p.substring(0, mid));
-                float y1 = Float.parseFloat(p.substring(mid + 1, p.length()));
-                graphpointTEST.add(new Vec2f(x1, y1));
-            } else
-                // else its an ID
-                sav = object.get(k).getAsInt();
-
-        }  
-        
-       
-
-        switch (type) {
-            case SWITCH:
-                sav = objIDMap.get(sav);
-                HolonSwitch sw = (HolonSwitch) objDispatch.get(sav);
-                sw.setGraphPoints(graphpointTEST);
-                sw.sampleGraph();
-                break;
-            case ELEMENT:                
-                break;
-            case TESTELEMENT:
-                sav = eleIDMap.get(sav);
-                HolonElement ele1 = eleDispatch.get(sav);
-                ele1.setGraphPoints(graphpointTEST);
-                ele1.sampleGraph();
-                break;
-            default:
-                break;
-        }
-
-    }
-
-    /**
-     * loads an edge from json
-     */
-    private void loadEdge(EDGETYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                          GroupNode upperNode) {
-        JsonObject object = jsonElement.getAsJsonObject();
-        Edge temp = GuiSettings.gson.fromJson(object.get("properties"), Edge.class);
-        load.initCpsEdge(temp);
-        // look for A and B inside the Table
-        temp.setA(objDispatch.get(objIDMap.get(object.get("A").getAsInt())));
-        temp.setB(objDispatch.get(objIDMap.get(object.get("B").getAsInt())));
-
-        switch (type) {
-            case LAYER:
-                // if in canvas add it into the canvas but delete connection before
-                model.getEdgesOnCanvas().add(temp);
-                break;
-            case CONNECTION:
-                break;
-            default:
-                break;
-        }
-
-    }
-
-    /**
-     * Modified Method from LoadController. Slightly different
-     */
-    private void edgeToJson(EDGETYPE type, JsonObject file, int id, Set<Edge> arr) {
-        String k = null;
-        boolean b = false;
-        JsonObject temp = new JsonObject();
-
-        for (Edge edge : arr) {
-            if (GuiSettings.getClipboardObjects().contains(edge.getA())
-                    && GuiSettings.getClipboardObjects().contains(edge.getB())) {
-                // add properties and only the ids from a and b
-                temp.add("properties", GuiSettings.gson.toJsonTree(edge));
-                temp.add("A", new JsonPrimitive(edge.getA().getId()));
-                temp.add("B", new JsonPrimitive(edge.getB().getId()));
-
-                // Key and occasionally the id of Uppernode
-                switch (type) {
-                    case LAYER:
-                        temp.add("ID", new JsonPrimitive(id));
-                        k = "LAYEREDGE" + store.getNumerator(NUMTYPE.EDGE);
-                        break;
-                    case CONNECTION:
-                        k = "CONNEDGE" + store.getNumerator(NUMTYPE.CONNECTION);
-                        break;
-                    case NODE:
-                        temp.add("ID", new JsonPrimitive(id));
-                        k = "NODEEDGE" + store.getNumerator(NUMTYPE.NODEEDGE);
-                        break;
-                    case OLD:
-                        temp.add("ID", new JsonPrimitive(id));
-                        k = "OLDEDGE" + store.getNumerator(NUMTYPE.OLDEDGE);
-                        break;
-                    default:
-                        break;
-                }
-                temp.add("connection", new JsonPrimitive(b));
-                file.add(k, GuiSettings.gson.toJsonTree(temp));
-                temp = new JsonObject();
-            }
-        }
-    }
-
-    /**
-     * Adds all Objects in Depth into Clipboardobjects preemptive when objects are selected
-     */
-    void getObjectsInDepth() {
-        GuiSettings.getClipboardObjects().clear();
-        for (AbstractCanvasObject obj : GuiSettings.getSelectedObjects()) {
-        	GuiSettings.getClipboardObjects().add(obj);
-        	if (obj instanceof GroupNode groupnode) {
-        		groupnode.getAllObjectsRecursive().forEach(object -> GuiSettings.getClipboardObjects().add(object));
-            }
-        }
-    }
-
-    /**
-     * Map the Copied Object ID into a new One
-     */
-    private void objIDMapper(AbstractCanvasObject temp) {
-        int id = temp.getId();
-        // oldID -> currentID
-        objIDMap.put(id, temp.getId());
-    }
-
-    /**
-     * Map the Copied Element ID into a new One
-     */
-    private void eleIDMapper(HolonElement temp) {
-        int id = temp.getId();
-        // oldID -> currentID
-        eleIDMap.put(id, temp.getId());
-
-    }
-
-    private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) {
-        int x = temp.getPosition().getX() - point.x;
-        int y = temp.getPosition().getY() - point.y;
-
-        if (y < 0)
-            y = 0 + GuiSettings.getPictureScaleDiv2() + 1;
-        if (upperNode != null) {
-            if (x < GuiSettings.getPictureScaleDiv2() + 1)
-                x = GuiSettings.getPictureScaleDiv2() + 1;
-        } else if (x < 0)
-            x = 0 + GuiSettings.getPictureScaleDiv2() + 1;
-        if (x > GuiSettings.canvasSize.getX())
-            x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1;
-        if (y > GuiSettings.canvasSize.getY())
-            y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1;
-
-        temp.setPosition(new Vec2i(x, y));
-    }
-
-}

+ 205 - 317
src/holeg/ui/controller/Control.java

@@ -1,120 +1,43 @@
 package holeg.ui.controller;
 
-import com.google.gson.JsonParseException;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import holeg.adapter.EdgeSerializer;
+import holeg.adapter.ModelDeserializer;
 import holeg.model.*;
+import holeg.preferences.ImagePreference;
 import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
 import holeg.ui.view.dialog.CreateTemplatePopUp;
 import holeg.ui.view.main.Category;
 import holeg.utility.events.Action;
 import holeg.utility.events.Event;
-import org.apache.commons.compress.archivers.ArchiveException;
+import holeg.utility.math.vector.Vec2i;
 
 import javax.swing.*;
-import java.awt.*;
-import java.awt.datatransfer.UnsupportedFlavorException;
 import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
-import java.util.List;
 import java.util.*;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 
 /**
- * The Class represents the controller in the model, controller view Pattern.
- *
- * @author Gruppe14
+ * The Class represents the controller.
  */
 public class Control {
     private static final Logger log = Logger.getLogger(Control.class.getName());
-
-
-    private final CategoryController categoryController;
     private final CanvasController canvasController;
-    private final SaveController saveController;
-    private final LoadController loadController;
-    private final AutoSaveController autoSaveController;
-    private final NodeController nodeController;
-    private final ClipboardController clipboardController;
+    private Model model;
+    private final SimulationManager simulationManager;
     public Event OnCategoryChanged = new Event();
     public Event OnSelectionChanged = new Event();
     public Event OnCanvasUpdate = new Event();
     public Action<Boolean> OnGuiSetEnabled = new Action<>();
-    private Model model;
-    private SimulationManager simulationManager;
-    private String autosaveDir = "";
-    private String categoryDir = "";
-    private String otherDir = "";
-    private String dimensionsFileName = "dimensions";
-    private int rand;
 
-    /**
-     * Constructor.
-     *
-     * @param model the Model
-     */
     public Control(Model model) {
         this.model = model;
-        this.categoryController = new CategoryController(this);
-        this.canvasController = new CanvasController(model);
-        this.saveController = new SaveController(model);
-        this.nodeController = new NodeController(model, canvasController);
-        this.loadController = new LoadController(model, categoryController, canvasController,
-                nodeController);
-        this.simulationManager = new SimulationManager(model);
-        this.autoSaveController = new AutoSaveController();
-        this.clipboardController = new ClipboardController(model, saveController, loadController, canvasController,
-                nodeController, this.simulationManager);
-
-        autosaveDir = System.getProperty("user.home") + "/.config/HolonGUI/Autosave/";
-        categoryDir = System.getProperty("user.home") + "/.config/HolonGUI/Category/";
-        otherDir = System.getProperty("user.home") + "/.config/HolonGUI/Other/";
-        File autoSave = new File(autosaveDir);
-        File category = new File(categoryDir);
-        File other = new File(otherDir);
-        // deleteDirectory(dest);
-        autoSave.mkdirs();
-        category.mkdirs();
-        other.mkdirs();
-        createAutoRandom();
-
-        tryAutoSave();
-    }
-
-    /**
-     * Generate random number, so that every instance of the program has unique save
-     * files
-     */
-    private void createAutoRandom() {
-        rand = (int) (Math.random() * 1000);
-        while (new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-            rand = (int) Math.random() * 1000;
-        }
-    }
-
-    /**
-     * Delete a Directory.
-     *
-     * @param path to delete
-     */
-    public void deleteDirectory(File path) {
-        if (path.exists()) {
-            File[] files = path.listFiles();
-            for (File file : files) {
-                if (file.isDirectory()) {
-                    deleteDirectory(file);
-                } else {
-                    if (file.getName().contains("" + rand))
-                        file.delete();
-                }
-            }
-            // path.delete();
-        }
-    }
-
-
-    public Optional<Category> findCategoryWithName(String name) {
-        return GuiSettings.getCategories().stream().filter(cat -> cat.getName().equals(name)).findAny();
+        this.canvasController = new CanvasController(this);
+        this.simulationManager = new SimulationManager(this);
     }
 
 
@@ -124,20 +47,8 @@ public class Control {
      * init default category and objects.
      */
     public void resetCategories() {
-        categoryController.clearCategories();
-        categoryController.initCategories();
-        saveCategory();
-
-    }
-
-    /**
-     * Adds New Category into Model.
-     *
-     * @param cat name of the new Category
-     * @throws IOException
-     */
-    public void createCategoryWithName(String cat) {
-        categoryController.createCategoryWithName(cat);
+        clearCategories();
+        initCategories();
         saveCategory();
     }
 
@@ -147,21 +58,14 @@ public class Control {
      * @return a array of strings from all Categorys
      */
     public String[] getCategoriesStrings() {
-        return GuiSettings.getCategories().stream().map(c -> c.getName()).collect(Collectors.toList())
-                .toArray(new String[GuiSettings.getCategories().size()]);
+        return GuiSettings.getCategories().stream().map(Category::getName).toArray(String[]::new);
     }
 
     /**
      * Add new Holon Object to a Category.
-     *
-     * @param cat  Category
-     * @param obj  New Object Name
-     * @param list Array of Elements
-     * @param img  the image Path
-     * @throws IOException
      */
     public void addObject(Category cat, String obj, List<HolonElement> list, String img) {
-        categoryController.addNewHolonObject(cat, obj, list, img);
+        addNewHolonObject(cat, obj, list, img);
         saveCategory();
     }
 
@@ -170,15 +74,14 @@ public class Control {
      *
      * @param cat Category
      * @param obj New Object Name
-     * @throws IOException
      */
     public void addSwitch(Category cat, String obj) {
-        categoryController.addNewHolonSwitch(cat, obj);
+        addNewHolonSwitch(cat, obj);
         saveCategory();
     }
 
     public void deleteCategory(Category category) {
-        categoryController.removeCategory(category);
+        removeCategory(category);
         saveCategory();
     }
 
@@ -202,11 +105,6 @@ public class Control {
         }
     }
 
-    /**
-     * add an Object to selectedObject.
-     *
-     * @param obj AbstractCpsobject
-     */
     public void addSelectedObject(AbstractCanvasObject obj) {
         if (GuiSettings.getSelectedObjects().add(obj)) {
             OnSelectionChanged.broadcast();
@@ -249,35 +147,27 @@ public class Control {
      *
      * @param object the Object
      */
-    public void addObjectCanvas(AbstractCanvasObject object) {
-        canvasController.addNewObject(object);
+    public void addObjectCanvas(GroupNode node, AbstractCanvasObject object) {
+        canvasController.addObject(node, object);
         calculateStateAndVisualForTimeStep(model.getCurrentIteration());
-        if (!(object instanceof Node)) {
-            tryAutoSave();
-        }
     }
 
     /**
      * Deletes an CpsObject on the Canvas and its connections.
      *
      * @param obj  AbstractCpsObject
-     * @param save
      */
-    public void delCanvasObject(AbstractCanvasObject obj, boolean save) {
-        canvasController.deleteObjectOnCanvas(obj);
+    public void deleteCanvasObject(AbstractCanvasObject obj) {
+        canvasController.deleteObject(obj);
         if (obj instanceof GroupNode groupnode) {
             canvasController.deleteAllObjectsInGroupNode(groupnode);
         }
         calculateStateAndVisualForCurrentTimeStep();
-        if (save) {
-            tryAutoSave();
-        }
     }
 
-    public void delCanvasObjects(Collection<AbstractCanvasObject> objects) {
-        canvasController.deleteObjectsOnCanvas(objects);
+    public void deleteCanvasObjects(Collection<AbstractCanvasObject> objects) {
+        canvasController.deleteObjects(objects);
         calculateStateAndVisualForCurrentTimeStep();
-        tryAutoSave();
     }
 
     /**
@@ -287,8 +177,7 @@ public class Control {
      * @param by           the object that will replace it
      */
     public void replaceCanvasObject(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
-        canvasController.replaceObjectOnCanvas(toBeReplaced, by);
-        tryAutoSave();
+        canvasController.replaceObject(toBeReplaced, by);
     }
 
     /**
@@ -299,12 +188,11 @@ public class Control {
     public boolean addEdgeOnCanvas(Edge edge) {
         boolean connectsItSelf = edge.getA() == edge.getB();
         boolean connectionExist = model.getEdgesOnCanvas().stream().anyMatch(e -> (e.getA() == edge.getA() && e.getB() == edge.getB())
-				|| (e.getB() == edge.getA() && e.getA() == edge.getB()));
+                || (e.getB() == edge.getA() && e.getA() == edge.getB()));
         if (connectsItSelf || connectionExist) {
             return false;
         }
         canvasController.addEdgeOnCanvas(edge);
-        tryAutoSave();
         return true;
     }
 
@@ -315,52 +203,9 @@ public class Control {
      */
     public void removeEdgesOnCanvas(Edge edge) {
         canvasController.removeEdgesOnCanvas(edge);
-        tryAutoSave();
     }
 
 
-    /**
-     * Writes the current State of the Modelling into a JSON File which can be
-     * loaded.
-     *
-     * @param path the Path
-     * @throws IOException exception
-     */
-    public void saveFile(String path) throws IOException, ArchiveException {
-        saveController.writeSave(path);
-    }
-
-    /**
-     * Reads the the Save File and load the state into the Model.
-     *
-     * @param path the Path
-     * @throws IOException      exception
-     * @throws ArchiveException
-     */
-    public void loadFile(String path) throws IOException, ArchiveException {
-        loadController.readSave(path);
-        saveCategory();
-        autoSave();
-    }
-
-    /**
-     * Reads the Json File from Autosave
-     *
-     * @param path
-     * @throws IOException
-     */
-    public void loadAutoSave(String path) throws IOException {
-        loadController.readJson(path);
-    }
-
-    public ArrayList<Integer> loadSavedWindowDimensionsIfExistent() {
-        try {
-            return loadController.readWindowDimensions(otherDir + dimensionsFileName);
-        } catch (Exception e) {
-            return new ArrayList<>();
-        }
-    }
-
     /**
      * calculates the flow of the edges and the supply for objects for the current
      * Timestep.
@@ -370,7 +215,7 @@ public class Control {
     }
 
     public void calculateStateOnlyForCurrentTimeStep() {
-        simulationManager.calculateStateForTimeStep(model.getCurrentIteration());
+        calculateStateForTimeStep(model.getCurrentIteration());
     }
 
     /**
@@ -380,9 +225,19 @@ public class Control {
      */
     public void calculateStateAndVisualForTimeStep(int x) {
         simulationManager.calculateStateForTimeStep(x);
+        log.info("OnCanvasUpdate");
         OnCanvasUpdate.broadcast();
     }
 
+    /**
+     * calculates the flow of the edges and the supply for objects.
+     *
+     * @param x current Iteration
+     */
+    public void calculateStateForTimeStep(int x) {
+        simulationManager.calculateStateForTimeStep(x);
+    }
+
     /**
      * resets the whole State of the simulation including a reset of all Edges to
      * the default "is working" state
@@ -391,197 +246,230 @@ public class Control {
         model.reset();
     }
 
-    /**
-     * make an autosave.
-     *
-     * @throws IOException Exception
-     */
-    private void autoSave() throws IOException {
-        autoSaveController.increaseAutoSaveNr();
-        saveController.writeAutosave(autosaveDir + rand + GuiSettings.autoSaveNr);
-        if (autoSaveController.allowed()) {
-            new File(autosaveDir + rand + (GuiSettings.autoSaveNr - GuiSettings.numberOfSaves)).delete();
-        }
-    }
 
-    public void tryAutoSave() {
-        try {
-            autoSave();
-        } catch (IOException e) {
-            log.warning(e.getStackTrace().toString());
-        }
+    public void saveCategory() {
+        //TODO(Tom2022-01-27):
     }
 
+
     /**
-     * find all old auto save files (with a file-name, that does not contain the
-     * current rand)
+     * Getter for Model.
      *
-     * @return a list of files, that are not from the current run
+     * @return the Model
      */
-    public ArrayList<File> filterOldAutoSaveFiles() {
-        File[] files = new File(autosaveDir).listFiles();
-        ArrayList<File> oldAutoSaves = new ArrayList<>();
+    public Model getModel() {
+        return model;
+    }
+
 
-        for (File file : files) {
-            if (!file.getName().contains(String.valueOf(rand)))
-                oldAutoSaves.add(file);
-        }
 
-        return oldAutoSaves;
+    public void replaceObject(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
+        canvasController.replaceObject(toBeReplaced, by);
     }
 
     /**
-     * deletes the old autosave files
+     * Copy all Selected Objects.
      */
-    public void deleteObsoleteAutoSaveFiles() {
-        for (File file : filterOldAutoSaveFiles()) {
-            file.delete();
-        }
+    public void copy(GroupNode upperNode) {
+        //TODO(Tom2022-01-27):
     }
 
-    public void saveCategory() {
-        try {
-            saveController.writeCategory(categoryDir + "Category.json");
-        } catch (IOException e) {
-        }
+    public void paste(GroupNode upperNode, Vec2i point) {
+        //TODO(Tom2022-01-27):
+        OnSelectionChanged.broadcast();
     }
 
-    public void savePosAndSizeOfWindow(int x, int y, int width, int height) throws IOException, ArchiveException {
-        saveController.writeWindowStatus(otherDir + dimensionsFileName, x, y, width, height);
+    public void cut(GroupNode upperNode) {
+        //TODO(Tom2022-01-27):
+        OnSelectionChanged.broadcast();
     }
 
     /**
-     * Returns the undo save.
+     * creates a new Template for the given cps Object
      *
-     * @return the undo save
+     * @param cps         Object, which should become a template
+     * @param parentFrame
      */
-    public String getUndoSave() {
-        autoSaveController.decreaseAutoSaveNr();
-        if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-            autoSaveController.increaseAutoSaveNr();
-        }
-        return autosaveDir + rand + (GuiSettings.autoSaveNr);
+    public void createTemplate(HolonObject cps, JFrame parentFrame) {
+        CreateTemplatePopUp t = new CreateTemplatePopUp(cps, model, parentFrame, this);
+        t.setVisible(true);
     }
 
+
+    public void guiSetEnabled(boolean state) {
+        log.info("guiDisabled");
+        OnGuiSetEnabled.broadcast(state);
+    }
+
+
+
+
     /**
-     * Returns the redo save.
-     *
-     * @return the redo save
+     * init default category and objects.
      */
-    public String getRedoSave() {
-        autoSaveController.increaseAutoSaveNr();
-        if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-            autoSaveController.decreaseAutoSaveNr();
-
-            // if it still does not exist, try old autosaves
-            if (!new File(autosaveDir + rand + (GuiSettings.autoSaveNr)).exists()) {
-                ArrayList<File> oldAutoSaves = filterOldAutoSaveFiles();
-                if (oldAutoSaves.size() > 0) {
-                    return autosaveDir + oldAutoSaves.get(oldAutoSaves.size() - 1).getName();
-                }
-            }
+    public void initCategories() {
+        Category energy = createCategoryWithName("Energy");
+        Category building = createCategoryWithName("Building");
+        Category component = createCategoryWithName("Component");
+        HolonObject powerPlant = addNewHolonObject(energy, "Power Plant", new ArrayList<>(),
+                ImagePreference.Canvas.DefaultObject.PowerPlant);
+        HolonObject house = addNewHolonObject(building, "House", new ArrayList<>(), ImagePreference.Canvas.DefaultObject.House);
+        addNewHolonSwitch(component, "Switch");
+        powerPlant.add(new HolonElement(null, "Power", 10000));
+        energy.getObjects().add(powerPlant);
+
+        house.add(new HolonElement(null, "TV", -250));
+        house.add(new HolonElement(null, "TV", -250));
+        house.add(new HolonElement(null, "Fridge", -500));
+        house.add(new HolonElement(null, "Radio", -100));
+        house.add(new HolonElement(null, "PC", -250));
+        house.add(new HolonElement(null, "PC", -250));
+        house.add(new HolonElement(null, "PC", -250));
+        house.add(new HolonElement(null, "Light", -50));
+        house.add(new HolonElement(null, "Light", -50));
+        house.add(new HolonElement(null, "Light", -50));
+        house.add(new HolonElement(null, "Light", -50));
+        house.add(new HolonElement(null, "Light", -50));
+        house.add(new HolonElement(null, "Solar Panel", 300));
+        building.getObjects().add(house);
+        OnCategoryChanged.broadcast();
+    }
+
+
+    public Category createCategoryWithName(String categoryName) {
+        Optional<Category> category = findCategoryWithName(categoryName);
+        if(category.isEmpty()) {
+            Category cat = new Category(categoryName);
+            GuiSettings.getCategories().add(cat);
+            OnCategoryChanged.broadcast();
+            return cat;
+        }else {
+            return category.get();
         }
-        return autosaveDir + rand + (GuiSettings.autoSaveNr);
+
     }
 
+
     /**
-     * Getter for Model.
+     * remove a Category from Model.
      *
-     * @return the Model
+     * @param c
+     *            Category
      */
-    public Model getModel() {
-        return model;
+    public void removeCategory(Category c) {
+        GuiSettings.getCategories().remove(c);
+        OnCategoryChanged.broadcast();
+    }
+
+    public void clearCategories() {
+        GuiSettings.getCategories().clear();
     }
 
     /**
-     * get the Simulation Manager.
+     * Add Object into a Category.
      *
-     * @return the Simulation Manager
-     */
-    public SimulationManager getSimManager() {
-        return simulationManager;
+     * @param category
+     *            Category
+     * @param object
+     *            Object
+     */
+    public void addObject(Category category, AbstractCanvasObject object) {
+        int i = 0;
+        //TODO(Tom2021-12-1) remove/redo this search
+        while (category.findObjectWithName(object.getName()).isPresent()) {
+            if (object.getName().contains("_"))
+                object.setName(object.getName().substring(0, object.getName().indexOf('_')));
+            object.setName(object.getName() + "_" + i);
+            i++;
+        }
+        category.getObjects().add(object);
     }
 
-    // ========================== MANAGING TRACKED OBJECTS END ================
-
     /**
-     * Controlling GroupNodes
+     * Add new Holon Object to a Category.
+     *
+     * @param category
+     *            Category
+     * @param object
+     *            New Object Name
+     * @param list
+     *            Array of Elements
+     * @param image
+     *            the image Path
      */
-
-    public void addGroupNode(String nodeName, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
-        nodeController.addGroupNode(nodeName, groupNode, toGroup);
-        tryAutoSave();
+    public HolonObject addNewHolonObject(Category category, String object, List<HolonElement> list, String image) {
+        HolonObject obj = new HolonObject(object);
+        obj.setImagePath(image);
+        obj.clearElements();
+        obj.add(list);
+        addObject(category, obj);
+        return obj;
     }
 
-    public void undoGroupNode(GroupNode node, GroupNode groupNode) {
-        nodeController.undoGroupNode(node, groupNode);
-        tryAutoSave();
-    }
 
-    public void addObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
-        nodeController.addObjectInGroupNode(object, groupNode, true);
-        tryAutoSave();
+    public HolonSwitch addNewHolonSwitch(Category cat, String objName) {
+        HolonSwitch holonSwitch = new HolonSwitch(objName);
+        addObject(cat, holonSwitch);
+        return holonSwitch;
     }
 
-    public void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
-        nodeController.deleteObjectInGroupNode(object, groupNode);
-        if (object instanceof GroupNode groupnode) {
-            canvasController.deleteAllObjectsInGroupNode(groupnode);
-        }
-        tryAutoSave();
-    }
 
-    /**
-     * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
-     *
-     * @param toBeReplaced
-     * @param by
-     * @param upperNode
-     */
-    public void replaceObjectInGroupNode(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by, GroupNode upperNode) {
-        nodeController.replaceObjectInUpperNode(toBeReplaced, by, upperNode);
-        tryAutoSave();
-    }
 
     /**
-     * Copy all Selected Objects.
+     * Removes an Object from a Category.
+     * @param category Category
+     * @param cps the Object
      */
-    public void copy(GroupNode upperNode) {
-        clipboardController.copy(upperNode);
+    public void removeObject(Category category, AbstractCanvasObject cps) {
+        category.getObjects().remove(cps);
+        OnCategoryChanged.broadcast();
     }
 
-    public void paste(GroupNode upperNode, Point point)
-            throws JsonParseException, UnsupportedFlavorException, IOException {
-        clipboardController.paste(upperNode, point);
-        OnSelectionChanged.broadcast();
-        tryAutoSave();
-    }
 
-    public void cut(GroupNode upperNode) {
-        clipboardController.cut(upperNode);
-        OnSelectionChanged.broadcast();
-        tryAutoSave();
-    }
 
-    /**
-     * creates a new Template for the given cps Object
-     *
-     * @param cps         Object, which should become a template
-     * @param parentFrame
-     */
-    public void createTemplate(HolonObject cps, JFrame parentFrame) {
-        CreateTemplatePopUp t = new CreateTemplatePopUp(cps, model, parentFrame, this);
-        t.setVisible(true);
+    public Optional<Category> findCategoryWithName(String categoryName) {
+        return GuiSettings.getCategories().stream().filter(cat -> cat.getName().equals(categoryName)).findAny();
     }
 
-    public void getObjectsInDepth() {
-        clipboardController.getObjectsInDepth();
+    public void loadFile(File file) {
+        log.info("load" + file);
+        try {
+            FileReader reader = new FileReader(file);
+            Gson gson = initGson();
+            Model model = gson.fromJson(reader, Model.class);
+            reader.close();
+            //this.model = model;
+            calculateStateAndVisualForCurrentTimeStep();
+        } catch (IOException e) {
+            log.warning(e.getLocalizedMessage());
+        }
     }
 
 
-    public void guiSetEnabled(boolean state) {
-        log.info("guiDisabled");
-        OnGuiSetEnabled.broadcast(state);
+    public void saveFile(File file) {
+        log.info("save" + file);
+        try {
+            FileWriter  writer = new FileWriter(file);
+            Gson gson = initGson();
+            gson.toJson(model, writer);
+            writer.close();
+        } catch (IOException e) {
+            log.warning(e.getLocalizedMessage());
+        }
+    }
+
+    public Gson initGson() {
+        GsonBuilder builder = new GsonBuilder();
+        //new GraphAdapterBuilder().addType(AbstractCanvasObject.class).registerOn(builder);
+        //RuntimeTypeAdapterFactory.of(AbstractCanvasObject.class).registerSubtype(Group)
+        builder.registerTypeAdapter(Edge.class, new EdgeSerializer());
+        builder.registerTypeAdapter(Model.class, new ModelDeserializer(this));
+        builder.serializeNulls();
+        //builder.excludeFieldsWithoutExposeAnnotation();
+        builder.setPrettyPrinting();
+        //builder.registerTypeAdapter(AbstractCanvasObject.class, new AbstractCpsObjectAdapter());
+        return builder.create();
     }
 
+
 }

+ 4 - 12
src/holeg/ui/controller/IndexTranslator.java

@@ -1,28 +1,20 @@
 package holeg.ui.controller;
 
 import holeg.interfaces.LocalMode;
-import holeg.ui.model.Model;
 
 
 public class IndexTranslator {
-	public static int STANDARD_GRAPH_ACCURACY = 100;
-	public static Model model;
 	   /**
      * Determines the index of the internal value array
      * of an element that should be used, since elements only save 100 values,
      * but iterations and local period can be anything between 1 and 100000.
-     * 
-     * @param m the corresponding model.
+     *
      * @param e the element for which the calculation should be made.
      * @param timeStep the iteration for which the calculation should be made.
-     * @return
+     * @return effective Index
      */
     public static int getEffectiveIndex(LocalMode e, int timeStep){
-    	if(e.isUsingLocalPeriod()) {
-    		return timeStep % e.getLocalPeriod()* 100 /e.getLocalPeriod();
-    	}
-    	else {
-    		return timeStep * 100 / (model == null?STANDARD_GRAPH_ACCURACY:model.getMaxIterations());
-    	}
+		int period = e.getPeriod().getInterval();
+		return timeStep % period * 100 / period;
     }
 }

+ 0 - 487
src/holeg/ui/controller/LoadController.java

@@ -1,487 +0,0 @@
-package holeg.ui.controller;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.reflect.TypeToken;
-
-import holeg.model.*;
-import holeg.model.HolonElement.Priority;
-import holeg.ui.model.GuiSettings;
-import holeg.ui.model.IdCounter;
-import holeg.ui.model.Model;
-import holeg.ui.model.IdCounter.CounterType;
-import holeg.utility.math.vector.Vec2f;
-
-import org.apache.commons.compress.archivers.ArchiveEntry;
-import org.apache.commons.compress.archivers.ArchiveException;
-import org.apache.commons.compress.archivers.ArchiveInputStream;
-import org.apache.commons.compress.archivers.ArchiveStreamFactory;
-import org.apache.commons.compress.utils.IOUtils;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-/**
- * Controller for the Loading.
- *
- * @author Gruppe14
- */
-public class LoadController {
-	private static final Logger log = Logger.getLogger(Model.class.getName());
-    private Model model;
-    private CategoryController cgC;
-    private CanvasController cvsC;
-    private NodeController uppC;
-    private static HashMap<String,String> OldTypeNameReplacement = new HashMap<String, String>();
-    
-    static {
-    	OldTypeNameReplacement.put("CpsNode", "Node");
-    	OldTypeNameReplacement.put("CpsUpperNode", "GroupNode");
-    	
-    }
-    /**
-     * Constructor.
-     *
-     * @param model Model
-     * @param cg    CategoryController
-     * @param cvs   CanvasController
-     */
-    LoadController(Model model, CategoryController cg, CanvasController cvs,
-                   NodeController uppC) {
-    	
-        this.model = model;
-        this.cgC = cg;
-        this.cvsC = cvs;
-        this.uppC = uppC;
-    }
-
-    /**
-     * Reads the the JSON File and load the state into the Model.
-     *
-     * @param path the Path
-     * @throws IOException exception
-     */
-    void readSave(String path) throws IOException, ArchiveException {
-
-        File src = new File(path);
-        File folder = readArchive(src);
-        folder.deleteOnExit();
-        String trim = folder.getPath().substring(0,
-                folder.getPath().lastIndexOf(folder.getName()) + folder.getName().length());
-
-        forwardFiles(folder, trim);
-
-    }
-
-    /**
-     * reads the dimensions file containing the saved position and dimensions of the frame
-     *
-     * @return a list of the form [x, y, width, height]
-     */
-    ArrayList<Integer> readWindowDimensions(String path) throws FileNotFoundException {
-        JsonObject json = (JsonObject) JsonParser.parseReader(new FileReader(path));
-        ArrayList<Integer> dimensions = new ArrayList<>();
-
-        List<String> keys = getKeys(json);
-        for (int i = 1; i < 5; i++) {
-            dimensions.add(json.get(keys.get(i)).getAsInt());
-        }
-
-        return dimensions;
-    }
-
-    void readJson(String path) throws IOException {
-        JsonObject json = (JsonObject) JsonParser.parseReader(new FileReader(path));
-        // get all keys via stream
-        List<String> keys = getKeys(json);
-        List<String> edges = keys.stream().filter(key -> key.contains("EDGE"))
-                .collect(Collectors.toCollection(ArrayList::new));
-
-        HashMap<Integer, AbstractCanvasObject> objDispatch = new HashMap<>();
-        HashMap<Integer, HolonElement> eleDispatch = new HashMap<>();
-
-        initialize(json);
-        forwardObjects(keys, json, objDispatch, eleDispatch);
-        forwardEdges(edges, json, objDispatch);
-
-    }
-
-    /**
-     * Loads the Files from the Savefile
-     *
-     * @param trim the part of the file's path to be trimmed
-     * @throws IOException if anythings goes wrong reading the files
-     */
-    private void forwardFiles(File folder, String trim) throws IOException {
-        for (File file : folder.listFiles()) {
-            File dst = new File(
-                    System.getProperty("user.home") + "/.config/HolonGUI/" + file.getPath().replace(trim, ""));
-
-            if (file.getName().contains(".json"))
-                readJson(file.getPath());
-            else if (file.isDirectory())
-                forwardFiles(file, trim);
-            else {
-                dst.getParentFile().mkdirs();
-                Files.copy(file.toPath(), dst.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            }
-
-        }
-    }
-
-    /**
-     * distribute the Edges
-     */
-    private void forwardEdges(List<String> edges, JsonObject json, HashMap<Integer, AbstractCanvasObject> objDispatch) {
-        for (String edge : edges) {
-            if (edge.contains("CVSEDGE"))
-                loadEdge(EDGETYPE.CANVAS, json.get(edge), objDispatch);
-            if (edge.contains("CONNEDGE"))
-            	loadEdge(EDGETYPE.CONNECTION, json.get(edge), objDispatch);
-            if (edge.contains("NODE"))
-                loadEdge(EDGETYPE.NODE, json.get(edge), objDispatch);
-            if (edge.contains("OLD"))
-                loadEdge(EDGETYPE.OLD, json.get(edge), objDispatch);
-        }
-
-    }
-
-    /**
-     * Distribute the given keys for right processing
-     */
-    private void forwardObjects(List<String> keys, JsonObject json, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                                HashMap<Integer, HolonElement> eleDispatch) {
-        for (String key : keys) {
-            if (key.contains("CATEGORY"))
-                loadCategory(json.get(key));
-            else if (key.contains("CGOBJECT"))
-                loadCategoryObject(json.get(key).getAsJsonObject());
-            else if (key.contains("CGELEMENT"))
-                loadCategoryElements(json.get(key), eleDispatch);
-            else if (key.contains("CVSOBJECT"))
-                loadCanvasObject(json.get(key).getAsJsonObject(), objDispatch);
-            else if (key.contains("CVSELEMENT"))
-                loadCanvasElements(json.get(key), objDispatch, eleDispatch);
-            else if (key.contains("SWUNITGRAPH"))
-                loadUnitGraph(GRAPHTYPE.SWITCH, json.get(key), objDispatch, null);
-            else if (key.contains("ELEUNITGRAPH") && key.contains("ELETESTUNITGRAPH"))
-                loadUnitGraph(GRAPHTYPE.ELEMENT, json.get(key), null, eleDispatch);
-        }
-
-    }
-
-    /**
-     * Init the Global Parameters
-     */
-    private void initialize(JsonObject json) {
-
-        switch (MODE.valueOf(json.get("MODE").getAsString())) {
-            case COMPLETE:
-            case PARTIAL:
-                model.getEdgesOnCanvas().clear();
-                GuiSettings.canvasSize.setX(json.get("CANVAS_SIZE_X").getAsInt());
-                GuiSettings.canvasSize.setY(json.get("CANVAS_SIZE_Y").getAsInt());
-                IdCounter.setCounter(json.get("IDCOUNTER").getAsInt(), CounterType.Object);
-                IdCounter.setCounter(json.get("IDCOUNTERELEMENT").getAsInt(), CounterType.Element);
-                break;
-            case CATEGORY:
-
-            default:
-                break;
-        }
-
-    }
-
-    /**
-     * Load a given Category
-     */
-    private void loadCategory(JsonElement jsonElement) {
-        if (cgC.findCategoryWithName(jsonElement.getAsString()).isEmpty()) {
-        	cgC.createCategoryWithName(jsonElement.getAsString());
-        }
-
-        
-    }
-
-    /**
-     * Load a given Object in Category by Deserialization
-     */
-    private void loadCategoryObject(JsonObject jsonObject) {
-    	AbstractCanvasObject temp;
-    	replaceOldClassNames(jsonObject);
-    	try {
-    		temp = GuiSettings.gson.fromJson(jsonObject, AbstractCanvasObject.class);
-    	}catch (com.google.gson.JsonParseException e){
-    		log.warning(jsonObject.get("type").getAsString());
-    		return;
-    	}
-        
-        temp.initForReflection();
-        temp.setImage(checkOS(temp.getImage()));
-        //TODO(Tom2022-01-16): Cat name should be stored somewhere
-        cgC.findCategoryWithName(temp.getName()).ifPresent(cat -> {
-        	cat.findObjectWithName(temp.getName()).ifPresent(obj -> {
-        		cgC.removeObject(cat, obj);
-        	});
-        	cgC.addObject(cat, temp);
-        });
-    }
-
-    /**
-     * Load a given Element in Category by Deserialization
-     * @param eleDispatch 
-     */
-    private void loadCategoryElements(JsonElement jsonElement, HashMap<Integer, HolonElement> eleDispatch) {
-        JsonObject object = jsonElement.getAsJsonObject();
-        HolonElement ele = GuiSettings.gson.fromJson(object.get("properties"), HolonElement.class); 
-        eleDispatch.put(ele.getId(), ele);
-        initElements(ele);
-        ele.flexList = GuiSettings.gson.fromJson(object.get("FlexList"), new TypeToken<List<Flexibility>>() {}.getType());
-        if(ele.flexList == null) ele.flexList = new ArrayList<Flexibility>();
-        ele.flexList.stream().forEach(flex -> {
-        	flex.setElement(ele);
-        	flex.constrainList.forEach(con -> con.fixJson());
-        	
-        });
-        //Fix old amount
-        JsonElement amount = object.get("properties").getAsJsonObject().get("amount");
-        if(amount != null) {
-        	ele.setEnergy(amount.getAsInt() * ele.getEnergy());
-        }
-        
-    }
-
-    /**
-     * Load a given Object in Canvas by Deserialization
-     */
-    private void loadCanvasObject(JsonObject jsonObject, HashMap<Integer, AbstractCanvasObject> objDispatch) {
-    	AbstractCanvasObject temp = null;
-    	replaceOldClassNames(jsonObject);
-    	try {
-    		temp = GuiSettings.gson.fromJson(jsonObject, AbstractCanvasObject.class);
-    	}catch (com.google.gson.JsonParseException e){
-            log.warning(e + jsonObject.get("type").getAsString());
-    		return;
-    	}
-        temp.initForReflection();
-        temp.setImage(checkOS(temp.getImage()));
-        cvsC.addObject(temp, false);
-
-        objDispatch.put(temp.getId(), temp);
-
-    }
-
-    
-    
-	private void replaceOldClassNames(JsonObject abstractCanvasClassJsonObject) {
-		String type = abstractCanvasClassJsonObject.get("type").getAsString();
-		if(OldTypeNameReplacement.containsKey(type)) {
-			abstractCanvasClassJsonObject.addProperty("type", OldTypeNameReplacement.get(type));
-		}
-	}
-
-    /**
-     * Load a given Element in Canvas by Deserialization
-     */
-    private void loadCanvasElements(JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                                    HashMap<Integer, HolonElement> eleDispatch) {
-
-        JsonObject object = jsonElement.getAsJsonObject();
-        HolonElement ele = GuiSettings.gson.fromJson(object.get("properties"), HolonElement.class);
-        initElements(ele);
-        ele.flexList = GuiSettings.gson.fromJson(object.get("FlexList"), new TypeToken<List<Flexibility>>() {}.getType());
-        if(ele.flexList == null) ele.flexList = new ArrayList<>();
-        ele.flexList.stream().forEach(flex -> {
-        	flex.setElement(ele);
-        	flex.constrainList.forEach(con -> con.fixJson());
-        	
-        });
-        
-        //Fix old amount
-        JsonElement amount = object.get("properties").getAsJsonObject().get("amount");
-        if(amount != null) {
-        	ele.setEnergy(amount.getAsInt() * ele.getEnergy());
-        }
-        // id which Object it was stored before
-        int stored = object.get("ID").getAsInt();
-        // lookup that object
-        HolonObject hObject = (HolonObject) objDispatch.get(stored);
-        // add it
-        hObject.add(ele);
-        ele.parentObject = hObject;
-        // store element also inside a table
-        eleDispatch.put(ele.getId(), ele);
-    }
-
-    /**
-     * Load a given Edge by Deserialization
-     */
-    private void loadEdge(EDGETYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch) {
-        JsonObject object = jsonElement.getAsJsonObject();
-        Edge temp = GuiSettings.gson.fromJson(object.get("properties"), Edge.class);
-        initCpsEdge(temp);
-        // look for A and B inside the Table
-        temp.setA(objDispatch.get(object.get("A").getAsInt()));
-        temp.setB(objDispatch.get(object.get("B").getAsInt()));
-        model.getEdgesOnCanvas().add(temp);
-    }
-
-    /**
-     * Load a Unitgraph by Deserialization
-     */
-    private void loadUnitGraph(GRAPHTYPE type, JsonElement jsonElement, HashMap<Integer, AbstractCanvasObject> objDispatch,
-                               HashMap<Integer, HolonElement> eleDispatch) {
-        JsonObject object = jsonElement.getAsJsonObject();
-        List<String> keys = getKeys(object);
-        String p;
-        int mid;
-        int sav = 0;
-     	LinkedList<Vec2f> graphpointTEST = new LinkedList<>();
-        for (String k : keys) {
-            if (!k.equals("ID")) {
-                p = object.get(k).getAsString();
-                mid = p.indexOf(':');
-                float x1 = Float.parseFloat(p.substring(0, mid));
-                float y1 = Float.parseFloat(p.substring(mid + 1, p.length()));
-                graphpointTEST.add(new Vec2f(x1, y1));
-            } else
-                // else its an ID
-                sav = object.get(k).getAsInt();
-
-        }  
-        
-       
-        switch (type) {
-            case SWITCH:
-                HolonSwitch sw = (HolonSwitch) objDispatch.get(sav);
-                sw.setGraphPoints(graphpointTEST);
-                sw.sampleGraph();
-                break;
-            case ELEMENT:
-                HolonElement ele1 = eleDispatch.get(sav);
-                ele1.setGraphPoints(graphpointTEST);
-                ele1.sampleGraph();
-                break;
-            default:
-                break;
-        }
-    }
-
-    private File readArchive(File src) throws IOException, ArchiveException {
-        File tmp = Files.createTempDirectory("tmpHolon").toFile();
-        tmp.deleteOnExit();
-        InputStream input = new FileInputStream(src);
-        ArchiveInputStream stream = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.ZIP,
-                input);
-
-        ArchiveEntry entry = stream.getNextEntry();
-        while (entry != null) {
-            // String entryName = checkOS(entry.getName());
-            File file = new File(tmp, entry.getName());
-            file.getParentFile().mkdirs();
-            OutputStream output = new FileOutputStream(file);
-            IOUtils.copy(stream, output);
-            output.close();
-            // file.createNewFile();
-            entry = stream.getNextEntry();
-        }
-
-        stream.close();
-        input.close();
-
-        return tmp;
-    }
-
-    private String checkOS(String entryName) {
-        String os = System.getProperty("os.name").toLowerCase();
-        String ret = entryName;
-//        String partition = System.getProperty("user.home");
-
-        if (!ret.contains("HolonGUI"))
-            return ret;
-
-        if (os.contains("windows")) {
-            ret = ret.replace("/", "\\");
-            ret = System.getProperty("user.home") + "\\.config"
-                    + ret.substring(ret.indexOf("\\HolonGUI\\"), ret.length());
-
-        }
-        if (os.contains("mac")) {
-            // dosmth
-            ret = ret.replace("\\", "/");
-            ret = System.getProperty("user.home") + "/.config" + ret.substring(ret.indexOf("/HolonGUI/"), ret.length());
-        }
-        if (os.contains("linux")) {
-            // dosmth
-            ret = ret.replace("\\", "/");
-            ret = System.getProperty("user.home") + "/.config" + ret.substring(ret.indexOf("/HolonGUI/"), ret.length());
-        }
-//        if (os.contains("solaris")) {
-//            // dosmth
-//        }
-        return ret;
-    }
-    
-    
-    
-    /**
-     * Init Elements (set available energy, set new graph points)
-     *
-     * @param ele the element to be initialized
-     */
-    void initElements(HolonElement ele) {
-        ele.flexList = new ArrayList<Flexibility>();
-        ele.setGraphPoints(new LinkedList<>());
-        if(ele.getPriority() == null) ele.setPriority(Priority.Low);
-        ele.reset();
-        if(ele.getPriority() == null) {
-        	ele.setPriority(Priority.Low);
-        }
-    }
-
-    /**
-     * TODO(Tom2021-12-1) DELETE
-     * Init Edges (set tags and reset source and target)
-     *
-     * @param edge the edge to be initialized
-     */
-    void initCpsEdge(Edge edge) {
-        edge.setA(null);
-        edge.setB(null);
-        edge.setState(Edge.EdgeState.Working);
-    }
-
-    /**
-     * Get Set of Keys
-     *
-     * @return the keys from the json object
-     */
-    List<String> getKeys(JsonObject json) {
-        return json.entrySet().stream().map(i -> i.getKey()).collect(Collectors.toCollection(ArrayList::new));
-    }
-
-    /**
-     * enum Mode. (in SaveController there is an additional mode called SIZE,
-     * it is not currently needed here and was therefore not added)
-     */
-    public enum MODE {
-        COMPLETE, PARTIAL, CATEGORY
-    }
-
-    public enum EDGETYPE {
-        CANVAS, CONNECTION, NODE, OLD
-    }
-
-    public enum GRAPHTYPE {
-        SWITCH, ELEMENT
-    }
-
-}

+ 0 - 238
src/holeg/ui/controller/NodeController.java

@@ -1,238 +0,0 @@
-package holeg.ui.controller;
-
-import java.awt.*;
-import java.util.List;
-import java.util.Collection;
-import java.util.LinkedList;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Edge;
-import holeg.model.GroupNode;
-import holeg.model.Node;
-import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
-import holeg.utility.math.vector.Vec2i;
-
-
-class NodeController {
-
-	private Model model;
-	private CanvasController cvs;
-	private Point point;
-
-    NodeController(Model model, CanvasController cvs) {
-        this.model = model;
-		this.cvs = cvs;
-	}
-
-	/**
-	 * Add a CpsUpperNode into Canvas
-	 */
-    void addGroupNode(String nodeName, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
-		GroupNode node = new GroupNode(nodeName);
-		node.setPosition(calculatePos(toGroup));
-		makeGroupNode(node, groupNode, toGroup);
-		if (groupNode == null) {
-			cvs.addNewObject(node);
-		}
-		else {
-			addObjectInGroupNode(node, groupNode, false);			
-		}
-
-	}
-
-	/**
-	 * Delete a CpsUpperNode from the Canvas
-	 */
-    void undoGroupNode(GroupNode node, GroupNode groupNode) {
-    	if(node.getObjectsInThisLayer().findAny().isPresent()) {
-    		cvs.deleteObjectOnCanvas(node);
-    		return;
-    	}
-		Vec2i old = calculatePos(node.getObjectsInThisLayer().toList());
-		Vec2i p = node.getPosition();
-		point = new Point(old.getX() - p.getX(), old.getY() - p.getY());
-
-		unmakeNodesOfNodes(node, groupNode);
-		if (groupNode == null)
-			cvs.deleteObjectOnCanvas(node);
-		else
-			deleteObjectInGroupNode(node, groupNode);
-	}
-
-	/**
-	 * Put selected Nodes inside the Upper Node
-	 */
-	private void makeGroupNode(GroupNode node, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
-	
-
-		// Put all selected Nodes into the Upper Node
-        for (AbstractCanvasObject obj : toGroup) {
-			addObjectInGroupNode(obj, node, false);
-		}
-
-		for (AbstractCanvasObject abs : toGroup) {
-			if (groupNode == null)
-				removeForNodeOfNode(abs);
-			else
-				removeForNodeOfNode(abs, groupNode);
-		}
-
-	}
-
-	/**
-	 * Transfer all relevant data from Node into the next higher layer of Node
-	 * (upperNode)
-	 */
-	private void unmakeNodesOfNodes(GroupNode node, GroupNode upperNode) {
-		// add all nodes into upperNode
-
-		node.getObjectsInThisLayer().forEach(obj -> {
-			updatePosition(obj, upperNode);
-		});
-		if (upperNode == null) {
-			model.getCanvas().addAll(node.getObjectsInThisLayer());
-		} else {
-			node.getObjectsInThisLayer().forEach(obj -> upperNode.add(obj));
-		}
-		
-	}
-
-
-
-	/**
-	 * Calculate new Position of the Upper Node
-	 */
-    Vec2i calculatePos(Collection<AbstractCanvasObject> toGroup) {
-		Vec2i pos = new Vec2i(0, 0);
-		for (AbstractCanvasObject abs : toGroup) {
-			pos = pos.add(abs.getPosition());
-		}
-		return pos.divide(toGroup.size());
-	}
-
-	/**
-	 * Removes the Given Obj from current Layer and adjusts the idx
-	 */
-	private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) {
-		upperNode.remove(obj);
-	}
-
-	/**
-	 * Removes the Given Obj from current Layer and adjusts the idx
-	 */
-	private void removeForNodeOfNode(AbstractCanvasObject obj) {
-		model.getCanvas().remove(obj);
-	}
-
-
-	/**
-	 * Adds object to the upperNode, might replace objects if replace==true
-	 * @param object
-	 * @param upperNode
-	 * @param replace
-	 */
-    void addObjectInGroupNode(AbstractCanvasObject object, GroupNode upperNode, boolean replace) {
-        if(object == null){
-        		new Error("object == null while adding to "+upperNode.toString()).printStackTrace();
-        		return;
-        	}
-        if(upperNode == null){
-    		new Error("upperNode == null while adding "+object.toString()).printStackTrace();
-    		return;
-    	}
-		upperNode.add(object);
-		
-		/**
-		 * check if we should drag & drop replace
-		 */
-		if(replace && !(object instanceof Node) ){
-			/** x of the dragged Object */
-			int x = object.getPosition().getX();
-		
-			/** y of the dragged Object */
-			int y = object.getPosition().getY();
-			
-			/** distance threshold for replacement */
-			int treshhold = GuiSettings.getPictureScaleDiv2();
-		
-			/** number of Objects that might be replaced (should be 1) */
-			int replaceCounter = 0;
-		
-			/** last object that could be replaced */
-			AbstractCanvasObject toBeReplaced = null;
-			
-			/** for each cps on Canvas */
-			for (AbstractCanvasObject cps : upperNode.getObjectsInThisLayer().toList()){
-				
-				/** same object -> ignore */
-				if(cps == object)continue;
-			
-				/** x of object that might get replaced */
-				int c_x = cps.getPosition().getX();
-				
-				/** y of object that might get replaced */
-				int c_y = cps.getPosition().getY();
-				
-				/** if near enough */
-				if(Math.abs(x-c_x)<treshhold && Math.abs(y-c_y)<treshhold){
-					replaceCounter++;
-					toBeReplaced = cps;
-				}
-			}
-			/** if replacement of exactly one object possible */
-			if(replaceCounter == 1 && toBeReplaced != null){
-				replaceObjectInUpperNode(toBeReplaced, object, upperNode);
-			}
-		}
-	}
-
-	/**
-	 * Delete a AbstactCpsObject from CPSUpperNode
-	 */
-    void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
-		LinkedList<Edge> edgesToDelete = new LinkedList<Edge>();
-		for (Edge p : model.getEdgesOnCanvas()) {
-			if(p.isConnectedTo(object)) {
-				edgesToDelete.add(p);
-			}
-		}
-		model.getEdgesOnCanvas().removeAll(edgesToDelete);				
-		groupNode.remove(object);
-	}
-
-    /**
-     * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
-     * @param toBeReplaced
-     * @param by
-     * @param upperNode
-     */
-	public void replaceObjectInUpperNode(AbstractCanvasObject toBeReplaced,
-			AbstractCanvasObject by, GroupNode upperNode) {
-		/** let all edges of 'toBeReplaced' connect to 'by' */
-		/**
-		 * set Position of by to exactly toBeReplaced
-		 */
-		by.setPosition(toBeReplaced.getPosition());
-		deleteObjectInGroupNode(toBeReplaced, upperNode);
-	}
-
-    private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) {
-        int x = temp.getPosition().getX() - point.x;
-        int y = temp.getPosition().getY() - point.y;
-
-        if (y < 0)
-            y = 0 + GuiSettings.getPictureScaleDiv2() + 1;
-        if (upperNode != null) {
-            if (x < GuiSettings.getPictureScaleDiv2() + 1)
-                x = GuiSettings.getPictureScaleDiv2() + 1;
-        } else if (x < 0)
-            x = 0 + GuiSettings.getPictureScaleDiv2() + 1;
-        if (x > GuiSettings.canvasSize.getX())
-            x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1;
-        if (y > GuiSettings.canvasSize.getY())
-            y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1;
-
-        temp.setPosition(new Vec2i(x, y));
-    }
-}

+ 0 - 478
src/holeg/ui/controller/SaveController.java

@@ -1,478 +0,0 @@
-package holeg.ui.controller;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.reflect.TypeToken;
-
-import holeg.model.*;
-import holeg.ui.model.GuiSettings;
-import holeg.ui.model.IdCounter;
-import holeg.ui.model.Model;
-import holeg.ui.model.IdCounter.CounterType;
-import holeg.ui.view.main.Category;
-import holeg.utility.math.vector.Vec2f;
-
-import org.apache.commons.compress.archivers.ArchiveException;
-import org.apache.commons.compress.archivers.ArchiveOutputStream;
-import org.apache.commons.compress.archivers.ArchiveStreamFactory;
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.utils.IOUtils;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.*;
-
-/**
- * Controller for Storage.
- *
- * @author Gruppe14
- */
-public class SaveController {
-
-    private Model model;
-    private int nCat, nObj, nEle, nEdge, nConn, nNodeEdge, nOldEdge, nUnitGraph, nStatsGraph;
-
-    /**
-     * Constructor.
-     *
-     * @param model the Model
-     */
-    SaveController(Model model) {
-        this.model = model;
-    }
-
-    /**
-     * Writes the current State of the Modelling into a JSON File which can be
-     * loaded.
-     *
-     * @param path the Path
-     * @throws IOException exception
-     */
-    void writeSave(String path) throws IOException, ArchiveException {
-
-        File dst = new File(path);
-        File holonFile = File.createTempFile("tmp", ".json");
-        holonFile.deleteOnExit();
-        dst.delete();
-
-        OutputStream output = new FileOutputStream(dst);
-        ArchiveOutputStream stream = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP,
-                output);
-
-        initNumeration();
-        JsonObject file = new JsonObject();
-        initialize(MODE.COMPLETE, file);
-        storeCategory(file);
-        storeCanvas(file);
-        storeData(stream);
-
-        FileWriter writer = new FileWriter(holonFile);
-        writer.write(GuiSettings.gson.toJson(file));
-        writer.flush();
-        writer.close();
-
-        addFileToSave(holonFile, stream, false);
-
-        stream.finish();
-        output.close();
-    }
-
-    /**
-     * Writes the windows status (its position and dimensions)
-     *
-     * @param path the Path where to save it
-     */
-    void writeWindowStatus(String path, int x, int y, int width, int height)
-            throws IOException, ArchiveException {
-        JsonObject file = new JsonObject();
-        initialize(MODE.SIZE, file);
-        storeWindowPosAndSize(file, x, y, width, height);
-
-        FileWriter writer = new FileWriter(path);
-        writer.write(GuiSettings.gson.toJson(file));
-        writer.flush();
-        writer.close();
-    }
-
-    /**
-     * Writes the Autosave File.
-     *
-     * @param path the Path
-     * @throws IOException Exception
-     */
-    void writeAutosave(String path) throws IOException {
-
-        initNumeration();
-        JsonObject file = new JsonObject();
-        initialize(MODE.PARTIAL, file);
-        storeCanvas(file);
-
-        FileWriter writer = new FileWriter(path);
-        writer.write(GuiSettings.gson.toJson(file));
-
-        writer.flush();
-        writer.close();
-    }
-
-    /**
-     * Writes the Category File in Case of Changes
-     */
-    void writeCategory(String path) throws IOException {
-
-        initNumeration();
-        JsonObject file = new JsonObject();
-        initialize(MODE.CATEGORY, file);
-        storeCategory(file);
-
-        FileWriter writer = new FileWriter(path);
-        writer.write(GuiSettings.gson.toJson(file));
-
-        writer.flush();
-        writer.close();
-
-    }
-
-    /**
-     * Write needed default parameter into the JsonObject. Can be extended later
-     * on
-     */
-    private void initialize(MODE mode, JsonObject file) {
-        switch (mode) {
-            case COMPLETE:
-            case PARTIAL:
-                file.add("MODE", new JsonPrimitive(mode.name()));
-                file.add("IDCOUNTER", new JsonPrimitive(IdCounter.actualId(CounterType.Object)));
-                file.add("IDCOUNTERELEMENT", new JsonPrimitive(IdCounter.actualId(CounterType.Element)));
-                file.add("CANVAS_SIZE_X", new JsonPrimitive(GuiSettings.canvasSize.getX()));
-                file.add("CANVAS_SIZE_Y", new JsonPrimitive(GuiSettings.canvasSize.getY()));
-                break;
-            case CATEGORY:
-                file.add("MODE", new JsonPrimitive(mode.name()));
-                break;
-            case SIZE:
-                file.add("MODE", new JsonPrimitive(mode.name()));
-            default:
-                break;
-        }
-
-    }
-
-    /**
-     * Store all Categories and Object into a Json File via Serialization
-     */
-    private void storeCategory(JsonObject file) {
-        // forall categories store them into the jsontree
-        for (Category cat : GuiSettings.getCategories()) {
-            String key = "CATEGORY" + getNumerator(NUMTYPE.CATEGORY);
-
-            file.add(key, new JsonPrimitive(cat.getName()));
-            // forall object in the category store them into the jsontree
-            for (AbstractCanvasObject obj : cat.getObjects()) {
-                file.add("CGOBJECT" + getNumerator(NUMTYPE.OBJECT),
-                        GuiSettings.gson.toJsonTree(obj, AbstractCanvasObject.class));
-                // if its a holonobject add elements too
-                if (obj instanceof HolonObject)
-                    elementsToJson(TYPE.CATEGORY, file, obj);
-            }
-        }
-    }
-
-    private void storeWindowPosAndSize(JsonObject file, int x, int y, int width, int height) {
-        file.add("POS_X", new JsonPrimitive(x));
-        file.add("POS_Y", new JsonPrimitive(y));
-        file.add("WIDTH", new JsonPrimitive(width));
-        file.add("HEIGHT", new JsonPrimitive(height));
-
-    }
-
-    /**
-     * Travers through all Objects via BFS and Stores everything relevant
-     */
-    private void storeCanvas(JsonObject file) {
-    	//TODO(Tom2021-12-20): remove QUEUE
-        ArrayDeque<AbstractCanvasObject> queue = new ArrayDeque<>();
-        queue.addAll(model.getCanvas().getObjectsInThisLayer().toList());
-        // while quene not empty
-        while (!queue.isEmpty()) {
-
-            // u = current node
-        	AbstractCanvasObject u = queue.pop();
-            // add currentnode into jsontree
-            String key = "CVSOBJECT" + getNumerator(NUMTYPE.OBJECT);
-            file.add(key, GuiSettings.gson.toJsonTree(u, AbstractCanvasObject.class));
-            // and its connections too
-            edgeToJson(EDGETYPE.CONNECTION, file, u.getId(), new HashSet<>());
-            // if holonobject elements too
-            if (u instanceof HolonObject)
-                elementsToJson(TYPE.CANVAS, file, u);
-            // if switch graphpoints too
-            if (u instanceof HolonSwitch sw)
-                if (sw.getGraphPoints().size() != 0)
-                    unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
-            // if uppernode put all nodes inside the uppernode into queue
-            if (u instanceof GroupNode groupnode) {
-                queue.addAll( groupnode.getObjectsInThisLayer().toList());
-            }
-        }
-        // lastly add canvasedges into json
-        edgeToJson(EDGETYPE.CANVAS, file, 0, model.getEdgesOnCanvas());
-
-    }
-
-    /**
-     * Save wanted Data
-     */
-    private void storeData(ArchiveOutputStream stream) throws IOException {
-        File images = new File(System.getProperty("user.home") + "/.config/HolonGUI/Images");
-        File background = new File(System.getProperty("user.home") + "/.config/HolonGUI/BackgroundImages");
-        addFilesToSave(images, stream);
-        addFilesToSave(background, stream);
-
-    }
-
-    /**
-     * Stores Category or Canvas Elements into Json
-     */
-    void elementsToJson(TYPE type, JsonObject file, AbstractCanvasObject obj) {
-        JsonObject temp = new JsonObject();
-        String key = null;
-        // forall elements store them into json and include the id of the object
-        for (HolonElement ele : ((HolonObject) obj).getElements().toList()) {
-            temp.add("properties", GuiSettings.gson.toJsonTree(ele));
-            temp.add("ID", new JsonPrimitive(obj.getId()));
-            temp.add("FlexList", GuiSettings.gson.toJsonTree(ele.flexList,  new TypeToken<List<Flexibility>>() {
-            }.getType()));
-            // switch for deciding the key
-            switch (type) {
-                case CANVAS:
-                    key = "CVSELEMENT" + getNumerator(NUMTYPE.ELEMENT);
-                    break;
-                case CATEGORY:
-                    key = "CGELEMENT" + getNumerator(NUMTYPE.ELEMENT);
-                    break;
-                default:
-                    break;
-            }
-            file.add(key, GuiSettings.gson.toJsonTree(temp));
-            // if there are gps add them into
-            if (!ele.getGraphPoints().isEmpty())
-            	unitgraphTESTToJson(file, ele.getId(), ele.getGraphPoints());
-            temp = new JsonObject();
-        }
-
-    }
-
-    /**
-     * Put the UnitGraphs of Switches or Elements into Json
-     */
-    void unitgraphToJson(GRAPHTYPE type, JsonObject file, int id, LinkedList<Vec2f> graph) {
-
-        JsonObject temp = new JsonObject();
-        String key = null;
-        // forall points add them
-        for (int i = 0; i < graph.size(); i++) {
-            temp.add("" + i, new JsonPrimitive(graph.get(i).x + ":" + graph.get(i).y));
-        }
-        // decide key
-        switch (type) {
-            case SWITCH:
-                key = "SWUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
-                break;
-            case ELEMENT:
-                key = "ELEUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
-                break;
-            case TESTELEMENT:
-                key = "ELETESTUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
-                break;
-            default:
-                break;
-        }
-        // add id of element so it can be found again
-        temp.add("ID", new JsonPrimitive(id));
-
-        file.add(key, GuiSettings.gson.toJsonTree(temp));
-    }
-    /**
-     * Put the UnitGraphs of Switches or Elements into Json
-     */
-    void unitgraphTESTToJson(JsonObject file, int id, LinkedList<Vec2f> graph) {
-
-        JsonObject temp = new JsonObject();
-        String key = null;
-        // forall points add them
-        for (int i = 0; i < graph.size(); i++) {
-            temp.add("" + i, new JsonPrimitive(graph.get(i).x + ":" + graph.get(i).y));
-        }
-        key = "ELETESTUNITGRAPH" + getNumerator(NUMTYPE.UNITGRAPH);
-        // add id of element so it can be found again
-        temp.add("ID", new JsonPrimitive(id));
-        file.add(key, GuiSettings.gson.toJsonTree(temp));
-    }
-
-    /**
-     * Canvas-Edge, Connections, Node-Edge and Old-Edges to json
-     */
-    private void edgeToJson(EDGETYPE type, JsonObject file, int id, Set<Edge> arr) {
-        String k = null;
-        boolean b = false;
-        JsonObject temp = new JsonObject();
-
-        for (Edge edge : arr) {
-            // add properties and only the ids from a and b
-            temp.add("properties", GuiSettings.gson.toJsonTree(edge));
-            temp.add("A", new JsonPrimitive(edge.getA().getId()));
-            temp.add("B", new JsonPrimitive(edge.getB().getId()));
-
-            // Key and occasionally the id of Uppernode
-            switch (type) {
-                case CANVAS:
-                    k = "CVSEDGE" + getNumerator(NUMTYPE.EDGE);
-                    break;
-                case CONNECTION:
-                    k = "CONNEDGE" + getNumerator(NUMTYPE.CONNECTION);
-                    break;
-                case NODE:
-                    temp.add("ID", new JsonPrimitive(id));
-                    k = "NODEEDGE" + getNumerator(NUMTYPE.NODEEDGE);
-                    break;
-                case OLD:
-                    temp.add("ID", new JsonPrimitive(id));
-                    k = "OLDEDGE" + getNumerator(NUMTYPE.OLDEDGE);
-                    break;
-                default:
-                    break;
-            }
-            // lookup if the CVS, NODE or OLDEDGE are also connections
-            temp.add("connection", new JsonPrimitive(b));
-            file.add(k, GuiSettings.gson.toJsonTree(temp));
-            temp = new JsonObject();
-        }
-
-    }
-
-
-
-    /**
-     * Differs Between Single file or whole Directory to Store
-     */
-    private void addFilesToSave(File src, ArchiveOutputStream stream) throws IOException {
-        if (!src.exists())
-            return;
-
-        ArrayList<File> files = new ArrayList<>();
-        files.addAll(Arrays.asList(src.listFiles()));
-
-        for (File file : files) {
-            if (file.isDirectory())
-                addFilesToSave(file, stream);
-            else
-                addFileToSave(file, stream, true);
-        }
-
-    }
-
-    /**
-     * Add a File into the Archive
-     */
-    private void addFileToSave(File src, ArchiveOutputStream stream, boolean dir) throws IOException {
-        String entryName = (dir ? src.getCanonicalPath() : src.getName());
-
-        entryName = checkOS(entryName);
-
-        ZipArchiveEntry entry = new ZipArchiveEntry(entryName);
-        stream.putArchiveEntry(entry);
-        BufferedInputStream input = new BufferedInputStream(new FileInputStream(src));
-
-        IOUtils.copy(input, stream);
-        input.close();
-        stream.closeArchiveEntry();
-    }
-
-    private String checkOS(String entryName) {
-        String os = System.getProperty("os.name").toLowerCase();
-        String ret = entryName;
-        String partition = null;
-
-        if (os.contains("windows")) {
-            partition = ret.substring(0, ret.indexOf(":") + 1);
-            ret = ret.replace(System.getProperty("user.home") + "\\.config\\HolonGUI\\", "");
-            ret = ret.replace(partition, "");
-        }
-        if (os.contains("mac")) {
-            // dosmth
-            ret = ret.replace(System.getProperty("user.home") + "/.config/HolonGUI/", "");
-        }
-        if (os.contains("linux")) {
-            // dosmth
-            ret = ret.replace(System.getProperty("user.home") + "/.config/HolonGUI/", "");
-        }
-        if (os.contains("solaris")) {
-            // dosmth
-        }
-        return ret;
-    }
-
-    /**
-     * Just initialize the Numerators for the Json Keys. Maybe bad Style..
-     */
-    void initNumeration() {
-        this.nCat = this.nObj = this.nEle = this.nEdge = this.nConn = this.nNodeEdge = this.nOldEdge = this.nStatsGraph = 0;
-    }
-
-    /**
-     * Get the wanted numerator and increment it
-     */
-    int getNumerator(NUMTYPE type) {
-
-        switch (type) {
-            case CATEGORY:
-                return nCat++;
-            case OBJECT:
-                return nObj++;
-            case ELEMENT:
-                return nEle++;
-            case EDGE:
-                return nEdge++;
-            case CONNECTION:
-                return nConn++;
-            case NODEEDGE:
-                return nNodeEdge++;
-            case OLDEDGE:
-                return nOldEdge++;
-            case UNITGRAPH:
-                return nUnitGraph++;
-            case STATSGRAPH:
-                return nStatsGraph++;
-
-            default:
-                break;
-        }
-        return -1;
-    }
-
-    public enum MODE {
-        COMPLETE, PARTIAL, CATEGORY, SIZE,
-    }
-
-    public enum TYPE {
-        CATEGORY, CANVAS
-    }
-
-    public enum EDGETYPE {
-        CANVAS, CONNECTION, NODE, OLD, LAYER
-    }
-
-    public enum NUMTYPE {
-        CATEGORY, OBJECT, ELEMENT, EDGE, CONNECTION, NODEEDGE, OLDEDGE, UNITGRAPH, STATSGRAPH
-    }
-
-    public enum GRAPHTYPE {
-        SWITCH, ELEMENT, TESTELEMENT
-    }
-
-}

+ 5 - 4
src/holeg/ui/controller/SimulationManager.java

@@ -7,7 +7,7 @@ import holeg.model.HolonObject;
 import holeg.model.HolonSwitch;
 import holeg.model.HolonSwitch.SwitchState;
 import holeg.model.Holon;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 import java.util.*;
 import java.util.logging.Logger;
@@ -15,16 +15,17 @@ import java.util.stream.Collectors;
 
 public class SimulationManager {
     private static final Logger log = Logger.getLogger(SimulationManager.class.getName());
-    private final Model model;
+    private final Control control;
 
-    public SimulationManager(Model m) {
+    public SimulationManager(Control control) {
         log.fine("Construct SimulationManager");
-        model = m;
+        this.control = control;
     }
 
     public void calculateStateForTimeStep(int timeStep) {
         log.fine("Calculate");
         long start = System.currentTimeMillis();
+        Model model =  control.getModel();
         model.getCanvas().getAllSwitchObjectsRecursive().forEach(sw -> sw.calculateState(timeStep));
         List<HolonObject> holonObjectList = model.getCanvas().getAllHolonObjectsRecursive().collect(Collectors.toList());
         List<Edge> edgeList = new ArrayList<>(model.getEdgesOnCanvas());

+ 1 - 18
src/holeg/ui/model/GuiSettings.java

@@ -2,11 +2,6 @@ package holeg.ui.model;
 
 import java.util.HashSet;
 import java.util.Set;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import holeg.adapter.AbstractCpsObjectAdapter;
 import holeg.model.AbstractCanvasObject;
 import holeg.model.Edge;
 import holeg.ui.view.main.Category;
@@ -66,17 +61,5 @@ public class GuiSettings {
 	public static void setSelectedObjects(Set<AbstractCanvasObject> selectedObjects) {
 		GuiSettings.selectedObjects = selectedObjects;
 	}
-    
-	
-	//TODO(Tom2021-12-20) maybe moved somewhere else
-    public static Gson gson = initGson();
-    
-    public static Gson initGson() {
-        GsonBuilder builder = new GsonBuilder();
-        builder.serializeNulls();
-        builder.excludeFieldsWithoutExposeAnnotation();
-        builder.setPrettyPrinting();
-        builder.registerTypeAdapter(AbstractCanvasObject.class, new AbstractCpsObjectAdapter());
-        return builder.create();
-    }
+
 }

+ 10 - 40
src/holeg/ui/model/IdCounter.java

@@ -7,24 +7,13 @@ package holeg.ui.model;
  * @author Gruppe14
  */
 public class IdCounter {
-	private static int counterObjects = 1;
-	private static int counterElements = 1;
-
-	public enum CounterType {
-		Object, Element
-	}
+	private static int counter = 1;
 	/**
 	 * Return the next ID and increment the ID counter by 1.
 	 * @return the next ID
 	 */
-	public static synchronized int nextId(CounterType type) {
-		switch(type){
-			case Element:
-				return counterObjects++;
-			case Object:
-			default:
-				return counterElements++;
-		}
+	public static synchronized int next() {
+			return counter++;
 	}
 
 	/**
@@ -32,43 +21,24 @@ public class IdCounter {
 	 * 
 	 * @return the counter
 	 */
-	public static int actualId(CounterType type) {
-		switch(type){
-			case Element:
-				return counterObjects;
-			case Object:
-			default:
-				return counterElements;
-		}
+	public static int get() {
+		return counter;
 	}
 
 	/**
 	 * Set the Counter.
-	 * 
+	 *
 	 * @param counter
 	 *            the counter to set
 	 */
-	public static void setCounter(int counter, CounterType type) {
-		
-		switch(type){
-		case Element:
-			counterElements = counter;
-		case Object:
-		default:
-			counterObjects = counter;
-	}
+	public static void set(int counter) {
+		IdCounter.counter = counter;
 	}
 
 	/**
 	 * Reset the Counter.
 	 */
-	public static void resetObjectCounter(CounterType type) {
-		switch(type){
-			case Element:
-				counterObjects = 1;
-			case Object:
-			default:
-				counterElements = 1;
-		}
+	public static void reset() {
+				counter = 0;
 	}
 }

+ 0 - 177
src/holeg/ui/model/Model.java

@@ -1,177 +0,0 @@
-package holeg.ui.model;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-import holeg.model.*;
-
-
-/**
- * The Class Model is the class where everything is saved. All changes made to
- * the Data is managed via a controller.
- *
- * @author Gruppe14
- */
-public class Model {
-
-	private static final Logger log = Logger.getLogger(Model.class.getName());
-    private int currentIteration = 0;
-    private int maxIterations=100;
-    
-    /** the amount of iterations */
-    
-    /**
-	 * All implemented FairnessModels:<br>
-	 * {@link FairnessModel#MininumDemandFirst}<br>
-	 * {@link FairnessModel#AllEqual}
-	 */
-	public enum FairnessModel{
-		/**
-		 * One Element of each HolonObject will be powered first, starting with the
-		 * smallest Demand. If ale HolonObjects have an active Element, the
-		 * simulation will try to fully supply as many HolonObjects as possible.
-		 */
-		MininumDemandFirst, 
-		/**
-		 * All HolonObjects will receive the same amount of energy.
-		 */
-		AllEqual
-	}
-    /** the Fairness model in use */
-    private FairnessModel fairnessModel = FairnessModel.MininumDemandFirst;
-   
-    private final GroupNode canvas = new GroupNode("Canvas");
-    /*
-     * Array of all CpsObjects in our canvas. It is set by default as an empty
-     * list.
-     */
-    private Set<Edge> edgesOnCanvas = new HashSet<>();
-   
-    public Model() {
-    	log.fine("Init Model");
-    }
-    
-    public GroupNode getCanvas() {
-    	return canvas;
-    }
-
-    public Set<Holon> holons = new HashSet<>();
-
-
-
-
-
-    /**
-     * Get all Edges on the Canvas.
-     *
-     * @return the edgesOnCanvas
-     */
-    public Set<Edge> getEdgesOnCanvas() {
-        return edgesOnCanvas;
-    }
-
-
-    /**
-     * Adds an Edge to The Canvas.
-     *
-     * @param edge the edgesOnCanvas to add
-     */
-    public void addEdgeOnCanvas(Edge edge) {
-        this.edgesOnCanvas.add(edge);
-    }
-
-    /**
-     * Remove an edge from the Canvas.
-     *
-     * @param edge the edge to remove
-     */
-    public void removeEdgesOnCanvas(Edge edge) {
-        this.edgesOnCanvas.remove(edge);
-    }
-
-    /**
-     * Returns the maximum iterations.
-     *
-     * @return iterations
-     */
-    public int getMaxIterations() {
-        return maxIterations;
-    }
-
-
-    /**
-     * Returns the current iteration.
-     *
-     * @return current iteration
-     */
-    public int getCurrentIteration() {
-        return currentIteration;
-    }
-
-    /**
-     * sets the current Iteration.
-     *
-     * @param value the current Iteration
-     */
-    public void setCurrentIteration(int value) {
-        this.currentIteration = value;
-    }
-
-
-
-    public List<HolonElement> getAllHolonElements() {
-    	return canvas.getAllHolonObjectsRecursive().flatMap(HolonObject::getElements).collect(Collectors.toList());
-    }
-    
-    public List<Flexibility> getAllFlexibilities() {
-    	return canvas.getAllHolonObjectsRecursive().flatMap(hO -> hO.getElements().flatMap(ele -> ele.flexList.stream())).collect(Collectors.toList());
-    }
-    
-    public void reset() {
-    	resetFlexibilities();
-    	resetEdges();
-    }
-    
-    private void resetFlexibilities() {
-    	getAllFlexibilities().forEach(Flexibility::reset);
-    }
-    private void resetEdges() {
-    	this.getEdgesOnCanvas().forEach(Edge::reset);
-    }
-   
-	
-	/**
-	 * @param iterations the number of steps for this simulation
-	 */
-	public void setIterations(int iterations){
-		this.maxIterations=iterations;
-	}
-	
-	/**
-	 * @return the fairnessModel
-	 */
-	public FairnessModel getFairnessModel() {
-		return fairnessModel;
-	}
-	
-	/**
-	 * @param fairnessModel the fairnessModel to set
-	 */
-	public void setFairnessModel(FairnessModel fairnessModel) {
-		this.fairnessModel = fairnessModel;
-	}
-	
-	public void clear() {
-		this.edgesOnCanvas.clear();
-		canvas.clear();
-	}
-
-
-
-
-
-}

+ 5 - 2
src/holeg/ui/view/canvas/Canvas.java

@@ -18,7 +18,7 @@ import java.util.logging.Logger;
 
 public class Canvas extends JPanel {
     private static final Logger log = Logger.getLogger(Canvas.class.getName());
-    private final GroupNode groupNode;
+    private GroupNode groupNode;
     private final Control control;
     private final CanvasMouseListener canvasMouseListener = new CanvasMouseListener();
     private boolean enabled = true;
@@ -34,6 +34,10 @@ public class Canvas extends JPanel {
         this.addMouseMotionListener(canvasMouseListener);
     }
 
+    public void setGroupNode(GroupNode groupNode){
+        this.groupNode = groupNode;
+    }
+
     public static Rectangle getBoundsOfObject(AbstractCanvasObject obj) {
         int pictureScale = GuiSettings.getPictureScale();
         int pictureScaleDiv2 = GuiSettings.getPictureScaleDiv2();
@@ -161,7 +165,6 @@ public class Canvas extends JPanel {
                 case EdgeCreation -> repaint();
             }
             lastPosition = actualPos;
-
         }
 
         @Override

+ 3 - 3
src/holeg/ui/view/canvas/Rendering.java

@@ -41,14 +41,14 @@ class Rendering {
 		g.setColor(stateColor);
         g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() - GuiSettings.getPictureScaleDiv2(),
                 GuiSettings.getPictureScale(), GuiSettings.getPictureScale());
-        drawCanvasObject(g, hO.getImage(), pos);
+        drawCanvasObject(g, hO.getImagePath(), pos);
         if(GuiSettings.showSupplyBars && hO.getActualEnergy() <= 0){
             drawSupplyBar(g, hO.getSupplyBarPercentage(), stateColor, pos);
         }
     }
 
     static void drawCanvasObject(Graphics2D g, AbstractCanvasObject obj) {
-        drawCanvasObject(g, obj.getImage(), obj.getPosition());
+        drawCanvasObject(g, obj.getImagePath(), obj.getPosition());
     }
 
     static void drawCanvasObject(Graphics2D g, String imageName, Vec2i pos) {
@@ -103,7 +103,7 @@ class Rendering {
         g.setColor(Color.gray);
         g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() - GuiSettings.getPictureScaleDiv2(),
                 GuiSettings.getPictureScale(), GuiSettings.getPictureScale());
-        drawCanvasObject(g, groupNode.getImage(), pos);
+        drawCanvasObject(g, groupNode.getImagePath(), pos);
     }
 
     static void drawSelection(Graphics2D g) {

+ 2 - 2
src/holeg/ui/view/dialog/AddElementPopUp.java

@@ -161,8 +161,8 @@ public class AddElementPopUp extends JDialog {
 	 */
 	private void okAction() {
 		boolean repeated = false;
-		for (HolonElement e :  tempCps.getElements().toList()) {
-			if (elementName.getText().equals(e.getName())&&(hl == null || hl.getId()!=e.getId())) {
+		for (HolonElement e :  tempCps.elementsStream().toList()) {
+			if (elementName.getText().equals(e.getName())&&(hl == null)) {
 				repeated = true;
 				break;
 			}

+ 3 - 4
src/holeg/ui/view/dialog/AddObjectPopUp.java

@@ -13,7 +13,6 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 
 import javax.swing.DefaultListModel;
@@ -149,11 +148,11 @@ public class AddObjectPopUp extends JDialog {
 				}
 			});
 			if (edit) {
-				lblImagePreview.setIcon(new ImageIcon(Import.loadImage(obj.getImage(), 50, 50)));
+				lblImagePreview.setIcon(new ImageIcon(Import.loadImage(obj.getImagePath(), 50, 50)));
 			}
 			sourcePath.setBounds(148, 77, 271, 20);
 			if (edit) {
-				this.filePath = obj.getImage();
+				this.filePath = obj.getImagePath();
 				sourcePath.setText(filePath);
 			}
 			contentPanel.add(sourcePath);
@@ -195,7 +194,7 @@ public class AddObjectPopUp extends JDialog {
 			}
 		}
 		if (edit) {
-			((HolonObject) obj).getElements().forEach(hE -> {
+			((HolonObject) obj).elementsStream().forEach(hE -> {
 				addElement(hE);
 			});
 		}

+ 1 - 1
src/holeg/ui/view/dialog/CanvasResizePopUp.java

@@ -5,7 +5,7 @@ import javax.swing.*;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
 import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.canvas.Canvas;
 import holeg.ui.view.image.Import;
 import holeg.utility.math.vector.Vec2i;

+ 10 - 13
src/holeg/ui/view/dialog/CreateTemplatePopUp.java

@@ -3,7 +3,6 @@ package holeg.ui.view.dialog;
 import java.awt.BorderLayout;
 import java.awt.Choice;
 import java.io.File;
-import java.util.AbstractMap.SimpleEntry;
 
 import javax.swing.DefaultListModel;
 import javax.swing.ImageIcon;
@@ -24,7 +23,7 @@ import holeg.model.HolonObject;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
 import holeg.ui.model.GuiSettings;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.main.Category;
 import holeg.ui.view.image.Import;
 
@@ -88,13 +87,11 @@ public class CreateTemplatePopUp extends JDialog {
 	JFrame parent;
 	/**
 	 * Create the dialog.
-	 * 
-	 * @param edit
+	 *
 	 *            true if edit
 	 * @param obj
 	 *            the object
 	 * @param model
-	 * @param cat
 	 *            the categorie
 	 */
 	public CreateTemplatePopUp(HolonObject obj, Model model,
@@ -177,7 +174,7 @@ public class CreateTemplatePopUp extends JDialog {
 		textField_imagePath.setBounds(86, 86, 172, 22);
 		contentPanel.add(textField_imagePath);
 		textField_imagePath.setColumns(10);
-		textField_imagePath.setText(template.getImage());
+		textField_imagePath.setText(template.getImagePath());
 
 		/**
 		 * Browse Image Button
@@ -194,7 +191,7 @@ public class CreateTemplatePopUp extends JDialog {
 		 */
 		lblImagePreview = new JLabel("Image Preview");
 		lblImagePreview.setIcon(new ImageIcon(Import.loadImage(
-				template.getImage(), 62, 62)));
+				template.getImagePath(), 62, 62)));
 		lblImagePreview.setBounds(298, 13, 62, 62);
 		contentPanel.add(lblImagePreview);
 
@@ -206,7 +203,7 @@ public class CreateTemplatePopUp extends JDialog {
 		/**
 		 * Add Elements to List
 		 */
-		template.getElements().forEach(hE -> {
+		template.elementsStream().forEach(hE -> {
 			listModel.addElement(hE.getName()
 					+ ": " + hE.getEnergy() + "U");			
 		});
@@ -293,11 +290,11 @@ public class CreateTemplatePopUp extends JDialog {
 	 */
 	private void createTemplate() {
 		template.setName(textField_name.getText());
-		template.setImage(textField_imagePath.getText());
+		template.setImagePath(textField_imagePath.getText());
 		controller.findCategoryWithName(choice
 				.getItem(choice.getSelectedIndex())).ifPresent(cat -> {
 					controller.addObject(cat, template.getName(),
-							template.getElements().toList(), template.getImage());
+							template.elementsStream().toList(), template.getImagePath());
 				});
 		this.dispose();
 	}
@@ -324,7 +321,7 @@ public class CreateTemplatePopUp extends JDialog {
 		int index = list.getSelectedIndex();
 		if (index == -1)
 			return;
-		template.removeElement(index);
+		//TODO(Tom2022-01-27): template.remove(index);
 		listModel.remove(index);
 	}
 
@@ -338,14 +335,14 @@ public class CreateTemplatePopUp extends JDialog {
 		
 		AddElementPopUp popUp = new AddElementPopUp(parent);
 		popUp.setActualHolonObject(template);
-		popUp.setElement(template.getElements().toList().get(index));
+		popUp.setElement(template.elementsStream().toList().get(index));
 		popUp.setVisible(true);
 		HolonElement he = popUp.getElement();
 		if (he != null) {
 			listModel.remove(index);
 			listModel.addElement(he.getName()
 					+ ": " + he.getEnergy() + "U");
-			template.removeElement(index);
+			//TODO(Tom2022-01-27): template.removeElement(index);
 			template.add(he);
 		}
 	}

+ 9 - 3
src/holeg/ui/view/inspector/Inspector.java

@@ -6,6 +6,7 @@ import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.event.ItemEvent;
 import java.util.Set;
+import java.util.logging.Logger;
 import java.util.stream.Collectors;
 
 import javax.swing.Box;
@@ -20,9 +21,11 @@ import javax.swing.JScrollPane;
 import javax.swing.JSplitPane;
 import javax.swing.JToolBar;
 
+import holeg.interfaces.LocalMode;
 import holeg.interfaces.TimelineDependent;
 import holeg.model.HolonElement;
 import holeg.model.HolonSwitch;
+import holeg.model.Model;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
 import holeg.ui.model.GuiSettings;
@@ -32,6 +35,7 @@ import holeg.utility.math.Maths;
 import holeg.utility.math.decimal.Format;
 
 public class Inspector extends JSplitPane {
+	private static final Logger log = Logger.getLogger(Inspector.class.getName());
 	private final UnitGraph unitGraph;
 	private final InspectorTable table;
 	private final JPanel scrollGraph = new JPanel();
@@ -110,7 +114,7 @@ public class Inspector extends JSplitPane {
 		localPeriodButton.addActionListener(actionEvent -> {
 			boolean newState = !localPeriodInput.isVisible();
 			changeLocalPeriodButtonAppeareance(newState);
-			unitGraph.setUseLocalPeriod(newState);
+			log.info("LocalPeriodButton");
 		});
 
 		toolBarGraph.add(Box.createHorizontalGlue());
@@ -138,14 +142,16 @@ public class Inspector extends JSplitPane {
 				JOptionPane.showMessageDialog(null, '"' + text + '"' + " is not a valid Input. \n Use whole numbers.");
 			return;
 		}
-		unitGraph.setLocalPeriod(localPeriodInputValue);
+		LocalMode.Period period = new LocalMode.Period(7);
+		period.setInterval(localPeriodInputValue);
+		unitGraph.setPeriod(period);
 	}
 
 	/**
 	 * This Method updates the UnitGraph, saves the old LocalModeState and load the
 	 * new LocalModeState.
 	 * 
-	 * @param element The new Element to load the UnitGraph
+	 * @param elements The new Element to load the UnitGraph
 	 */
 	private void updateUnitGraph(Set<HolonElement> elements) {
 		// SaveOld LocalMode State.

+ 2 - 2
src/holeg/ui/view/inspector/InspectorTable.java

@@ -375,10 +375,10 @@ public class InspectorTable extends JPanel {
 	// Extract elements from a list of AbstractCanvasObjects
 	static Stream<HolonElement> extractElements(Collection<AbstractCanvasObject> toInspect) {
 		Stream<HolonElement> recursiveLayer = toInspect.stream().filter(object -> object instanceof GroupNode).flatMap(
-				obj -> ((GroupNode) obj).getAllHolonObjectsRecursive().flatMap(hO -> hO.getElements()));
+				obj -> ((GroupNode) obj).getAllHolonObjectsRecursive().flatMap(hO -> hO.elementsStream()));
 		Stream<HolonElement> thisLayer = toInspect.stream().filter(obj -> obj instanceof HolonObject).flatMap(obj -> {
 			HolonObject ho = (HolonObject) obj;
-			return ho.getElements();
+			return ho.elementsStream();
 		});
 		return Stream.concat(thisLayer, recursiveLayer);
 	}

+ 52 - 60
src/holeg/ui/view/inspector/UnitGraph.java

@@ -18,14 +18,16 @@ import java.util.List;
 import java.util.ListIterator;
 import java.util.Optional;
 import java.util.Set;
+import java.util.logging.Logger;
 
 import javax.swing.JPanel;
 
+import holeg.interfaces.LocalMode;
 import holeg.interfaces.TimelineDependent;
 import holeg.interfaces.GraphEditable.GraphType;
 import holeg.model.HolonElement;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.utility.math.Maths;
 import holeg.utility.math.vector.Vec2f;
 import holeg.utility.math.vector.Vec2i;
@@ -37,7 +39,7 @@ import holeg.utility.math.vector.Vec2i;
  * @author Tom Troppmann
  */
 public class UnitGraph extends JPanel implements MouseListener, MouseMotionListener, ComponentListener {
-
+	private static final Logger log = Logger.getLogger(UnitGraph.class.getName());
 	// Normal Settings
 	private static final int border = 4;
 	private static final int clickThreshholdSquared = 25;
@@ -49,6 +51,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	private static final int dotSize = 8;
 
 	/** The Color of a dot in the graph. */
+	//TODO(Tom2022-01-25): export them to ColorPreferences
 	private static final Color dotColor = Color.blue;
 	private static final Color editDotColor = new Color(255, 119, 0);
 	private static final Color[] seriesColorArray = { Color.blue, Color.cyan, Color.black, Color.green, Color.gray,
@@ -64,7 +67,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 		public Color color;
 	}
 
-	private ArrayList<Series> seriesList = new ArrayList<Series>();
+	private final ArrayList<Series> seriesList = new ArrayList<>();
 	private Vec2i editPosition;
 	private Optional<Series> actualSeries;
 
@@ -92,8 +95,6 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 
 	/**
 	 * Constructor.
-	 *
-	 * @param ModelTest   the Model
 	 * @param control the Controller
 	 */
 	public UnitGraph(Control control) {
@@ -180,28 +181,28 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 */
 	public void paintComponent(Graphics g) {
 		super.paintComponent(g);
-		Graphics2D g2D = (Graphics2D) g;
-		drawGrid(g2D);
-		g2D.setColor(Color.BLACK);
-		g2D.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
-		g2D.setStroke(new BasicStroke(2f));
-		drawUnitGraph(g2D);
-		g2D.setColor(dotColor);
+		Graphics2D g2d = (Graphics2D) g;
+		drawGrid(g2d);
+		g2d.setColor(Color.BLACK);
+		g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
+		g2d.setStroke(new BasicStroke(2f));
+		drawUnitGraph(g2d);
+		g2d.setColor(dotColor);
 		if (editMode) {
-			drawUnitGraphPointsReleased(g2D);
+			drawUnitGraphPointsReleased(g2d);
 		} else {
-			drawUnitGraphPoints(g2D);
+			drawUnitGraphPoints(g2d);
 		}
-		g2D.setColor(dotColor);
-		g2D.setStroke(new BasicStroke(1));
-		drawCurrentIterartionLine(g2D);
-		g2D.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 1.0f, new float[]{6}, 3));
+		g2d.setColor(dotColor);
+		g2d.setStroke(new BasicStroke(1));
+		drawCurrentIterartionLine(g2d);
+		g2d.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 1.0f, new float[]{6}, 3));
 		this.globalCurve.ifPresent(curve -> {
-			g2D.setColor(globalCurveColor);
-			drawDoubleGraph(g2D, curve.points);
-			g2D.setColor(zeroLineColor);
-			g2D.setStroke(new BasicStroke(1));
-			drawDoubleGraph(g2D, curve.zeroLinePoints);
+			g2d.setColor(globalCurveColor);
+			drawDoubleGraph(g2d, curve.points);
+			g2d.setColor(zeroLineColor);
+			g2d.setStroke(new BasicStroke(1));
+			drawDoubleGraph(g2d, curve.zeroLinePoints);
 		});
 	}
 
@@ -281,17 +282,17 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Methods draws the Grid on the Canvas.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
-	private void drawGrid(Graphics2D g2D) {
-		g2D.setStroke(new BasicStroke(1));
-		g2D.setColor(Color.lightGray);
+	private void drawGrid(Graphics2D g) {
+		g.setStroke(new BasicStroke(1));
+		g.setColor(Color.lightGray);
 		int amountOfLines = 10;
 		int width = widthWithBorder + 2 * border;
 		int height = heightWithBorder;
 		for (int i = 0; i <= amountOfLines; i++) {
 			int linehieght = (int) (((double) i / (double) amountOfLines) * (double) height) + border;
-			g2D.drawLine(0, linehieght, width, linehieght);
+			g.drawLine(0, linehieght, width, linehieght);
 		}
 	}
 
@@ -301,20 +302,20 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws the CurrentIterationLine.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawCurrentIterartionLine(Graphics2D g) {
 		int cur = model.getCurrentIteration();
 		int max = model.getMaxIterations();
 		if (isLocalPeriedDifferentInSeries()) {
 			for (Series series : seriesList) {
-				double where;
-				if (!series.element.isUsingLocalPeriod()) {
-					where = ((double) cur) / ((double) max);
-				} else {
-					int lPeriod = series.element.getLocalPeriod();
-					where = ((double) cur % lPeriod) / ((double) lPeriod);
-				}
+				double where = switch(series.element.getPeriod().getType()){
+					case Local -> {
+						int interval = series.element.getPeriod().getInterval();
+						yield ((double) cur % interval) / ((double) interval);
+					}
+					case Global -> ((double) cur) / ((double) max);
+				};
 				Vec2i oben = new Vec2i(border + (int) (where * widthWithBorder), 0);
 				Vec2i unten = new Vec2i(border + (int) (where * widthWithBorder),
 						2 * border + heightWithBorder);
@@ -343,7 +344,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws a line between two Positions on the Canvas.
 	 * 
-	 * @param g2D   to draw.
+	 * @param g   to draw.
 	 * @param start the Position of one end of the line to draw.
 	 * @param end   the other Ends Position of the Line to draw.
 	 */
@@ -378,7 +379,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * to make the wanted behavior.
 	 * 
 	 * @param path   the path of the Bezier.
-	 * @param actaul the actual Position of the Path.
+	 * @param actual the actual Position of the Path.
 	 * @param target the end Position of the Curve.
 	 */
 	private void curveTo(Path2D.Double path, Vec2i actual, Vec2i target) {
@@ -405,7 +406,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws the UnitGraph as BoolGraph.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawBoolGraph(Graphics2D g, Series series) {
 		if (series.points.size() <= 1)
@@ -439,7 +440,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws the UnitGraph as BoolGraph in EditMode.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawBoolGraphInEditMode(Graphics2D g, Series series) {
 		LinkedList<Vec2i> before = new LinkedList<Vec2i>();
@@ -474,7 +475,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * This Method draws a red Hint to signal the User the snapping of the hovered
 	 * Point under the Cursor in EditMode.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawSnappingHint(Graphics2D g) {
 		// ColorHint
@@ -497,7 +498,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws a partial Graph from a Position List as BoolGraph.
 	 * 
-	 * @param g2D  to draw.
+	 * @param g  to draw.
 	 * @param list the PositionList to draw a BoolGraph
 	 */
 	private void drawBoolGraphFromList(Graphics2D g, LinkedList<Vec2i> list) {
@@ -529,7 +530,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws the UnitGraph as DoubleGraph.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawDoubleGraph(Graphics2D g, List<UnitGraphPoint> points) {
 		if (points.isEmpty())
@@ -552,7 +553,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws the UnitGraph as DoubleGraph in EditMode.
 	 * 
-	 * @param g2D to draw.
+	 * @param g to draw.
 	 */
 	private void drawDoubleGraphInEditMode(Graphics2D g, Series series) {
 		LinkedList<Vec2i> before = new LinkedList<Vec2i>();
@@ -583,7 +584,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	 * <p>
 	 * This Method draws a partial Graph from a Position List as DoubleGraph.
 	 * 
-	 * @param g2D  to draw.
+	 * @param g  to draw.
 	 * @param list the PositionList to draw a DoubleGraph
 	 */
 	private void drawUnitGraphFromList(Graphics2D g, LinkedList<Vec2i> list) {
@@ -735,8 +736,7 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 
 	/**
 	 * When the Mouse Drag a Point it updates each time the position.
-	 * 
-	 * @param newPosition
+	 *
 	 */
 	private void updateEditPointPosition(Vec2i newPosition, EditPointType editPointType, GraphType graphType) {
 		// make it in the bounds of the UnitGraph no Point out of the Border
@@ -949,30 +949,22 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 		repaint();
 	}
 
-	// LocalMode access methods...
-	// To access a element from the GUI for the LocalMode
-	public void setUseLocalPeriod(boolean state) {
-		for (Series series : seriesList) {
-			series.element.setUseLocalPeriod(state);
-		}
-	}
-
-	public void setLocalPeriod(int localLength) {
+	public void setPeriod(LocalMode.Period period) {
 		for (Series series : seriesList) {
-			series.element.setLocalPeriod(localLength);
+			series.element.setPeriod(new LocalMode.Period(period));
 		}
 	}
 
 	public boolean isLocalPeriedDifferentInSeries() {
-		return seriesList.stream().map(series -> series.element.getLocalPeriod()).distinct().count() > 1;
+		return seriesList.stream().map(series -> series.element.getPeriod().getInterval()).distinct().count() > 1;
 	}
 
 	public int getFirstLocalPeriod() {
-		return seriesList.isEmpty() ? 0 : seriesList.get(0).element.getLocalPeriod();
+		return seriesList.isEmpty() ? 0 : seriesList.get(0).element.getPeriod().getInterval();
 	}
 
 	public boolean isUsingLocalPeriod() {
-		return seriesList.stream().anyMatch(series -> series.element.isUsingLocalPeriod());
+		return seriesList.stream().anyMatch(series -> series.element.getPeriod().getType() != LocalMode.Period.PeriodType.Global);
 	}
 
 }

+ 0 - 1
src/holeg/ui/view/main/Category.java

@@ -20,7 +20,6 @@ public class Category {
 	// objects: is a ArrayList of all Objects that belongs to the Category
 	private Set<AbstractCanvasObject> objects = new HashSet<AbstractCanvasObject>();
 	// name: is a String chosen by the User
-	@Expose
 	private String name; 
 
 	/**

+ 83 - 265
src/holeg/ui/view/main/GUI.java

@@ -5,14 +5,10 @@ import java.awt.Color;
 import java.awt.Component;
 import java.awt.Cursor;
 import java.awt.Dimension;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.HeadlessException;
 import java.awt.Image;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
-import java.awt.datatransfer.UnsupportedFlavorException;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ComponentAdapter;
@@ -23,12 +19,10 @@ import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseMotionAdapter;
 import java.io.File;
-import java.io.IOException;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
+import java.util.prefs.Preferences;
 
 import javax.swing.AbstractAction;
 import javax.swing.ActionMap;
@@ -60,10 +54,7 @@ import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreeCellRenderer;
 
-import org.apache.commons.compress.archivers.ArchiveException;
-
-import com.google.gson.JsonParseException;
-
+import holeg.interfaces.LocalMode;
 import holeg.model.AbstractCanvasObject;
 import holeg.model.GroupNode;
 import holeg.model.HolonObject;
@@ -73,9 +64,8 @@ import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
 import holeg.ui.model.GuiSettings;
 import holeg.ui.model.IdCounter;
-import holeg.ui.model.IdCounter.CounterType;
-import holeg.ui.model.Model;
-import holeg.ui.model.Model.FairnessModel;
+import holeg.model.Model;
+import holeg.model.Model.FairnessModel;
 import holeg.ui.view.canvas.Canvas;
 import holeg.ui.view.component.ButtonTabComponent;
 import holeg.ui.view.dialog.AboutUsPopUp;
@@ -198,7 +188,7 @@ public class GUI {
 	private final JToolBar toolBarHolonEl = new JToolBar();
 
 	// Languages
-	private final Canvas canvas;
+	private Canvas canvas;
 	private final UnitGraph unitGraph;
 	/** Textfield to show the period of an element */
 	private final JTextField unitGraphLocalPeriod = new JTextField(6);
@@ -238,6 +228,10 @@ public class GUI {
 
 	private JMenuItem removeItem = new JMenuItem("Remove");
 
+	// Save / Load
+	private final JFileChooser safeLoadFileChooser = initSaveLoadFileChooser();
+
+
 	/**
 	 * Create the application.
 	 *
@@ -263,20 +257,9 @@ public class GUI {
 	private void initialize() {
 		holegJFrame = new JFrame();
 		holegJFrame.setTitle("HOLEG Simulator");
-		// try to restore old position/dimensions
-		ArrayList<Integer> savedWindowDim = control.loadSavedWindowDimensionsIfExistent();
-		if (savedWindowDim.size() == 4) {
-			holegJFrame.setBounds(savedWindowDim.get(0), savedWindowDim.get(1), savedWindowDim.get(2),
-					savedWindowDim.get(3));
-		}
-
-		// if the upper part of the window is showing, the windows can still be
-		// moved,
-		// but if it is not, we need to move it to somewhere else
-		if (savedWindowDim.size() != 4 || !isUpperPanelInsideBounds()) {
-			holegJFrame.setBounds(100, 100, 1000, 800);
-			holegJFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
-		}
+		holegJFrame.setBounds(new Rectangle(1200, 800));
+		//Center
+		holegJFrame.setLocationRelativeTo(null);
 		holegJFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 
 		holegJFrame.addWindowListener(new java.awt.event.WindowAdapter() {
@@ -284,18 +267,7 @@ public class GUI {
 			public void windowClosing(java.awt.event.WindowEvent windowEvent) {
 				if (JOptionPane.showConfirmDialog(holegJFrame, "Are you sure you want to exit?", "HOLEG",
 						JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
-					control
-							.deleteDirectory(new File(System.getProperty("user.home") + "/.config/HolonGUI/Autosave"));
-
-					// try to save the position and size of the window, such
-					// that (if possible)
-					// it can be opened in the same position the next time
-					try {
-						control.savePosAndSizeOfWindow(holegJFrame.getX(), holegJFrame.getY(),
-								holegJFrame.getWidth(), holegJFrame.getHeight());
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
+					//TODO(Tom2022-01-27):
 					System.exit(0);
 				}
 			}
@@ -310,21 +282,9 @@ public class GUI {
 		String cntrlZDown = "controlZ";
 		inputMap.put(KeyStroke.getKeyStroke("control Z"), cntrlZDown);
 		actionMap.put(cntrlZDown, new AbstractAction() {
-
-			private static final long serialVersionUID = 1L;
-
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				try {
-					control.loadAutoSave(control.getUndoSave());
-					closeInvalidUpperNodeTabs();
-
-					control.calculateStateAndVisualForCurrentTimeStep();
-					log.info("canvas.repaint0");
-					canvas.repaint();
-				} catch (IOException eex) {
-					eex.printStackTrace();
-				}
+				//TODO(Tom2022-01-27): CtrlZ
 			}
 		});
 
@@ -334,42 +294,17 @@ public class GUI {
 
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				try {
-					control.loadAutoSave(control.getRedoSave());
-
-					closeInvalidUpperNodeTabs();
-
-					control.calculateStateAndVisualForCurrentTimeStep();
-					log.info("canvas.repaint1");
-					canvas.repaint();
-				} catch (IOException ex) {
-					ex.printStackTrace();
-				}
+				//TODO Ctrl Y
 			}
 		});
 
 		String cntrlADown = "controlA";
 		inputMap.put(KeyStroke.getKeyStroke("control A"), cntrlADown);
 		AbstractAction controlA = new AbstractAction() {
-			private static final long serialVersionUID = 1L;
-
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				chooseTabTemp();
-
 				GuiSettings.getSelectedObjects().clear();
-
-				// Uppernode Canvas?
-				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-				Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-				if (canvasOrUpperNodeCanvas instanceof Canvas groupNodeCanvas) {
-					control.addSelectedObjects(
-							groupNodeCanvas.getGroupNode().getObjectsInThisLayer().collect(Collectors.toSet()));
-					groupNodeCanvas.repaint();
-					// or Canvas?
-				}
-				control.getObjectsInDepth();
+				//TODO(Tom2022-01-27): Ctrl A
 			}
 		};
 		actionMap.put(cntrlADown, controlA);
@@ -383,34 +318,7 @@ public class GUI {
 			@Override
 			public void actionPerformed(ActionEvent e) {
 				chooseTabTemp();
-
-				// Uppernode Canvas?
-				JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-				Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-				// check whether a producer was deleted (this triggers a
-				// complete re-evaluation of the net)
-				boolean wasProducerDeleted = true;
-
-				if (canvasOrUpperNodeCanvas instanceof Canvas groupNodeCanvas) {
-					for (AbstractCanvasObject cps : GuiSettings.getSelectedObjects()) {
-						if (groupNodeCanvas.getGroupNode().getObjectsInThisLayer().anyMatch(object -> object == cps)) {
-							control.deleteObjectInGroupNode(cps, groupNodeCanvas.getGroupNode());
-
-							// remove UpperNodeTab if UpperNode deleted
-							removeUpperNodeTab(cps);
-						}
-					}
-					groupNodeCanvas.repaint();
-					control.clearSelection();
-				}
-
-				// recalculate net if a producer was deleted
-				if (wasProducerDeleted) {
-					control.resetSimulation();
-					control.calculateStateAndVisualForCurrentTimeStep();
-				}
-
+				//TODO(Tom2022-01-27): delete
 				GuiSettings.getSelectedObjects().clear();
 			}
 		});
@@ -444,34 +352,7 @@ public class GUI {
 
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				try {
-					tabTemp = null;
-					if (tabbedPaneOriginal.getMousePosition() != null) {
-						tabTemp = tabbedPaneOriginal;
-					} else {
-					}
-
-					if (tabTemp == null)
-						return;
-					JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-					Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
-
-					if (tabTemp != null && canvasOrUpperNodeCanvas instanceof Canvas groupNodeCanvas) {
-
-						control.paste(groupNodeCanvas.getGroupNode(), canvasOrUpperNodeCanvas.getMousePosition());
-						control.calculateStateAndVisualForCurrentTimeStep();
-						scrollPane.getViewport().getComponent(0).repaint();
-					} else {
-						control.paste(null, canvas.getMousePosition());
-						control.calculateStateAndVisualForCurrentTimeStep();
-						log.info("canvas.repaint2");
-						canvas.repaint();
-					}
-				} catch (HeadlessException | JsonParseException | UnsupportedFlavorException | IOException e1) {
-					JLabel message = new JLabel("The Clipboard information cannot be pasted into Application.");
-					JOptionPane.showMessageDialog(holegJFrame, message, "", JOptionPane.ERROR_MESSAGE);
-				}
-
+				//TODO(Tom2022-01-27): Paste
 			}
 		};
 		actionMap.put(cntrlVDown, controlV);
@@ -658,8 +539,11 @@ public class GUI {
 					/**
 					 * set local graph Period
 					 */
-					if (e.getKeyCode() == KeyEvent.VK_ENTER)
-						unitGraph.setLocalPeriod(localLength);
+					if (e.getKeyCode() == KeyEvent.VK_ENTER){
+						LocalMode.Period period = new LocalMode.Period(localLength);
+						period.setInterval(localLength);
+						unitGraph.setPeriod(period);
+					}
 				} catch (NumberFormatException ex) {
 					unitGraphLocalPeriod.setBackground(ColorPreference.GUI.PALE_RED);
 				}
@@ -693,7 +577,7 @@ public class GUI {
 					for (Category cat : GuiSettings.getCategories()) {
 						for (AbstractCanvasObject cps : cat.getObjects()) {
 							if (value.toString().equals(cps.getName())) {
-								imgR = Import.loadImage(cps.getImage(), 50, 50);
+								imgR = Import.loadImage(cps.getImagePath(), 50, 50);
 								if (imgR != null) {
 									label.setIcon(new ImageIcon(imgR));
 								}
@@ -815,12 +699,7 @@ public class GUI {
 								h = new HolonSwitch(sw);
 							}
 							h.setPosition(x, y);
-
-							/**
-							 * close UpperNodeTabs of replaced UpperNode
-							 */
-							//TODO(Tom2022-01-14): replacement with upperNode
-							control.addObjectInGroupNode(h, groupNodeCanvas.getGroupNode());
+							control.addObjectCanvas(model.getCanvas(), h);
 
 							/**
 							 * object would be replaced
@@ -845,7 +724,8 @@ public class GUI {
 							/**
 							 * close UpperNodeTabs of replaced UpperNode
 							 */
-							control.addObjectCanvas(h);
+							//TODO(Tom2022-01-27):
+							control.addObjectCanvas(model.getCanvas(), h);
 							/**
 							 * no object should get replaced
 							 */
@@ -893,12 +773,12 @@ public class GUI {
 						for (Category cat : GuiSettings.getCategories()) {
 							for (AbstractCanvasObject cps : cat.getObjects()) {
 								if (actualObjectClicked.equals(cps.getName())) {
-									File checkPath = new File(cps.getImage());
+									File checkPath = new File(cps.getImagePath());
 									if (checkPath.exists()) {
-										img = new ImageIcon(cps.getImage()).getImage().getScaledInstance(32, 32,
+										img = new ImageIcon(cps.getImagePath()).getImage().getScaledInstance(32, 32,
 												java.awt.Image.SCALE_SMOOTH);
 									} else {
-										img = Import.loadImage(cps.getImage(), 32, 32);
+										img = Import.loadImage(cps.getImagePath(), 32, 32);
 									}
 									tempCps = cps;
 									dragging = true;
@@ -1075,87 +955,35 @@ public class GUI {
 			elementGraph.setText("None");
 			log.info("canvas.repaint7");
 			canvas.repaint();
-			IdCounter.resetObjectCounter(CounterType.Object);
-			IdCounter.resetObjectCounter(CounterType.Element);
+			IdCounter.reset();
+			IdCounter.reset();
 			control.calculateStateAndVisualForCurrentTimeStep();
 		});
 
-		mntmOpen.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				menuFileExitActionPerformed();
-			}
-
-			private void menuFileExitActionPerformed() {
-				JFileChooser fileChooser = new JFileChooser();
-				fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir") + "/exampleNetworks/"));
-				FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon");
-				fileChooser.setFileFilter(holonFilter);
-
-				if (fileChooser.showOpenDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) {
-					File file = fileChooser.getSelectedFile();
-
-					try {
-						while (tabbedPaneInnerOriginal.getTabCount() > 1) {
-							tabbedPaneInnerOriginal.remove(1);
-						}
-						GuiSettings.getSelectedObjects().clear();
-						control.loadFile(file.getAbsolutePath());
-						log.info("canvas.repaint8");
-						canvas.repaint();
-						categoryTree.repaint();
-						control.calculateStateAndVisualForCurrentTimeStep();
-					} catch (IOException | ArchiveException e) {
-						e.printStackTrace();
-						JLabel message = new JLabel("The savefile is corrupt and cannot be opened.");
-						JOptionPane.showMessageDialog(holegJFrame, message, "", JOptionPane.ERROR_MESSAGE);
-					}
-				}
+		mntmOpen.addActionListener(clicked -> {
+			if(safeLoadFileChooser.showOpenDialog(this.holegJFrame) == JFileChooser.APPROVE_OPTION){
+				control.loadFile(safeLoadFileChooser.getSelectedFile());
+				//TODO(Tom2022-01-27): make better
+				this.canvas.setGroupNode(control.getModel().getCanvas());
+				this.canvas.repaint();
 			}
 		});
 
-		mntmSave.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				menuSaveActionPerformed();
-			}
 
-			private void menuSaveActionPerformed() {
-				JFileChooser fileChooser = new JFileChooser();
-				FileNameExtensionFilter holonFilter = new FileNameExtensionFilter("Holon Save File(*.holon)", "holon");
-				fileChooser.setFileFilter(holonFilter);
-
-				if (fileChooser.showSaveDialog(holegJFrame) == JFileChooser.APPROVE_OPTION) {
-					File selectedFile = fileChooser.getSelectedFile();
-					String fileName = selectedFile.getName();
-					String fullPath = fileChooser.getSelectedFile().getPath();
-					if (fileChooser.getFileFilter().equals(holonFilter)) {
-						if (!fileName.contains("."))
-							fullPath += ".holon";
-					}
-					if (!fullPath.endsWith(".holon")) {
-						String suffix = fullPath.substring(fullPath.lastIndexOf("."), fullPath.length());
-						String[] options = new String[] { "keep .holon", "use " + suffix };
 
-						JLabel message = new JLabel(
-								"Are you sure to use the extension \"" + suffix + "\" instead of \".holon\"?");
 
-						int response = JOptionPane.showOptionDialog(holegJFrame, message, "",
-								JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
-
-						if (response == 0)
-							fullPath = fullPath.replace(suffix, ".holon");
-					}
-
-					try {
-						control.saveFile(new File(fullPath).getAbsolutePath());
-					} catch (IOException | ArchiveException e) {
-						e.printStackTrace();
-					}
+		mntmSave.addActionListener(clicked -> {
+			log.info("Save Button Pressed");
+			if(safeLoadFileChooser.showSaveDialog(this.holegJFrame) == JFileChooser.APPROVE_OPTION){
+				String path = safeLoadFileChooser.getSelectedFile().getPath();
+				if(!path.endsWith(".json")){
+					path += ".json";
 				}
+				control.saveFile(new File(path));
 			}
 		});
 
+
 		mntmUndo.addActionListener(new ActionListener() {
 			@Override
 			public void actionPerformed(ActionEvent evt) {
@@ -1163,17 +991,17 @@ public class GUI {
 			}
 
 			private void menuUndoActionPerformed() {
-				try {
-					control.loadAutoSave(control.getUndoSave());
-
-					closeInvalidUpperNodeTabs();
-
-					control.calculateStateAndVisualForCurrentTimeStep();
-					log.info("canvas.repaint9");
-					canvas.repaint();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
+//				try {
+//					control.loadAutoSave(control.getUndoSave());
+//
+//					closeInvalidUpperNodeTabs();
+//
+//					control.calculateStateAndVisualForCurrentTimeStep();
+//					log.info("canvas.repaint9");
+//					canvas.repaint();
+//				} catch (IOException e) {
+//					e.printStackTrace();
+//				}
 			}
 		});
 
@@ -1184,17 +1012,17 @@ public class GUI {
 			}
 
 			private void menuRedoActionPerformed() {
-				try {
-					control.loadAutoSave(control.getRedoSave());
-
-					closeInvalidUpperNodeTabs();
-
-					control.calculateStateAndVisualForCurrentTimeStep();
-					log.info("canvas.repaint10");
-					canvas.repaint();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
+//				try {
+//					control.loadAutoSave(control.getRedoSave());
+//
+//					closeInvalidUpperNodeTabs();
+//
+//					control.calculateStateAndVisualForCurrentTimeStep();
+//					log.info("canvas.repaint10");
+//					canvas.repaint();
+//				} catch (IOException e) {
+//					e.printStackTrace();
+//				}
 			}
 		});
 
@@ -1244,10 +1072,10 @@ public class GUI {
 
 		holegJFrame.getContentPane().add(timePanel, BorderLayout.SOUTH);
 
-		try {
-			control.loadAutoSave(System.getProperty("user.home") + "/.config/HolonGUI/Category/Category.json");
-		} catch (IOException e1) {
-		}
+//		try {
+//			control.loadAutoSave(System.getProperty("user.home") + "/.config/HolonGUI/Category/Category.json");
+//		} catch (IOException e1) {
+//		}
 
 		canvasSP.addComponentListener(new ComponentAdapter() {
 			@Override
@@ -1265,6 +1093,17 @@ public class GUI {
 		//TODO(Tom2022-01-14): recreateTryToAlignObjects
 	}
 
+	private JFileChooser initSaveLoadFileChooser(){
+		JFileChooser safeLoadFileChooser = new JFileChooser(Preferences.userRoot().absolutePath());
+		safeLoadFileChooser.setFileFilter(new FileNameExtensionFilter("Holeg json files", "json"));
+		safeLoadFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+		safeLoadFileChooser.setAcceptAllFileFilterUsed(false);
+		return safeLoadFileChooser;
+	}
+
+
+
+
 	private void initWindowMenu() {
 		menuBar.add(menuWindow);
 		// Algo
@@ -1295,27 +1134,6 @@ public class GUI {
 		menuWindow.add(openFlexMenuItem);
 	}
 
-	private boolean isUpperPanelInsideBounds() {
-		int x = holegJFrame.getX();
-		int y = holegJFrame.getY();
-		int width = holegJFrame.getWidth();
-
-		// get all connected screen devices
-		GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
-		boolean isUpperPanelVisible = false;
-
-		// and check whether they contain the upper left or upper right point of
-		// the frame
-		for (GraphicsDevice device : screenDevices) {
-			Rectangle bounds = device.getDefaultConfiguration().getBounds();
-			if (bounds.contains(x, y) || bounds.contains(x + width, y)) {
-				isUpperPanelVisible = true;
-				break;
-			}
-		}
-
-		return isUpperPanelVisible;
-	}
 
 	/**
 	 * reloads the Categories from Model.

+ 1 - 2
src/holeg/ui/view/main/Main.java

@@ -4,7 +4,7 @@ import javax.swing.*;
 
 import holeg.ui.controller.Control;
 import holeg.ui.controller.IndexTranslator;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 
 import java.awt.*;
 import java.io.FileInputStream;
@@ -43,7 +43,6 @@ public class Main {
             Model model = new Model();
             Control control = new Control(model);
             GUI view = new GUI(control);
-            IndexTranslator.model = model;
             view.setVisible(true);
         });
     }

+ 9 - 13
src/holeg/ui/view/window/FlexWindow.java

@@ -58,7 +58,7 @@ import holeg.model.HolonObject;
 import holeg.preferences.ColorPreference;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.image.Import;
 import holeg.utility.listener.WindowClosingListener;
 
@@ -248,19 +248,16 @@ public class FlexWindow extends JFrame {
 
 
 	private String createToolTipp(Flexibility actual) {
-		String tooltipString = "<html>" +
+		return "<html>" +
 	"<b>" + actual.name + "( </b>" + actual.getElement().getName() + "<b> )</b><br>"
-	+ ((actual.remainingDuration() != 0)?"<i>Remaining Duration:"+ actual.remainingDuration()+"</i><br>":"") 
+	+ ((actual.remainingDuration() != 0)?"<i>Remaining Duration:"+ actual.remainingDuration()+"</i><br>":"")
 	+ ((actual.remainingTimeTillActivation() != 0)?"<i>Remaining TimeTillActivation:"+ actual.remainingTimeTillActivation()+"</i><br>":"")
 	+ "Duration: " + actual.getDuration()  + "<br>"
 	+ "Cooldown: " + actual.getCooldown() + "<br>"
-	//+ "Speed: " + actual.speed + "<br>"
 	+ "Cost: " + actual.cost + "<br>"
 	+ "EnergyReleased: " + actual.energyReleased() + "<br>"
-	+ "Constrains: " + actual.constrainList.stream().map(constrain -> constrain.getName()).collect(Collectors.joining( "," )) + "<br>"
+	+ "Constrains: " + actual.constrainList.stream().map(Constrain::getName).collect(Collectors.joining( "," )) + "<br>"
 	+ "</html>";
-		
-		return tooltipString;
 	}
 
 
@@ -418,7 +415,7 @@ public class FlexWindow extends JFrame {
 
 
 	private void expandTreeHolonObject(HolonObject hObject, DefaultMutableTreeNode root) {
-		hObject.getElements().forEach(hE -> {
+		hObject.elementsStream().forEach(hE -> {
 			DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(new ElementInfo(hE));
 			expandTreeFlex(hE, newChild);
 			root.add(newChild);			
@@ -448,7 +445,7 @@ public class FlexWindow extends JFrame {
 		Flexibility toDeleteFlex =(Flexibility) JOptionPane.showInputDialog(this, "Select to Delete Flexibility:", "Flexibility?",  JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , allFlexes, "");
 		if(toDeleteFlex != null) {
 			toDeleteFlex.getElement().flexList.remove(toDeleteFlex);
-			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration());
+			control.calculateStateOnlyForCurrentTimeStep();
 			updateSelectedPanel();
 		}
 	}
@@ -494,14 +491,14 @@ public class FlexWindow extends JFrame {
 		JComboBox<HolonObject> holonObjectSelector = new JComboBox<HolonObject>(comboBoxModel);
 		holonObjectSelector.setBounds(10,30, 800, 30);
 		
-		DefaultComboBoxModel<HolonElement> comboBoxModelElements = new DefaultComboBoxModel<HolonElement>( holonObjects[0].getElements().toArray(size -> new HolonElement[size]));
+		DefaultComboBoxModel<HolonElement> comboBoxModelElements = new DefaultComboBoxModel<HolonElement>( holonObjects[0].elementsStream().toArray(size -> new HolonElement[size]));
 		JComboBox<HolonElement> holonElementSelector  = new JComboBox<HolonElement>(comboBoxModelElements);
 		holonElementSelector.setBounds(10,80, 800, 30);
 		
 		
 		holonObjectSelector.addItemListener(aListener -> {
 			if(aListener.getStateChange() == ItemEvent.SELECTED) {
-				DefaultComboBoxModel<HolonElement> newComboBoxModelElements = new DefaultComboBoxModel<HolonElement>( ((HolonObject) aListener.getItem()).getElements().toArray(size -> new HolonElement[size]));
+				DefaultComboBoxModel<HolonElement> newComboBoxModelElements = new DefaultComboBoxModel<HolonElement>( ((HolonObject) aListener.getItem()).elementsStream().toArray(size -> new HolonElement[size]));
 				holonElementSelector.setModel(newComboBoxModelElements);
 			}
 		});
@@ -662,8 +659,7 @@ public class FlexWindow extends JFrame {
 			this.offConstrain = offConstrainCheckBox.isSelected();
 			
 			
-			//if(!model.getSelectedCpsObjects().contains(holonObjectSelector.getSelectedItem()))model.getSelectedCpsObjects().add((AbstractCpsObject)holonObjectSelector.getSelectedItem());
-			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration());
+			control.calculateStateOnlyForCurrentTimeStep();
 			
 			update();
 			addDialog.dispose();

+ 1 - 1
src/holeg/ui/view/window/Outliner.java

@@ -20,7 +20,7 @@ import holeg.model.AbstractCanvasObject;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
 import holeg.model.Holon;
-import holeg.ui.model.Model;
+import holeg.model.Model;
 import holeg.ui.view.image.Import;
 import holeg.utility.listener.WindowClosingListener;