TomTroppmann 2 роки тому
батько
коміт
e8d0e4a566
38 змінених файлів з 505 додано та 860 видалено
  1. 3 3
      src/holeg/addon/RandomOfferdFlexibility.java
  2. 4 18
      src/holeg/addon/Randomizer.java
  3. 5 5
      src/holeg/addon/helper/RandomPriotity.java
  4. 26 6
      src/holeg/algorithm/binary/BaseLine.java
  5. 26 7
      src/holeg/algorithm/example/DemoAlgo.java
  6. 25 6
      src/holeg/algorithm/example/FlexExample.java
  7. 8 8
      src/holeg/algorithm/objective_function/GraphMetrics.java
  8. 3 3
      src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java
  9. 31 31
      src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java
  10. 25 31
      src/holeg/api/AlgorithmFrameworkFlex.java
  11. 10 9
      src/holeg/api/TopologieAlgorithmFramework.java
  12. 1 1
      src/holeg/connect/ConnectHandheld.java
  13. 2 2
      src/holeg/connect/ConnectPhysical.java
  14. 15 0
      src/holeg/model/AbstractCanvasObject.java
  15. 69 152
      src/holeg/model/GroupNode.java
  16. 1 0
      src/holeg/model/HolonObject.java
  17. 3 2
      src/holeg/model/HolonSwitch.java
  18. 1 1
      src/holeg/ui/controller/CanvasController.java
  19. 4 15
      src/holeg/ui/controller/ClipboardController.java
  20. 2 20
      src/holeg/ui/controller/Control.java
  21. 0 16
      src/holeg/ui/controller/MultiPurposeController.java
  22. 26 31
      src/holeg/ui/controller/NodeController.java
  23. 4 22
      src/holeg/ui/controller/ObjectController.java
  24. 2 4
      src/holeg/ui/controller/SaveController.java
  25. 4 4
      src/holeg/ui/controller/SimulationManager.java
  26. 42 0
      src/holeg/ui/model/GuiSettings.java
  27. 27 0
      src/holeg/ui/model/HolegModel.java
  28. 15 29
      src/holeg/ui/model/MinimumModel.java
  29. 19 37
      src/holeg/ui/model/Model.java
  30. 21 23
      src/holeg/ui/model/VisualRepresentationalState.java
  31. 2 11
      src/holeg/ui/view/canvas/AbstractCanvas.java
  32. 8 3
      src/holeg/ui/view/canvas/Canvas.java
  33. 24 14
      src/holeg/ui/view/canvas/GroupNodeCanvas.java
  34. 0 281
      src/holeg/ui/view/dialog/BackgroundPopUp.java
  35. 32 24
      src/holeg/ui/view/inspector/InspectorTable.java
  36. 3 23
      src/holeg/ui/view/main/GUI.java
  37. 2 2
      src/holeg/ui/view/main/Main.java
  38. 10 16
      src/holeg/ui/view/window/FlexWindow.java

+ 3 - 3
src/holeg/addon/RandomOfferdFlexibility.java

@@ -41,7 +41,7 @@ import holeg.ui.controller.Control;
 
 
 public class RandomOfferdFlexibility implements AddOn {
-	private static final Logger LOGGER = Logger.getLogger(RandomOfferdFlexibility.class.getName());
+	private static final Logger log = Logger.getLogger(RandomOfferdFlexibility.class.getName());
 	
 	
 	
@@ -178,9 +178,9 @@ public class RandomOfferdFlexibility implements AddOn {
 		low.offer.negative.maximumOffered = low.offer.negative.actualOffered = 2000;
 		double distribution = 0.8; 
 		low.offer.updateTarget(distribution);
-		LOGGER.info("distribution:" + distribution + " Positive:" + low.offer.positive.targetOffered
+		log.info("distribution:" + distribution + " Positive:" + low.offer.positive.targetOffered
 				+ " Negative:" + low.offer.negative.targetOffered);
-		LOGGER.info("actualDistribution:" + low.offer.getActualProportion());
+		log.info("actualDistribution:" + low.offer.getActualProportion());
 		
 		
 		content.setLayout(new BorderLayout());

+ 4 - 18
src/holeg/addon/Randomizer.java

@@ -40,8 +40,6 @@ 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.GroupNode;
 import holeg.model.HolonElement;
 import holeg.model.HolonObject;
 import holeg.ui.controller.Control;
@@ -244,25 +242,13 @@ public class Randomizer implements AddOn {
 		
 		
 	}
-	
-	private void fillObjectMap(List<AbstractCanvasObject> nodes) {
-		for (AbstractCanvasObject aCps : nodes) {
-			if (aCps instanceof HolonObject hO) {
-				objectMap.put(hO, true);
-			}
-			else if(aCps instanceof GroupNode groupNpde) {
-				fillObjectMap(groupNpde.getNodes());
-			}
-			
-		}
-		
-	}
+
 	
 	public void updateFilterList() {
 		objectMap.clear();
-		if(control != null)
-			fillObjectMap(control.getModel().getObjectsOnCanvas());
-		
+		if(control != null) {
+			control.getModel().getAllHolonObjectsOnCanvas().forEach(object -> objectMap.put(object, true));
+		}
 		this.fillTablePanel();
 	}
 	

+ 5 - 5
src/holeg/addon/helper/RandomPriotity.java

@@ -12,7 +12,7 @@ import javax.swing.JSlider;
 import holeg.model.HolonElement.Priority;
 
 public class RandomPriotity extends JPanel{
-	private static final Logger LOGGER = Logger.getLogger("holeg");
+	private static final Logger log = Logger.getLogger(RandomPriotity.class.getName());
 	/**
 	 * Its like a Gradient the Values are on one Axis from Start to End:
 	 * |--start--lm--mh--he--end--|
@@ -43,27 +43,27 @@ public class RandomPriotity extends JPanel{
 			setLM(lowChanceSlider.getValue());
 			updateSliders();
 			lowChanceSlider.setToolTipText("" +((double)lowChanceSlider.getValue()/ 100.0));
-			LOGGER.info("lowChance = " +lowChanceSlider.getValue());
+			log.info("lowChance = " +lowChanceSlider.getValue());
 		});
 		mediumChanceSlider.addChangeListener(actionEvent ->{
 			if(lm + mediumChanceSlider.getValue() <= 100) setMH(lm + mediumChanceSlider.getValue());
 			else setLM(end - mediumChanceSlider.getValue());
 			updateSliders();
 			mediumChanceSlider.setToolTipText("" +((double)mediumChanceSlider.getValue()/ 100.0));
-			LOGGER.info("mediumChance = " +  mediumChanceSlider.getValue());
+			log.info("mediumChance = " +  mediumChanceSlider.getValue());
 		});
 		highChanceSlider.addChangeListener(actionEvent ->{
 			if(mh + highChanceSlider.getValue() <= 100) setHE(mh + highChanceSlider.getValue());
 			else setMH(end - highChanceSlider.getValue());
 			updateSliders();
 			highChanceSlider.setToolTipText("" +((double)highChanceSlider.getValue()/ 100.0));
-			LOGGER.info("highChance = " +highChanceSlider.getValue());
+			log.info("highChance = " +highChanceSlider.getValue());
 		});
 		essentialChanceSlider.addChangeListener(actionEvent ->{
 			setHE(end - essentialChanceSlider.getValue());
 			updateSliders();
 			essentialChanceSlider.setToolTipText("" +((double)essentialChanceSlider.getValue()/ 100.0));
-			LOGGER.info("essentialChance = " +essentialChanceSlider.getValue());
+			log.info("essentialChance = " +essentialChanceSlider.getValue());
 		});
 	}
 

+ 26 - 6
src/holeg/algorithm/binary/BaseLine.java

@@ -340,7 +340,7 @@ public class BaseLine implements AddOn {
 		objectList = new ArrayList<HolonObject>();
 		initialState = new ArrayList<Boolean>(); 
 		access= new HashMap<Integer, AccessWrapper>();
-		rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getActualTimeStep());
+		rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getObjectsInThisLayer() :model.getObjectsOnCanvas().stream(), initialState, model.getActualTimeStep());
 		return initialState;
 	}
 	/**
@@ -349,8 +349,8 @@ public class BaseLine implements AddOn {
 	 * @param positionToInit
 	 * @param timeStep
 	 */
-	private void rollOutNodes(List<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
-		for(AbstractCanvasObject aCps : nodes) {
+	private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
+		nodes.forEach(aCps -> {
 			if (aCps instanceof HolonObject hO) {
 				for (HolonElement hE : hO.getElements()) {
 					positionToInit.add(hE.active);
@@ -363,11 +363,31 @@ public class BaseLine implements AddOn {
 				switchList.add(sw);
 				access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
 			}
-			else if(aCps instanceof GroupNode groupnode) {
-				rollOutNodes(groupnode.getNodes(), positionToInit ,timeStep );
+			else if(aCps instanceof GroupNode groupnode) {			
+				rollOutGroupNode(groupnode, positionToInit ,timeStep);
 			}
-		}
+		});
+
+	}
+	
+	
+	private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
+		groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
+			for (HolonElement hE : hObject.getElements()) {
+				positionToInit.add(hE.active);
+				access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
+			}
+			objectList.add(hObject);
+		});
+		groupNode.getAllSwitchObjectsRecursive().forEach(sw -> {
+			positionToInit.add(sw.getState(timeStep));
+			switchList.add(sw);
+			access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
+		});
+		
 	}
+	
+	
 	/**
 	 * To let the User See the current state without touching the Canvas.
 	 */

+ 26 - 7
src/holeg/algorithm/example/DemoAlgo.java

@@ -10,6 +10,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 import javax.swing.BorderFactory;
 import javax.swing.ImageIcon;
@@ -343,7 +344,7 @@ public class DemoAlgo implements AddOn {
 			objectList = new ArrayList<HolonObject>();
 			initialState = new ArrayList<Boolean>(); 
 			access= new HashMap<Integer, AccessWrapper>();
-			rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getActualTimeStep());
+			rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getObjectsInThisLayer() :model.getObjectsOnCanvas().stream(), initialState, model.getActualTimeStep());
 			return initialState;
 		}
 		/**
@@ -352,8 +353,8 @@ public class DemoAlgo implements AddOn {
 		 * @param positionToInit
 		 * @param timeStep
 		 */
-		private void rollOutNodes(List<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
-			for(AbstractCanvasObject aCps : nodes) {
+		private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
+			nodes.forEach(aCps -> {
 				if (aCps instanceof HolonObject hO) {
 					for (HolonElement hE : hO.getElements()) {
 						positionToInit.add(hE.active);
@@ -366,10 +367,28 @@ public class DemoAlgo implements AddOn {
 					switchList.add(sw);
 					access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
 				}
-				else if(aCps instanceof GroupNode groupnode) {
-					rollOutNodes(groupnode.getNodes(), positionToInit ,timeStep );
+				else if(aCps instanceof GroupNode groupnode) {			
+					rollOutGroupNode(groupnode, positionToInit ,timeStep);
 				}
-			}
+			});
+
+		}
+		
+		
+		private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
+			groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
+				for (HolonElement hE : hObject.getElements()) {
+					positionToInit.add(hE.active);
+					access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
+				}
+				objectList.add(hObject);
+			});
+			groupNode.getAllSwitchObjectsRecursive().forEach(sw -> {
+				positionToInit.add(sw.getState(timeStep));
+				switchList.add(sw);
+				access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
+			});
+			
 		}
 		/**
 		 * To let the User See the current state without touching the Canvas.
@@ -415,7 +434,7 @@ public class DemoAlgo implements AddOn {
 			for (AbstractCanvasObject aCps : listToSearch) {
 				if (aCps instanceof HolonObject hO) listToAdd.add(hO);
 				else if(aCps instanceof GroupNode groupNode) {
-					addObjectToList(groupNode.getNodes(),listToAdd);
+					listToAdd.addAll(groupNode.getAllHolonObjectsRecursive().toList());
 				}
 			}
 		}

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

@@ -13,6 +13,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.swing.BorderFactory;
 import javax.swing.ImageIcon;
@@ -466,7 +467,7 @@ public class FlexExample implements AddOn {
 			objectList = new ArrayList<HolonObject>();
 			initialState = new ArrayList<Boolean>();
 			access= new HashMap<Integer, AccessWrapper>();
-			rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getActualTimeStep());			
+			rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getObjectsInThisLayer() :model.getObjectsOnCanvas().stream(), initialState, model.getActualTimeStep());			
 			resetChain.add(initialState); 
 			return initialState;
 		}
@@ -476,8 +477,8 @@ public class FlexExample implements AddOn {
 		 * @param positionToInit
 		 * @param timeStep
 		 */
-		private void rollOutNodes(List<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
-			for(AbstractCanvasObject aCps : nodes) {
+		private void rollOutNodes(Stream<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
+			nodes.forEach(aCps -> {
 				if (aCps instanceof HolonObject hO) {
 					for (HolonElement hE : hO.getElements()) {
 						positionToInit.add(hE.active);
@@ -490,10 +491,28 @@ public class FlexExample implements AddOn {
 					switchList.add(sw);
 					access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
 				}
-				else if(aCps instanceof GroupNode groupnode) {
-					rollOutNodes(groupnode.getNodes(), positionToInit ,timeStep );
+				else if(aCps instanceof GroupNode groupnode) {			
+					rollOutGroupNode(groupnode, positionToInit ,timeStep);
 				}
-			}
+			});
+
+		}
+		
+		
+		private void rollOutGroupNode (GroupNode groupNode, List<Boolean> positionToInit, int timeStep) {
+			groupNode.getAllHolonObjectsRecursive().forEach(hObject -> {
+				for (HolonElement hE : hObject.getElements()) {
+					positionToInit.add(hE.active);
+					access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
+				}
+				objectList.add(hObject);
+			});
+			groupNode.getAllSwitchObjectsRecursive().forEach(sw -> {
+				positionToInit.add(sw.getState(timeStep));
+				switchList.add(sw);
+				access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
+			});
+			
 		}
 		/**
 		 * To let the User See the current state without touching the Canvas.

+ 8 - 8
src/holeg/algorithm/objective_function/GraphMetrics.java

@@ -19,7 +19,7 @@ import holeg.ui.model.Supplier;
 import java.util.Set;
 
 public class GraphMetrics {
-	private static final Logger LOGGER = Logger.getLogger(GraphMetrics.class.getName());
+	private static final Logger log = Logger.getLogger(GraphMetrics.class.getName());
 	
 	
 	public static class Vertex{
@@ -96,11 +96,11 @@ public class GraphMetrics {
 			AbstractCanvasObject objectA = cable.getA();
 			AbstractCanvasObject objectB = cable.getB();
 			if(objectA == null) {
-				LOGGER.warning("Edge: " + cable + "objectA == null");
+				log.warning("Edge: " + cable + "objectA == null");
 				continue;
 			}
 			if(objectB == null) {
-				LOGGER.warning("Edge: " + cable + "objectB == null");
+				log.warning("Edge: " + cable + "objectB == null");
 				continue;
 			}
 			
@@ -173,10 +173,10 @@ public class GraphMetrics {
 		 G.S[1] = new Vertex(1);
 		 G.S[2] = new Vertex(2);
 		 G.S[3] = new Vertex(3);
-		 LOGGER.info(G.toString());
-		 LOGGER.info("minimumCut: " + minimumCut(G.V, G.E));
-		 LOGGER.info("AvgShortestDistance " + averageShortestDistance(G));
-		 LOGGER.info("DisjointPath " + averageEdgeDisjointPathProblem(G));
+		 log.info(G.toString());
+		 log.info("minimumCut: " + minimumCut(G.V, G.E));
+		 log.info("AvgShortestDistance " + averageShortestDistance(G));
+		 log.info("DisjointPath " + averageEdgeDisjointPathProblem(G));
 	 }
 	 
 	 static int[][] generateDisjointWeightMatrix(Vertex[] V, Edge[] E){
@@ -435,7 +435,7 @@ public class GraphMetrics {
 			L[E[i].idA][E[i].idB] = E[i].weight;
 			L[E[i].idB][E[i].idA] = E[i].weight;
 			}catch(java.lang.NullPointerException e) {
-				LOGGER.info("E[i].idA:" + E[i].idA + " E[i].idB:" + E[i].idB + " E[i].weight:" + E[i].weight);
+				log.info("E[i].idA:" + E[i].idA + " E[i].idB:" + E[i].idB + " E[i].weight:" + E[i].weight);
 			}
 		}
 		for(int i=0;i<L.length;i++)

+ 3 - 3
src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java

@@ -11,7 +11,7 @@ import holeg.ui.model.DecoratedState;
 
 public class ObjectiveFunctionByCarlos {
 	// Parameters
-	private static final Logger LOGGER = Logger.getLogger(ObjectiveFunctionByCarlos.class.getName());
+	private static final Logger log = Logger.getLogger(ObjectiveFunctionByCarlos.class.getName());
 	// weight for f_g(H)
 	static double w_eb = .3, w_state = .3, w_pro = .2, w_perf = .1, w_holon = .1;
 	// killswitch weights
@@ -65,7 +65,7 @@ public class ObjectiveFunctionByCarlos {
 	private static void checkParameter() {
 		boolean parameterSumOne = Math.abs(w_eb + w_state + w_pro + w_perf + w_holon - 1) < 0.001;
 		if (!parameterSumOne) {
-			LOGGER.warning("ParameterError in ObjectiveFunction: w1 + w2 + w3 + w4 + w5 should be 1");
+			log.warning("ParameterError in ObjectiveFunction: w1 + w2 + w3 + w4 + w5 should be 1");
 		}
 	}
 
@@ -156,7 +156,7 @@ public class ObjectiveFunctionByCarlos {
 		double q3 = squash(f_pro, k_pro);
 		double q4 = squash(f_perf, k_perf);
 		double q5 = squash(f_holon, k_holon);
-		LOGGER.finer("f_eb= " + f_eb + " f_state= " + f_state + " f_pro= " + f_pro + " f_perf= " + f_perf + " f_holon= "
+		log.finer("f_eb= " + f_eb + " f_state= " + f_state + " f_pro= " + f_pro + " f_perf= " + f_perf + " f_holon= "
 				+ f_holon + " q1= " + q1 + " q2= " + q2 + " q3= " + q3 + " q4= " + q4 + " q5= " + q5);
 
 		return w_eb * q1 + w_state * q2 + w_pro * q3 + w_perf * q4 + w_holon * q5;

+ 31 - 31
src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java

@@ -11,7 +11,7 @@ import holeg.ui.model.DecoratedState;
 import holeg.utility.FloatLog;
 
 public class TopologieObjectiveFunction {
-	private static final Logger LOGGER = Logger.getLogger(TopologieObjectiveFunction.class.getName());
+	private static final Logger log = Logger.getLogger(TopologieObjectiveFunction.class.getName());
 	//Parameters
 	//weight for f_g(H)
 	static double w_eb = 0.2, w_max = 0.5, w_holon= 0.1, w_selection = .1, w_grid = 0.1;
@@ -70,7 +70,7 @@ public class TopologieObjectiveFunction {
 	static double range_for_k_avg_shortest_path = range(k_avg_shortest_path);
 	static double range_for_k_disjoint_path = range(k_disjoint_path - centerValue_disjoint_path);
 
-	public static FloatLog log = new FloatLog();
+	public static FloatLog averageLog = new FloatLog();
 	static boolean useLog = false;
 	static {
         //init
@@ -158,7 +158,7 @@ public class TopologieObjectiveFunction {
 			double avgShortestPath = GraphMetrics.averageShortestDistance(G);
 			//double disjpointPaths = GraphMetrics.averageEdgeDisjointPathProblem(G);
 			if(useLog) {
-				log.addSample("avgShortestPath", (float)avgShortestPath);
+				averageLog.addSample("avgShortestPath", (float)avgShortestPath);
 			}
 			f_grid += avgShortestPathPenalty(avgShortestPath);// + disjoinPathPenalty(disjpointPaths);
 		}
@@ -171,16 +171,16 @@ public class TopologieObjectiveFunction {
 		if(moreInformation) {
 			printWeightedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
 			if(useLog) {
-				LOGGER.info(log.toString());
+				log.info(averageLog.toString());
 			}
 		}
 		//printUnsquashedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
 		if(useLog) {
-			log.addSample("Unsquashed f_eb", (float)f_eb);
-			log.addSample("Unsquashed f_maximum", (float)f_maximum);
-			log.addSample("Unsquashed f_holon", (float)f_holon);
-			log.addSample("Unsquashed f_selection", (float)f_selection);
-			log.addSample("Unsquashed f_grid", (float)f_grid);
+			averageLog.addSample("Unsquashed f_eb", (float)f_eb);
+			averageLog.addSample("Unsquashed f_maximum", (float)f_maximum);
+			averageLog.addSample("Unsquashed f_holon", (float)f_holon);
+			averageLog.addSample("Unsquashed f_selection", (float)f_selection);
+			averageLog.addSample("Unsquashed f_grid", (float)f_grid);
 		}
 		return (float) (w_eb * squash(f_eb, k_eb) 
 				+ w_max * squash(f_maximum, k_max) 
@@ -278,34 +278,34 @@ public class TopologieObjectiveFunction {
 	}
 	
 	static void printWeightedValues(double f_eb, double f_maximum, double f_holon, double f_selection, double f_grid){
-		 LOGGER.info("===================================================================");
-		 LOGGER.info(" f_eb: " + f_eb + ", k_eb: " + k_eb + ", w_eb: " + w_eb); 
-		 LOGGER.info(" squash(f_eb, k_eb): " + doubleToString(squash(f_eb, k_eb))); 
-		 LOGGER.info(" w_eb * squash(f_eb, k_eb): " + doubleToString(w_eb * squash(f_eb, k_eb))); 
-		 LOGGER.info("===================================================================");
-		 LOGGER.info(" f_maximum: " + f_maximum + ", k_max: " + k_max + ", w_max: " + w_max); 
-		 LOGGER.info(" squash(f_maximum, k_max): " + doubleToString(squash(f_maximum, k_max))); 
-		 LOGGER.info(" w_max * squash(f_maximum, k_max): " + doubleToString(w_max * squash(f_maximum, k_max))); 
-		 LOGGER.info("===================================================================");
-		 LOGGER.info(" f_selection: " + f_selection + ", k_selection: " + k_selection + ", w_selection: " + w_selection); 
-		 LOGGER.info(" squash(f_selection, k_selection): " + doubleToString(squash(f_selection, k_selection))); 
-		 LOGGER.info(" w_selection * squash(f_selection, k_selection): " + doubleToString(w_selection * squash(f_selection, k_selection))); 
-		 LOGGER.info("===================================================================");
-		 LOGGER.info(" f_holon: " + f_holon + ", k_holon: " + k_holon + ", w_holon: " + w_holon); 
-		 LOGGER.info(" squash(f_holon, k_holon): " + doubleToString(squash(f_holon, k_holon))); 
-		 LOGGER.info(" w_holon * squash(f_holon, k_holon): " + doubleToString(w_holon * squash(f_holon, k_holon))); 
-		 LOGGER.info("===================================================================");
-		 LOGGER.info(" f_grid: " + f_grid + ", k_grid: " + k_grid + ", w_grid: " + w_grid); 
-		 LOGGER.info(" squash(f_grid, k_grid): " + doubleToString(squash(f_grid, k_grid))); 
-		 LOGGER.info(" w_grid * squash(f_grid, k_grid): " + doubleToString(w_grid * squash(f_grid, k_grid))); 
-		 LOGGER.info("===================================================================");
+		 log.info("===================================================================");
+		 log.info(" f_eb: " + f_eb + ", k_eb: " + k_eb + ", w_eb: " + w_eb); 
+		 log.info(" squash(f_eb, k_eb): " + doubleToString(squash(f_eb, k_eb))); 
+		 log.info(" w_eb * squash(f_eb, k_eb): " + doubleToString(w_eb * squash(f_eb, k_eb))); 
+		 log.info("===================================================================");
+		 log.info(" f_maximum: " + f_maximum + ", k_max: " + k_max + ", w_max: " + w_max); 
+		 log.info(" squash(f_maximum, k_max): " + doubleToString(squash(f_maximum, k_max))); 
+		 log.info(" w_max * squash(f_maximum, k_max): " + doubleToString(w_max * squash(f_maximum, k_max))); 
+		 log.info("===================================================================");
+		 log.info(" f_selection: " + f_selection + ", k_selection: " + k_selection + ", w_selection: " + w_selection); 
+		 log.info(" squash(f_selection, k_selection): " + doubleToString(squash(f_selection, k_selection))); 
+		 log.info(" w_selection * squash(f_selection, k_selection): " + doubleToString(w_selection * squash(f_selection, k_selection))); 
+		 log.info("===================================================================");
+		 log.info(" f_holon: " + f_holon + ", k_holon: " + k_holon + ", w_holon: " + w_holon); 
+		 log.info(" squash(f_holon, k_holon): " + doubleToString(squash(f_holon, k_holon))); 
+		 log.info(" w_holon * squash(f_holon, k_holon): " + doubleToString(w_holon * squash(f_holon, k_holon))); 
+		 log.info("===================================================================");
+		 log.info(" f_grid: " + f_grid + ", k_grid: " + k_grid + ", w_grid: " + w_grid); 
+		 log.info(" squash(f_grid, k_grid): " + doubleToString(squash(f_grid, k_grid))); 
+		 log.info(" w_grid * squash(f_grid, k_grid): " + doubleToString(w_grid * squash(f_grid, k_grid))); 
+		 log.info("===================================================================");
 	}
 	static void printUnsquashedValues(double f_eb, double f_maximum, double f_holon, double f_selection, double f_grid){
 		 System.out.print(" f_eb(" + f_eb + ") ");
 		 System.out.print(" f_maximum(" + f_maximum + ") ");
 		 System.out.print(" f_holon(" + f_holon + ") ");
 		 System.out.print(" f_selection(" + f_selection + ") ");
-		 LOGGER.info(" f_grid(" + f_grid + ") ");
+		 log.info(" f_grid(" + f_grid + ") ");
 	}
 
 }

+ 25 - 31
src/holeg/api/AlgorithmFrameworkFlex.java

@@ -46,9 +46,7 @@ import javax.swing.text.NumberFormatter;
 import holeg.addon.helper.EmailNotification;
 import holeg.algorithm.objective_function.ObjectiveFunctionByCarlos;
 import holeg.algorithm.objective_function.SwitchObjectiveFunction;
-import holeg.model.AbstractCanvasObject;
 import holeg.model.Flexibility;
-import holeg.model.GroupNode;
 import holeg.model.HolonElement;
 import holeg.model.HolonObject;
 import holeg.model.HolonSwitch;
@@ -779,7 +777,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 		this.accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
 		access= new ArrayList<AccessWrapper>();
 		List<Boolean> initialState = new ArrayList<Boolean>();
-		rollOutNodes((dGroupNode != null)? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getActualTimeStep());			
+		rollOutNodes(initialState);			
 		resetChain.add(initialState);
 		if(algoUseFlexes) {		
 			List<Flexibility> flexList = model.getAllFlexibilities();
@@ -804,38 +802,34 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 	
 	
 
-	/**
-	 * Method to extract the Informations recursively out of the Model.
-	 * @param nodes
-	 * @param positionToInit
-	 * @param timeStep
-	 */
-	private void rollOutNodes(List<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
-		for(AbstractCanvasObject aCps : nodes) {
-			if (aCps instanceof HolonObject hObject) {
-				AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
-				if(this.algoUseKillSwitch) {
-					positionToInit.add(false);
-					access.add(killSwitchAccess);
-					accessKillSwitch.put(hObject, killSwitchAccess);					
-				}
-				if(this.algoUseElements) {
-					for (HolonElement hE : hObject.getElements()) {
-						positionToInit.add(hE.active);
-						access.add(new AccessWrapper(hE, killSwitchAccess));
-					}					
-				}
-			}
-			else if (aCps instanceof HolonSwitch sw && algoUseSwitches) {
-				positionToInit.add(sw.getState(timeStep));
-				access.add(new AccessWrapper(sw));
+	private void rollOutNodes(List<Boolean> positionToInit) {
+		boolean groupNodeSelected = dGroupNode != null;
+		int timeStep = control.getModel().getActualTimeStep();
+		Stream<HolonObject> holonObjects = groupNodeSelected ? dGroupNode.getModel().getAllHolonObjectsRecursive() : control.getModel().getAllHolonObjectsOnCanvas().stream();
+		Stream<HolonSwitch> holonSwitches = groupNodeSelected ? dGroupNode.getModel().getAllSwitchObjectsRecursive(): control.getModel().getAllSwitches().stream();
+		holonObjects.forEach(hObject -> {
+			AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
+			if(this.algoUseKillSwitch) {
+				positionToInit.add(false);
+				access.add(killSwitchAccess);
+				accessKillSwitch.put(hObject, killSwitchAccess);					
 			}
-			else if(aCps instanceof GroupNode groupnode) {
-				rollOutNodes(groupnode.getNodes(), positionToInit ,timeStep );
+			if(this.algoUseElements) {
+				for (HolonElement hE : hObject.getElements()) {
+					positionToInit.add(hE.active);
+					access.add(new AccessWrapper(hE, killSwitchAccess));
+				}					
 			}
-		}
+		});
+		
+		holonSwitches.forEach(sw -> {
+			positionToInit.add(sw.getState(timeStep));
+			access.add(new AccessWrapper(sw));
+		});
 	}
 	
+
+	
 	
 	
 	private RunValues getRunValuesFromActualState() {

+ 10 - 9
src/holeg/api/TopologieAlgorithmFramework.java

@@ -23,6 +23,7 @@ import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
@@ -542,7 +543,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 			executeAlgoWithParameter();
 			
 		}
-		TopologieObjectiveFunction.log.clear();
+		TopologieObjectiveFunction.averageLog.clear();
 		updateVisual();
 		runProgressbar.finishedCancel();
 		control.guiDisable(false);
@@ -731,7 +732,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 		
 		
 		List<Integer> initialState = new ArrayList<Integer>();
-		generateAccess(model.getObjectsOnCanvas(), null);			
+		generateAccess(model.getObjectsOnCanvas().stream(), null);			
 		addCables(model.getEdgesOnCanvas());
 		model.getEdgesOnCanvas().clear();
 		//New Cables
@@ -788,8 +789,8 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	 * @param positionToInit
 	 * @param timeStep
 	 */
-	private void generateAccess(List<AbstractCanvasObject> nodes, GroupNode groupnode) {
-		for(AbstractCanvasObject aCps : nodes) {
+	private void generateAccess(Stream<AbstractCanvasObject> nodes, GroupNode groupnode) {
+		nodes.forEach(aCps -> {
 			if(aCps instanceof HolonObject hO) {
 				accessIntToObject.put(++countForAccessMap, hO);
 				accessObjectToInt.put(hO, countForAccessMap);
@@ -815,9 +816,9 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 				}
 			}
 			else if(aCps instanceof GroupNode groupNode) {
-				generateAccess(groupNode.getNodes(), groupNode);
+				generateAccess(groupNode.getObjectsInThisLayer(), groupNode);
 			}
-		}
+		});
 	}
 	
 	
@@ -879,11 +880,11 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 			//If fromObject is in Group
 			if(accessGroupNode.containsKey(fromObject)) {
 				GroupNode groupnode = accessGroupNode.get(fromObject);
-				groupnode.getNodes().add(newSwitch);
+				groupnode.add(newSwitch);
 				accessSwitchGroupNode.put(newSwitch, groupnode);
 			} else if(accessGroupNode.containsKey(toObject)) {
 				GroupNode groupnode = accessGroupNode.get(toObject);
-				groupnode.getNodes().add(newSwitch);
+				groupnode.add(newSwitch);
 				accessSwitchGroupNode.put(newSwitch, groupnode);
 			}else {
 				control.getModel().getObjectsOnCanvas().add(newSwitch);		
@@ -914,7 +915,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 		//control.getModel().getObjectsOnCanvas().removeAll(switchList);
 		for(HolonSwitch hSwitch: switchList) {
 			if(this.accessSwitchGroupNode.containsKey(hSwitch)) {
-				accessSwitchGroupNode.get(hSwitch).getNodes().remove(hSwitch);
+				accessSwitchGroupNode.get(hSwitch).remove(hSwitch);
 			}
 			else {
 				control.getModel().getObjectsOnCanvas().remove(hSwitch);

+ 1 - 1
src/holeg/connect/ConnectHandheld.java

@@ -199,7 +199,7 @@ public class ConnectHandheld implements AddOn{
 			for (AbstractCanvasObject aCps : listToSearch) {
 				if (aCps instanceof HolonObject hO) listToAdd.add(hO);
 				else if(aCps instanceof GroupNode groupNode) {
-					addObjectToList(groupNode.getNodes(),listToAdd);
+					listToAdd.addAll(groupNode.getAllHolonObjectsRecursive().toList());
 				}
 			}
 		}

+ 2 - 2
src/holeg/connect/ConnectPhysical.java

@@ -469,8 +469,8 @@ public class ConnectPhysical implements AddOn{
 	private void addObjectToList(List<AbstractCanvasObject> listToSearch, List<HolonObject> listToAdd){
 		for (AbstractCanvasObject aCps : listToSearch) {
 			if (aCps instanceof HolonObject hO) listToAdd.add(hO);
-			else if(aCps instanceof GroupNode groupnode) {
-				addObjectToList(groupnode.getNodes(),listToAdd);
+			else if(aCps instanceof GroupNode groupNode) {
+				listToAdd.addAll(groupNode.getAllHolonObjectsRecursive().toList());
 			}
 		}
 	}

+ 15 - 0
src/holeg/model/AbstractCanvasObject.java

@@ -36,6 +36,9 @@ public abstract class AbstractCanvasObject {
 	Vector2Int position = new Vector2Int(0,0);
 	@Expose
 	String sav;
+	
+	
+	private GroupNode groupNode = null;
 
 	/**
 	 * Constructor for a CpsObejct with an unique ID.
@@ -48,6 +51,18 @@ public abstract class AbstractCanvasObject {
 		this.id = IdCounter.nextId(CounterType.Object);
 	}
 
+	public void setGroupNode(GroupNode groupNode) {
+		this.groupNode = groupNode;
+	}
+	
+	public GroupNode getGroupNode() {
+		return groupNode;
+	}
+	
+	public boolean isInGroupNode() {
+		return groupNode != null;
+	}
+	
 	/**
 	 * Constructor for a new CpsObject with an unique ID (This constructor
 	 * correspond to the interaction between the Categories and Canvas)-->

+ 69 - 152
src/holeg/model/GroupNode.java

@@ -1,23 +1,16 @@
 package holeg.model;
 
-import com.google.gson.annotations.Expose;
-
 import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.logging.Logger;
+import java.util.stream.Stream;
 
 public class GroupNode extends AbstractCanvasObject {
+	private static final Logger log = Logger.getLogger(AbstractCanvasObject.class.getName());
 
-	private ArrayList<AbstractCanvasObject> nodes = new ArrayList<>();
-	private HashMap<Integer, Integer> nodesIdx = new HashMap<>();
-	
-	@Expose
-	private String imgPath = "";
-	@Expose
-	private int backgroundMode = 0;
-	@Expose
-	private int backgroundWidth = 0;
-	@Expose
-	private int backgroundHeight = 0;
+	private ArrayList<HolonObject> objectList = new ArrayList<>();
+	private ArrayList<HolonSwitch> switchList = new ArrayList<>();
+	private ArrayList<Node> nodeList = new ArrayList<>();
+	private ArrayList<GroupNode> groupNodeList = new ArrayList<>();
 
 	public GroupNode(String nodeName) {
 		super(nodeName);
@@ -27,161 +20,85 @@ public class GroupNode extends AbstractCanvasObject {
 
 	@Override
 	public void initForReflection() {
+		log.info("Executed");
 		super.initForReflection();
-		nodes = new ArrayList<>();
-        nodesIdx = new HashMap<>();
-	}
-	
-	
-	
-	
-	/**
-	 * @return the nodes
-	 */
-	public ArrayList<AbstractCanvasObject> getNodes() {
-		return nodes;
-	}
-
-	/**
-	 * @param nodes
-	 *            the nodes to set
-	 */
-	public void setNodes(ArrayList<AbstractCanvasObject> nodes) {
-		this.nodes = nodes;
+		objectList = new ArrayList<>();
+		switchList = new ArrayList<>();
+		nodeList = new ArrayList<>();
+		groupNodeList = new ArrayList<>();
 	}
 
-
-	/**
-	 * @return the nodesIdx
-	 */
-	public HashMap<Integer, Integer> getNodesIdx() {
-		return nodesIdx;
-	}
-
-	/**
-	 * @param nodesIdx
-	 *            the nodesIdx to set
-	 */
-	public void setNodesIdx(HashMap<Integer, Integer> nodesIdx) {
-		this.nodesIdx = nodesIdx;
-	}
-
-	public ArrayList<AbstractCanvasObject> getNodesAndGroupnodeNodes(){
-		ArrayList<AbstractCanvasObject> nodes = new ArrayList<AbstractCanvasObject>();
-		nodes.addAll(getNodes());
-		for (AbstractCanvasObject temp : getNodes()) {
-			if(temp instanceof GroupNode groupnode) {
-				nodes.addAll(groupnode.getNodesAndGroupnodeNodes());
-			}
+	
+	public void add(AbstractCanvasObject object) {
+		if (object instanceof HolonObject hObject) {
+			objectList.add(hObject);
+		}else if(object instanceof HolonSwitch hSwitch) {
+			switchList.add(hSwitch);
+		}else if(object instanceof Node node) {
+			nodeList.add(node);
+		}else if(object instanceof GroupNode groupNode) {
+			groupNodeList.add(groupNode);
 		}
-		return nodes;
+		object.setGroupNode(this);
 	}
 	
-	
-	
-	public ArrayList<HolonObject> getNumHolonObj() {
-		ArrayList<HolonObject> onlyHolonObj = new ArrayList<HolonObject>();
-		for (AbstractCanvasObject temp : getNodes()) {
-			if (temp instanceof HolonObject hO) {
-				onlyHolonObj.add(hO);
-			}
-			if(temp instanceof GroupNode groupnode) {
-				onlyHolonObj.addAll(groupnode.getNumHolonObj());
-			}
+	public void remove(AbstractCanvasObject object) {
+		if (object instanceof HolonObject hObject) {
+			objectList.remove(hObject);
+		}else if(object instanceof HolonSwitch hSwitch) {
+			switchList.remove(hSwitch);
+		}else if(object instanceof Node node) {
+			nodeList.remove(node);
+		}else if(object instanceof GroupNode groupNode) {
+			groupNodeList.remove(groupNode);
 		}
-		return onlyHolonObj;
+		object.setGroupNode(null);
 	}
+	
 
-	public ArrayList<HolonSwitch> getNumSwitches() {
-		ArrayList<HolonSwitch> onlySwitsches = new ArrayList<HolonSwitch>();
-		for (AbstractCanvasObject temp : getNodes()) {
-			if (temp instanceof HolonSwitch sw) {
-				onlySwitsches.add(sw);
-			}
-			if(temp instanceof GroupNode groupnode) {
-				onlySwitsches.addAll(groupnode.getNumSwitches());
-			}
-		}
-		return onlySwitsches;
+	public Stream<AbstractCanvasObject> getObjectsInThisLayer() {
+		return Stream.of(objectList.stream(), switchList.stream(), nodeList.stream(), groupNodeList.stream())
+				.flatMap(s -> s);
 	}
 
-	public ArrayList<GroupNode> getNumUpperNodes() {
-		ArrayList<GroupNode> onlyUpperNodes = new ArrayList<GroupNode>();
-		for (AbstractCanvasObject temp : getNodes()) {
-			if (temp instanceof GroupNode groupnode) {
-				onlyUpperNodes.add(groupnode);
-				onlyUpperNodes.addAll(groupnode.getNumUpperNodes());
-			}
-		}
-		return onlyUpperNodes;
-	}
+	public Stream<AbstractCanvasObject> getAllObjectsRecursive() {
+		Stream<AbstractCanvasObject> objects = Stream.of(objectList.stream(), switchList.stream(), nodeList.stream())
+				.flatMap(s -> s);
+		return Stream.concat(objects,
+				groupNodeList.stream().flatMap(groupnode -> groupnode.getObjectsInThisLayer()));
 
-	public AbstractCanvasObject searchObj(int ID) {
-		AbstractCanvasObject result = null;
-		for (AbstractCanvasObject obj : getNodes()) {
-			if (obj.getId() == ID) {
-				result = obj;
-				break;
-			}
-		}
-		return result;
 	}
 
-	/**
-	 * Set the Background Image;
-	 * 
-	 * @param imagePath
-	 *            Image Path
-	 * @param mode
-	 *            Image Mode
-	 * @param width
-	 *            Image custom width
-	 * @param height
-	 *            Image custom height
-	 */
-	public void setBackgroundImage(String imagePath, int mode, int width, int height) {
-		imgPath = imagePath;
-		backgroundMode = mode;
-		backgroundWidth = width;
-		backgroundHeight = height;
+	public Stream<HolonObject> getAllHolonObjectsRecursive() {
+		return Stream.concat(objectList.stream(),
+				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllHolonObjectsRecursive()));
 	}
-
-	/**
-	 * Get the Background Image Path.
-	 * 
-	 * @return imgPath Path of the Image
-	 */
-	public String getImagePath() {
-		return imgPath;
+	public Stream<HolonSwitch> getAllSwitchObjectsRecursive() {
+		return Stream.concat(switchList.stream(),
+				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllSwitchObjectsRecursive()));
 	}
-
-	/**
-	 * Get the Background mode.
-	 * 
-	 * @return mode the mode
-	 */
-	public int getBackgroundMode() {
-		return backgroundMode;
+	public Stream<Node> getAllNodeObjectsRecursive() {
+		return Stream.concat(nodeList.stream(),
+				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllNodeObjectsRecursive()));
 	}
-
-	/**
-	 * Get the Background image Width.
-	 * 
-	 * @return mode the width of the Image
-	 */
-	public int getImageWidht() {
-		return backgroundWidth;
+	public Stream<GroupNode> getAllGroupNodeObjectsRecursive() {
+		return Stream.concat(groupNodeList.stream(),
+				groupNodeList.stream().flatMap(groupnode -> groupnode.getAllGroupNodeObjectsRecursive()));
 	}
-
-	/**
-	 * Get the Background image Height.
-	 * 
-	 * @return mode the mode
-	 */
-	public int getImageHeight() {
-		return backgroundHeight;
+	
+	public Stream<HolonObject> getHolonObjects() {
+		return objectList.stream();
 	}
-
-
-
+	
+	public Stream<HolonSwitch> getSwitches() {
+		return switchList.stream();
+	}
+	public Stream<Node> getNodes() {
+		return nodeList.stream();
+	}
+	
+	public Stream<GroupNode> getGroupNodes() {
+		return groupNodeList.stream();
+	}
+	
 }

+ 1 - 0
src/holeg/model/HolonObject.java

@@ -17,6 +17,7 @@ public class HolonObject extends AbstractCanvasObject {
     /* Array of all consumers */
     private List<HolonElement> elements = new ArrayList<HolonElement>();
     
+    
     /**
      * Constructor Set by default the name of the object equals to the category
      * name, until the user changes it.

+ 3 - 2
src/holeg/model/HolonSwitch.java

@@ -112,9 +112,9 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
 			setManualMode(true);
 		}
 		if (this.manualActive == true) {
-			setImage("/Images/switch-off.png");
+			setImage(getSwitchOpenImage());
 		} else {
-			setImage("/Images/switch-on.png");
+			setImage(getSwitchClosedImage());
 		}
 		this.manualActive = !manualActive;
 
@@ -128,6 +128,7 @@ public class HolonSwitch extends AbstractCanvasObject implements TimelineDepende
 		return "/Images/switch-off.png";
 	}
 
+	//TODO(Tom2021-12-20): remove getState timestep
 	/**
 	 * Getter for the status of the Switch at a given timestep.
 	 * 

+ 1 - 1
src/holeg/ui/controller/CanvasController.java

@@ -270,7 +270,7 @@ public class CanvasController {
 	 * @param node
 	 */
 	public void bfsNodeCleaner(GroupNode node) {
-		List<AbstractCanvasObject> objectsInGroupNode = node.getNodesAndGroupnodeNodes();
+		List<AbstractCanvasObject> objectsInGroupNode = node.getAllObjectsRecursive().toList();
 		ListIterator<Edge>  iter = model.getEdgesOnCanvas().listIterator();
 		while(iter.hasNext() ) {
 			Edge edge = iter.next();

+ 4 - 15
src/holeg/ui/controller/ClipboardController.java

@@ -79,7 +79,7 @@ public class ClipboardController {
                     store.unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
 
             if (u instanceof GroupNode groupnode) {
-                for (AbstractCanvasObject adjacent : groupnode.getNodes()) {
+                for (AbstractCanvasObject adjacent : groupnode.getObjectsInThisLayer().toList()) {
                     queue.add(adjacent);
                 }
             }
@@ -380,22 +380,11 @@ public class ClipboardController {
     void getObjectsInDepth() {
         model.getClipboradObjects().clear();
         for (AbstractCanvasObject obj : model.getSelectedObjects()) {
-            clipboadDepth(obj);
-        }
-    }
-
-    /**
-     * Get all Objects inside the Currentobject and add them into ClipboardObjects
-     */
-    private void clipboadDepth(AbstractCanvasObject obj) {
-        //modified backtracking Algorithm no True/False
-    	model.getClipboradObjects().add(obj);
-        if (obj instanceof GroupNode groupnode) {
-            for (AbstractCanvasObject abs : groupnode.getNodes()) {
-                clipboadDepth(abs);
+        	model.getClipboradObjects().add(obj);
+        	if (obj instanceof GroupNode groupnode) {
+        		groupnode.getAllObjectsRecursive().forEach(object -> model.getClipboradObjects().add(object));
             }
         }
-
     }
 
     /**

+ 2 - 20
src/holeg/ui/controller/Control.java

@@ -72,7 +72,7 @@ public class Control {
 		this.canvasController = new CanvasController(model, multiPurposeController);
 		this.globalController = new GlobalController(model);
 		this.saveController = new SaveController(model);
-		this.nodeController = new NodeController(model, canvasController, multiPurposeController);
+		this.nodeController = new NodeController(model, canvasController);
 		this.loadController = new LoadController(model, categoryController, canvasController, objectController,
 				nodeController, multiPurposeController);
 		this.simulationManager = new SimulationManager(model);
@@ -138,15 +138,6 @@ public class Control {
 		return multiPurposeController.searchByID(id);
 	}
 
-	/**
-	 * Search for Object by ID in upperNode
-	 *
-	 * @param id the id of the Object
-	 * @return the CpsObject
-	 */
-	public AbstractCanvasObject searchByIDUpperNode(int id, GroupNode upperNode) {
-		return multiPurposeController.searchByIDUpperNode(id, upperNode);
-	}
 
 	public AbstractCanvasObject searchTracked(int id) {
 		return multiPurposeController.searchByID(id);
@@ -676,7 +667,7 @@ public class Control {
 	 * Controlling Nodes of Nodes
 	 */
 
-	public void addUpperNode(String nodeName, GroupNode upperNode, ArrayList<AbstractCanvasObject> toGroup) {
+	public void addUpperNode(String nodeName, GroupNode upperNode, List<AbstractCanvasObject> toGroup) {
 		nodeController.doUpperNode(nodeName, upperNode, toGroup);
 		tryAutoSave();
 	}
@@ -711,15 +702,6 @@ public class Control {
 		tryAutoSave();
 	}
 
-	/**
-	 * Get the number of HolonObjects in the given List
-	 *
-	 * @param list
-	 */
-	public int getNumberHolonObjects(ArrayList<AbstractCanvasObject> list) {
-		return objectController.getNumberHolonObjects(list);
-	}
-
 
 	/**
 	 * Copy all Selected Objects.

+ 0 - 16
src/holeg/ui/controller/MultiPurposeController.java

@@ -5,7 +5,6 @@ import java.util.Map.Entry;
 
 import holeg.model.AbstractCanvasObject;
 import holeg.model.Edge;
-import holeg.model.GroupNode;
 import holeg.ui.model.Model;
 import holeg.ui.view.main.Category;
 
@@ -86,21 +85,6 @@ public class MultiPurposeController {
 			return model.getObjectsOnCanvas().get(idx);
 	}
 
-	/**
-	 * 
-	 * @param upperNode
-	 * @param id
-	 * @return
-	 */
-	public AbstractCanvasObject searchByIDUpperNode(int id, GroupNode upperNode) {
-	
-		Integer idx;
-	
-		if ((idx = upperNode.getNodesIdx().get(id)) == null || upperNode.getNodesIdx().size() < 1)
-			return null;
-		else
-			return upperNode.getNodes().get(idx);
-	}
 
 
 	/**

+ 26 - 31
src/holeg/ui/controller/NodeController.java

@@ -1,6 +1,7 @@
 package holeg.ui.controller;
 
 import java.awt.*;
+import java.util.List;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -17,19 +18,17 @@ class NodeController {
 
 	private Model model;
 	private CanvasController cvs;
-	private MultiPurposeController mpC;
 	private Point point;
 
-    NodeController(Model model, CanvasController cvs, MultiPurposeController mpC) {
+    NodeController(Model model, CanvasController cvs) {
         this.model = model;
 		this.cvs = cvs;
-		this.mpC = mpC;
 	}
 
 	/**
 	 * Add a CpsUpperNode into Canvas
 	 */
-    void doUpperNode(String nodeName, GroupNode upperNode, ArrayList<AbstractCanvasObject> toGroup) {
+    void doUpperNode(String nodeName, GroupNode upperNode, List<AbstractCanvasObject> toGroup) {
 		GroupNode node = new GroupNode(nodeName);
 		node.setPosition(calculatePos(toGroup));
 		makeNodeOfNodes(node, upperNode, toGroup);
@@ -44,11 +43,11 @@ class NodeController {
 	 * Delete a CpsUpperNode from the Canvas
 	 */
     void undoUpperNode(GroupNode node, GroupNode upperNode) {
-    	if(node.getNodes().size() == 0) {
+    	if(node.getObjectsInThisLayer().findAny().isPresent()) {
     		cvs.deleteObjectOnCanvas(node);
     		return;
     	}
-		Vector2Int old = calculatePos(node.getNodes());
+		Vector2Int old = calculatePos(node.getObjectsInThisLayer().toList());
 		Vector2Int p = node.getPosition();
 		point = new Point(old.getX() - p.getX(), old.getY() - p.getY());
 
@@ -62,18 +61,17 @@ class NodeController {
 	/**
 	 * Put selected Nodes inside the Upper Node
 	 */
-	private void makeNodeOfNodes(GroupNode node, GroupNode upperNode, ArrayList<AbstractCanvasObject> toGroup) {
+	private void makeNodeOfNodes(GroupNode node, GroupNode upperNode, List<AbstractCanvasObject> toGroup) {
 	
 
 		// Put all selected Nodes into the Upper Node
         for (AbstractCanvasObject obj : toGroup) {
-            // füge Neue Objecte in Neuen Node hinzu
 			addObjectInUpperNode(obj, node, false);
 		}
 
 		for (AbstractCanvasObject abs : toGroup) {
 			if (upperNode == null)
-				removeForNodeOfNode(abs, null);
+				removeForNodeOfNode(abs);
 			else
 				removeForNodeOfNode(abs, upperNode);
 		}
@@ -94,28 +92,26 @@ class NodeController {
 				edge.getA().getConnections().remove(edge);
 		}
 
-		for (AbstractCanvasObject obj : node.getNodes()) {
+		node.getObjectsInThisLayer().forEach(obj -> {
 			updatePosition(obj, upperNode);
 			if (upperNode == null)
 				obj.setSav("CVS");
 			else
 				obj.setSav("" + upperNode.getId());
+		});
+		if (upperNode == null) {
+			model.getObjectsOnCanvas().addAll(node.getObjectsInThisLayer().toList());
+		} else {
+			node.getObjectsInThisLayer().forEach(obj -> upperNode.add(obj));
 		}
-
-		(upperNode == null ? model.getObjectsOnCanvas() : upperNode.getNodes()).addAll(node.getNodes());
-		// change the indices accordingly the higher layer
-		mpC.adjustIdx(mpC.getHighestIdx((upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx())),
-				node.getNodesIdx());
-		// add all indices of nodes into upperNode
-		(upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx()).putAll(node.getNodesIdx());
-
+		
 	}
 
 
 	/**
 	 * Just checking if an Egde already exists
 	 */
-    boolean lookforDuplicates(AbstractCanvasObject a, AbstractCanvasObject b, ArrayList<Edge> list) {
+    boolean lookforDuplicates(AbstractCanvasObject a, AbstractCanvasObject b, List<Edge> list) {
         for (Edge cpsEdge : list) {
 			if ((a.equals(cpsEdge.getA()) && b.equals(cpsEdge.getB()))
 					|| (b.equals(cpsEdge.getA()) && a.equals(cpsEdge.getB())))
@@ -141,13 +137,15 @@ class NodeController {
 	 * Removes the Given Obj from current Layer and adjusts the idx
 	 */
 	private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) {
-
-		mpC.decIdx(obj.getId(), (upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx()));
-		(upperNode == null ? model.getCvsObjIdx() : upperNode.getNodesIdx()).remove(obj.getId());
-		(upperNode == null ? model.getObjectsOnCanvas() : upperNode.getNodes()).remove(obj);
+		upperNode.remove(obj);
 	}
 
-
+	/**
+	 * Removes the Given Obj from current Layer and adjusts the idx
+	 */
+	private void removeForNodeOfNode(AbstractCanvasObject obj) {
+		model.getObjectsOnCanvas().remove(obj);
+	}
 
 
 	/**
@@ -166,8 +164,7 @@ class NodeController {
     		return;
     	}
     	object.setSav("" + upperNode.getId());
-		upperNode.getNodesIdx().put(object.getId(), upperNode.getNodes().size());
-		upperNode.getNodes().add(object);
+		upperNode.add(object);
 		
 		/**
 		 * check if we should drag & drop replace
@@ -189,7 +186,7 @@ class NodeController {
 			AbstractCanvasObject toBeReplaced = null;
 			
 			/** for each cps on Canvas */
-			for (AbstractCanvasObject cps : upperNode.getNodes()){
+			for (AbstractCanvasObject cps : upperNode.getObjectsInThisLayer().toList()){
 				
 				/** same object -> ignore */
 				if(cps == object)continue;
@@ -216,7 +213,7 @@ class NodeController {
 	/**
 	 * Delete a AbstactCpsObject from CPSUpperNode
 	 */
-    void deleteObjectInUpperNode(AbstractCanvasObject object, GroupNode upperNode) {
+    void deleteObjectInUpperNode(AbstractCanvasObject object, GroupNode groupNode) {
 		LinkedList<Edge> edgesToDelete = new LinkedList<Edge>();
 		for (Edge p : model.getEdgesOnCanvas()) {
 			if(p.isConnectedTo(object)) {
@@ -224,9 +221,7 @@ class NodeController {
 			}
 		}
 		model.getEdgesOnCanvas().removeAll(edgesToDelete);				
-		mpC.decIdx(object.getId(), upperNode.getNodesIdx());
-		upperNode.getNodesIdx().remove(object.getId());
-		upperNode.getNodes().remove(object);
+		groupNode.remove(object);
 	}
 
     /**

+ 4 - 22
src/holeg/ui/controller/ObjectController.java

@@ -3,14 +3,12 @@ package holeg.ui.controller;
 import java.util.AbstractMap.SimpleEntry;
 
 import holeg.model.AbstractCanvasObject;
-import holeg.model.GroupNode;
 import holeg.model.HolonElement;
 import holeg.model.HolonObject;
 import holeg.ui.model.Model;
-
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Optional;
+import java.util.logging.Logger;
 
 /**
  * Controller for Objects.
@@ -18,7 +16,8 @@ import java.util.Optional;
  * @author Gruppe14
  */
 public class ObjectController {
-
+	
+	private static final Logger log = Logger.getLogger(ObjectController.class.getName());
 	private Model model;
 	private MultiPurposeController mpC;
 
@@ -95,7 +94,7 @@ public class ObjectController {
 		Optional<AbstractCanvasObject> object = mpC.searchCatObj(mpC.searchCat(category), objectName);
 		object.ifPresent(obj -> ((HolonObject) obj).addElement(element));
 		if(object.isEmpty()) {
-			System.out.println(String.format("Category %s ObjectName %s element %s", category, objectName, element.getName()));
+			log.info(String.format("Category %s ObjectName %s element %s", category, objectName, element.getName()));
 			//throw new UnsupportedOperationException();
 		}
 	}
@@ -150,22 +149,5 @@ public class ObjectController {
 		model.getSelectedObjects().addAll(objects);
 	}
 
-	/**
-	 * Get the number of HolonObjects in the given List
-	 *
-	 * @param list
-	 */
-	public int getNumberHolonObjects(ArrayList<AbstractCanvasObject> list) {
-		int val = 0;
-
-		for (AbstractCanvasObject obj : list) {
-			if (obj instanceof HolonObject) {
-				val++;
-			} else if (obj instanceof GroupNode groupnode) {
-				val += getNumberHolonObjects(groupnode.getNodes());
-			}
-		}
-		return val;
-	}
 
 }

+ 2 - 4
src/holeg/ui/controller/SaveController.java

@@ -203,6 +203,7 @@ public class SaveController {
      * 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<>();
         AbstractCanvasObject u = null;
         // put all objects into queue since there is not starting object
@@ -228,10 +229,7 @@ public class SaveController {
                     unitgraphToJson(GRAPHTYPE.SWITCH, file, u.getId(), ((HolonSwitch) u).getGraphPoints());
             // if uppernode put all nodes inside the uppernode into queue
             if (u instanceof GroupNode groupnode) {
-                for (AbstractCanvasObject adjacent : groupnode.getNodes()) {
-                    queue.add(adjacent);
-                }
-
+                queue.addAll( groupnode.getObjectsInThisLayer().toList());
             }
         }
         // lastly add canvasedges into json

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

@@ -25,7 +25,7 @@ import holeg.ui.model.Model.FairnessModel;
  * @author Gruppe14
  */
 public class SimulationManager {
-	private static final Logger LOGGER = Logger.getLogger(SimulationManager.class.getName());
+	private static final Logger log = Logger.getLogger(SimulationManager.class.getName());
 	private Model model;
 	private HashMap<Integer, VisualRepresentationalState> savesVisual = new HashMap<Integer, VisualRepresentationalState>();
 	private int timeStep;
@@ -37,7 +37,7 @@ public class SimulationManager {
 	 * @param m Model
 	 */
 	public SimulationManager(Model m) {
-		LOGGER.fine("Construct SimulationManager");
+		log.fine("Construct SimulationManager");
 		model = m;
 	}
 
@@ -49,7 +49,7 @@ public class SimulationManager {
 	 * @param updateVisual Determine if the Visuals should also be calculated
 	 */
 	public void calculateStateForTimeStep(int timestep, boolean updateVisual) {
-		LOGGER.fine("Calculate");
+		log.fine("Calculate");
 		timeStep = timestep;
 		long start = System.currentTimeMillis();
 		ArrayList<MinimumNetwork> list = new ArrayList<MinimumNetwork>();
@@ -93,7 +93,7 @@ public class SimulationManager {
 			savesVisual.put(timestep, new VisualRepresentationalState(stateFromThisTimestep, minimumModel));
 		actualDecorState = Optional.of(stateFromThisTimestep);
 		long end = System.currentTimeMillis();
-		LOGGER.finer("Simulation: " + (end - start) + "ms");
+		log.finer("Simulation: " + (end - start) + "ms");
 	}
 
 	/**

+ 42 - 0
src/holeg/ui/model/GuiSettings.java

@@ -0,0 +1,42 @@
+package holeg.ui.model;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import holeg.model.AbstractCanvasObject;
+import holeg.model.Edge;
+import holeg.ui.view.main.Category;
+import holeg.utility.Vector2Int;
+
+public class GuiSettings {
+	private static final Logger log = Logger.getLogger(Model.class.getName());
+
+    private static int pictureScale = 50; // Picture Scale
+    private static int halfPictureScale = pictureScale / 2;
+    public static Vector2Int canvasSize = new Vector2Int(3000,3000);
+    
+    
+    public static int timerSpeed = 1000;
+    public static boolean showSupplyBars = true;
+    public static float maxCapacityForNewCreatedEdges = 10000;
+    
+    
+    private static Edge selectedEdge;
+    private static ArrayList<Category> categories = new ArrayList<>();
+    private static Set<AbstractCanvasObject> clipboardObjects = new HashSet<>();
+    private static Set<AbstractCanvasObject> selectedObjects = new HashSet<>();
+    
+    public int getPictureScale() {
+        return pictureScale;
+    }
+
+    public static int getPictureScaleDiv2() {
+        return halfPictureScale;
+    }
+    public static void setPictureScale(int value) {
+    	pictureScale = value;
+    	halfPictureScale = (value + 1) / 2;
+    }
+}

+ 27 - 0
src/holeg/ui/model/HolegModel.java

@@ -0,0 +1,27 @@
+package holeg.ui.model;
+
+import java.util.logging.Logger;
+
+public class HolegModel {
+	private static final Logger log = Logger.getLogger(HolegModel.class.getName());
+	
+	
+
+	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
+	}
+    private FairnessModel fairnessModel = FairnessModel.MininumDemandFirst;
+    
+    
+    
+
+}

+ 15 - 29
src/holeg/ui/model/MinimumModel.java

@@ -25,8 +25,7 @@ public class MinimumModel {
 	private ArrayList<Node> nodeList = new ArrayList<>();
 	private ArrayList<HolonSwitch> switchList = new ArrayList<>();
 	//-->Only for Visual:
-	private ArrayList<GroupNode> uppderNodeList = new ArrayList<>();
-	private HashMap<AbstractCanvasObject, GroupNode> inGroupObjects = new HashMap<>();
+	private ArrayList<GroupNode> groupNodeList = new ArrayList<>();
 	HashMap<Edge, ArrayList<GroupNode>> inGroupEdges = new HashMap<>();
 	//<--
 	
@@ -47,41 +46,31 @@ public class MinimumModel {
 			else if (aCps instanceof HolonSwitch sw) switchList.add(sw);
 			else if(aCps instanceof GroupNode groupnode) {
 				addGroupNodeObjects(groupnode, timestep);
-				uppderNodeList.add(groupnode);
+				groupNodeList.add(groupnode);
 			}
 		}
 		for (Edge edge : edgeList) {
 			this.edgeList.add(edge);
 			AbstractCanvasObject objectA = edge.getA();
 			AbstractCanvasObject objectB = edge.getB();
-			if(inGroupObjects.containsKey(objectA) || inGroupObjects.containsKey(objectB)){
-				ArrayList<GroupNode> list = new ArrayList<GroupNode>(); 
-				if(inGroupObjects.containsKey(objectA)) {
-					list.add(inGroupObjects.get(objectA));
-				}
-				if(inGroupObjects.containsKey(objectB)) {
-					list.add(inGroupObjects.get(objectB));					
-				}
-				inGroupEdges.put(edge, list);
+			ArrayList<GroupNode> list = new ArrayList<GroupNode>(); 
+			if(objectA.getGroupNode() != null) {
+				list.add(objectA.getGroupNode());
 			}
+			if(objectB.getGroupNode() != null) {
+				list.add(objectB.getGroupNode());					
+			}
+			inGroupEdges.put(edge, list);
 		}
 		//Calculate Energy of HolonObjects
 		holonObjectList.forEach(obj -> obj.calculateEnergy(timestep));
 	}
 
-	private void addGroupNodeObjects(GroupNode aUpperNode, int timestep) {
-		for(AbstractCanvasObject aCps : aUpperNode.getNodes()) {
-			if (aCps instanceof HolonObject hObject) {
-				holonObjectList.add(hObject);
-			}
-			else if (aCps instanceof Node node) nodeList.add(node);
-			else if (aCps instanceof HolonSwitch sw) switchList.add(sw);
-			else if(aCps instanceof GroupNode groupnode) {
-				addGroupNodeObjects(groupnode, timestep);
-				uppderNodeList.add(groupnode);
-			}
-			inGroupObjects.put(aCps, aUpperNode);
-		}
+	private void addGroupNodeObjects(GroupNode groupNode, int timestep) {
+		holonObjectList.addAll(groupNode.getAllHolonObjectsRecursive().toList());
+		nodeList.addAll(groupNode.getAllNodeObjectsRecursive().toList());
+		switchList.addAll(groupNode.getAllSwitchObjectsRecursive().toList());
+		groupNodeList.addAll(groupNode.getAllGroupNodeObjectsRecursive().toList());
 	}
 	
 	public ArrayList<HolonObject> getHolonObjectList() {
@@ -110,12 +99,9 @@ public class MinimumModel {
 	}
 
 	public ArrayList<GroupNode> getUppderNodeList() {
-		return uppderNodeList;
+		return groupNodeList;
 	}
 
-	public HashMap<AbstractCanvasObject, GroupNode> getInGroupObjects() {
-		return inGroupObjects;
-	}
 
 	
 }

+ 19 - 37
src/holeg/ui/model/Model.java

@@ -9,6 +9,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -35,7 +36,7 @@ import holeg.utility.Vector2Int;
  */
 public class Model {
 
-   private static final Logger LOGGER = Logger.getLogger(Model.class.getName());
+	private static final Logger log = Logger.getLogger(Model.class.getName());
     private static final int GRAPH_ITERATIONS = 100;
     // Global Variables
     // TODO(Tom2021-12-07): REMOVE
@@ -105,7 +106,7 @@ public class Model {
      */
     private ArrayList<Edge> edgesOnCanvas;
     
-    
+    //TODO(Tom2021-12-20) remove replace with groupnode
     private ArrayList<HolonObject> holonObjectsOnCanvas = new ArrayList<HolonObject>();
     private ArrayList<Node> nodesOnCanvas= new ArrayList<Node>();
     private ArrayList<HolonSwitch> switchsOnCanvas= new ArrayList<HolonSwitch>();
@@ -113,6 +114,7 @@ public class Model {
     private HashMap<Integer, GroupNode> hashcodeMap = new HashMap<>();
 
 
+    //TODO(Tom2021-12-20) should be moved in Save/Load Controller
     private Gson gson;
 
     /**
@@ -121,7 +123,7 @@ public class Model {
      * default values.
      */
     public Model() {
-    	LOGGER.fine("Init Model");
+    	log.fine("Init Model");
         setCategories(new ArrayList<>());
         setObjectsOnCanvas(new ArrayList<>());
         setEdgesOnCanvas(new ArrayList<>());
@@ -482,34 +484,32 @@ public class Model {
     
     public ArrayList<HolonObject> getAllHolonObjectsOnCanvas(){
 		ArrayList<HolonObject> objectToReturn = new ArrayList<HolonObject>();
-		getAllHolonObjectsRecursive(objectToReturn, getObjectsOnCanvas());
-    	return objectToReturn;
-    }
-    
-    private void getAllHolonObjectsRecursive(ArrayList<HolonObject> addObjectsToThisList, List<AbstractCanvasObject> listOfObjectsToSearch){
-    	for(AbstractCanvasObject aCps : listOfObjectsToSearch) {
-    		if(aCps instanceof HolonObject hO) {
-    			addObjectsToThisList.add(hO);
-    		}else if(aCps instanceof GroupNode groupnode){
-    			getAllHolonObjectsRecursive(addObjectsToThisList, groupnode.getNodes());
+		objectToReturn.addAll(this.holonObjectsOnCanvas);
+		//TODO(Tom2021-12-18) create GroupNodeOnCanvas
+		for(AbstractCanvasObject aCps : objectsOnCanvas) {
+    		if(aCps instanceof GroupNode groupnode){
+    			objectToReturn.addAll(groupnode.getAllHolonObjectsRecursive().toList());
     		}
     	}
+    	return objectToReturn;
     }
     
+
+    
     public ArrayList<AbstractCanvasObject> getAllAbstractObjectsOnCanvas(){
 		ArrayList<AbstractCanvasObject> objectToReturn = new ArrayList<AbstractCanvasObject>();
-		getAllAsbtractObjectsRecursive(objectToReturn, getObjectsOnCanvas());
+		getAllAsbtractObjectsRecursive(objectToReturn, getObjectsOnCanvas().stream());
     	return objectToReturn;
     }
-    private void getAllAsbtractObjectsRecursive(ArrayList<AbstractCanvasObject> addObjectsToThisList, List<AbstractCanvasObject> listOfObjectsToSearch){
-    	for(AbstractCanvasObject aCps : listOfObjectsToSearch) {
+    private void getAllAsbtractObjectsRecursive(ArrayList<AbstractCanvasObject> addObjectsToThisList, Stream<AbstractCanvasObject> listOfObjectsToSearch){
+    	listOfObjectsToSearch.forEach(aCps -> {
     		if(aCps instanceof GroupNode groupnode){
-    			getAllAsbtractObjectsRecursive(addObjectsToThisList, groupnode.getNodes());
+    			getAllAsbtractObjectsRecursive(addObjectsToThisList, groupnode.getObjectsInThisLayer());
     		}
     		else{
     			addObjectsToThisList.add(aCps);
     		}
-    	}
+    	});
     }
     
     
@@ -523,25 +523,7 @@ public class Model {
             if (obj instanceof HolonSwitch sw) {
                 switches.add(sw);
             } else if (obj instanceof GroupNode groupnode) {
-                getSwitchesRec(groupnode.getNodes(), switches);
-            }
-        }
-        return switches;
-    }
-
-    /**
-     * get the Amount of Switches help function
-     *
-     * @param objects  objects
-     * @param switches List of switches
-     */
-    private ArrayList<HolonSwitch> getSwitchesRec(ArrayList<AbstractCanvasObject> objects,
-                                                  ArrayList<HolonSwitch> switches) {
-        for (AbstractCanvasObject obj : objects) {
-            if (obj instanceof HolonSwitch sw) {
-                switches.add(sw);
-            } else if (obj instanceof GroupNode groupnode) {
-                getSwitchesRec(groupnode.getNodes(), switches);
+            	switches.addAll(groupnode.getAllSwitchObjectsRecursive().toList());
             }
         }
         return switches;

+ 21 - 23
src/holeg/ui/model/VisualRepresentationalState.java

@@ -59,7 +59,6 @@ public class VisualRepresentationalState {
 	
 	//Reassignments:
 	private void reassignObjects(DecoratedState stateFromThisTimestep, MinimumModel minimumModel) {
-		HashMap<AbstractCanvasObject, GroupNode> inGroupObjects = minimumModel.getInGroupObjects();
 		
 		//generate CableLookUp
 		HashMap<Edge, ArrayList<GroupNode>> inGroupEdges = minimumModel.getInGroupEdges();
@@ -75,54 +74,54 @@ public class VisualRepresentationalState {
 		//unrolling Networks
 		for(DecoratedNetwork net : stateFromThisTimestep.getNetworkList()) {
 			for(Consumer con : net.getConsumerList()) {
-				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, con.getModel(), consumerList, con);
+				DecoratedGroupNode groupNodeFromObject = addObject(con.getModel(), consumerList, con);
 				if(groupNodeFromObject != null) {
 					addToGroupNode(con, groupNodeFromObject.getConsumerList());
 				}
 				this.createdHolonObjects.put(con.getModel(), con);
 			}
 			for(Consumer con : net.getConsumerSelfSuppliedList()) {
-				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, con.getModel(), consumerList, con);
+				DecoratedGroupNode groupNodeFromObject = addObject(con.getModel(), consumerList, con);
 				if(groupNodeFromObject != null) {
 					addToGroupNode(con, groupNodeFromObject.getConsumerList());
 				}
 				this.createdHolonObjects.put(con.getModel(), con);
 			}
 			for(Supplier sup : net.getSupplierList()) {
-				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, sup.getModel(), supplierList, sup);
+				DecoratedGroupNode groupNodeFromObject = addObject(sup.getModel(), supplierList, sup);
 				if(groupNodeFromObject != null) {
 					addToGroupNode(sup, groupNodeFromObject.getSupplierList());
 				}
 				this.createdHolonObjects.put(sup.getModel(), sup);
 			}
 			for(Passiv pas : net.getPassivNoEnergyList()) {
-				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, pas.getModel(), passivList, pas);
+				DecoratedGroupNode groupNodeFromObject = addObject(pas.getModel(), passivList, pas);
 				if(groupNodeFromObject != null) {
 					addToGroupNode(pas, groupNodeFromObject.getPassivList());
 				}
 				this.createdHolonObjects.put(pas.getModel(), pas);
 			}
 			for(Edge cable : net.getDecoratedCableList()) {
-				addCable(cable, inGroupEdges, inGroupObjects,createdGroupNodes, exitCables);
+				addCable(cable, inGroupEdges,createdGroupNodes, exitCables);
 			}
 		}
 		for(Edge cable : stateFromThisTimestep.getLeftOverEdges()) {
-			addCable(cable, inGroupEdges, inGroupObjects, createdGroupNodes, exitCables);
+			addCable(cable, inGroupEdges, createdGroupNodes, exitCables);
 		}
 		for(Node node : minimumModel.getNodeList()) {
-			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, node, nodeList ,node);
+			DecoratedGroupNode groupNodeFromObject = addObject(node, nodeList ,node);
 			if(groupNodeFromObject != null) {
 				addToGroupNode(node, groupNodeFromObject.getNodeList());
 			}
 		}
 		for(DecoratedSwitch dSwitch: stateFromThisTimestep.getDecoratedSwitches()) {
-			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, dSwitch.getModel(), switchList, dSwitch);
+			DecoratedGroupNode groupNodeFromObject = addObject(dSwitch.getModel(), switchList, dSwitch);
 			if(groupNodeFromObject != null) {
 				addToGroupNode(dSwitch, groupNodeFromObject.getSwitchList());
 			}
 		}
 		for(DecoratedGroupNode dGroupNode: createdGroupNodes.values()) {
-			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, dGroupNode.getModel(), groupNodeList, dGroupNode);
+			DecoratedGroupNode groupNodeFromObject = addObject(dGroupNode.getModel(), groupNodeList, dGroupNode);
 			if(groupNodeFromObject != null) {
 				addToGroupNode(dGroupNode, groupNodeFromObject.getGroupNodeList());
 			}
@@ -263,28 +262,27 @@ public class VisualRepresentationalState {
 	}
 
 
-	private void addCable(Edge cable, HashMap<Edge, ArrayList<GroupNode>> inGroupEdges, HashMap<AbstractCanvasObject, GroupNode> inGroupObjects,
+	private void addCable(Edge cable, HashMap<Edge, ArrayList<GroupNode>> inGroupEdges,
 			HashMap<GroupNode, DecoratedGroupNode> createdGroupNodes, ArrayList<IntermediateCalculationCable> exitCables) {
 		boolean isInGroup = false;
-		if(inGroupObjects.containsKey(cable.getA())) {
+		if(cable.getA().isInGroupNode()) {
 			isInGroup = true;
 		}
-		if(inGroupObjects.containsKey(cable.getB())) {
+		if(cable.getB().isInGroupNode()) {
 			isInGroup = true;
 		}
 		if(isInGroup) {
 			
-			boolean isIntern = inGroupObjects.get(cable.getA()) == inGroupObjects.get(cable.getB()); //Case null == null is not possible trough before Filtering MinimumModel#addUpperObjects(CpsUpperNode)
+			boolean isIntern = cable.getA().getGroupNode() == cable.getB().getGroupNode(); //Case null == null is not possible trough before Filtering MinimumModel#addUpperObjects(CpsUpperNode)
 			if(isIntern) {
-				DecoratedGroupNode groupNodeFromBoth = createdGroupNodes.get(inGroupObjects.get(cable.getA()));
+				DecoratedGroupNode groupNodeFromBoth = createdGroupNodes.get(cable.getA().getGroupNode());
 				groupNodeFromBoth.getInternCableList().add(cable);				
 			}else {
-				if(inGroupObjects.containsKey(cable.getA())) {
-					exitCables.add(new IntermediateCalculationCable(cable, inGroupObjects.get(cable.getA()),inGroupObjects.get(cable.getB()), cable.getA(), cable.getB()));
-				} else if(inGroupObjects.containsKey(cable.getB())) {
-					exitCables.add(new IntermediateCalculationCable(cable, inGroupObjects.get(cable.getB()),inGroupObjects.get(cable.getA()), cable.getB(), cable.getA()));
+				if(cable.getA().isInGroupNode()) {
+					exitCables.add(new IntermediateCalculationCable(cable, cable.getA().getGroupNode(),cable.getB().getGroupNode(), cable.getA(), cable.getB()));
+				} else if(cable.getB().isInGroupNode()) {
+					exitCables.add(new IntermediateCalculationCable(cable, cable.getB().getGroupNode(),cable.getA().getGroupNode(), cable.getB(), cable.getA()));
 				}
-				
 			}
 		}else {
 			cableList.add(cable);					
@@ -326,9 +324,9 @@ public class VisualRepresentationalState {
 	
 
 	//Generics
-	private <ModelOfObject, DecoratedObject> DecoratedGroupNode addObject(HashMap<ModelOfObject, GroupNode> inGroupObjects, ModelOfObject modelOfObject, ArrayList<DecoratedObject> listToAdd, DecoratedObject object) {
-		if(inGroupObjects.containsKey(modelOfObject)) {
-			return  createdGroupNodes.get(inGroupObjects.get(modelOfObject));
+	private <DecoratedObject> DecoratedGroupNode addObject(AbstractCanvasObject modelOfObject, ArrayList<DecoratedObject> listToAdd, DecoratedObject object) {
+		if(modelOfObject.getGroupNode()  != null) {
+			return  createdGroupNodes.get(modelOfObject.getGroupNode());
 		}
 		listToAdd.add(object);
 		return null;

+ 2 - 11
src/holeg/ui/view/canvas/AbstractCanvas.java

@@ -92,7 +92,7 @@ public abstract class AbstractCanvas extends JPanel {
 	Timer animT; // animation Timer
 	int animDuration = ANIMTIME; // animation Duration
 	int animSteps = animDuration / animDelay; // animation Steps;
-	ArrayList<AbstractCanvasObject> animCps = null;
+	List<AbstractCanvasObject> animCps = null;
 	// Graphics
 	Image img = null; // Contains the image to draw on the Canvas
 	Graphics2D g2; // For Painting
@@ -258,16 +258,7 @@ public abstract class AbstractCanvas extends JPanel {
 		return false;
 	}
 
-	boolean setToolTipInfoAndPosition(boolean on, AbstractCanvasObject cps) {
-		if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
-			on = true;
-			toolTipPos.setX(cps.getPosition().getX() - controller.getScaleDiv2());
-			toolTipPos.setY(cps.getPosition().getY() + controller.getScaleDiv2());
-			toolTipText = cps.getName() + ", " + cps.getId();
-		}
 
-		return on;
-	}
 
 	abstract void drawDeleteEdge();
 
@@ -282,7 +273,7 @@ public abstract class AbstractCanvas extends JPanel {
 	 * @param y          Position of the objects that might replace
 	 * @return true if exactly one Object could be replaced
 	 */
-	protected boolean checkForReplacement(ArrayList<AbstractCanvasObject> objects, AbstractCanvasObject draggedCps,
+	protected boolean checkForReplacement(List<AbstractCanvasObject> objects, AbstractCanvasObject draggedCps,
 			int x, int y) {
 
 		/** distance treshold for replacement */

+ 8 - 3
src/holeg/ui/view/canvas/Canvas.java

@@ -153,7 +153,7 @@ public class Canvas extends AbstractCanvas implements MouseListener, MouseMotion
 			closeUpperNodeTab(upperNodeId);
 
 			savePos = new ArrayList<>();
-			animCps = ((GroupNode) tempCps).getNodes();
+			animCps = ((GroupNode) tempCps).getAllObjectsRecursive().toList();
 			controller.ungroupGroupNode((GroupNode) tempCps, groupNode);
 
 			for (int i = 0; i < animCps.size(); i++) {
@@ -822,7 +822,12 @@ public class Canvas extends AbstractCanvas implements MouseListener, MouseMotion
 				cx = cps.getPosition().getX() - controller.getScaleDiv2();
 				cy = cps.getPosition().getY() - controller.getScaleDiv2();
 
-				on = setToolTipInfoAndPosition(on, cps);
+				if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
+					on = true;
+					toolTipPos.setX(cps.getPosition().getX() - controller.getScaleDiv2());
+					toolTipPos.setY(cps.getPosition().getY() + controller.getScaleDiv2());
+					toolTipText = cps.getName() + ", " + cps.getId();
+				}
 			}
 			if (on || (!on && toolTip))
 				repaint();
@@ -870,7 +875,7 @@ public class Canvas extends AbstractCanvas implements MouseListener, MouseMotion
 							controller.addEdgeOnCanvas(e);
 						} else if (cps instanceof GroupNode groupnode && !(tempCps instanceof GroupNode)) {
 							GroupNode thisUpperNode = groupnode;
-							Object[] possibilities = thisUpperNode.getNodes().stream().map(aCps -> new ACpsHandle(aCps))
+							Object[] possibilities = thisUpperNode.getObjectsInThisLayer().map(aCps -> new ACpsHandle(aCps))
 									.filter(aCpsHandle -> !(aCpsHandle.object instanceof GroupNode)).toArray();
 							if (possibilities.length != 0) {
 								ACpsHandle selected = (ACpsHandle) JOptionPane.showInputDialog(this,

+ 24 - 14
src/holeg/ui/view/canvas/GroupNodeCanvas.java

@@ -10,6 +10,7 @@ import java.awt.event.MouseEvent;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Optional;
+import java.util.logging.Logger;
 
 import holeg.model.AbstractCanvasObject;
 import holeg.model.Edge;
@@ -33,6 +34,7 @@ import holeg.utility.Vector2Int;
 
 //TODO(Tom2021-12-1) delete GroupNodeCanvas completely and only have canvas Class
 public class GroupNodeCanvas extends Canvas {
+	private static final Logger log = Logger.getLogger(GroupNodeCanvas.class.getName());
 	private String parentPath;
 	private Component parentComponent;
 
@@ -82,8 +84,9 @@ public class GroupNodeCanvas extends Canvas {
 		if (model.getSelectedEdge() != null)
 			selectedEdges.add(model.getSelectedEdge());
 
-		Optional<VisualRepresentationalState> visState = controller.getSimManager().getActualVisualRepresentationalState();
-		if(visState.isEmpty()) {
+		Optional<VisualRepresentationalState> visState = controller.getSimManager()
+				.getActualVisualRepresentationalState();
+		if (visState.isEmpty()) {
 			return;
 		}
 		DecoratedGroupNode actualGroupNode = visState.get().getCreatedGroupNodes().get(groupNode);
@@ -168,7 +171,7 @@ public class GroupNodeCanvas extends Canvas {
 			// Object Selection
 
 			if (e.getX() > 0) {
-				for (AbstractCanvasObject cps : groupNode.getNodes()) {
+				for (AbstractCanvasObject cps : groupNode.getObjectsInThisLayer().toList()) {
 					cx = cps.getPosition().getX() - Model.getScaleDiv2();
 					cy = cps.getPosition().getY() - Model.getScaleDiv2();
 					if (x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx && y >= cy) {
@@ -176,7 +179,7 @@ public class GroupNodeCanvas extends Canvas {
 
 						dragging = true;
 						if (e.isControlDown() && tempCps != null) {
-							System.out.println("Add Remove Selection GROUPNODECANVAS");
+							log.info("Add Remove Selection GROUPNODECANVAS");
 							if (model.getSelectedObjects().contains(tempCps)) {
 								controller.removeObjectFromSelection(tempCps);
 							} else {
@@ -271,7 +274,7 @@ public class GroupNodeCanvas extends Canvas {
 				/**
 				 * check if tempCps could replace an Object on the UpperNodeanvas
 				 */
-				if (model.getSelectedObjects().size() == 1 && checkForReplacement(groupNode.getNodes(), tempCps,
+				if (model.getSelectedObjects().size() == 1 && checkForReplacement(groupNode.getObjectsInThisLayer().toList(), tempCps,
 						tempCps.getPosition().getX(), tempCps.getPosition().getY())) {
 					/**
 					 * if UpperNode would be replaced, close its tabs
@@ -327,7 +330,7 @@ public class GroupNodeCanvas extends Canvas {
 				try {
 					// tempCps in the upperNode? else its a connected Object from
 					// outside
-					if (groupNode.getNodes().contains(tempCps)) {
+					if (groupNode.getObjectsInThisLayer().anyMatch(obj -> obj.equals(tempCps))) {
 						dragged = true;
 						float xDist, yDist; // Distance
 
@@ -380,7 +383,7 @@ public class GroupNodeCanvas extends Canvas {
 					 * check if something would be replaced
 					 */
 					if (model.getSelectedObjects().size() == 1)
-						checkForReplacement(groupNode.getNodes(), tempCps, x, y);
+						checkForReplacement(groupNode.getObjectsInThisLayer().toList(), tempCps, x, y);
 
 					repaint();
 				} catch (Exception eex) {
@@ -392,7 +395,8 @@ public class GroupNodeCanvas extends Canvas {
 			// Mark Objects
 			if (doMark) {
 				tempSelected.clear();
-				for (AbstractCanvasObject cps : groupNode.getNodes()) {
+				groupNode.getObjectsInThisLayer().forEach(cps -> 
+				{
 					int x1 = sx, x2 = x, y1 = sy, y2 = y;
 
 					if (sx >= x) {
@@ -407,9 +411,8 @@ public class GroupNodeCanvas extends Canvas {
 							&& y1 <= cps.getPosition().getY() + Model.getScaleDiv2() && x2 >= cps.getPosition().getX()
 							&& y2 >= cps.getPosition().getY()) {
 						tempSelected.add(cps);
-
 					}
-				}
+				});
 				int count = 0;
 				for (Edge ed : groupNode.getConnections()) {
 					AbstractCanvasObject cps;
@@ -450,13 +453,20 @@ public class GroupNodeCanvas extends Canvas {
 			y = e.getY();
 			// Everything for the tooltip :)
 			boolean on = false;
-			for (AbstractCanvasObject cps : groupNode.getNodes()) {
+			Optional<AbstractCanvasObject> objectUnderCursor = groupNode.getObjectsInThisLayer().filter(cps -> {
 
 				cx = cps.getPosition().getX() - controller.getScaleDiv2();
 				cy = cps.getPosition().getY() - controller.getScaleDiv2();
-
-				on = setToolTipInfoAndPosition(on, cps);
-			}
+				boolean mouseOverObject = x - controller.getScale() <= cx && y - controller.getScale() <= cy && x >= cx
+						&& y >= cy;
+				return mouseOverObject;
+			}).findAny();
+			on |= objectUnderCursor.isPresent();
+			objectUnderCursor.ifPresent(cps -> {
+				toolTipPos.setX(cps.getPosition().getX() - controller.getScaleDiv2());
+				toolTipPos.setY(cps.getPosition().getY() + controller.getScaleDiv2());
+				toolTipText = cps.getName() + ", " + cps.getId();
+			});
 			int count = 0;
 			for (Edge ed : groupNode.getConnections()) {
 

+ 0 - 281
src/holeg/ui/view/dialog/BackgroundPopUp.java

@@ -1,281 +0,0 @@
-package holeg.ui.view.dialog;
-
-import javax.swing.*;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
-import holeg.model.GroupNode;
-import holeg.ui.controller.Control;
-import holeg.ui.model.Model;
-import holeg.ui.view.canvas.Canvas;
-import holeg.utility.ImageImport;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.io.*;
-
-/**
- * Popup for setting the Background Image for the current View.
- **/
-public class BackgroundPopUp extends JDialog {
-
-    // Modes
-    public static final int IMAGE_PIXELS = 0, STRETCHED = 1, CUSTOM = 2;
-    /**
-     *
-     */
-	private final JTextField textPath = new JTextField("");
-	private final JButton btnBrowse = new JButton("Browse");
-	private final JPanel panelBrowse = new JPanel();
-	private final JPanel panelOK = new JPanel();
-	private final JButton btnOK = new JButton("OK");
-	private final JLabel lblImage = new JLabel();
-	private final JButton btnCancel = new JButton("Cancel");
-	private final JPanel panelRadio = new JPanel();
-	private final JRadioButton rdbtnImagePixel = new JRadioButton("Use Image Size");
-	private final JRadioButton rdbtnStretched = new JRadioButton("Strech Image");
-	private final JRadioButton rdbtnCustom = new JRadioButton("Custom Size");
-	private final JButton removeImageBtn = new JButton("Remove Background Image");
-	private final JPanel panel = new JPanel();
-	private final JTextField imageWidth = new JTextField();
-	private final JTextField imageHeight = new JTextField();
-	JFileChooser fileChooser;
-    private JPanel panelImageRadio = new JPanel();
-    private String path = "";
-    private boolean imageChanged = false;
-    private ImageIcon icon = null;
-    private double imgScale = 1;
-    private boolean imageBtnClearedPressed = false;
-    private int mode = 0;
-
-    public BackgroundPopUp(Model model, Control controller, Canvas canvas, GroupNode uNode, JFrame parentFrame) {
-        super((java.awt.Frame) null, true);
-		getContentPane().setBackground(Color.WHITE);
-		this.setTitle("Set View Background");
-		// Show background Image
-		if (canvas != null) {
-			path = model.getCanvasImagePath();
-		} else if (uNode != null) {
-			path = uNode.getImagePath();
-		}
-		if (!path.isEmpty()) {
-			textPath.setText(path);
-			icon = new ImageIcon(path);
-			imageWidth.setText("" + icon.getIconWidth());
-			imageHeight.setText("" + icon.getIconHeight());
-		}
-		this.setIconImage(ImageImport.loadImage("/Images/Holeg.png",30,30));
-		setBounds(100, 100, 600, 340);
-        setLocationRelativeTo(parentFrame);
-
-		panelBrowse.setBorder(null);
-		panelImageRadio.setBorder(null);
-		panelOK.setBorder(null);
-		panelRadio.setBorder(null);
-
-		getContentPane().add(panelImageRadio, BorderLayout.CENTER);
-		panelImageRadio.setLayout(new BorderLayout(0, 0));
-		lblImage.setBackground(Color.WHITE);
-		lblImage.setHorizontalAlignment(SwingConstants.LEFT);
-
-		panelImageRadio.add(lblImage, BorderLayout.CENTER);
-
-		panelImageRadio.add(panelRadio, BorderLayout.EAST);
-
-		// Radio Buttons
-		panelRadio.setLayout(new GridLayout(0, 1, 0, 0));
-
-		rdbtnImagePixel.setBackground(Color.WHITE);
-		rdbtnImagePixel.setSelected(true);
-
-		panelRadio.add(rdbtnImagePixel);
-		rdbtnStretched.setBackground(Color.WHITE);
-
-		panelRadio.add(rdbtnStretched);
-		panelBrowse.setBackground(Color.WHITE);
-
-		ButtonGroup bgroup = new ButtonGroup();
-		bgroup.add(rdbtnImagePixel);
-		bgroup.add(rdbtnStretched);
-		panelRadio.add(rdbtnCustom);
-		rdbtnCustom.setBackground(Color.white);
-		bgroup.add(rdbtnCustom);
-		panel.setBackground(Color.WHITE);
-
-		panelRadio.add(panel);
-		panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
-		panel.add(imageWidth);
-		imageWidth.setColumns(10);
-		panel.add(imageHeight);
-		imageHeight.setColumns(10);
-
-		// remove BackgroundImage Button
-		removeImageBtn.setBackground(Color.WHITE);
-		removeImageBtn.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				path = "";
-				textPath.setText("");
-				imageBtnClearedPressed = true;
-				lblImage.setIcon(null);
-			}
-		});
-		JPanel removePanel = new JPanel();
-		removePanel.add(removeImageBtn);
-		removePanel.setBackground(Color.WHITE);
-		panelRadio.add(removePanel);
-
-		// Browse Panel
-		getContentPane().add(panelBrowse, BorderLayout.NORTH);
-		panelBrowse.setLayout(new BorderLayout(0, 0));
-		panelBrowse.add(btnBrowse, BorderLayout.WEST);
-
-		// Browse Row Functions
-		btnBrowse.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				fileChooser = new JFileChooser();
-				FileNameExtensionFilter filter = new FileNameExtensionFilter("png, jpg or jpeg", "png", "jpg", "jpeg");
-				fileChooser.setFileFilter(filter);
-				if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
-					path = fileChooser.getSelectedFile().getPath();
-					textPath.setText(path);
-					icon = new ImageIcon(textPath.getText());
-					imageWidth.setText("" + icon.getIconWidth());
-					imageHeight.setText("" + icon.getIconHeight());
-
-					imageChanged = true;
-
-					// Calculate the Image scale to fit the Panel
-					if (Math.min(panelImageRadio.getWidth() - panelRadio.getWidth(),
-							panelImageRadio.getHeight()) == (panelImageRadio.getWidth() - panelRadio.getWidth())) {
-						imgScale = (double) Math.min(icon.getIconWidth(), icon.getIconHeight())
-								/ panelImageRadio.getWidth();
-					} else {
-						imgScale = (double) Math.min(icon.getIconWidth(), icon.getIconHeight())
-								/ panelImageRadio.getHeight();
-					}
-
-					lblImage.setIcon(new ImageIcon(
-							new ImageIcon(path).getImage().getScaledInstance((int) (icon.getIconWidth() / imgScale),
-									(int) (icon.getIconHeight() / imgScale), java.awt.Image.SCALE_FAST)));
-				}
-			}
-		});
-		textPath.setEditable(false);
-
-		panelBrowse.add(textPath, BorderLayout.CENTER);
-		textPath.setColumns(20);
-		panelOK.setBackground(Color.WHITE);
-
-		getContentPane().add(panelOK, BorderLayout.SOUTH);
-		panelOK.add(btnOK);
-		btnOK.addActionListener(new ActionListener() {
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				// picture selected?
-				if (!path.isEmpty()) {
-					if (rdbtnImagePixel.isSelected()) {
-						mode = 0;
-					} else if (rdbtnStretched.isSelected()) {
-						mode = 1;
-					} else if (rdbtnCustom.isSelected()) {
-						mode = 2;
-					}
-
-					if (canvas != null) {
-						if (imageChanged) {
-							copieImage();
-						}
-						controller.setBackgroundImage(path, mode, Integer.parseInt(imageWidth.getText()),
-								Integer.parseInt(imageHeight.getText()));
-						canvas.repaint();
-					} else if (uNode != null) {
-						if (imageChanged) {
-							copieImage();
-						}
-						uNode.setBackgroundImage(path, mode, Integer.parseInt(imageWidth.getText()),
-								Integer.parseInt(imageHeight.getText()));
-					}
-					dispose();
-				} else if (imageBtnClearedPressed) {
-					if (canvas != null) {
-						controller.setBackgroundImage(path, mode, Integer.parseInt(imageWidth.getText()),
-								Integer.parseInt(imageHeight.getText()));
-						canvas.repaint();
-					} else if (uNode != null) {
-						uNode.setBackgroundImage(path, mode, Integer.parseInt(imageWidth.getText()),
-								Integer.parseInt(imageHeight.getText()));
-					}
-					dispose();
-				} else {
-					JOptionPane.showMessageDialog(null, "No image selected!", "Warning!", JOptionPane.WARNING_MESSAGE);
-				}
-			}
-		});
-
-		panelOK.add(btnCancel);
-		btnCancel.addActionListener(new ActionListener() {
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				dispose();
-			}
-		});
-		this.addComponentListener(new ComponentAdapter() {
-			@Override
-			public void componentResized(ComponentEvent e) {
-				if (icon != null) {
-					// Calculate the Image scale to fit the Panel
-					if (Math.min(panelImageRadio.getWidth() - panelRadio.getWidth(),
-							panelImageRadio.getHeight()) == (panelImageRadio.getWidth() - panelRadio.getWidth())) {
-						imgScale = (double) Math.min(icon.getIconWidth(), icon.getIconHeight())
-								/ panelImageRadio.getWidth();
-					} else {
-						imgScale = (double) Math.min(icon.getIconWidth(), icon.getIconHeight())
-								/ panelImageRadio.getHeight();
-					}
-
-					lblImage.setIcon(new ImageIcon(
-							new ImageIcon(path).getImage().getScaledInstance((int) (icon.getIconWidth() / imgScale),
-									(int) (icon.getIconHeight() / imgScale), java.awt.Image.SCALE_SMOOTH)));
-				}
-			}
-		});
-	}
-
-	protected void copieImage() {
-		InputStream inStream = null;
-		OutputStream outStream = null;
-		try {
-			File source = new File(path);
-			File dest = new File(System.getProperty("user.home") + "/HolonGUI/BackgroundImages/");
-			dest.mkdirs();
-			dest = new File(dest, source.getName());
-			path = "" + dest;
-
-			inStream = new FileInputStream(source);
-			outStream = new FileOutputStream(dest);
-			byte[] buffer = new byte[1024];
-
-			int length;
-			while ((length = inStream.read(buffer)) > 0) {
-				outStream.write(buffer, 0, length);
-			}
-
-			if (inStream != null)
-				inStream.close();
-			if (outStream != null)
-				outStream.close();
-
-		} catch (IOException eex) {
-			eex.printStackTrace();
-		}
-	}
-}

+ 32 - 24
src/holeg/ui/view/inspector/InspectorTable.java

@@ -78,9 +78,10 @@ public class InspectorTable extends JPanel {
 	private ArrayList<SortButton<ElementRow>> headerButtonList = new ArrayList<>();
 	private final static NumberFormatter doubleFormatter = generateNumberFormatter();
 
-	//sorting
-	private Comparator<ElementRow> actual_comp = (ElementRow a, ElementRow b) -> Float.compare(a.element.getEnergy(), b.element.getEnergy());
-	
+	// sorting
+	private Comparator<ElementRow> actual_comp = (ElementRow a, ElementRow b) -> Float.compare(a.element.getEnergy(),
+			b.element.getEnergy());
+
 	// Colors
 
 	// Events
@@ -170,14 +171,20 @@ public class InspectorTable extends JPanel {
 	}
 
 	private void initHeaderButtons() {
-		Comparator<ElementRow> objectComp = (ElementRow a, ElementRow b) -> a.element.parentObject.getName().compareTo(b.element.parentObject.getName());
-		Comparator<ElementRow> idComp = (ElementRow a, ElementRow b) -> Integer.compare(a.element.parentObject.getId(), b.element.parentObject.getId());
-		Comparator<ElementRow> deviceComp = (ElementRow a, ElementRow b) -> a.element.getName().compareTo(b.element.getName());
-		Comparator<ElementRow> energyComp = (ElementRow a, ElementRow b) -> Float.compare(a.element.getEnergy(), b.element.getEnergy());
-		Comparator<ElementRow> priorityComp = (ElementRow a, ElementRow b) -> a.element.getPriority().compareTo(b.element.getPriority());
-		Comparator<ElementRow> activeComp = (ElementRow a, ElementRow b) -> Boolean.compare(a.element.active, b.element.active);
-;
-		
+		Comparator<ElementRow> objectComp = (ElementRow a, ElementRow b) -> a.element.parentObject.getName()
+				.compareTo(b.element.parentObject.getName());
+		Comparator<ElementRow> idComp = (ElementRow a, ElementRow b) -> Integer.compare(a.element.parentObject.getId(),
+				b.element.parentObject.getId());
+		Comparator<ElementRow> deviceComp = (ElementRow a, ElementRow b) -> a.element.getName()
+				.compareTo(b.element.getName());
+		Comparator<ElementRow> energyComp = (ElementRow a, ElementRow b) -> Float.compare(a.element.getEnergy(),
+				b.element.getEnergy());
+		Comparator<ElementRow> priorityComp = (ElementRow a, ElementRow b) -> a.element.getPriority()
+				.compareTo(b.element.getPriority());
+		Comparator<ElementRow> activeComp = (ElementRow a, ElementRow b) -> Boolean.compare(a.element.active,
+				b.element.active);
+		;
+
 		headerButtonList.add(new SortButton<ElementRow>("Object", objectComp));
 		headerButtonList.add(new SortButton<ElementRow>("Id", idComp));
 		headerButtonList.add(new SortButton<ElementRow>("Device", deviceComp));
@@ -185,11 +192,10 @@ public class InspectorTable extends JPanel {
 		headerButtonList.add(new SortButton<ElementRow>("Priority", priorityComp));
 		headerButtonList.add(new SortButton<ElementRow>("Activ", activeComp));
 	}
-	
-	
+
 	private void addHeader() {
 		this.add(selectAllCheckBox);
-		for(SortButton<ElementRow> button : headerButtonList) {
+		for (SortButton<ElementRow> button : headerButtonList) {
 			this.add(button);
 		}
 	}
@@ -220,7 +226,7 @@ public class InspectorTable extends JPanel {
 			updateElementSelection();
 		});
 	}
-	
+
 	private void initButtons() {
 		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
 		buttonPanel.add(Box.createRigidArea(new Dimension(2, 0)));
@@ -313,8 +319,8 @@ public class InspectorTable extends JPanel {
 			int numberOfRows = rowPool.getBorrowedCount();
 			this.removeAll();
 			addHeader();
-			rowPool.getBorrowedStream().sorted(actual_comp).skip(actualPage * maxDisplayedRowsNumber).limit(maxDisplayedRowsNumber)
-					.takeWhile(row -> !abortThread).forEach(row -> {
+			rowPool.getBorrowedStream().sorted(actual_comp).skip(actualPage * maxDisplayedRowsNumber)
+					.limit(maxDisplayedRowsNumber).takeWhile(row -> !abortThread).forEach(row -> {
 						row.addContainerToInspector();
 					});
 			if (numberOfRows > maxDisplayedRowsNumber) {
@@ -367,8 +373,8 @@ 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 -> extractElements(((GroupNode) obj).getNodes()));
+		Stream<HolonElement> recursiveLayer = toInspect.stream().filter(object -> object instanceof GroupNode).flatMap(
+				obj -> ((GroupNode) obj).getAllHolonObjectsRecursive().flatMap(hO -> hO.getElements().stream()));
 		Stream<HolonElement> thisLayer = toInspect.stream().filter(obj -> obj instanceof HolonObject).flatMap(obj -> {
 			HolonObject ho = (HolonObject) obj;
 			return ho.getElements().stream();
@@ -530,7 +536,8 @@ public class InspectorTable extends JPanel {
 		@SuppressWarnings("unchecked")
 		private void changeStateOnClick() {
 			setState((this.state == SortState.Ascending) ? SortState.Descending : SortState.Ascending);
-			headerButtonList.stream().filter(button -> (button !=this)).forEach(button -> button.setState(SortState.None));
+			headerButtonList.stream().filter(button -> (button != this))
+					.forEach(button -> button.setState(SortState.None));
 			actual_comp = (Comparator<ElementRow>) getComp();
 			updateInspectorUi();
 		}
@@ -554,14 +561,15 @@ public class InspectorTable extends JPanel {
 				break;
 			}
 		}
-		public Comparator<T> getComp(){
-			switch(state){
+
+		public Comparator<T> getComp() {
+			switch (state) {
 			case Descending:
-				return comp.reversed();	
+				return comp.reversed();
 			case Ascending:
 			case None:
 			default:
-				return comp;				
+				return comp;
 			}
 		}
 	}

+ 3 - 23
src/holeg/ui/view/main/GUI.java

@@ -28,6 +28,7 @@ import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.stream.Collectors;
 
 import javax.swing.AbstractAction;
 import javax.swing.ActionMap;
@@ -82,7 +83,6 @@ import holeg.ui.view.canvas.GroupNodeCanvas;
 import holeg.ui.view.component.ButtonTabComponent;
 import holeg.ui.view.dialog.AboutUsPopUp;
 import holeg.ui.view.dialog.AddObjectPopUp;
-import holeg.ui.view.dialog.BackgroundPopUp;
 import holeg.ui.view.dialog.CanvasResizePopUp;
 import holeg.ui.view.dialog.CreateNewDialog;
 import holeg.ui.view.dialog.EditEdgesPopUp;
@@ -146,7 +146,6 @@ public class GUI {
 	private final JMenuItem mntmNew = new JMenuItem("New");
 	private final JMenuItem mntmSave = new JMenuItem("Save");
 	private final JMenuItem mntmCanvasSize = new JMenuItem("Set View Size");
-	private final JMenuItem mntmBackground = new JMenuItem("Set Background Image");
 	private final JSplitPane splitPane = new JSplitPane();
 	private final JSplitPane splitPane1 = new JSplitPane();
 	// the tabbed canvas containing the different sub-net tabs of the grid (Main
@@ -375,7 +374,7 @@ public class GUI {
 				Component canvasOrUpperNodeCanvas = scrollPane.getViewport().getComponent(0);
 
 				if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas groupNodeCanvas) {
-					controller.addSelectedObjects(groupNodeCanvas.getGroupNode().getNodes());
+					controller.addSelectedObjects(groupNodeCanvas.getGroupNode().getObjectsInThisLayer().collect(Collectors.toSet()));
 					groupNodeCanvas.repaint();
 					// or Canvas?
 				} else if (canvasOrUpperNodeCanvas instanceof Canvas) {
@@ -407,7 +406,7 @@ public class GUI {
 
 				if (canvasOrUpperNodeCanvas instanceof GroupNodeCanvas groupNodeCanvas) {
 					for (AbstractCanvasObject cps : model.getSelectedObjects()) {
-						if (groupNodeCanvas.getGroupNode().getNodes().contains(cps)) {
+						if (groupNodeCanvas.getGroupNode().getObjectsInThisLayer().anyMatch(object -> object == cps)) {
 							controller.delObjUpperNode(cps, groupNodeCanvas.getGroupNode());
 							unc.setToolTip(false);
 
@@ -692,25 +691,6 @@ public class GUI {
 		});
 		initWindowMenu();
 
-		mnNewMenuView.add(mntmBackground);
-
-		mntmBackground.addActionListener(actionEvent -> {
-			tabTemp = tabbedPaneOriginal;
-			JScrollPane scrollPane = getScrollPaneFromTabbedPane();
-
-			if (scrollPane.getViewport().getComponent(0) instanceof Canvas) {
-				BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, canvas, null, holegJFrame);
-				backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-				backgroundDialog.setVisible(true);
-			} else if (scrollPane.getViewport().getComponent(0) instanceof GroupNodeCanvas groupNodeCanvas) {
-				BackgroundPopUp backgroundDialog = new BackgroundPopUp(model, controller, null,
-						groupNodeCanvas.getGroupNode(), holegJFrame);
-				backgroundDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-				backgroundDialog.setVisible(true);
-				groupNodeCanvas.repaint();
-			}
-		});
-
 		/**
 		 * add Help Menu and its items
 		 */

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

@@ -22,12 +22,12 @@ import java.util.logging.Logger;
  */
 public class Main {
 	private static final LogManager logManager = LogManager.getLogManager();
-    private static final Logger LOGGER = Logger.getLogger(Main.class.getName());
+    private static final Logger log = Logger.getLogger(Main.class.getName());
     static{
         try {
             logManager.readConfiguration(new FileInputStream("./config/log.properties"));
         } catch (IOException exception) {
-            LOGGER.log(Level.SEVERE, "Error in loading configuration",exception);
+            log.log(Level.SEVERE, "Error in loading configuration",exception);
         }
     }
 	/**

+ 10 - 16
src/holeg/ui/view/window/FlexWindow.java

@@ -406,13 +406,15 @@ public class FlexWindow extends JFrame {
 
 
 	private void expandTreeUpperNode(GroupNode groupNode, DefaultMutableTreeNode root) {
-		for(AbstractCanvasObject aCps: groupNode.getNodes()) {
-			DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(aCps.getName() + " ID:" + aCps.getId());
-			if(aCps instanceof HolonObject hO) expandTreeHolonObject(hO, newObjectChild);
-			if(aCps instanceof GroupNode groupnode)expandTreeUpperNode(groupnode, newObjectChild);
+		groupNode.getHolonObjects().forEach(object -> {
+			DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(object.getName() + " ID:" + object.getId());
 			root.add(newObjectChild);
-		}
-		
+		});
+		groupNode.getGroupNodes().forEach(groupnode -> {
+			DefaultMutableTreeNode newObjectChild = new DefaultMutableTreeNode(groupnode.getName() + " ID:" + groupnode.getId());
+			expandTreeUpperNode(groupnode, newObjectChild);
+			root.add(newObjectChild);
+		});
 	}
 
 
@@ -437,7 +439,7 @@ public class FlexWindow extends JFrame {
 	
 	private void createDeleteDialog() {
 		
-		List<HolonObject> list= createListOfHolonObjects(model.getObjectsOnCanvas());
+		List<HolonObject> list= model.getAllHolonObjectsOnCanvas();
 		
 		//String test = list.stream().map(Object::toString).collect(Collectors.joining(","));
 		Object[] allFlexes = list.stream().flatMap(hObject -> hObject.getElements().stream()).flatMap(hElement -> hElement.flexList.stream()).toArray(size -> new Flexibility[size]);
@@ -461,14 +463,6 @@ public class FlexWindow extends JFrame {
 	
 	
 	
-	private List<HolonObject> createListOfHolonObjects(List<AbstractCanvasObject> objectsOnCanvas) {
-		List<HolonObject> list = new ArrayList<HolonObject>();
-		for(AbstractCanvasObject aCps :  objectsOnCanvas) {
-			if(aCps instanceof HolonObject hO) list.add(hO);
-			else if (aCps instanceof GroupNode groupnode) list.addAll(createListOfHolonObjects(groupnode.getNodes()));
-		}
-		return list;
-	}
 
 
 
@@ -500,7 +494,7 @@ public class FlexWindow extends JFrame {
 		
 
 		//Erstelle HolonObject AuswahlBox
-		HolonObject[] holonObjects = createListOfHolonObjects(model.getObjectsOnCanvas()).stream().toArray(HolonObject[]::new);
+		HolonObject[] holonObjects = model.getAllHolonObjectsOnCanvas().stream().toArray(HolonObject[]::new);
 
 		DefaultComboBoxModel<HolonObject> comboBoxModel = new DefaultComboBoxModel<HolonObject>( holonObjects );